texlive[71408] Master/texmf-dist: latex2e (2jun24)

commits+karl at tug.org commits+karl at tug.org
Sun Jun 2 22:26:41 CEST 2024


Revision: 71408
          https://tug.org/svn/texlive?view=revision&revision=71408
Author:   karl
Date:     2024-06-02 22:26:39 +0200 (Sun, 02 Jun 2024)
Log Message:
-----------
latex2e (2jun24)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/amsmath/README.md
    trunk/Master/texmf-dist/doc/latex/amsmath/ams-external.txt
    trunk/Master/texmf-dist/doc/latex/amsmath/amsbsy.pdf
    trunk/Master/texmf-dist/doc/latex/amsmath/amscd.pdf
    trunk/Master/texmf-dist/doc/latex/amsmath/amsgen.pdf
    trunk/Master/texmf-dist/doc/latex/amsmath/amsldoc.pdf
    trunk/Master/texmf-dist/doc/latex/amsmath/amsldoc.tex
    trunk/Master/texmf-dist/doc/latex/amsmath/amsmath.pdf
    trunk/Master/texmf-dist/doc/latex/amsmath/amsopn.pdf
    trunk/Master/texmf-dist/doc/latex/amsmath/amstext.pdf
    trunk/Master/texmf-dist/doc/latex/amsmath/amsxtra.pdf
    trunk/Master/texmf-dist/doc/latex/amsmath/changes.txt
    trunk/Master/texmf-dist/doc/latex/amsmath/subeqn.pdf
    trunk/Master/texmf-dist/doc/latex/amsmath/technote.pdf
    trunk/Master/texmf-dist/doc/latex/amsmath/testmath.pdf
    trunk/Master/texmf-dist/doc/latex/base/README.md
    trunk/Master/texmf-dist/doc/latex/base/alltt.pdf
    trunk/Master/texmf-dist/doc/latex/base/cfgguide.pdf
    trunk/Master/texmf-dist/doc/latex/base/changes.txt
    trunk/Master/texmf-dist/doc/latex/base/classes.pdf
    trunk/Master/texmf-dist/doc/latex/base/clsguide-historic.pdf
    trunk/Master/texmf-dist/doc/latex/base/clsguide-historic.tex
    trunk/Master/texmf-dist/doc/latex/base/clsguide.pdf
    trunk/Master/texmf-dist/doc/latex/base/clsguide.tex
    trunk/Master/texmf-dist/doc/latex/base/cmfonts.pdf
    trunk/Master/texmf-dist/doc/latex/base/cyrguide.pdf
    trunk/Master/texmf-dist/doc/latex/base/doc-code.pdf
    trunk/Master/texmf-dist/doc/latex/base/doc.pdf
    trunk/Master/texmf-dist/doc/latex/base/docstrip.pdf
    trunk/Master/texmf-dist/doc/latex/base/encguide.pdf
    trunk/Master/texmf-dist/doc/latex/base/exscale.pdf
    trunk/Master/texmf-dist/doc/latex/base/fix-cm.pdf
    trunk/Master/texmf-dist/doc/latex/base/fntguide.pdf
    trunk/Master/texmf-dist/doc/latex/base/fntguide.tex
    trunk/Master/texmf-dist/doc/latex/base/graphpap.pdf
    trunk/Master/texmf-dist/doc/latex/base/ifthen.pdf
    trunk/Master/texmf-dist/doc/latex/base/inputenc.pdf
    trunk/Master/texmf-dist/doc/latex/base/lamport-manual.pdf
    trunk/Master/texmf-dist/doc/latex/base/latexrelease.pdf
    trunk/Master/texmf-dist/doc/latex/base/latexsym.pdf
    trunk/Master/texmf-dist/doc/latex/base/lb2.err
    trunk/Master/texmf-dist/doc/latex/base/lb2.pdf
    trunk/Master/texmf-dist/doc/latex/base/letter.pdf
    trunk/Master/texmf-dist/doc/latex/base/lgc2.pdf
    trunk/Master/texmf-dist/doc/latex/base/lppl.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-code.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-doc.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltfilehook-code.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltfilehook-doc.pdf
    trunk/Master/texmf-dist/doc/latex/base/lthooks-code.pdf
    trunk/Master/texmf-dist/doc/latex/base/lthooks-doc.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltluatex.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltmarks-code.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltmarks-doc.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews01.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews02.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews03.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews04.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews05.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews06.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews07.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews08.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews09.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews10.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews11.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews12.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews13.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews14.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews15.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews16.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews17.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews18.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews19.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews20.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews21.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews22.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews23.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews24.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews25.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews26.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews27.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews28.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews28.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews29.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews30.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews31.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews31.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews32.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews33.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews34.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews35.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews35.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews36.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews37.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews38.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews38.tex
    trunk/Master/texmf-dist/doc/latex/base/ltpara-code.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltpara-doc.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltproperties-code.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltproperties-doc.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltshipout-code.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltshipout-doc.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltsockets-code.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltsockets-doc.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltx3info.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltxdoc.pdf
    trunk/Master/texmf-dist/doc/latex/base/makeindx.pdf
    trunk/Master/texmf-dist/doc/latex/base/modguide.pdf
    trunk/Master/texmf-dist/doc/latex/base/nfssfont.pdf
    trunk/Master/texmf-dist/doc/latex/base/proc.pdf
    trunk/Master/texmf-dist/doc/latex/base/slides.pdf
    trunk/Master/texmf-dist/doc/latex/base/slifonts.pdf
    trunk/Master/texmf-dist/doc/latex/base/source2e.pdf
    trunk/Master/texmf-dist/doc/latex/base/source2e.tex
    trunk/Master/texmf-dist/doc/latex/base/syntonly.pdf
    trunk/Master/texmf-dist/doc/latex/base/tlc2.pdf
    trunk/Master/texmf-dist/doc/latex/base/tlc3.err
    trunk/Master/texmf-dist/doc/latex/base/tlc3.pdf
    trunk/Master/texmf-dist/doc/latex/base/tulm.pdf
    trunk/Master/texmf-dist/doc/latex/base/usrguide-historic.pdf
    trunk/Master/texmf-dist/doc/latex/base/usrguide-historic.tex
    trunk/Master/texmf-dist/doc/latex/base/usrguide.pdf
    trunk/Master/texmf-dist/doc/latex/base/usrguide.tex
    trunk/Master/texmf-dist/doc/latex/base/utf8ienc.pdf
    trunk/Master/texmf-dist/doc/latex/base/webcomp.err
    trunk/Master/texmf-dist/doc/latex/base/webcomp.pdf
    trunk/Master/texmf-dist/doc/latex/cyrillic/README.md
    trunk/Master/texmf-dist/doc/latex/cyrillic/changes.txt
    trunk/Master/texmf-dist/doc/latex/cyrillic/cyinpenc.pdf
    trunk/Master/texmf-dist/doc/latex/cyrillic/cyoutenc.pdf
    trunk/Master/texmf-dist/doc/latex/cyrillic/lcy.pdf
    trunk/Master/texmf-dist/doc/latex/cyrillic/lcycmlh.pdf
    trunk/Master/texmf-dist/doc/latex/cyrillic/ot2.pdf
    trunk/Master/texmf-dist/doc/latex/cyrillic/ot2cmams.pdf
    trunk/Master/texmf-dist/doc/latex/cyrillic/ot2cmlh.pdf
    trunk/Master/texmf-dist/doc/latex/cyrillic/t2lhfnt.pdf
    trunk/Master/texmf-dist/doc/latex/firstaid/changes.txt
    trunk/Master/texmf-dist/doc/latex/firstaid/latex2e-first-aid-for-external-files.pdf
    trunk/Master/texmf-dist/doc/latex/graphics/README.md
    trunk/Master/texmf-dist/doc/latex/graphics/changes.txt
    trunk/Master/texmf-dist/doc/latex/graphics/color.pdf
    trunk/Master/texmf-dist/doc/latex/graphics/drivers.pdf
    trunk/Master/texmf-dist/doc/latex/graphics/epsfig.pdf
    trunk/Master/texmf-dist/doc/latex/graphics/graphics.pdf
    trunk/Master/texmf-dist/doc/latex/graphics/graphicx.pdf
    trunk/Master/texmf-dist/doc/latex/graphics/grfguide.pdf
    trunk/Master/texmf-dist/doc/latex/graphics/grfguide.tex
    trunk/Master/texmf-dist/doc/latex/graphics/keyval.pdf
    trunk/Master/texmf-dist/doc/latex/graphics/lscape.pdf
    trunk/Master/texmf-dist/doc/latex/graphics/mathcolor.pdf
    trunk/Master/texmf-dist/doc/latex/graphics/rotating.pdf
    trunk/Master/texmf-dist/doc/latex/graphics/rotex.pdf
    trunk/Master/texmf-dist/doc/latex/graphics/trig.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/README.md
    trunk/Master/texmf-dist/doc/latex/latex-lab/blocks-code.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/blocks-doc.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/changes.txt
    trunk/Master/texmf-dist/doc/latex/latex-lab/documentmetadata-support-code.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/documentmetadata-support-doc.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-amsmath.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-bib.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-block.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-firstaid.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-float.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-footnotes.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-graphic.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-math.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-mathpkg.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-mathtools.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-minipage.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-namespace.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-new-or-1.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-new-or-2.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-sec.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-table.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-testphase.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-text.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-toc-hyperref-changes.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-toc-kernel-changes.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-toc.pdf
    trunk/Master/texmf-dist/doc/latex/tools/README.md
    trunk/Master/texmf-dist/doc/latex/tools/afterpage.pdf
    trunk/Master/texmf-dist/doc/latex/tools/array.pdf
    trunk/Master/texmf-dist/doc/latex/tools/bm.pdf
    trunk/Master/texmf-dist/doc/latex/tools/calc.pdf
    trunk/Master/texmf-dist/doc/latex/tools/changes.txt
    trunk/Master/texmf-dist/doc/latex/tools/dcolumn.pdf
    trunk/Master/texmf-dist/doc/latex/tools/delarray.pdf
    trunk/Master/texmf-dist/doc/latex/tools/enumerate.pdf
    trunk/Master/texmf-dist/doc/latex/tools/fileerr.pdf
    trunk/Master/texmf-dist/doc/latex/tools/fontsmpl.pdf
    trunk/Master/texmf-dist/doc/latex/tools/ftnright.pdf
    trunk/Master/texmf-dist/doc/latex/tools/hhline.pdf
    trunk/Master/texmf-dist/doc/latex/tools/indentfirst.pdf
    trunk/Master/texmf-dist/doc/latex/tools/layout.pdf
    trunk/Master/texmf-dist/doc/latex/tools/longtable.pdf
    trunk/Master/texmf-dist/doc/latex/tools/multicol.pdf
    trunk/Master/texmf-dist/doc/latex/tools/rawfonts.pdf
    trunk/Master/texmf-dist/doc/latex/tools/shellesc.pdf
    trunk/Master/texmf-dist/doc/latex/tools/showkeys.pdf
    trunk/Master/texmf-dist/doc/latex/tools/somedefs.pdf
    trunk/Master/texmf-dist/doc/latex/tools/tabularx.pdf
    trunk/Master/texmf-dist/doc/latex/tools/theorem.pdf
    trunk/Master/texmf-dist/doc/latex/tools/tools-overview.pdf
    trunk/Master/texmf-dist/doc/latex/tools/tools-overview.tex
    trunk/Master/texmf-dist/doc/latex/tools/trace.pdf
    trunk/Master/texmf-dist/doc/latex/tools/varioref.pdf
    trunk/Master/texmf-dist/doc/latex/tools/verbatim.pdf
    trunk/Master/texmf-dist/doc/latex/tools/xr.pdf
    trunk/Master/texmf-dist/doc/latex/tools/xspace.pdf
    trunk/Master/texmf-dist/makeindex/latex/gglo.ist
    trunk/Master/texmf-dist/makeindex/latex/gind.ist
    trunk/Master/texmf-dist/source/latex/amsmath/amsbsy.ins
    trunk/Master/texmf-dist/source/latex/amsmath/amscd.dtx
    trunk/Master/texmf-dist/source/latex/amsmath/amscd.ins
    trunk/Master/texmf-dist/source/latex/amsmath/amsgen.dtx
    trunk/Master/texmf-dist/source/latex/amsmath/amsgen.ins
    trunk/Master/texmf-dist/source/latex/amsmath/amsmath.dtx
    trunk/Master/texmf-dist/source/latex/amsmath/amsmath.ins
    trunk/Master/texmf-dist/source/latex/amsmath/amsopn.dtx
    trunk/Master/texmf-dist/source/latex/amsmath/amsopn.ins
    trunk/Master/texmf-dist/source/latex/amsmath/amstext.dtx
    trunk/Master/texmf-dist/source/latex/amsmath/amstext.ins
    trunk/Master/texmf-dist/source/latex/amsmath/amsxtra.dtx
    trunk/Master/texmf-dist/source/latex/amsmath/amsxtra.ins
    trunk/Master/texmf-dist/source/latex/base/alltt.dtx
    trunk/Master/texmf-dist/source/latex/base/classes.dtx
    trunk/Master/texmf-dist/source/latex/base/doc.dtx
    trunk/Master/texmf-dist/source/latex/base/docstrip.dtx
    trunk/Master/texmf-dist/source/latex/base/fontdef.dtx
    trunk/Master/texmf-dist/source/latex/base/format.ins
    trunk/Master/texmf-dist/source/latex/base/ifthen.dtx
    trunk/Master/texmf-dist/source/latex/base/inputenc.dtx
    trunk/Master/texmf-dist/source/latex/base/latexrelease.ins
    trunk/Master/texmf-dist/source/latex/base/ltboxes.dtx
    trunk/Master/texmf-dist/source/latex/base/ltclass.dtx
    trunk/Master/texmf-dist/source/latex/base/ltcmd.dtx
    trunk/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx
    trunk/Master/texmf-dist/source/latex/base/ltcounts.dtx
    trunk/Master/texmf-dist/source/latex/base/ltdefns.dtx
    trunk/Master/texmf-dist/source/latex/base/ltdirchk.dtx
    trunk/Master/texmf-dist/source/latex/base/ltexpl.dtx
    trunk/Master/texmf-dist/source/latex/base/ltfilehook.dtx
    trunk/Master/texmf-dist/source/latex/base/ltfiles.dtx
    trunk/Master/texmf-dist/source/latex/base/ltfinal.dtx
    trunk/Master/texmf-dist/source/latex/base/ltfloat.dtx
    trunk/Master/texmf-dist/source/latex/base/ltfntcmd.dtx
    trunk/Master/texmf-dist/source/latex/base/ltfssaxes.dtx
    trunk/Master/texmf-dist/source/latex/base/ltfssbas.dtx
    trunk/Master/texmf-dist/source/latex/base/ltfssini.dtx
    trunk/Master/texmf-dist/source/latex/base/ltfsstrc.dtx
    trunk/Master/texmf-dist/source/latex/base/lthooks.dtx
    trunk/Master/texmf-dist/source/latex/base/ltkeys.dtx
    trunk/Master/texmf-dist/source/latex/base/ltluatex.dtx
    trunk/Master/texmf-dist/source/latex/base/ltmarks.dtx
    trunk/Master/texmf-dist/source/latex/base/ltmeta.dtx
    trunk/Master/texmf-dist/source/latex/base/ltmiscen.dtx
    trunk/Master/texmf-dist/source/latex/base/ltoutenc.dtx
    trunk/Master/texmf-dist/source/latex/base/ltoutput.dtx
    trunk/Master/texmf-dist/source/latex/base/ltpara.dtx
    trunk/Master/texmf-dist/source/latex/base/ltplain.dtx
    trunk/Master/texmf-dist/source/latex/base/ltproperties.dtx
    trunk/Master/texmf-dist/source/latex/base/ltsect.dtx
    trunk/Master/texmf-dist/source/latex/base/ltshipout.dtx
    trunk/Master/texmf-dist/source/latex/base/ltsockets.dtx
    trunk/Master/texmf-dist/source/latex/base/ltspace.dtx
    trunk/Master/texmf-dist/source/latex/base/lttextcomp.dtx
    trunk/Master/texmf-dist/source/latex/base/ltthm.dtx
    trunk/Master/texmf-dist/source/latex/base/ltvers.dtx
    trunk/Master/texmf-dist/source/latex/base/ltxdoc.dtx
    trunk/Master/texmf-dist/source/latex/base/nfssfont.dtx
    trunk/Master/texmf-dist/source/latex/base/slifonts.fdd
    trunk/Master/texmf-dist/source/latex/base/syntonly.dtx
    trunk/Master/texmf-dist/source/latex/base/utf8ienc.dtx
    trunk/Master/texmf-dist/source/latex/cyrillic/cyoutenc.dtx
    trunk/Master/texmf-dist/source/latex/firstaid/firstaid.ins
    trunk/Master/texmf-dist/source/latex/firstaid/latex2e-first-aid-for-external-files.dtx
    trunk/Master/texmf-dist/source/latex/graphics/color.dtx
    trunk/Master/texmf-dist/source/latex/graphics/drivers.dtx
    trunk/Master/texmf-dist/source/latex/graphics/epsfig.dtx
    trunk/Master/texmf-dist/source/latex/graphics/graphics.dtx
    trunk/Master/texmf-dist/source/latex/graphics/graphicx.dtx
    trunk/Master/texmf-dist/source/latex/graphics/keyval.dtx
    trunk/Master/texmf-dist/source/latex/graphics/lscape.dtx
    trunk/Master/texmf-dist/source/latex/graphics/rotating.dtx
    trunk/Master/texmf-dist/source/latex/graphics/trig.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/documentmetadata-support.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-amsmath.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-bib.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-block.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-firstaid.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-float.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-footnotes.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-graphic.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-math.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathpkg.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathtools.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-minipage.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-namespace.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-1.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-2.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-sec.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-table.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-testphase.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-text.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-hyperref-changes.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-kernel-changes.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab.ins
    trunk/Master/texmf-dist/source/latex/tools/afterpage.dtx
    trunk/Master/texmf-dist/source/latex/tools/afterpage.ins
    trunk/Master/texmf-dist/source/latex/tools/array.dtx
    trunk/Master/texmf-dist/source/latex/tools/bm.dtx
    trunk/Master/texmf-dist/source/latex/tools/bm.ins
    trunk/Master/texmf-dist/source/latex/tools/calc.dtx
    trunk/Master/texmf-dist/source/latex/tools/dcolumn.dtx
    trunk/Master/texmf-dist/source/latex/tools/delarray.dtx
    trunk/Master/texmf-dist/source/latex/tools/enumerate.dtx
    trunk/Master/texmf-dist/source/latex/tools/fileerr.dtx
    trunk/Master/texmf-dist/source/latex/tools/fontsmpl.dtx
    trunk/Master/texmf-dist/source/latex/tools/ftnright.dtx
    trunk/Master/texmf-dist/source/latex/tools/hhline.dtx
    trunk/Master/texmf-dist/source/latex/tools/indentfirst.dtx
    trunk/Master/texmf-dist/source/latex/tools/layout.dtx
    trunk/Master/texmf-dist/source/latex/tools/longtable.dtx
    trunk/Master/texmf-dist/source/latex/tools/longtable.ins
    trunk/Master/texmf-dist/source/latex/tools/multicol.dtx
    trunk/Master/texmf-dist/source/latex/tools/multicol.ins
    trunk/Master/texmf-dist/source/latex/tools/rawfonts.dtx
    trunk/Master/texmf-dist/source/latex/tools/shellesc.dtx
    trunk/Master/texmf-dist/source/latex/tools/showkeys.dtx
    trunk/Master/texmf-dist/source/latex/tools/somedefs.dtx
    trunk/Master/texmf-dist/source/latex/tools/tabularx.dtx
    trunk/Master/texmf-dist/source/latex/tools/tabularx.ins
    trunk/Master/texmf-dist/source/latex/tools/theorem.dtx
    trunk/Master/texmf-dist/source/latex/tools/tools.ins
    trunk/Master/texmf-dist/source/latex/tools/trace.dtx
    trunk/Master/texmf-dist/source/latex/tools/varioref.dtx
    trunk/Master/texmf-dist/source/latex/tools/varioref.ins
    trunk/Master/texmf-dist/source/latex/tools/verbatim.dtx
    trunk/Master/texmf-dist/source/latex/tools/xr.dtx
    trunk/Master/texmf-dist/source/latex/tools/xspace.dtx
    trunk/Master/texmf-dist/tex/latex/amsmath/amsbsy.sty
    trunk/Master/texmf-dist/tex/latex/amsmath/amscd.sty
    trunk/Master/texmf-dist/tex/latex/amsmath/amsgen.sty
    trunk/Master/texmf-dist/tex/latex/amsmath/amsmath-2018-12-01.sty
    trunk/Master/texmf-dist/tex/latex/amsmath/amsmath.sty
    trunk/Master/texmf-dist/tex/latex/amsmath/amsopn.sty
    trunk/Master/texmf-dist/tex/latex/amsmath/amstext.sty
    trunk/Master/texmf-dist/tex/latex/amsmath/amsxtra.sty
    trunk/Master/texmf-dist/tex/latex/base/alltt.sty
    trunk/Master/texmf-dist/tex/latex/base/ansinew.def
    trunk/Master/texmf-dist/tex/latex/base/applemac.def
    trunk/Master/texmf-dist/tex/latex/base/article.cls
    trunk/Master/texmf-dist/tex/latex/base/ascii.def
    trunk/Master/texmf-dist/tex/latex/base/atbegshi-ltx.sty
    trunk/Master/texmf-dist/tex/latex/base/atveryend-ltx.sty
    trunk/Master/texmf-dist/tex/latex/base/bk10.clo
    trunk/Master/texmf-dist/tex/latex/base/bk11.clo
    trunk/Master/texmf-dist/tex/latex/base/bk12.clo
    trunk/Master/texmf-dist/tex/latex/base/book.cls
    trunk/Master/texmf-dist/tex/latex/base/cp1250.def
    trunk/Master/texmf-dist/tex/latex/base/cp1252.def
    trunk/Master/texmf-dist/tex/latex/base/cp1257.def
    trunk/Master/texmf-dist/tex/latex/base/cp437.def
    trunk/Master/texmf-dist/tex/latex/base/cp437de.def
    trunk/Master/texmf-dist/tex/latex/base/cp850.def
    trunk/Master/texmf-dist/tex/latex/base/cp852.def
    trunk/Master/texmf-dist/tex/latex/base/cp858.def
    trunk/Master/texmf-dist/tex/latex/base/cp865.def
    trunk/Master/texmf-dist/tex/latex/base/decmulti.def
    trunk/Master/texmf-dist/tex/latex/base/doc.sty
    trunk/Master/texmf-dist/tex/latex/base/docstrip.tex
    trunk/Master/texmf-dist/tex/latex/base/fontenc.sty
    trunk/Master/texmf-dist/tex/latex/base/fontmath.cfg
    trunk/Master/texmf-dist/tex/latex/base/fontmath.ltx
    trunk/Master/texmf-dist/tex/latex/base/fonttext.cfg
    trunk/Master/texmf-dist/tex/latex/base/fonttext.ltx
    trunk/Master/texmf-dist/tex/latex/base/ifthen.sty
    trunk/Master/texmf-dist/tex/latex/base/inputenc.sty
    trunk/Master/texmf-dist/tex/latex/base/latex.ltx
    trunk/Master/texmf-dist/tex/latex/base/latexrelease.sty
    trunk/Master/texmf-dist/tex/latex/base/latin1.def
    trunk/Master/texmf-dist/tex/latex/base/latin10.def
    trunk/Master/texmf-dist/tex/latex/base/latin2.def
    trunk/Master/texmf-dist/tex/latex/base/latin3.def
    trunk/Master/texmf-dist/tex/latex/base/latin4.def
    trunk/Master/texmf-dist/tex/latex/base/latin5.def
    trunk/Master/texmf-dist/tex/latex/base/latin9.def
    trunk/Master/texmf-dist/tex/latex/base/ltluatex.tex
    trunk/Master/texmf-dist/tex/latex/base/ltxdoc.cls
    trunk/Master/texmf-dist/tex/latex/base/macce.def
    trunk/Master/texmf-dist/tex/latex/base/next.def
    trunk/Master/texmf-dist/tex/latex/base/nfssfont.tex
    trunk/Master/texmf-dist/tex/latex/base/omllcmm.fd
    trunk/Master/texmf-dist/tex/latex/base/omslcmsy.fd
    trunk/Master/texmf-dist/tex/latex/base/omxlcmex.fd
    trunk/Master/texmf-dist/tex/latex/base/ot1lcmss.fd
    trunk/Master/texmf-dist/tex/latex/base/ot1lcmtt.fd
    trunk/Master/texmf-dist/tex/latex/base/preload.cfg
    trunk/Master/texmf-dist/tex/latex/base/report.cls
    trunk/Master/texmf-dist/tex/latex/base/sfonts.def
    trunk/Master/texmf-dist/tex/latex/base/shortvrb.sty
    trunk/Master/texmf-dist/tex/latex/base/size10.clo
    trunk/Master/texmf-dist/tex/latex/base/size11.clo
    trunk/Master/texmf-dist/tex/latex/base/size12.clo
    trunk/Master/texmf-dist/tex/latex/base/source2edoc.cls
    trunk/Master/texmf-dist/tex/latex/base/structuredlog.sty
    trunk/Master/texmf-dist/tex/latex/base/syntonly.sty
    trunk/Master/texmf-dist/tex/latex/base/t1lcmss.fd
    trunk/Master/texmf-dist/tex/latex/base/t1lcmtt.fd
    trunk/Master/texmf-dist/tex/latex/base/textcomp-2018-08-11.sty
    trunk/Master/texmf-dist/tex/latex/base/textcomp.sty
    trunk/Master/texmf-dist/tex/latex/base/ullasy.fd
    trunk/Master/texmf-dist/tex/latex/cyrillic/t2aenc.def
    trunk/Master/texmf-dist/tex/latex/cyrillic/t2benc.def
    trunk/Master/texmf-dist/tex/latex/cyrillic/t2cenc.def
    trunk/Master/texmf-dist/tex/latex/cyrillic/x2enc.def
    trunk/Master/texmf-dist/tex/latex/firstaid/filehook-ltx.sty
    trunk/Master/texmf-dist/tex/latex/firstaid/latex2e-first-aid-for-external-files.ltx
    trunk/Master/texmf-dist/tex/latex/firstaid/underscore-ltx.sty
    trunk/Master/texmf-dist/tex/latex/graphics/color.sty
    trunk/Master/texmf-dist/tex/latex/graphics/dvipdf.def
    trunk/Master/texmf-dist/tex/latex/graphics/dvipsnam.def
    trunk/Master/texmf-dist/tex/latex/graphics/dvipsone.def
    trunk/Master/texmf-dist/tex/latex/graphics/dviwin.def
    trunk/Master/texmf-dist/tex/latex/graphics/emtex.def
    trunk/Master/texmf-dist/tex/latex/graphics/epsfig.sty
    trunk/Master/texmf-dist/tex/latex/graphics/graphics-2017-06-25.sty
    trunk/Master/texmf-dist/tex/latex/graphics/graphics.sty
    trunk/Master/texmf-dist/tex/latex/graphics/graphicx.sty
    trunk/Master/texmf-dist/tex/latex/graphics/keyval.sty
    trunk/Master/texmf-dist/tex/latex/graphics/lscape.sty
    trunk/Master/texmf-dist/tex/latex/graphics/pctex32.def
    trunk/Master/texmf-dist/tex/latex/graphics/pctexhp.def
    trunk/Master/texmf-dist/tex/latex/graphics/pctexps.def
    trunk/Master/texmf-dist/tex/latex/graphics/pctexwin.def
    trunk/Master/texmf-dist/tex/latex/graphics/rotating.sty
    trunk/Master/texmf-dist/tex/latex/graphics/tcidvi.def
    trunk/Master/texmf-dist/tex/latex/graphics/trig.sty
    trunk/Master/texmf-dist/tex/latex/graphics/truetex.def
    trunk/Master/texmf-dist/tex/latex/latex-lab/bib-latex-lab-testphase.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/block-latex-lab-testphase.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/documentmetadata-support.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/firstaid-latex-lab-testphase.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/float-latex-lab-testphase.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/graphic-latex-lab-testphase.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-amsmath.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-footmisc.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-footnotes.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-kernel-changes.sty
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-math.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-mathpkg.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-mathtools.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-testphase-bib.sty
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-testphase-block.sty
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-testphase-firstaid.sty
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-testphase-float.sty
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-testphase-graphic.sty
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-testphase-minipage.sty
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-testphase-new-or-1.sty
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-testphase-sec.sty
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-testphase-table.sty
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-testphase-text.sty
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-testphase-toc.sty
    trunk/Master/texmf-dist/tex/latex/latex-lab/minipage-latex-lab-testphase.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/new-or-1-latex-lab-testphase.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/phase-I-latex-lab-testphase.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/phase-II-latex-lab-testphase.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/phase-III-latex-lab-testphase.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/sec-latex-lab-testphase.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/table-latex-lab-testphase.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/tagpdf-latex-lab-testphase.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/tagpdf-ns-latex-lab.def
    trunk/Master/texmf-dist/tex/latex/latex-lab/text-latex-lab-testphase.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/toc-latex-lab-testphase.ltx
    trunk/Master/texmf-dist/tex/latex/tools/.tex
    trunk/Master/texmf-dist/tex/latex/tools/afterpage.sty
    trunk/Master/texmf-dist/tex/latex/tools/array-2016-10-06.sty
    trunk/Master/texmf-dist/tex/latex/tools/array-2020-02-10.sty
    trunk/Master/texmf-dist/tex/latex/tools/array.sty
    trunk/Master/texmf-dist/tex/latex/tools/bm.sty
    trunk/Master/texmf-dist/tex/latex/tools/calc.sty
    trunk/Master/texmf-dist/tex/latex/tools/dcolumn.sty
    trunk/Master/texmf-dist/tex/latex/tools/delarray.sty
    trunk/Master/texmf-dist/tex/latex/tools/e.tex
    trunk/Master/texmf-dist/tex/latex/tools/enumerate.sty
    trunk/Master/texmf-dist/tex/latex/tools/fontsmpl.sty
    trunk/Master/texmf-dist/tex/latex/tools/fontsmpl.tex
    trunk/Master/texmf-dist/tex/latex/tools/ftnright.sty
    trunk/Master/texmf-dist/tex/latex/tools/h.tex
    trunk/Master/texmf-dist/tex/latex/tools/hhline.sty
    trunk/Master/texmf-dist/tex/latex/tools/indentfirst.sty
    trunk/Master/texmf-dist/tex/latex/tools/layout.sty
    trunk/Master/texmf-dist/tex/latex/tools/longtable-2020-01-07.sty
    trunk/Master/texmf-dist/tex/latex/tools/longtable.sty
    trunk/Master/texmf-dist/tex/latex/tools/multicol-2017-04-11.sty
    trunk/Master/texmf-dist/tex/latex/tools/multicol-2019-10-01.sty
    trunk/Master/texmf-dist/tex/latex/tools/multicol.sty
    trunk/Master/texmf-dist/tex/latex/tools/q.tex
    trunk/Master/texmf-dist/tex/latex/tools/r.tex
    trunk/Master/texmf-dist/tex/latex/tools/rawfonts.sty
    trunk/Master/texmf-dist/tex/latex/tools/s.tex
    trunk/Master/texmf-dist/tex/latex/tools/shellesc.sty
    trunk/Master/texmf-dist/tex/latex/tools/showkeys-2014-10-28.sty
    trunk/Master/texmf-dist/tex/latex/tools/showkeys.sty
    trunk/Master/texmf-dist/tex/latex/tools/somedefs.sty
    trunk/Master/texmf-dist/tex/latex/tools/tabularx.sty
    trunk/Master/texmf-dist/tex/latex/tools/thb.sty
    trunk/Master/texmf-dist/tex/latex/tools/thc.sty
    trunk/Master/texmf-dist/tex/latex/tools/thcb.sty
    trunk/Master/texmf-dist/tex/latex/tools/theorem.sty
    trunk/Master/texmf-dist/tex/latex/tools/thm.sty
    trunk/Master/texmf-dist/tex/latex/tools/thmb.sty
    trunk/Master/texmf-dist/tex/latex/tools/thp.sty
    trunk/Master/texmf-dist/tex/latex/tools/trace.sty
    trunk/Master/texmf-dist/tex/latex/tools/varioref-2016-02-16.sty
    trunk/Master/texmf-dist/tex/latex/tools/varioref.sty
    trunk/Master/texmf-dist/tex/latex/tools/verbatim.sty
    trunk/Master/texmf-dist/tex/latex/tools/verbtest.tex
    trunk/Master/texmf-dist/tex/latex/tools/x.tex
    trunk/Master/texmf-dist/tex/latex/tools/xr.sty
    trunk/Master/texmf-dist/tex/latex/tools/xspace.sty

Added Paths:
-----------
    trunk/Master/texmf-dist/doc/latex/base/ltnews39.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews39.tex
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-marginpar.pdf
    trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-title.pdf
    trunk/Master/texmf-dist/doc/latex/tools/l3sys-query.pdf
    trunk/Master/texmf-dist/source/latex/base/lttagging.dtx
    trunk/Master/texmf-dist/source/latex/base/lttemplates.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-marginpar.dtx
    trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-title.dtx
    trunk/Master/texmf-dist/source/latex/tools/l3sys-query.dtx
    trunk/Master/texmf-dist/source/latex/tools/l3sys-query.ins
    trunk/Master/texmf-dist/tex/latex/base/checkencodingsubset.tex
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-testphase-marginpar.sty
    trunk/Master/texmf-dist/tex/latex/latex-lab/latex-lab-testphase-title.sty
    trunk/Master/texmf-dist/tex/latex/latex-lab/marginpar-latex-lab-testphase.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/tabular-latex-lab-testphase.ltx
    trunk/Master/texmf-dist/tex/latex/latex-lab/title-latex-lab-testphase.ltx
    trunk/Master/texmf-dist/tex/latex/tools/array-2023-11-01.sty
    trunk/Master/texmf-dist/tex/latex/tools/l3sys-query.sty
    trunk/Master/texmf-dist/tex/latex/tools/xr-2023-07-04.sty

Modified: trunk/Master/texmf-dist/doc/latex/amsmath/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/amsmath/README.md	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/amsmath/README.md	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,7 +1,7 @@
 The amsmath bundle for LaTeX
 ============================
 
-Release 2023-11-01
+Release 2024-06-01 patch level 0
 
 Overview
 --------
@@ -77,5 +77,5 @@
 -----
 
 <p>Copyright (C) 2001-2004, 2007, 2008, 2010, 2011, 2013 American Mathematical Society. <br />
-<p>Copyright (C) 2016-2023 The LaTeX Project and American Mathematical Society. <br />
+<p>Copyright (C) 2016-2024 The LaTeX Project and American Mathematical Society. <br />
 

Modified: trunk/Master/texmf-dist/doc/latex/amsmath/ams-external.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/amsmath/ams-external.txt	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/amsmath/ams-external.txt	2024-06-02 20:26:39 UTC (rev 71408)
@@ -60,7 +60,6 @@
 \Rightarrow
 \Tilde
 \Umathaccent
-\Umathcar
 \Umathchar
 \Umathcharnumdef
 \Umathcode

Modified: trunk/Master/texmf-dist/doc/latex/amsmath/amsbsy.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/amsmath/amscd.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/amsmath/amsgen.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/amsmath/amsldoc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/amsmath/amsldoc.tex
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/amsmath/amsmath.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/amsmath/amsopn.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/amsmath/amstext.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/amsmath/amsxtra.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/amsmath/changes.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/amsmath/changes.txt	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/amsmath/changes.txt	2024-06-02 20:26:39 UTC (rev 71408)
@@ -6,6 +6,22 @@
 # 2023-11-01 Release
 #########################
 
+2024-05-23  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* amsmath.dtx:
+	Do not error with "suspicous date" when rolling back to
+	early years of LaTeX2e (gh/1336)
+
+2024-03-11  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* amsmath.dtx (subsection{The \env{gather} environment}):
+	Reset \lineht@ to avoid that this is incorrectly picked
+        up by a following environment, such as align. (gh/1289)
+
+#########################
+# 2023-11-01 Release
+#########################
+
 2023-08-24  David Carlisle  <David.Carlisle at latex-project.org>
 
 	* testmath.tex: remove spaces before ~,

Modified: trunk/Master/texmf-dist/doc/latex/amsmath/subeqn.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/amsmath/technote.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/amsmath/testmath.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/README.md	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/base/README.md	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,7 +1,7 @@
 The LaTeX kernel
 ================
 
-Release 2023-11-01 patch level 1
+Release 2024-06-01 patch level 0
 
 Overview
 --------

Modified: trunk/Master/texmf-dist/doc/latex/base/alltt.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/cfgguide.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/changes.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/changes.txt	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/base/changes.txt	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,10 +1,10 @@
-================================================================================ 
-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.
+================================================================================
 
 ================================================================================
 All changes above are only part of the development branch for the next release.
@@ -11,6 +11,219 @@
 ================================================================================
 
 #########################
+# 2024-06-01 Release
+#########################
+
+2024-05-31  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltmarks.dtx (subsection{Allocating new mark classes}):
+	Initialize all marks with an id, use 0 when a new class is made (gh/1359)
+	(subsection{Placing and retrieving marks}):
+	Remove the id when returning the mark value (gh/1359)
+
+2024-05-30  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltmarks.dtx (subsection{Placing and retrieving marks}):
+	Use sequence marker to make all marks unique on nearby
+	regions (gh/1359)
+
+2024-05-30  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltmarks.dtx (subsection{Core \LaTeXe{} integration}):
+	Correct logic for first mark in page region if first column contains
+	no marks (gh/1359)
+
+2024-05-16  Yukai Chou  <muzimuzhi at gmail.com>
+
+	* ltmarks.dtx, ltmeta.dtx, ltpara.dtx:
+	Drop temp fixing for footnotes in function and variable envs.
+	Supported by l3doc since l3kernel 2023-10-10 (latex3 gh/1266)
+
+2024-04-26  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* doc.dtx:
+	Do not error with "suspicous date" when rolling back to
+	early years of LaTeX2e (gh/1336)
+
+2024-04-24  Yukai Chou  <muzimuzhi at gmail.com>
+
+* lttextcomp.dtx
+	Load the 2018 version when rolling back prior to 2018-08-11 (gh/1333)
+	Clean up \providecommand lines
+
+2024-04-22  Yukai Chou  <muzimuzhi at gmail.com>
+
+	* lttextcomp.dtx (section{The \texttt{textcomp} package})
+	Drop default package option "info" which changes kernel info to
+	package info (gh/1333)
+
+2024-04-19  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltboxes.dtx (section{\LaTeX\ Box commands}):
+	Use a \hrule strut not a \vrule if already in vertical mode
+	(bug seen first with footmisc/14)
+
+2024-04-17  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltproperties.dtx:
+	Renamed \IfLabelExistTF to \IfLabelExistsTF
+	Renamed \IfPropertyExistTF to \IfPropertyExistsTF
+	Provided T and F variants for both conditionals (gh/1262)
+
+2024-04-17 Joseph Wright  <Joseph.Wright at latex-project.org>
+	* ltexpl.dtx, ltdefns.dtx
+	Rename \@expl at cs@argument at spec@@N to \@expl at cs@parameter at spec@@N (gh/1014)
+	* ltexpl.dtx, ltcmd.dtx, ltcmdhooks.dtx
+	Use \cs_parameter_spec:N in place of \cs_argument_spec:N (gh/1014)
+
+2024-04-17 Joseph Wright  <Joseph.Wright at latex-project.org>
+	* lttemplates.dtx
+	Use \IfInstanceExistsTF with an 's'
+
+2024-04-15 Joseph Wright  <Joseph.Wright at latex-project.org>
+	* lttemplates.dtx
+	Re-factor internals
+
+2024-04-10  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltclass.dtx (section{Implementation}):
+	Provide \IfFileLoadedTF and variants (gh/1222)
+
+	Provide T and F conditionals not just TF for \IfPackageLoaded...
+	and friends (gh/1262)
+
+2024-03-22  Yukai Chou <muzimuzhi at gmail.com>
+	* ltfilehook.dtx
+	Apply one-step expansion to raw option list, when a package
+	providing key-value options is loaded the second time. The same
+	expansion for first-time loading was requested in gh/580. (gh/1298)
+
+2024-03-21  Joseph Wright  <Joseph.Wright at latex-project.org>
+
+	* ltcmd.dtx
+	Collect \endlinechar as \obeyedline
+	* usrguide.tex
+	Document use of \obeyedline in +v arguments
+
+2024-03-16  David Carlisle  <David.Carlisle at latex-project.org>
+	* ifthen.dtx guard against active <=> (gh/756)
+
+2024-03-15 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* ltthm.dtx: add link targets to begintheorem commands (hyperref/332)
+
+2024-03-13  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+	* ltfilehook.dtx (subsection{Kernel, class, and package interfaces for \LaTeX{}}):
+	Clarify that the commands in this section are meant to be usable
+	by the kernel and in classes or packages (gh/1292)
+
+2024-02-15 Joseph Wright  <Joseph.Wright at latex-project.org>
+	* lttemplates.dtx
+	Re-introduce \IfInstanceExist(TF)
+
+2024-01-30  David Carlisle  <David.Carlisle at 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 at latex-project.org>
+	* lttemplates.dtx
+	New file to replace loading xtemplate
+
+2024-01-30  Jérôme Laurens  <jerome.laurens at u-bourgogn.fr>
+	* lthooks.dtx:
+	Fix rollback to 2020-10-01.
+
+2024-01-29  Frank Mittelbach  <Frank.Mittelbach at 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 at 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 at latex-project.org>
+	* lthooks.dtx:
+	Correct expansion of \@@_print_args:nn argument (gh/1221).
+
+2023-12-30  Frank Mittelbach  <Frank.Mittelbach at 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 at 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 at 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 at latex-project.org>
+	* lttagging.dtx:
+	First version of lttagging module added
+
+2023-12-07 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* ltproperties.dtx: use \protected at write, (gh1200)
+
+2023-12-02  Frank Mittelbach  <Frank.Mittelbach at 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 at 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 at 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 at 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 at 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 at 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)
+
+#########################
 # 2023-11-01 PL1 Release
 #########################
 
@@ -22,9 +235,9 @@
 # 2023-11-01 Release
 #########################
 
-2023-10-15 Ulrike Fischer <Ulrike.Fischer at latex-project.org> 
-	* ltproperties.dtx: 
-	Add support for pagetarget property.  
+2023-10-15 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* ltproperties.dtx:
+	Add support for pagetarget property.
 
 2023-10-26  David Carlisle  <David.Carlisle at latex-project.org>
 	* ltboxes.dtx:
@@ -56,9 +269,9 @@
 	Explain the steps carried out by the replacement algorithm for @@.
 
 2023-09-13 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
-	* ltproperties.dtx: 
+	* ltproperties.dtx:
       Use \protected at edef for expansion in the LaTeX2e commands.
-      
+
 2023-09-13 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
 	* ltproperties.dtx:
 	Expand consistently the label/property names in the LaTeX2e commands.
@@ -143,7 +356,7 @@
 	* ltfiles.dtx
 	Allow for pipes in \input, etc.
 
-2023-06-16  Phelype Oleinik  <Joseph.Wright at latex-project.org>
+2023-06-16  Phelype Oleinik  <phelype.oleinik at latex-project.org>
 
 	* lthooks.dtx, ltcmdhooks.dtx
 	Correct some rollback labels and dates.

Modified: trunk/Master/texmf-dist/doc/latex/base/classes.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/clsguide-historic.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/clsguide-historic.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/clsguide-historic.tex	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/base/clsguide-historic.tex	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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 @@
 |\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 @@
                                       \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.

Modified: trunk/Master/texmf-dist/doc/latex/base/clsguide.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/clsguide.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/clsguide.tex	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/base/clsguide.tex	2024-06-02 20:26:39 UTC (rev 71408)
@@ -33,8 +33,8 @@
 \usepackage[T1]{fontenc}  % needed for \textbackslash in tt
 \usepackage{csquotes}
 
-\title{\LaTeX\ for package and class authors --- current version}
-\author{\copyright~Copyright 2023, \LaTeX\ Project Team.\\
+\title{\LaTeX\ for package and class authors\\current version}
+\author{\copyright~Copyright 2023--2024, \LaTeX\ Project Team.\\
    All rights reserved.%
    \footnote{This file may distributed and/or modified under the
      conditions of the \LaTeX{} Project Public License, either version 1.3c
@@ -42,7 +42,7 @@
     \texttt{clsguide.tex} for full details.}%
 }
 
-\date{2023-10-24}
+\date{2024-05-24}
 
 \NewDocumentCommand\cs{m}{\texttt{\textbackslash\detokenize{#1}}}
 \NewDocumentCommand\marg{m}{\arg{#1}}
@@ -64,7 +64,7 @@
 \section{Introduction}
 
 \LaTeXe{} was released in 1994 and added a number of then-new concepts to
-\LaTeX{}. For package and class authors, these are described in
+\LaTeX{}. For package and class authors, these are described in the document
 \texttt{clsguide-historic}, which has largely remained unchanged. Since then,
 the \LaTeX{} team have worked on a number of ideas, firstly a programming
 language for \LaTeX{} (L3 programming layer) and then a range of tools for
@@ -347,7 +347,7 @@
 |\AtBeginDocument|, a wrapper around the more powerful command |\AddToHook|.
 The \LaTeX{} kernel provides a large number of dedicated hooks (applying in
 a pre-defined location) and generic hooks (applying to arbitrary commands):
-the interface for using these is described in \texttt{lthooks} . There are
+the interface for using these is described in \texttt{lthooks}. There are
 also hooks to apply to files, described in \texttt{ltfilehooks}.
 
 \section{The structure of a class or package}
@@ -891,7 +891,7 @@
 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}
@@ -1104,11 +1104,13 @@
 Suppose that you want to define an environment for displaying text that is
 numbered as an equation. A straightforward way to do this is as follows:
 \begin{verbatim}
-  \newenvironment{texteqn}
-    {\begin{equation}
-       \begin{minipage}{0.9\linewidth}}
-      {\end{minipage}
-     \end{equation}}
+  \newenvironment{texteqn}{%
+    \begin{equation}%
+      \begin{minipage}{0.9\linewidth}%
+  }{%
+      \end{minipage}%
+    \end{equation}%
+  }
 \end{verbatim}
 However, if you have tried this then you will probably have noticed that it
 does not work perfectly when used in the middle of a paragraph because an
@@ -1118,12 +1120,14 @@
 You can avoid this problem using |\ignorespacesafterend|; it should be
 inserted as shown here:
 \begin{verbatim}
-  \newenvironment{texteqn}
-    {\begin{equation}
-       \begin{minipage}{0.9\linewidth}}
-      {\end{minipage}
-     \end{equation}
-     \ignorespacesafterend}
+  \newenvironment{texteqn}{%
+    \begin{equation}%
+      \begin{minipage}{0.9\linewidth}%
+  }{%
+      \end{minipage}%
+    \end{equation}%
+    \ignorespacesafterend
+  }
 \end{verbatim}
 
 This command may also have other uses.
@@ -1216,7 +1220,7 @@
 commands that are expanded. \meta{label} can expand to an arbitrary
 string (as long as it can safely be written to the \texttt{aux}-file)
 but note that the label names of \cs{label} and \cs{RecordProperties}
-share a singe namespace. This means that you get a \texttt{Label `A'
+share a single namespace. This means that you get a \texttt{Label `A'
   multiply defined} warning with the following code:
 \begin{verbatim}
 \label{A}\RecordProperties{A}{abspage}
@@ -1268,7 +1272,7 @@
    the standard \cs{label}/\cs{pageref}.
 
  \item[\texttt{pagenum} (default: \texttt{0}, at shipout)] The current page as arabic number. This is
-   suitable for integer operations and comparisions.
+   suitable for integer operations and comparisons.
 
  \item[\texttt{label} (default: \texttt{??})] The content of \cs{@currentlabel}. This is the value 
      that you get also with the standard \cs{label}/\cs{ref}. 

Modified: trunk/Master/texmf-dist/doc/latex/base/cmfonts.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/cyrguide.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/doc-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/docstrip.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/encguide.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/exscale.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/fix-cm.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/fntguide.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/fntguide.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/fntguide.tex	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/base/fntguide.tex	2024-06-02 20:26:39 UTC (rev 71408)
@@ -42,7 +42,7 @@
 
 \title{\LaTeXe{} font selection}
 
-\author{\copyright~Copyright 1995--2023, \LaTeX\ Project
+\author{\copyright~Copyright 1995--2024, \LaTeX\ Project
   Team.\thanks{Thanks to Arash Esbati for documenting the
     newer NFSS features of 2020}\\
   All rights reserved.%
@@ -52,7 +52,7 @@
    \texttt{fntguide.tex} for full details.}%
 }
 
-\date{October 2023}
+\date{March 2024}
 
 \begin{document}
 
@@ -1997,6 +1997,83 @@
 would use |sb| (semi-bold) when |\rmfamily\bfseries| is requested in
 document.
 
+\subsection{Handling of current and requested font series and shape}
+
+In the original NFSS implementation, the series was a single attribute
+stored in |\f at series| and so one always had to specify both weight and
+width together.  Hence, it was impossible to typeset a paragraph in a
+condensed font and inside have a few words in bold weight (but still
+condensed) without doing this manually by requesting
+|\fontseries{bc}\selectfont|.
+
+\NEWfeature{2020/02/02}
+The new implementation now works differently by looking both at the
+current value of |\f at series| and the requested new series and out of
+that combination selects a resulting series value.  Thus, if the current
+series is |c| and we ask for |b|, we now get |bc|.  This is done by
+consulting a simple lookup table where entries can be added or changed
+with |\DeclareFontSeriesChangeRule|:
+\begin{decl}
+  |\DeclareFontSeriesChangeRule| %
+  \arg{current series} \arg{requested series} \\
+  \leavevmode\hfill    \arg{result} \arg{alternative result}
+\end{decl}
+
+The \m{current series} is the value currently stored in |\f at series|,
+\m{requested series} is the new series requested, \m{result} is the
+combined value if it exists for the given font family, and
+\m{alternative result} is a fallback in case \m{result} doesn't exist.
+The example above now looks like this:
+\begin{verbatim}
+   \DeclareFontSeriesChangeRule{c}{b}{bc}{}
+\end{verbatim}
+which means: switch to the |bc| series if |c| is current and |b| is
+(additionally) requested, and if the current font doesn't have the
+combination, start the normal font substitution, i.e., switch back shape
+to |n| and if this combination doesn't succeed, switch back series to
+|m| as well, ending up with |m/n|.
+
+Another example is:
+\begin{verbatim}
+   \DeclareFontSeriesChangeRule{bc}{sc}{bsc}{bc}
+\end{verbatim}
+which means: if the current series is bold condensed (|bc|) and
+semi-condensed (|sc|) is requested (additionally), try bold
+semi-condensed (|bsc|) if available but stay with bold condensed if not.
+
+A special value is |m| which is used to reset both weight and width.  In
+order to reset only one of them, the special values |?m| (reset width)
+and |m?| (reset weight) are provided, e.g.:
+\begin{verbatim}
+   \DeclareFontSeriesChangeRule{bc}{m?}{c}{}
+\end{verbatim}
+
+The corresponding macro |\DeclareFontShapeChangeRule| is also provided
+for setting database entries for font shapes:
+\begin{decl}
+  |\DeclareFontShapeChangeRule| %
+  \arg{current shape} \arg{requested shape} \\
+  \leavevmode\hfill   \arg{result} \arg{alternative result}
+\end{decl}
+
+An example would be:
+\begin{verbatim}
+   \DeclareFontShapeChangeRule{it}{sc}{scit}{scsl}
+\end{verbatim}
+If italics is the current shape and small caps is requested, switch to
+|scit| (small caps italics) and if that doesn't exist, try |scsl| (small
+caps slanted).
+
+Finally, it is also possible to overrule the entries in the lookup
+tables and forcibly select a series or shape with:
+\begin{decl}
+  |\fontseriesforce| \arg{series} \qquad |\fontshapeforce| \arg{shape}
+\end{decl}
+
+With the example above for the |c| series, issuing |\fontseriesforce{b}|
+means that the series switches to |b| and not to |bc|.  Same applies to
+|\fontshapeforce|.
+
 \subsection{Handling of nested emphasis}
 
 \begin{decl}

Modified: trunk/Master/texmf-dist/doc/latex/base/graphpap.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ifthen.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/inputenc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/lamport-manual.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/latexrelease.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/latexsym.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/lb2.err
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/lb2.err	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/base/lb2.err	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,4 +1,4 @@
-\newcommand\erratafiledate{2014/09/30}
+\newcommand\erratafiledate{2024/01/03}
 
 \def\comando#1{\texttt{\string#1}}
 
@@ -1203,6 +1203,14 @@
 \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 @@
 \contributor{SZi}{Stefan Ziesemer}
 \contributor{TNdz}{Timo Niedenzu}
 \contributor{VVo}{Vladimir Volovich}
+\contributor{WOs}{Wolfgang Ostmann}
 \contributor{YiL}{Yiannis Lazarides}
 \end{multicols}
 

Modified: trunk/Master/texmf-dist/doc/latex/base/lb2.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/letter.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/lgc2.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/lppl.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltfilehook-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltfilehook-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/lthooks-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/lthooks-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltluatex.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltmarks-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltmarks-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews.tex	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews.tex	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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}{}{}
 

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews01.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews02.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews03.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews04.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews05.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews06.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews07.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews08.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews09.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews10.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews11.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews12.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews13.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews14.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews15.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews16.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews17.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews18.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews19.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews20.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews21.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews22.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews23.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews24.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews25.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews26.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews27.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews28.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews28.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews28.tex	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews28.tex	2024-06-02 20:26:39 UTC (rev 71408)
@@ -126,7 +126,7 @@
 German keyboard could show up as ``Gr\v T\`ae'' on a different
 computer using a different encoding by default.
 
-So in summmary the situation wasn't at all good and it was clear in
+So in summary the situation wasn't at all good and it was clear in
 the early nineties that \LaTeXe{} (that was being developed to provide
 a \LaTeX{} version usable across the world) had to provide a solution
 to this issue.
@@ -318,7 +318,7 @@
 
 The fix required a redesign of the output routines used by
 \pkg{multicol} and while it ``should'' be transparent in other cases
-(and all tests in the regession test suite came out fine) there is the
+(and all tests in the regression test suite came out fine) there is the
 off-chance that code that hooked into internals of \pkg{multicol}
 needs adjustment.
 

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews29.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews30.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews31.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews31.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews31.tex	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews31.tex	2024-06-02 20:26:39 UTC (rev 71408)
@@ -552,8 +552,8 @@
 \subsection{Ensure that \cs{textbackslash} remains robust}
 
 In the last release we made most document-level commands robust, but
-\cs{textbackslash} became fragile again\\
-whenever  \cs{raggedright} or similar typesetting\\
+\cs{textbackslash} became fragile again
+whenever  \cs{raggedright} or similar typesetting
 was used. This has been fixed.
 %
 \githubissue{203}

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews32.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews33.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews34.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews35.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews35.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews35.tex	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews35.tex	2024-06-02 20:26:39 UTC (rev 71408)
@@ -547,7 +547,7 @@
 quote environment.
 \end{quote}
 Thus, if you are keen to use the plain \TeX{} trick, you need to say
-\cs{let}\cs{obeyedlines}\texttt{=}\cs{cr} now.
+\cs{let}\cs{obeyedline}\texttt{=}\cs{cr} now.
 %
 \githubissue{367}
 

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews36.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews37.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews38.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews38.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews38.tex	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews38.tex	2024-06-02 20:26:39 UTC (rev 71408)
@@ -177,7 +177,7 @@
 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

Added: trunk/Master/texmf-dist/doc/latex/base/ltnews39.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/latex/base/ltnews39.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews39.pdf	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews39.pdf	2024-06-02 20:26:39 UTC (rev 71408)

Property changes on: trunk/Master/texmf-dist/doc/latex/base/ltnews39.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/base/ltnews39.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews39.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews39.tex	2024-06-02 20:26:39 UTC (rev 71408)
@@ -0,0 +1,893 @@
+% \iffalse meta-comment
+%
+% Copyright 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
+% 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}
+
+\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#2{#2} % 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)
+\let\finalvspace\vspace       % for document layout fixes
+
+\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
+
+
+% Undo ltnews's \verbatim at font with active < and >
+\makeatletter
+\def\verbatim at font{\normalsize\ttfamily}
+\makeatother
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\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}
+
+The \LaTeX{} Project team remains strongly focused on producing
+automatically tagged PDF output for accessibility and reuse. At the
+beginning of 2024 the ISO PDF/UA-2 and the WTPDF (well-tagged PDF)
+standards were released and we are glad to be able to report that it
+is now possible to use \LaTeX{} to automatically produce documents
+that conform to these new standards.\footnote{At the present time we
+are still in a trial/prototype phase in which only a limited set of
+document classes and packages are supported.  Over the next releases
+we expect to gradually lift these restrictions and eventually provide
+the full functionality as part of the core distribution, rather than
+through \texttt{latex-lab} modules.}  A sample collection of such
+documents ranging from classical texts, such as the Bible, to recent
+technical papers submitted to arXiv.org can be found at
+\url{https://github.com/latex3/tagging-project/discussions/72}.
+
+In February Ulrike and Frank presented the current project status
+during the 5th International Workshop on \enquote{Digitization and
+  E-Inclusion in Mathematics and Science 2024} (DEIMS 2024) at Nihon
+University, Tokyo, Japan; see~\cite{39:deims}.
+
+
+\section{News from the \enquote{\LaTeX{} Tagged PDF} project}
+
+In the previous \LaTeX{} News~\cite{39:ltnews38} we announced some prototype
+support for tagged tabulars. Some of the necessary 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 re-enables 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{39: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 look very promising. Examples of PDF files tagged with the
+new method can be found at
+\url{https://github.com/latex3/tagging-project/discussions/72}.
+
+At last various small bugs and problems reported at
+\url{https://github.com/latex3/tagging-project}
+have been fixed.
+Such 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~\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 its size. \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 differences 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
+avoid an error being 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:
+\begingroup
+\makeatletter
+\def\verbatim at font{%
+  \small\ttfamily}
+\makeatother
+\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 when error messages and their texts are
+hard-wired in the engine.
+
+\endgroup
+
+So why all this? There are two reasons: we do not lose marks in edge
+cases any more, 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 necessary, for example, to
+support extended marks in \env{multicols} environments or extract them
+from floats, marginpars, etc.\tubcommand{\looseness-1}
+
+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{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,
+%% CAR added text: ---  FMi: but it is wrong
+%% variations of the document markup can be accommodated,
+and design decisions can be implemented 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 directly encounter templates only rarely.
+We anticipate though that they will be \emph{using} templates provided
+by the team or others.
+
+%% CAR added this paragraph: FMi: doesn't belong in ltnews
+%We shall continue to develop these generic ideas and interfaces in various ways: for example, to support the varied document markup possibilities
+%provided in \pkg{ltcmd} and elsewhere.
+
+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}
+\item \cs{IfInstanceExistsTF} and variants
+\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{New or improved commands}
+
+\subsection{\pkg{doc}:\ Provide \cs{ProvideDocElement}}
+
+In addition to
+\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 and
+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 added only for \cs{verb} and the \env{verbatim}
+environments. However,
+in a typical \texttt{.dtx} file, most of the code will be in the body
+of some \env{macrocode} or \env{macrocode*} environments, and neither
+of these was affected by adding \pkg{upquote}.
+We have now updated \pkg{doc} so that
+\pkg{upquote} alters the quote characters in these environments as
+well.
+%
+\githubissue{1230}
+
+\subsection[\pkg{ifthen}:\ Allow active characters in comparisons]
+           {\pkg{ifthen}:\ Guard against active characters in comparisons}
+The \cs{ifthenelse} command now ensures that \verb|<|, \verb|=| and
+\verb|>| are safe
+in numeric tests, even if they have been made active
+(typically by \pkg{babel} language shorthands).
+%
+\githubissue{756}
+
+\subsection%[New conditionals: \cs{IfClassAtLeastT}, etc.]
+           {New conditionals:\ \cs{IfClassAtLeastT} and friends}
+
+Around 2020 we added a number of conditionals with CamelCase names, i.e.,
+%
+\cs{IfClassAtLeastTF},
+\cs{IfClassLoadedTF},
+\cs{IfClassLoadedWithOptionsFF},
+\cs{IfFormatAtLeastTF},
+\cs{IfPackageAtLeastTF},
+\cs{IfPackageLoadedTF}, and
+\cs{IfPackageLoadedWithOptionsTF}
+%
+to help arranging conditional code that depends on the release of a
+particular class, package or format. However, we only provided the
+\texttt{TF} commands and not also the \texttt{T} and \texttt{F}
+variants. This has now been changed.
+
+In 2023 we introduced \cs{IfFileAtLeastTF} but we did not also provide
+\cs{IfFileLoadedTF} at the same time. This conditional and its
+\texttt{T} and \texttt{F} variants have now also been added. Remember
+that one can only test for files that contain a \cs{ProvidesFile}
+line.
+%
+We did the same for the conditionals \cs{IfLabelExistsTF} and
+\cs{IfPropertyExistsTF}, also introduced in 2023.\footnote{By mistake they
+were initially introduced under the names \cs{IfLabelExistTF} and
+\cs{IfPropertyExistTF}; we corrected that at the same time. This is a
+breaking change, but the commands have been used so far only in
+kernel code.}
+%
+\githubissue[s]{1222 1262}
+
+
+\section{Code improvements}
+
+\subsection{Load packages only at the top level}
+
+Classes and packages must be loaded only by using the commands
+\cs{documentclass} and \cs{usepackage} or the class interface commands
+such as \cs{LoadClass} or \cs{RequirePackageWithOptions}; moreover,
+all of these must always be used at the top level, and not inside a
+group of any type (for example, within an environment).
+Previously \LaTeX\ did not check this,
+which would often lead to low level errors later on if package declarations
+were reverted when 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} package is asked to load a font encoding for which it
+doesn't find a suitable \texttt{.def} file then 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 can include the MD5
+hash and 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 declarations such as \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{\texorpdfstring{\raggedright}{}Handling of end-of-lines in \texttt{+v} arguments of \cs{NewDocumentCommand} and friends}
+
+The \texttt{+v} argument type provided by declarations such as \cs{NewDocumentCommand}, etc., allows
+grabbing of multiple lines of text in a verbatim-like argument. Almost always,
+the result of this grabbing will be used in a typesetting context. Previously,
+the end-of-line characters were stored literally as category code~12
+(\enquote{other}) \verb|^^M| tokens. However, these are difficult to work with
+in general. We have now revised this behavior, such that end-of-line characters
+are converted to the \cs{obeyedline} command when parsed by \texttt{+v}-type
+arguments.
+This change may require adjustments to the source of some documents, but the
+enhanced ability of users and programmers to exploit the \texttt{+v}-type
+argument means we believe it is necessary.
+
+\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 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 symbol \cs{texteuro} (\texteuro) or \cs{textohm} (\textohm)
+no longer gets printed in your document, just because you altered the
+text font family.
+
+To mitigate this problem, in 2020 we also introduced 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
+taken from a fallback font.
+
+%% CAR -- this paragraph maybe needs more substantial rewording ??
+While this is not perfect, it is the best
+you can do other than painstakingly checking that your document
+%% CAR: was "painstrickenly" -- should be a word, but!!
+uses only glyphs that the font supports
+and, if necessary, switching to a different font or avoiding 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 \TL{} 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 that offers only a 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 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:
+\tubcommand{\begin{small}}
+\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}
+\tubcommand{\end{small}\noindent}%
+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}
+thus it claims that
+all glyphs are provided, while in reality more than twenty are missing
+and sub-encoding 5, as declared in the kernel, is in fact correct.
+%
+\githubissue{1257}
+
+
+\subsection{Behavior when loading \pkg{textcomp} without options}
+
+When incorporating the \pkg{textcomp} package into the \LaTeX{} kernel, in
+the February 2020 release~\cite{39:ltnews31}, the default type of its package messages was changed from package info (\texttt{Package textcomp Info})
+to \LaTeX{} kernel info (\texttt{LaTeX Info}). But if \pkg{textcomp}
+was loaded without options, the message type got restored to package info.
+This restoration has now been canceled.
+
+Note that loading \pkg{textcomp} with one of the options \option{error},
+\option{warn}, or \option{info} still changes the message
+type to an error, warning, or info message from the \pkg{textcomp} package.
+%
+\githubissue{1333}
+
+
+\subsection{Rollback improvements}
+
+When requesting a rollback of the \LaTeX{} kernel and/or packages,
+several packages produced the error \enquote{Suspicious rollback date}
+because their rollback section contained only data about recent
+releases even if the package, such as \pkg{array}, was available since
+the first release of \LaTeXe{} in 1994. We now suppress this error and
+load the first release that is still part of the distribution (and
+hope for the best). This change was implemented for the packages
+\pkg{amsmath},
+\pkg{array},
+\pkg{doc},
+\pkg{graphics},
+\pkg{longtable},
+\pkg{multicol},
+\pkg{showkeys},
+\pkg{textcomp}, and
+\pkg{varioref}.
+%
+\githubissue{1333}
+
+
+
+\section{Documentation improvements}
+
+\subsection{Further updates to the guides}
+
+We reported about the updated versions of \texttt{usrguide} and
+\texttt{clsguide} in \LaTeX{} News~37~\cite{39:ltnews37}. We have now
+revised \texttt{fntguide} as well to reflect the changes and macros
+added to the kernel over the last years of development. Note that the
+file name hasn't changed and there is no \texttt{fntguide-historic}.
+
+\section{Bug fixes}
+
+\subsection{Fix inconsistent expansion of the package option list}
+
+\LaTeX{} applies one-step expansion to the raw option list of packages
+and classes, so that constructions such as
+\begin{verbatim}
+  \def\myoptions{opt1,opt2}
+  \usepackage[\myoptions]{foo}
+\end{verbatim}
+are supported.
+%% CAR Rewritten sentence:
+But if a package declares its options using the new
+key/value approach~\cite{39:ltnews35} and it gets loaded a second time,
+then its raw option list will not be expanded and so an error might be raised.
+This has now been corrected.
+%
+\githubissue{1298}
+
+\subsection{Fix logic for first mark (page region)}
+
+In the new mark mechanism introduced in June 2022~\cite{39:ltnews35} the result of
+\cs{FirstMark} on a two-column page was incorrect if the first column
+contained no marks. In that case it should have returned the first
+mark of the second column but didn't.
+This has now been corrected.
+
+Documents using \cs{leftmark} are not effected, because that command is still
+using the old mechanism for now.
+%
+\githubissue{1359}
+
+
+\subsection{Struts at the end of footnotes or \texttt{p} columns}
+
+To produce consistent spacing in footnotes and tabular
+\texttt{p}-cells \LaTeX{} adds a strut at the beginning and end of
+the content.
+%%  CAR Rewritten sentences:
+%%  It assumed, however, that the footnote or tabular cell ended in
+%%  horizontal mode and until now added the struts unconditionally. As a
+%%  result, with vertical material at the end of the material this strut
+%%  started a new paragraph consisting of a single line with just the
+%%  strut inside.
+This assumed, however, that the content of the footnote or tabular cell ended in
+horizontal mode and so, until now, these struts were unconditionally added;
+as a result, if this content ended with vertical material then this strut
+started a new paragraph consisting of a single line with just the
+strut in it. This has finally been corrected and now the placement
+logic for the strut changes when vertical mode is detected.
+
+\emph{(First seen in a bug report for \pkg{footmisc} in combination with
+\pkg{bigfoot})}
+
+
+
+\section{Changes to packages in the \pkg{amsmath} category}
+
+\subsection{\pkg{amsmath}:\ Correct equation tag placement}
+
+If there is not enough space to place an equation tag on the same line
+as the equation then \pkg{amsmath} calculates a suitable offset and it
+places the tag above (or below) the equation. In the case of the
+\env{gather} environment this offset was not reset at the end, with
+the result that it also got applied to any following environment,
+resulting in incorrect spacing in certain situations. This has now
+been corrected.
+%
+\githubissue{1289}
+
+
+
+%\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}
+
+%% CAR Rewritten sentences
+These three packages have been extended so they can now, on request,
+produce tagged tabular. This is done by adding a number of sockets (see
+\cite{39:ltnews38}) that, by default, do nothing; but when tagged PDF
+is requested they get equipped with appropriate plugs.
+
+In the previous \LaTeX{} release this was handled in \texttt{latex-lab}, by
+patching the packages when tagging was requested.
+
+
+\subsection{\pkg{array}:\ No \cs{unskip} in math cells}
+
+Math cells in the standard \env{array} environment of the kernel are
+not subject to space removal at the right end of the cell, i.e., explicit
+spaces from \cs{hspace} or \verb*|\ |, etc.\ are honored
+(normal spaces are automatically ignored in math). In the \pkg{array}
+package all spaces got removed by calling \cs{unskip} unconditionally,
+regardless of the type of cell.
+This difference in behavior has now been removed by correcting the processing of
+math cells in \pkg{array}.
+%
+\githubissue{1323}
+
+
+\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 the November 2023 release.
+%
+\githubissue{1160}
+
+\subsection{\pkg{verbatim}:\ Support tabs in \cs{verbatiminput*}}
+
+Mimicking the November 2023 kernel update that allowed \cs{verb*}
+to mark tabs as spaces, the \pkg{verbatim} package
+has now been updated so that \cs{verbatiminput*} also marks tabs as spaces.
+\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}
+
+\subsection{\pkg{xr}:\ Support links and properties}
+%
+The \pkg{xr} package implements a system for eXternal References.
+The \pkg{xr-hyper} package (in the \pkg{hyperref} bundle)
+extended this to also support links to external documents.
+%% CAR: Rewritten sentences:
+Using last year's extension of the \cs{label} command, which unified
+the label syntax of \LaTeX{} and \pkg{hyperref},
+it became possible to merge the two packages and thus make
+\pkg{xr-hyper} obsolete.
+With this change it is also possible to refer to properties
+that are stored in external documents using \cs{RecordProperties}.
+%
+\githubissue{1180}
+
+\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}
+
+
+\tubcommand{\newpage}
+\begin{thebibliography}{9}\frenchspacing
+
+%\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:ltnews35} \LaTeX{} Project Team.
+  \emph{\LaTeXe{} news 35}. June 2022.\\
+  \url{https://latex-project.org/news/latex2e-news/ltnews35.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:deims} Frank Mittelbach and Ulrike Fischer.
+  \emph{Enhancing \LaTeX{} to automatically produce
+  tagged and accessible PDF}. \textsl{TUGboat} 45:1, 2024.
+  \url{https://latex-project.org/publications/indexbyyear/2024/}
+
+  %\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}
+


Property changes on: trunk/Master/texmf-dist/doc/latex/base/ltnews39.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/doc/latex/base/ltpara-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltpara-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltproperties-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltproperties-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltshipout-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltshipout-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltsockets-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltsockets-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltx3info.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltxdoc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/makeindx.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/modguide.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/nfssfont.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/proc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/slides.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/slifonts.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/source2e.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/source2e.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/source2e.tex	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/base/source2e.tex	2024-06-02 20:26:39 UTC (rev 71408)
@@ -342,6 +342,8 @@
 
  \DocInclude{ltoutput} % Output routine
 
+ \DocInclude{lttagging}% Tagging support
+
  \DocInclude{lthyphen} % Hyphenation (hyphen.ltx).
 
  \DocInclude{ltfinal}  % Last minute initialisations and dump
@@ -378,7 +380,7 @@
 \def\endash{--}
 \catcode`\-\active
 \def-{\futurelet\temp\indexdash}
-\def\indexdash{\ifx\temp-\endash\fi}
+\def\indexdash{\ifx\temp-\endash\else:\fi}
 
 \PrintIndex
 \endgroup

Modified: trunk/Master/texmf-dist/doc/latex/base/syntonly.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/tlc2.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/tlc3.err
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/tlc3.err	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/base/tlc3.err	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,4 +1,4 @@
-\newcommand\erratafiledate{2023/10/30}        % needs / and not -
+\newcommand\erratafiledate{2024/05/31}        % needs / and not -
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % To produce a printed version of this errata file run this file through
@@ -320,12 +320,15 @@
 
 \let\u\underline  % needs resetting after hyperref
 
+\usepackage{hologo}
+\providecommand\XeTeX{\hologo{XeTeX}}
 
+
 \begin{document}
 
 \erratatitle{The \LaTeX{} Companion, Third Edition, Parts I \& II}{\erratafiledate}
 
-
+\begin{small}
 \begin{verbatim}
 @book(A-W:MF:2023,
    author = {Frank Mittelbach and Ulrike Fischer},
@@ -339,11 +342,10 @@
    pagenums = {976 (Part I) and 1008 (Part II)},
    bibliography = {yes},
    index = {yes},
-   isbn = {978-0-13-816648-9},
-)
+   isbn = {978-0-13-816648-9})
 \end{verbatim}
+\end{small}
 
-
 \begin{list}{}{\setlength\leftmargin{0cm}%
                \setlength\rightmargin{3cm}%
 	       \setlength\listparindent{1em}}
@@ -372,7 +374,7 @@
 you own by changing the configuration in the file \texttt{\jobname.cfg}.
 
 \begin{center}
-  \Large \bfseries  To Err is Human --- Bug Contest
+  \large \bfseries  To Err is Human --- Bug Contest
 \end{center}
 
 Any mistake found and reported is a gain for all readers of our book.
@@ -398,7 +400,7 @@
 \begin{center}
 \begin{tabular}{clr}
 Contest period ends & Winner \\[4pt]
-2023/?? &                         & ??? suggestions\\
+2024/03 & Bernd Burghardt           & 52 suggestions\\
 \end{tabular}
 \end{center}
 
@@ -441,7 +443,7 @@
 
 \erroronpage{}{}{FMi}{2023/07/30}{}
 
-Text or graphics typeset in the the spot color (blue) are not always
+Text or graphics typeset in the spot color (blue) are not always
 perfectly aligned. This is a side-effect of the printing technology.
 On most pages everything is fine, but occasionally blue text in a
 paragraph seems to be slightly above or below the baseline or blue
@@ -592,6 +594,13 @@
   English. Personally, I prefer the version with accent (as does Don
   Knuth) so it is deliberate and will not change.
 
+
+\CHAPTER{Preface}
+
+\erroronpage{I-xlii}{para 1, l.3}{FMi}{2024/04/01}{s}
+\u{the designer} of the Lato fonts \> \u{a co-designer} of the Lato fonts
+
+
 \CHAPTER{Chapter 1 --- Introduction}
 
 \erroronpage{I-5}{para 4, l.4}{kb}{2023/04/04}{s}
@@ -606,6 +615,10 @@
 
 \CHAPTER{Chapter 2 --- The Structure of a \LaTeX{} Document}
 
+\erroronpage{I-31}{para-1,l.-1}{BeB}{2024/03/17}{s}
+would have resulted in ``\verb+# .+'' in the output. \> \\
+would have resulted in ``\verb+#+\u{\texttt{\&}}\verb+ .+'' in the output.
+
 \erroronpage{I-34}{l.-1}{FMi}{2023/04/04}{s}
 Moved first line of page 35 to 34.
 
@@ -624,6 +637,10 @@
 
 \CHAPTER{Chapter 3 --- Basic Formatting Tools -- Paragraph \ldots}
 
+\erroronpage{I-143}{exa 3-1-18}{BeB}{2024/03/17}{s}
+Replace in source: \verb+{ peine+ \> \verb+{peine+
+
+
 \erroronpage{I-160}{para -2, l.1}{BeB}{2023/07/14}{s}
 Repeated word: keys \u{keys} \> keys
 
@@ -636,18 +653,58 @@
 \erroronpage{I-163}{example 3-3-14}{BeB}{2023/07/25}{s}
 Output of example misses the page numbers in acronym list \> Run example 3 times (not only twice---there is no warning)
 
+\erroronpage{I-174}{para3,l. -2}{BeB}{2024/03/17}{s}
+the exponent is always a \u{power} of 3 \> the exponent is always a 
+\u{multiple} of 3
 
+\seriouserroronpage{I-177}{exa 3-3-39}{BeB/FMi}{2024/03/17}{s}
 
+The example doesn't really show what the paragraph above discusses
+because it was shortend to fit the available space on the page.
+Use
+\begin{verbatim}
+\newcommand\sample[1]{\textnormal{\noindent #1:}
+ The limit is \qty{30}{\kmh} not $\qty{50}{\kmh}$.\par}}
+\end{verbatim}
+so that both text and math usage of \verb=\qty= are compared in the example.
+
+
+\erroronpage{I-182}{para 4}{BeB}{2024/03/17}{s}
+Add sentence: The command \verb+\textcquote+ is used in Example 16-5-50 on page II-535.
+
 \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.
@@ -660,7 +717,15 @@
 \u{\cs{right}} \> \u{\cs{rightmark}}
 
 
+\erroronpage{I-393}{Documentation of \rlap{\cs{IfMarksEqualTF}}}{FMi}{2024/05/31}{s}
 
+Add paragraph:
+Note that two retrieved mark values are only considered equal if they
+originated from the same \cs{InsertMark} command — it is not enough
+that they contain the same data, as that may be conincidental.
+
+
+
 \CHAPTER{Chapter 6 --- Tabular  Material}
 
 \erroronpage{I-489}{para 1, l.3}{EOl}{2023/07/30}{s}
@@ -675,13 +740,27 @@
 the rest is dropped. For example, \texttt{31 December 2022} would
 result in ``31.00'', which is probably not desired.
 
+\erroronpage{I-491}{exa 6-7-22, Booklet 114}{EOl}{2024/05/13}{s} 
+            Change: remove `0,00' in `actual' column for item `loss'.  (This 
+is not really an error, but it looks better---and is consistent with the 
+`actual' item of `profit' for Booklet 113.)
 
+
+\erroronpage{I-494}{para -2, l.3}{MRu}{2024/03/16}{s}
+
+Use plural: The allowed key\u{s} are \ldots
+
+
 \CHAPTER{Chapter 7 --- Mastering Floats}
 
-\erroronpage{I-520}{paragraph 4, l.3}{EOl}{2023/09/09}{s}
+\erroronpage{I-520}{para 4, l.3}{EOl}{2023/09/09}{s}
 Change:
 For \u{a} example \> For example
 
+\erroronpage{I-612}{para -2, l.1}{EOl}{2024/05/13}{s} 
+Change: up \u{do} several \> up to several
+
+
 \CHAPTER{Chapter 8 --- Graphics Generation and Manipulation}
 
 \erroronpage{I-619}{para -2, l.2}{FMi}{2023/05/30}{s}
@@ -698,8 +777,11 @@
 \erroronpage{I-644}{syntaxbox for \cs{foreach}}{BeB}{2023/07/14}{s}
 superfluous ``in'': \ldots\{\textsl{commands}\} \u{in} \> \ldots\{\textsl{commands}\}
 
+\erroronpage{I-645}{para 3, l.4}{EOl}{2024/05/13}{s} 
+Correct hyphenation: stan-dalone \> stand-alone
 
 
+
 \CHAPTER{Chapter 9 --- Font Selection and Encodings}
 
 
@@ -716,12 +798,34 @@
 \erroronpage{I-708}{listing}{FMi}{2023/05/14}{s}
 Situation is the same in the 2023 distributions; listing output updated.
 
+\erroronpage{I-726}{para 4, l.5}{MRu}{2024/04/07}{s}
+Add word: more than hundred \> more than \u{one} hundred
+
 \erroronpage{I-759}{l.1}{BeB}{2023/08/20}{s}
 in the range of 0000 to \u{00FF} \> in the range of 0000 to \u{007F}
 
+\erroronpage{I-797}{exa 9-6-3}{BYu/FMi}{2024/04/08}{s}
 
+This example may fail with \XeTeX{} because of a deficiency in
+older versions of \pkg{fontspec}.  With versions prior 2.9e one has to
+use the \texttt{Extension} key and omit the extension on the other
+lines:
+\begin{verbatim}
+\setmainfont{Alegreya}[
+  Extension      = .otf,
+  UprightFont    = *-Medium,
+  ItalicFont     = *-MediumItalic,
+  BoldFont       = *-ExtraBold,
+  BoldItalicFont = *-ExtraBoldItalic
+]
+\end{verbatim}
+
+
 \CHAPTER{Chapter 10 --- Text and Symbol Fonts}
 
+\erroronpage{II-3}{para-1, l.-2}{BeB}{2024/03/17}{s}
+line first \> first line
+
 \erroronpage{II-5}{table 10.1, l. 5}{BeB/FMi}{2023/08/13}{s}
  official \u{companion} family name \> \u{related} official \u{font} family name
 
@@ -732,7 +836,7 @@
 
 
 \erroronpage{II-24}{para 3, l. -2}{BeB}{2023/08/13}{s}
-There is no slanted shape in Grande Mono: \\
+There is no slanted shape in Grande Mono (so it should be in blue): \\
 \u{\textsl{naïve}} \> \u{\textsl{\bl naïve}}
 
 
@@ -741,8 +845,8 @@
 \u{— no Open Type —} \> \u{Lucida Handwriting OT}
 
 \erroronpage{II-25}{para -2, l.-2}{BeB}{2023/08/13}{s}
-There are no italic blackletters:  \\
-\textit{phœnix's official rôle}\> \textit{\bl phœnix's official rôle}
+There are no italic blackletters (so it should be in blue):  \\
+\textit{phœnix's official rôle} \> \textit{\bl phœnix's official rôle}
 
 \erroronpage{II-28}{table 10.14, l. 3}{BeB}{2023/08/13}{s}
 Inconsistent order: sl, l \> l, sl
@@ -773,6 +877,8 @@
 \erroronpage{II-40}{table 10.24}{FMi}{2023/08/15}{s}
 In table note:   \textit{Unfortunately, \u{\texttt{sco}}} \> \textit{Unfortunately, \u{\textttu{sco}}}
 
+\erroronpage{II-42}{para 3, l.4}{MRu}{2024/04/12}{s}
+rudimentary \> rudimentarily 
 
 \erroronpage{II-50}{font sample Cambria}{FMi}{2023/08/14}{s}
 
@@ -786,7 +892,7 @@
      BoldItalicFont = cambriaz.ttf}     
 \end{verbatim}
 Without it, the bold fonts are not correctly set up, which is why
-\textbf{almost anything} is not in bold and \textbf{Fields} is not typeset in
+\textbf{almost anything} was not in bold and \textbf{Fields} was not typeset in
 bold small caps in the sample even though Cambria supports these typefaces.
 
 
@@ -928,37 +1034,37 @@
 
 \erroronpage{II-114}{table 10.89}{FMi}{2023/04/04}{s}
 Added missing \texttt{U+00Fx} line.
-There was a bug in code generating it.
+There was a bug in the code generating it.
 
 
 \erroronpage{II-117}{table 10.92}{FMi}{2023/04/04}{s}
 Added missing \texttt{U+00Fx} line.
-There was a bug in code generating it.
+There was a bug in the code generating it.
 
 
 \erroronpage{II-121}{table 10.96}{FMi}{2023/04/04}{s}
 Added missing \texttt{U+00Fx} line.
-There was a bug in code generating it.
+There was a bug in the code generating it.
 
 
 \erroronpage{II-122}{table 10.98}{FMi}{2023/04/04}{s}
 Added missing \texttt{U+00Fx} line.
-There was a bug in code generating it.
+There was a bug in the code generating it.
 
 
 \erroronpage{II-122}{table 10.99}{FMi}{2023/04/04}{s}
 Added missing \texttt{U+00Fx} line.
-There was a bug in code generating it.
+There was a bug in the code generating it.
 
 
 \erroronpage{II-123}{table 10.100}{FMi}{2023/04/04}{s}
 Added missing \texttt{U+00Fx} line.
-There was a bug in code generating it.
+There was a bug in the code generating it.
 
 
 \erroronpage{II-124}{table 10.103}{FMi}{2023/04/04}{s}
 Added missing \texttt{U+00Fx} line.
-There was a bug in code generating it.
+There was a bug in the code generating it.
 
 
 
@@ -1302,7 +1408,11 @@
 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}{s}
+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.
 
@@ -1319,7 +1429,8 @@
 \CHAPTER{Appendix A --- \LaTeX{} Overview for Preamble, \ldots}
 
 \erroronpage{II-624--629}{}{BeB/FMi}{2023/08/31}{s}
-Replace for consistency with section 1.4: \u{command definition} \> \u{code} 
+Replace for consistency with section 1.4: \u{command definition} \> \u{code} \\
+(in the various syntax boxes)
 
 \erroronpage{II-629}{para 1, l.3}{FMi}{2023/08/31}{s}
 \u{An} warning \> \u{A} warning
@@ -1328,11 +1439,35 @@
 \erroronpage{II-633}{para 2}{BeB/FMi}{2023/08/31}{s}
 Add at the end: A maximum of nine ``argument'' letters is supported.
 
+\erroronpage{II-657}{par -2, l. -2}{BeB}{2024/03/17}{s}
+a few that \> a few \u{commands} that
 
-\erroronpage{II-682}{para -2, l.3}{FMi}{2023/04/28}{s}
+
+\erroronpage{II-658}{first item in the list}{BeB}{2024/03/17}{s}
+square root $\sqrt{x}$ \> square root \texttt{sqrt} $x$
+
+\erroronpage{II-663}{A-3-7}{MRu}{2024/05/01}{}
+In the code, text should read either ``This is the content'' or ``These are the contents''.
+
+\erroronpage{II-682}{para -2, l .3}{FMi}{2023/04/28}{s}
 \texttt{Harf\u{b}uzz} \> \texttt{Harf\u{B}uzz}
 
+\erroronpage{II-678}{para -1, l. -1}{BeB}{2024/03/17}{s}
+it is better use\> it is better \u{to} use
 
+
+\erroronpage{II-687}{l .1}{BeB}{2024/03/17}{s}
+Two further tests should be listed in the syntax box: \verb+\ifVTeX+ \verb+\ifAlephTeX+
+
+
+\seriouserroronpage{II-701}{l. 6}{BeB}{2024/03/17}{s}
+Name changed after the book was typeset: \verb+.notif+\>\verb+.ifnot+
+ 
+\erroronpage{II-701}{para 3, l. 4; para -2, l. 1; and margin}{BeB}{2024/03/17}{s}
+\verb+.notif+\>\verb+.ifnot+
+ 
+
+
 \CHAPTER{Appendix B --- Tracing and Resolving Problems}
  
 
@@ -1349,9 +1484,10 @@
 \end{erratalist}
 
 
+\newpage
 
 
-\section*{Notes on this errata document}
+\section{Notes on this errata document}
 
 
 \setcounter{collectmore}{3}
@@ -1359,6 +1495,7 @@
 \begin{multicols}{3}[Thanks to all who have found errors or
    omissions. Listed are the people who found an errata entry first.]
 \contributor{BeB}{Bernd Burghardt}
+\contributor{BYu}{Boshi Yuan}
 \contributor{CAR}{Chris Rowley}
 \contributor{DC}{Davide Campagnari}
 \contributor{DFl}{Daniel Flipo}
@@ -1365,13 +1502,16 @@
 \contributor{EOl}{Edgar Olthof}
 \contributor{FMi}{Frank Mittelbach}
 \contributor{MJo}{Maciej Jończyk}
+\contributor{MRu}{Mark Rudolph}
 \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!
 

Modified: trunk/Master/texmf-dist/doc/latex/base/tlc3.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/tulm.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/usrguide-historic.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/usrguide-historic.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/usrguide-historic.tex	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/base/usrguide-historic.tex	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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}

Modified: trunk/Master/texmf-dist/doc/latex/base/usrguide.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/usrguide.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/usrguide.tex	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/base/usrguide.tex	2024-06-02 20:26:39 UTC (rev 71408)
@@ -34,8 +34,8 @@
 \usepackage{csquotes}
 \usepackage{url}
 
-\title{\LaTeX\ for authors --- current version}
-\author{\copyright~Copyright 2020-2023, \LaTeX\ Project Team.\\
+\title{\LaTeX\ for authors\\ current version}
+\author{\copyright~Copyright 2020--2024, \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
@@ -43,7 +43,7 @@
     \texttt{usrguide.tex} for full details.}%
 }
 
-\date{2023-05-23}
+\date{2024-05-24}
 
 \NewDocumentCommand\cs{m}{\texttt{\textbackslash\detokenize{#1}}}
 \NewDocumentCommand\marg{m}{\arg{#1}}
@@ -646,7 +646,7 @@
 (category code~$13$) and will split at such tokens. 
 Spaces are trimmed at each end of each item parsed. Exactly one set
 of braces will be stripped if an entire item is surrounded by them,
-i.e.~the following inputs and outputs result (each separte item as
+i.e.~the following inputs and outputs result (each separate item as
 a brace group).
 \begin{verbatim}
 a      ==> {a}
@@ -794,6 +794,73 @@
 \end{tabular}
 \end{verbatim}
 
+\subsection{Using the verbatim argument types}
+
+As described above, the \texttt{v}-type argument may be viewed as similar to
+\cs{verb}. Before looking at exactly what that means, it is important to
+highlight some key differences. Most notably, \emph{grabbing} a verbatim-like
+argument is separate from \emph{typesetting} it: the latter is covered in the
+next section.
+
+When grabbing a \texttt{v}-type argument, \LaTeX{} first uses the kernel
+command \cs{dospecials} to turn off the \enquote{special} nature of characters.
+It then makes both spaces and tabs \enquote{active}, so that they can be given
+a custom definition. Any other characters are grabbed as-is: this means that if
+any characters have been made \enquote{special} and are not listed in
+\cs{dospecials}, an error will arise (see below).
+
+The characters that are grabbed as the argument are all those between two
+identical: in contrast to \cs{verb}, the characters \texttt{\textbackslash},
+|{|, |}| and |%| \emph{cannot} be used as the delimiter character. If any of
+the grabbed tokens have \enquote{special} meaning, an error will be issued.
+
+For the \texttt{+v}-type argument, which allows line breaks within the
+argument, newline characters are converted into \cs{obeyedline} commands. The
+standard definition of \cs{obeyedline} is simple |\par|, thus allowing the
+grabbed tokens to be used directly in typesetting. A local redefinition of
+\cs{obeyedline} can be used to achieve other outputs. For example, to retain
+blank lines whilst typesetting, one could use
+\begin{verbatim}
+\renewcommand*\obeyedline{\mbox{}\par}
+\end{verbatim}
+More information about using these arguments in typesetting is in the following
+subsection.
+
+Some additional details that may be useful for those with more \TeX{}
+knowledge: do not worry if this does not make sense to you! Spaces and tabs are
+stored as active characters. In Unicode engines, all other characters are of
+type \enquote{other}. In $8$-bit engines, the ASCII characters other than tab
+and space are of type \enquote{other}, and non-ASCII characters are active. As
+such, token-based comparisons are likely to fail unless set up properly.
+
+\subsection{Typesetting verbatim-like material}
+
+In contrast to \cs{verb}, the \texttt{(+)v}-type argument is only about
+\emph{grabbing} the argument, not \emph{typesetting} it. As such, features that
+users often associate with \enquote{verbatim} are not automatically activated,
+e.g., selecting a monospaced font. Material grabbed by the \texttt{v}-type
+argument does not automatically suppress ligatures: with modern \TeX{} engines,
+this largely can be done without the token manipulation which \cs{verb} uses.
+(In \cs{verb}, ligatures are suppressed by making characters active and
+inserting a zero-width kern before the character itself.)
+
+The \cs{verb} command also selects a monospaced font: this is not intrinsic to
+verbatim material, so will need to be set up using for example \cs{ttfamily}.
+Similarly, the \texttt{verbatim} environment sets up the meaning of \cs{par}
+suitable for breaking lines.
+
+\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. It should be noted 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 +1018,7 @@
 \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}.
 
 
 
@@ -1052,11 +1119,17 @@
 Briefly, the floating point expressions may comprise:
 \begin{itemize}
   \item Basic arithmetic: addition $x\fpbin{+}y$, subtraction $x\fpbin{-}y$,
-    multiplication $x\fpbin{*}y$, division $x\fpbin{/}y$, square root~$\sqrt{x}$,
+    multiplication $x\fpbin{*}y$, division $x\fpbin{/}y$, square root~$\fpop{sqrt}{x}$,
     and parentheses.
   \item Comparison operators: $x\fprel{<}y$,
     $x\fprel{<=}y$, $x\fprel{>?}y$,
     $x\fprel{!=}y$ \emph{etc.}
+    
+    The relation $x\fprel{?}y$ is true exactly if one or both operands is~\nan{} or is
+   a tuple, unless they are equal tuples. Each \meta{relation}
+   can be any (non-empty) combination of |<|, |=|, |>|, and~|?|, plus
+   an optional leading~|!| (which negates the \meta{relation}), with
+   the restriction that the negated \meta{relation} may not start with~|?|.
   \item Boolean logic: sign $\fpop{sign} x$,
     negation $\fpop{!}x$, conjunction
     $x\fprel{\&\&}y$, disjunction $x\fprel{\string|\string|}y$, ternary
@@ -1161,7 +1234,7 @@
 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 +1259,13 @@
 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{tabular}{rl}
+\begin{flushleft}
+  \begin{tabular}{@{}ll}
     |\MakeUppercase{hello WORLD ßüé}| & \MakeUppercase{hello WORLD ßüé} \\
     |\MakeLowercase{hello WORLD ßüé}| & \MakeLowercase{hello WORLD ßüé} \\
     |\MakeTitlecase{hello WORLD ßüé}| & \MakeTitlecase{hello WORLD ßüé} \\
   \end{tabular}
-\end{quotation}
+\end{flushleft}
 
 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 +1281,14 @@
 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{tabular}{rl}
+\begin{flushleft}
+  \begin{tabular}{@{}ll}
     |\MakeUppercase{Some text $y = mx + c$}|
       & \MakeUppercase{Some text $y = mx + c$} \\
     |\MakeUppercase{\NoCaseChange{iPhone}}|
       & \MakeLowercase{\NoCaseChange{iPhone}} \\
   \end{tabular}
-\end{quotation}
+\end{flushleft}
 
 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 +1317,54 @@
 (\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}
-  |\DeclareUppercaseMapping{"01F0}{\v{J}}|
-\end{quotation}
+\begin{verbatim}
+\DeclareUppercaseMapping{"01F0}{\v{J}}
+\end{verbatim}
 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}
-  |\DeclareLowercaseMapping[xx]{"0049}{\i}|\\
-  |\DeclareLowercaseMapping[xx]{"0130}{i}|\\
-  |\DeclareUppercaseMapping[xx]{"0069}{\.{I}}|\\
-  |\DeclareUppercaseMapping[xx]{"0131}{I}|
-\end{quotation}
+\begin{verbatim}
+\DeclareLowercaseMapping[xx]{"0049}{\i}
+\DeclareLowercaseMapping[xx]{"0130}{i}
+\DeclareUppercaseMapping[xx]{"0069}{\.{I}}
+\DeclareUppercaseMapping[xx]{"0131}{I}
+\end{verbatim}
 
+\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}

Modified: trunk/Master/texmf-dist/doc/latex/base/utf8ienc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/webcomp.err
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/webcomp.err	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/base/webcomp.err	2024-06-02 20:26:39 UTC (rev 71408)
@@ -373,7 +373,7 @@
 \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}

Modified: trunk/Master/texmf-dist/doc/latex/base/webcomp.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/cyrillic/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/cyrillic/README.md	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/cyrillic/README.md	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,7 +1,7 @@
 The LaTeX `cyrillic` bundle
 ===========================
 
-Release 2022-06-01 patch level 1
+Release 2024-06-01 patch level 0
 
 Overview
 --------
@@ -51,4 +51,4 @@
 
 -----
 
-<p>Copyright (C) 2005-2019 The LaTeX Project <br />
+<p>Copyright (C) 2005-2024 The LaTeX Project <br />

Modified: trunk/Master/texmf-dist/doc/latex/cyrillic/changes.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/cyrillic/changes.txt	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/cyrillic/changes.txt	2024-06-02 20:26:39 UTC (rev 71408)
@@ -4,6 +4,11 @@
 are not part of the distribution.
 =======================================================================
 
+2023-11-07  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* cyoutenc.dtx (section{The Cyrillic font encodings: T2A, T2B, T2C, and X2}):
+	Add \hmode at bgroup to \k to match other encoding definitions (gh/1148)
+
 2022-06-11  David Carlisle  <David.Carlisle at latex-project.org>
 
 	* cyinpenc.dtx cyoutenc.dtx lyc.dtx ot2.dtx:

Modified: trunk/Master/texmf-dist/doc/latex/cyrillic/cyinpenc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/cyrillic/cyoutenc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/cyrillic/lcy.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/cyrillic/lcycmlh.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/cyrillic/ot2.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/cyrillic/ot2cmams.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/cyrillic/ot2cmlh.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/cyrillic/t2lhfnt.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/firstaid/changes.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/firstaid/changes.txt	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/firstaid/changes.txt	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,27 +1,37 @@
+2024-03-22  Ulrike Fischer  <Ulrike.Fischer at latex-project.org>
+
+	* latex2e-first-aid-for-external-files.dtx: add firstaid for cleveref
+      to support five data in \newlabel. 
+
+2024-03-18  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* latex2e-first-aid-for-external-files.dtx:
+	add first aid for acro to not patch longtable (never worked in
+	the past, but now errors)
+
 2024-02-29  Joseph Wright  <Joseph.Wright at latex-project.org>
 
 	* latex2e-first-aid-for-external-files.dtx:
-      - add firstaid for acro to declare a temporary prop
-      - add firstaid for chemformula to load l3keys2e
+      - add first aid for acro to declare a temporary prop
+      - add first aid for chemformula to load l3keys2e
       - add chemnum for acro to declare a temporary prop
 
 2023-09-20  Ulrike Fischer  <Ulrike.Fischer at latex-project.org>
 
-	* latex2e-first-aid-for-external-files.dtx: add firstaid for underscore to 
+	* latex2e-first-aid-for-external-files.dtx: add firstaid for underscore to
       make the active char protected and safe for use in csnames.
-      
+
 2023-07-18  Ulrike Fischer  <Ulrike.Fischer at latex-project.org>
-	* latex2e-first-aid-for-external-files.dtx: remove no longer needed code for 
-      everysel
-	* latex2e-first-aid-for-external-files.dtx: remove no longer needed code for bidi 
-	* latex2e-first-aid-for-external-files.dtx: 
-      remove no longer needed code for memoir/stockheight 
-     
+	* latex2e-first-aid-for-external-files.dtx:
+	remove no longer needed code for  everysel
+	remove no longer needed code for bidi
+	remove no longer needed code for memoir/stockheight
+
 2023-05-20  Ulrike Fischer  <Ulrike.Fischer at latex-project.org>
 
-	* latex2e-first-aid-for-external-files.dtx: removed temporary fix for 
-      GitHub issue 591, unneeded now and it breaks for luatex the fix for gh 989
-      (minipage/list spacing) 
+	* latex2e-first-aid-for-external-files.dtx: removed temporary fix for
+	GitHub issue 591, unneeded now and it breaks for luatex the fix for gh 989
+	(minipage/list spacing)
 
 2022-12-06  Ulrike Fischer  <Ulrike.Fischer at latex-project.org>
 
@@ -38,17 +48,17 @@
 	* latex2e-first-aid-for-external-files.dtx (subsection{The unicode-math package first aid}):
 	A first aid for unicode-math used together with the doc package.
 
-2022-10-27	Joseph Wright <Joseph.Wright at latex-project.org>
+2022-10-27 Joseph Wright <Joseph.Wright at latex-project.org>
 
 	* latex2e-first-aid-for-external-files.dtx:
 	Much easier babel patch
 
-2022-10-27	Joseph Wright <Joseph.Wright at latex-project.org>
+2022-10-27 Joseph Wright <Joseph.Wright at latex-project.org>
 
 	* latex2e-first-aid-for-external-files.dtx:
 	Add first aid for babel to undo a no-longer required patch
 
-2022-10-03	Joseph Wright <Joseph.Wright at latex-project.org>
+2022-10-03 Joseph Wright <Joseph.Wright at latex-project.org>
 
 	* latex2e-first-aid-for-external-files.dtx:
 	Add first aid for memoir to support kernel-provided

Modified: trunk/Master/texmf-dist/doc/latex/firstaid/latex2e-first-aid-for-external-files.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/graphics/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/graphics/README.md	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/graphics/README.md	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,7 +1,7 @@
 The LaTeX `graphics` bundle
 ===========================
 
-Release 2022-11-01
+Release 2024-06-01 patch level 0
 
 Overview
 --------
@@ -61,4 +61,4 @@
 
 -----
 
-<p>Copyright (C) 1993-2022 The LaTeX Project <br />
+<p>Copyright (C) 1993-2024 The LaTeX Project <br />

Modified: trunk/Master/texmf-dist/doc/latex/graphics/changes.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/graphics/changes.txt	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/graphics/changes.txt	2024-06-02 20:26:39 UTC (rev 71408)
@@ -9,6 +9,20 @@
 ================================================================================
 
 #########################
+# 2023-11-01 Release
+#########################
+
+2024-05-23  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* graphics.dtx:
+	Do not error with "suspicious date" when rolling back to
+	early years of LaTeX2e (gh/1336)
+
+2024-04-28  David Carlisle  <David.Carlisle at latex-project.org>
+
+	* grfguide.tex: add \resizebox* example for gh/1339
+
+#########################
 # 2022-11-01 Release
 #########################
 

Modified: trunk/Master/texmf-dist/doc/latex/graphics/color.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/graphics/drivers.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/graphics/epsfig.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/graphics/graphics.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/graphics/graphicx.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/graphics/grfguide.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/graphics/grfguide.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/graphics/grfguide.tex	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/graphics/grfguide.tex	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,5 +1,5 @@
 %% grfguide.tex Copyright (C) 1994-1999 David Carlisle
-%%              Copyright (C) 2005-2021
+%%              Copyright (C) 2005-2024
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
@@ -62,8 +62,9 @@
 \begin{document}
 \title{Packages in the `graphics' bundle}
 \author{D. P. Carlisle \and The \LaTeX\ Project}
-\date{2021-03-05}
 
+\date{2024-05-22}
+
 \maketitle
 
 \tableofcontents
@@ -95,8 +96,10 @@
 to set up a site default for these options. Suppose that you wish
 the \package{color} package to always default to use specials for the
 PostScript driver, |dvisvgm|. In that case, create a file |color.cfg|
-containing the line:\\
-|\ExecuteOptions{dvisvgm}|\\
+containing the line:
+\begin{quote}
+  |\ExecuteOptions{dvisvgm}|
+\end{quote}
 Normally you will want an identical file |graphics.cfg| to set a similar
 default for the graphics packages.
 
@@ -113,12 +116,12 @@
 to separate definition files, but are essentially aliases for the
 |dvips| option (and |monochrome| in the case of |xdvi|).
 \begin{quote}\raggedright
- |xdvi|,  |oztex|
+ |xdvi|, |oztex|
 \end{quote}
 
 The following set of options are supported by these packages
 with associated driver files extracted from the |drivers.dtx|
-documented source in this bundle. These are now, mainly of historic
+documented source in this bundle. These are now mainly of historic
 interest but the documented sources do contain some useful code
 and advice if you need to produce a new definition file for a new
 driver or \TeX\ system. |drivers.dtx| also contains documented
@@ -206,13 +209,13 @@
 
 
 This defines \m{name} as a colour which can be used in later colour
-commands. For example
-\begin{verbatim}
+commands. For example:
+\begin{quote}
+  |\definecolor{light-blue}{rgb}{0.8,0.85,1}| \\
+  |\definecolor{mygrey}{gray}{0.75}|
+\end{quote}
 \definecolor{light-blue}{rgb}{0.8,0.85,1}
 \definecolor{mygrey}{gray}{0.75}
-\end{verbatim}
-\definecolor{light-blue}{rgb}{0.8,0.85,1}
-\definecolor{mygrey}{gray}{0.75}
 
 Now |light-blue| and |mygrey| may be used in addition to the
 predefined colours above.
@@ -227,7 +230,7 @@
 |\color|\arg{name}
 \end{decl}
 
-This is a \emph{declaration}, like |\bfseries| It changes the current
+This is a \emph{declaration}, like |\bfseries|. It changes the current
 colour to \m{name} until the end of the current group or
 environment.
 
@@ -259,7 +262,6 @@
 
 \subsubsection{Using colour specifications directly}
 
-
 \begin{decl}
 |\color|\oarg{model}\arg{specification}\\
 |\textcolor|\oarg{model}\arg{specification}\arg{text}\\
@@ -271,18 +273,23 @@
 a colour without naming it first. To achieve this |\color| (and all
 the other colour commands) take an optional argument specifying the
 model. If this is used then the mandatory argument takes a
-\m{colour specification} instead of a \m{name}. For example:\\
-|\color[rgb]{1,0.2,0.3}|\\
+\m{colour specification} instead of a \m{name}. For example:
+\begin{quote}
+  |\color[rgb]{1,0.2,0.3}|
+\end{quote}
 would directly select that colour.
 
-This is particularly useful for accessing the \textbf{named} model:\\
-|\color[named]{BrickRed}| selects the |dvips| colour BrickRed.
+This is particularly useful for accessing the \textbf{named} model:
+\begin{quote}
+  |\color[named]{BrickRed}|
+\end{quote}
+selects the |dvips| colour BrickRed.
 
 Rather than repeatedly use |[named]| you may use |\definecolor| to
-provide convenient aliases:\\
-|\definecolor{myred}{named}{WildStrawberry}|
-     \ldots\ |\color{myred}|\ \ldots
-
+provide convenient aliases:
+\begin{quote}
+  |\definecolor{myred}{named}{WildStrawberry}|\ldots |\color{myred}|\kern-10pt
+\end{quote}
 Alternatively if you are happy to use the existing names from the
 \textbf{named} model, you may use the |usenames| package option, which
 effectively calls |\definecolor| on every colour in the \textbf{named}
@@ -396,7 +403,7 @@
 The graphics packages have some other options for controlling how many
 of the features to enable:
 \begin{description}
-\item[draft] suppress all the `special' features. In particular
+\item[draft] Suppress all the `special' features. In particular
   graphics files are not included (but they are still read for size
   info) just the filename is printed in a box of the correct size.
 \item[final] The opposite of |draft|. Useful to over-ride a global
@@ -480,12 +487,14 @@
  Scale \emph{text} so that the width is \emph{h-length}.
  If |!| is used as either length argument, the other argument is used
  to determine a scale factor that is used in both directions.
- Normally \emph{v-length} refers to the height of the box, but in the
- star form, it refers to the `height +  depth'.
+ 
  As normal for \LaTeXe\ box length arguments, |\height|,
  |\width|, |\totalheight|, |\depth| may be used to refer to the
  original size of the box.
 
+ Normally \emph{v-length} refers to the height of the box, but in the
+ star form, |\resizebox*|, it refers to the `height +  depth'.
+ 
 |\resizebox{1in}{\height}{Some text}|:
 \resizebox{1in}{\height}{Some text}
 
@@ -492,6 +501,9 @@
 |\resizebox{1in}{!}{Some text}|:
 \resizebox{1in}{!}{Some text}
 
+|\resizebox{!}{20pt}{Q} \resizebox*{!}{20pt}{Q}|:
+\resizebox{!}{20pt}{Q} \resizebox*{!}{20pt}{Q}
+
 \subsection{Including Graphics Files}
 The functions for graphics inclusion try to give the same user syntax
 for including any kind of graphics file that can be understood by the
@@ -568,7 +580,7 @@
 with a driver-defined order of preference.
 |MediaBox| is always present.
 
-The |pagebox| key may be used to specify which bounding box specification to use,
+The |pagebox| key may be used to specify which bounding box specification to use.
 The value should be one of
 |mediabox|, |cropbox|, |bleedbox|, |trimbox|, |artbox|.
 \item[viewport]\NEWfeature{1995/06/01}
@@ -602,7 +614,7 @@
 \item[scale] Scale factor.
 \item[clip] Either `true' or `false' (or no value, which is equivalent
   to `true'). Clip the graphic to the bounding box.
-\item[draft] a boolean valued key, like `clip'. Locally switches to
+\item[draft] A boolean valued key, like `clip'. Locally switches to
   draft mode.
 \item[type] Specify the graphics type.
 \item[ext]  Specify the file extension. This should \emph{only} be
@@ -614,12 +626,16 @@
 \item[quiet]\NEWfeature{2017/06/01}
  Skip writing information to the log.
 \item[page]\NEWfeature{2017/06/01}
-Page of a multi-page PDF file. (by default the first page will be used.)
+Page of a multi-page PDF file. (By default the first page will be used.)
 \item[interpolate]\NEWfeature{2017/06/01}
 Enable/disable interpolation of bitmap images by the viewer.
+\item[alt]\NEWfeature{2021/09/16}
+  Alternative text for accessibility uses. By default this key is not used
+  but users are encouraged to add descriptive text here that may be used in
+  tagged PDF or as the |alt| attribute in conversions to HTML.
 \end{description}
 
-For the keys specifying the original size (i.e,, the bounding box,
+For the keys specifying the original size (i.e., the bounding box,
 trim and viewport keys) the units can be omitted, in
 which case bp (i.e., PostScript points) are assumed.
 
@@ -710,7 +726,7 @@
  as the directory separator, even on Windows.)
 
  The default setting of this path is
- |\input at path| that is: graphics files will be found wherever \TeX\
+ |\input at path|, so that graphics files will be found wherever \TeX\
  files are found.
 
 \begin{decl}
@@ -748,7 +764,7 @@
  extension from the \emph{ext-list} specified with
  |\DeclareGraphicsExtensions|.)
 
-\emph{ext} the file extension for which this rule applies. As a special
+\emph{ext} is the file extension for which this rule applies. As a special
 case, \emph{ext} may be given as |*| to denote the default behaviour for
 all undeclared extensions (see the example below).
 
@@ -838,7 +854,7 @@
 \section{Remaining packages in the graphics bundle}
 
 \subsection{Epsfig}
-This is a small package essentially a `wrapper' around the
+This is a small package, essentially a `wrapper' around the
 \package{graphicx} package, defining a command |\psfig| which has the
 syntax\\
 |\psfig{file=xxx,...}| rather than |\includegraphics[...]{xxx}|.\\
@@ -860,7 +876,7 @@
 with the \package{docstrip} options \texttt{plain,package}. In this case
 the \LaTeX\ package declarations are omitted from the file, and the
 macros may be directly used as part of another macro file (they work
-with any format based on plain \TeX.)
+with any format based on plain \TeX).
 
 \subsection{Keyval}
 The \package{keyval} package is intended to be used by other

Modified: trunk/Master/texmf-dist/doc/latex/graphics/keyval.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/graphics/lscape.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/graphics/mathcolor.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/graphics/rotating.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/graphics/rotex.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/graphics/trig.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/latex-lab/README.md	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/latex-lab/README.md	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 # LaTeX laboratory
 
-Release 2023-11-01
+Release 2024-06-01 patch level 0
 
 ## Overview
 
@@ -38,5 +38,5 @@
 
 This README file is
 
-Copyright (C) 2021-2023
+Copyright (C) 2021-2024
 The LaTeX Project

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/blocks-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/blocks-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/changes.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/latex-lab/changes.txt	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/latex-lab/changes.txt	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,12 +1,176 @@
+2024-05-25 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-table.dtx: disable table headers in presentation tables.
+
+2024-05-25 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-firstaid.dtx: add firstaid for booktabs cmidrules, 
+	see tagging-issue 69.
+
+2024-04-18 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* documentmetadata-support.dtx: change handling of default language. 
+	The code now tries to detect languages set by babel/polyglossia.
+
+2024-04-16 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-math.dtx: use tagging socket to disable math-writing if tagging
+	is suspended
+
+2024-03-24  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* latex-lab-namespace.xlsx:
+	File added (draft) replacing tagnames-commands.md
+
+2024-03-23 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* documentmetadata-support.dtx: keys for A4-E and A4-F
+
+2024-03-23  Yukai Chou  <muzimuzhi at gmail.com>
+
+	* latex-lab-float.dtx (subsection{Patching}):
+	Fix missing underscore (_) in csname
+	Adjust white space before comment in \end at dblfloat
+
+2024-03-23 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-block.dtx: store main text-unit number for marginpars.
+
+2024-03-22  David Carlisle  <David.Carlisle at latex-project.org>
+
+	* latex-lab-float.dtx (subsection{Patching}):
+	Adjust white space before comments
+
+2024-03-19  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* latex-lab-firstaid.dtx (subsection{verse}):
+	Added first aid for the verse package.
+
+	* latex-lab-block.dtx (subsection{Object and template interfaces}):
+	Change default for item-indent from 0pt to \itemindent. Otherwise, an
+	explicit setting for \itemindent in a legacy \list environment is
+	not picked up.
+
+2024-03-12  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* latex-lab-footnotes.dtx (section{Reimplementing the \pkg{footmisc} package}):
+	Typeset the footnote mark twice if the hang option is used. This means it can't
+	contain material that alter state, e.g., counters or labels.
+
+2024-03-11  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* latex-lab-footnotes.dtx (subsection{Debugging sockets and hooks}):
+	Added \DebugFNotesOn (and  \DebugFNotesOff) not doing much for
+	now. Default is now to have debugging turned off (gh/58).
+
+	(subsubsection{Making documents use the new \cs{@makefntext}}):
+	Before attempting to patch old classes or packages check if the new
+	definition of \@makefntext is the one that was suppliedd by footmisc for
+	the hang option. (gh/12)
+
+	(subsubsection{Making documents use the new \cs{@makefntext}}):
+	Some classes/styles use \makebox rather than \hb at xt@, so try to patch
+	them too. Of course, none of this is very robust. By the end of the
+	day well need updating to the new standard solution.
+
+2024-02-23 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-amsmath.dtx, latex-lab-mathpkg.dtx: handle \pbm and poormans \bm
+	(luatex only)
+
+2024-02-23 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* update tagpdf and pdfmanagement
+
+2024-02-16 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-graphic.dtx: move end structure behind \fi, tagging-project#64
+
+2024-02-12 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-block.dtx: left align description labels.
+
+2024-02-07 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-table.dtx: change value layout to presentation (as in ARIA).
+
+2024-02-09 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-math.dtx: add keys to suppress AF-files locally
+
+2024-02-09 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-title.dtx: force DisplayDocTitle if UA-standard is detected
+
+2024-02-08 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-testphase.dtx: add marginpar tagging to phase-III
+
+2024-02-08 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-math.dtx, latex-lab-table.dtx: adapt tagpdfsetup keys
+
+2024-02-07 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-table.dtx: change key names from table-tagging to table/tagging
+
+2024-02-05 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-float.dtx: fix caption outside float error
+
+2024-02-05 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-toc-kernel-changes.dtx: fix spurious space, tagging-project#50
+
+2024-01-29 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-math.dtx: disable mathgrabbing in begindocument hook.
+
+2024-01-18 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-firstaid.dtx: add support for \authors from amsart.
+
+2024-01-18 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-title.dtx: make \@title and \@author robust to avoid errors
+	if they are not set.
+
+2024-01-18 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-table.dtx: add support for layout tables.
+
+2024-01-18 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-block.dtx: add support to set an attribute-class for para-main.
+
+2024-01-18 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-table.dtx: add option table-tagging=layout
+
+2024-01-17 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-math.dtx, latex-lab-amsmath.dtx, redefine \text to
+	avoid faulty structure and faulty PDF from \mathchoice.
+	Add statistic for mathml handling.
+
+2024-01-14 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-float.dtx, correct destination, see tagging issue #55
+
+2024-01-14 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-block.dtx, correct error message for environments,
+	  see tagging issue #57
+
+2024-01-12 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-table.dtx: add some variables for tag names
+
+2024-01-08 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* move mathml-AF support into latex-lab-math.ltx
+
+2023-12-27 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* added latex-lab-title.dtx for maketitle/title and author tagging.
+
+2023-11-18 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-block.dtx, correct error message for items outside lists
+      see tagging issue #35
+
+2023-11-17 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-block.dtx, latex-lab-sec.dtx: use wrapper for para counter,
+      see tagging issue #34
+
+2023-11-12 Joseph Wright <Joseph.Wright at latex-project.org>
+	* latex-lab-math.dtx: tidy variant creation, switch to e-type expansion
+
+2023-11-05 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-math.dtx: remove processor in \(..\), see tagging issue #29
+
+2023-11-05 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+	* latex-lab-math.dtx: handle also tabular*, see tagging issue #25
+	* latex-lab-table.dtx: use cmd hook for array, see tagging issue #28
+
 2023-10-30 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
-	* added latex-lab-table.dtx for basic table tagging. 
+	* added latex-lab-table.dtx for basic table tagging.
 
 2023-10-21 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
 	* latex-lab-minipage.dtx: use sockets to allow local changes
 
 2023-10-13 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
-	* latex-lab-toc.dtx, latex-lab-sec.dtx, latex-lab-toc-kernel-changes: extend 
-      \MakeLinkTarget to store the target-structure relationship too, see tagging issue #20 
+	* latex-lab-toc.dtx, latex-lab-sec.dtx, latex-lab-toc-kernel-changes: extend
+      \MakeLinkTarget to store the target-structure relationship too, see tagging issue #20
 
 2023-10-13 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
 	* latex-lab-graphic.dtx: fix handling of scale factor, tagging issue #16
@@ -21,7 +185,7 @@
 2023-09-04 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
 	* label-lab-new-or-1.dtx latex-lab-new-or-2.dtx
       fix position of kernel hook in \@makecol (tagpdf issue #58)
-      
+
 2023-09-04 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
 	* documentmetadata-support.dtx: add debug key to load tagpdf-debug.
 	* new latex-lab-namespace.dtx with role mappings

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/documentmetadata-support-code.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/documentmetadata-support-doc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-amsmath.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-bib.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-block.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-firstaid.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-float.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-footnotes.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-graphic.pdf
===================================================================
(Binary files differ)

Added: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-marginpar.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-marginpar.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-marginpar.pdf	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-marginpar.pdf	2024-06-02 20:26:39 UTC (rev 71408)

Property changes on: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-marginpar.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-math.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-mathpkg.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-mathtools.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-minipage.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-namespace.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-new-or-1.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-new-or-2.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-sec.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-table.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-testphase.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-text.pdf
===================================================================
(Binary files differ)

Added: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-title.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-title.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-title.pdf	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-title.pdf	2024-06-02 20:26:39 UTC (rev 71408)

Property changes on: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-title.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-toc-hyperref-changes.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-toc-kernel-changes.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/latex-lab/latex-lab-toc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/tools/README.md	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/tools/README.md	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,7 +1,7 @@
 The LaTeX `tools` bundle
 ========================
 
-Release 2023-11-01c
+Release 2024-06-01 patch level 0
 
 Overview
 --------

Modified: trunk/Master/texmf-dist/doc/latex/tools/afterpage.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/array.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/bm.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/calc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/changes.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/tools/changes.txt	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/tools/changes.txt	2024-06-02 20:26:39 UTC (rev 71408)
@@ -10,6 +10,73 @@
 ================================================================================
 
 #########################
+# 2023-11-01 Release
+#########################
+
+2024-05-23  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* array.dtx:
+	* longtable.dtx:
+	* multicol.dtx:
+	* showkeys.dtx:
+	* varioref.dtx:
+	Do not error with "suspicous date" when rolling back to
+	early years of LaTeX2e (gh/1336)
+
+2024-05-09  Yukai Chou  <muzimuzhi at gmail.com>
+
+	* amsmath.dtx:
+	Fix typo in comment, \Umathcar -> \Umathchar (gh/1343)
+
+2024-04-10  Ulrike Fischer  <Ulrike.Fischer at latex-project.org>
+
+	* xr.dtx:
+	Merged in the code from xr-hyper. This extends xr to properly support
+	targets and links and also adds support for properties (gh/1180).
+
+2024-04-08  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* array.dtx (section{The insertion of declarations):
+	Do not \unskip if in math mode, this way explicit spaces at the
+	end of the math cell remain as it is with array env in core LaTeX (gh/1323)
+
+2024-03-13  David Carlisle  <David.Carlisle at latex-project.org>
+
+	* l3sys-query.dtx
+	New package, providing a document interface to the l3sys-query Lua script.
+
+2024-01-22 Lars Madsen <daleif at math.au.dk>
+
+        * verbatim.dtx: added TAB marking support to \verbatiminput* (gh/1245)
+
+2023-12-16  David Carlisle  <David.Carlisle at latex-project.org>
+
+	* showkeys.dtx: avoid adding extra box to \@labels gh/1123
+
+2023-12-16  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* longtable.dtx:
+	Support for tagged PDF
+	Manage and provide cell indexes
+
+2023-12-12  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* array.dtx:
+	Support for tagged PDF
+	Manage and provide cell indexes
+
+2023-12-11  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* tabularx.dtx:
+	Require newer LaTeX kernel (that supports tagging)
+	Suspend any tagging while doing trial typesetting
+
+2023-11-10  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* multicol.dtx (subsection{Maintaining the mark registers}]):
+	Get rid of forced breaks for mark extraction (gh/1130)
+
+#########################
 # 2023-11-01c Release
 #########################
 
@@ -16,7 +83,7 @@
 2023-11-06  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
 
 	* verbatim.dtx (subsection{Preliminaries}):
-	Update code so that that \verb does not show visible spaces (gh/1160)
+	Update code so that \verb does not show visible spaces (gh/1160)
 
 #########################
 # 2023-11-01b Release

Modified: trunk/Master/texmf-dist/doc/latex/tools/dcolumn.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/delarray.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/enumerate.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/fileerr.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/fontsmpl.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/ftnright.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/hhline.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/indentfirst.pdf
===================================================================
(Binary files differ)

Added: trunk/Master/texmf-dist/doc/latex/tools/l3sys-query.pdf
===================================================================
(Binary files differ)

Index: trunk/Master/texmf-dist/doc/latex/tools/l3sys-query.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/tools/l3sys-query.pdf	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/tools/l3sys-query.pdf	2024-06-02 20:26:39 UTC (rev 71408)

Property changes on: trunk/Master/texmf-dist/doc/latex/tools/l3sys-query.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Modified: trunk/Master/texmf-dist/doc/latex/tools/layout.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/longtable.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/multicol.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/rawfonts.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/shellesc.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/showkeys.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/somedefs.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/tabularx.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/theorem.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/tools-overview.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/tools-overview.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/tools/tools-overview.tex	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/doc/latex/tools/tools-overview.tex	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,7 +1,7 @@
 \NeedsTeXFormat{LaTeX2e}
 \ProvidesFile{tools-overview.tex}[2015/03/31 v1.0 Tools overview]
 
-% Copyright (C) 2006-2023
+% Copyright (C) 2006-2024
 %
 % The LaTeX Project and any individual authors listed elsewhere
 % in this file.

Modified: trunk/Master/texmf-dist/doc/latex/tools/trace.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/varioref.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/verbatim.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/xr.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/tools/xspace.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/makeindex/latex/gglo.ist
===================================================================
--- trunk/Master/texmf-dist/makeindex/latex/gglo.ist	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/makeindex/latex/gglo.ist	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 %%
 %% 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.
 
 
 

Modified: trunk/Master/texmf-dist/makeindex/latex/gind.ist
===================================================================
--- trunk/Master/texmf-dist/makeindex/latex/gind.ist	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/makeindex/latex/gind.ist	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 %%
 %% 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.
 
 
 

Modified: trunk/Master/texmf-dist/source/latex/amsmath/amsbsy.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/amsmath/amsbsy.ins	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/amsmath/amsbsy.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -26,7 +26,7 @@
 \preamble
 
 Copyright (C) 1995, 1999 American Mathematical Society.
-Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society.
+Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society.
 
 This work may be distributed and/or modified under the
 conditions of the LaTeX Project Public License, either version 1.3c

Modified: trunk/Master/texmf-dist/source/latex/amsmath/amscd.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/amsmath/amscd.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/amsmath/amscd.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -2,7 +2,7 @@
 % \iffalse meta-comment
 %
 % Copyright (C) 1995, 1999 American Mathematical Society.
-% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society.
+% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society.
 %
 % This work may be distributed and/or modified under the
 % conditions of the LaTeX Project Public License, either version 1.3c

Modified: trunk/Master/texmf-dist/source/latex/amsmath/amscd.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/amsmath/amscd.ins	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/amsmath/amscd.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 %%
 %% Copyright (C) 2010 American Mathematical Society.
-%% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society.
+%% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society.
 %%
 %% This work may be distributed and/or modified under the
 %% conditions of the LaTeX Project Public License, either version 1.3c
@@ -25,7 +25,7 @@
 \preamble
 
 Copyright (C) 1995, 1999 American Mathematical Society.
-Copyright (C) 2016-2023  LaTeX Project and American Mathematical Society.
+Copyright (C) 2016-2024  LaTeX Project and American Mathematical Society.
 
 This work may be distributed and/or modified under the
 conditions of the LaTeX Project Public License, either version 1.3c

Modified: trunk/Master/texmf-dist/source/latex/amsmath/amsgen.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/amsmath/amsgen.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/amsmath/amsgen.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -2,7 +2,7 @@
 % \iffalse meta-comment
 %
 % Copyright (C) 1995, 1999 American Mathematical Society.
-% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society.
+% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society.
 %
 % This work may be distributed and/or modified under the
 % conditions of the LaTeX Project Public License, either version 1.3c

Modified: trunk/Master/texmf-dist/source/latex/amsmath/amsgen.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/amsmath/amsgen.ins	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/amsmath/amsgen.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -25,7 +25,7 @@
 \preamble
 
 Copyright (C) 1995, 1999 American Mathematical Society.
-Copyright (C) 2016-2023  LaTeX Project and American Mathematical Society.
+Copyright (C) 2016-2024  LaTeX Project and American Mathematical Society.
 
 This work may be distributed and/or modified under the
 conditions of the LaTeX Project Public License, either version 1.3c

Modified: trunk/Master/texmf-dist/source/latex/amsmath/amsmath.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/amsmath/amsmath.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/amsmath/amsmath.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -2,7 +2,7 @@
 % \iffalse meta-comment
 %
 % Copyright (C) 1995, 2000, 2013 American Mathematical Society.
-% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society.
+% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society.
 %
 % This work may be distributed and/or modified under the
 % conditions of the LaTeX Project Public License, either version 1.3c
@@ -76,17 +76,16 @@
 [1994/12/01]% LaTeX date must be December 1994 or later
 %    \end{macrocode}
 %
-%    Providing a rollback to earlier version(s)
+%    Providing a rollback to earlier version(s). Anything prior to
+%    2018 we attempt to fulfill by using the version from 2018.
 %    \begin{macrocode}
-\providecommand\DeclareRelease[3]{}
-\providecommand\DeclareCurrentRelease[2]{}
-%
+\DeclareRelease{}{1994-06-01}{amsmath-2018-12-01.sty}
 \DeclareRelease{}{2018-12-01}{amsmath-2018-12-01.sty}
 \DeclareCurrentRelease{}{2019-04-01}
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\ProvidesPackage{amsmath}[2023/05/13 v2.17o AMS math features]
+\ProvidesPackage{amsmath}[2024/05/23 v2.17q AMS math features]
 %    \end{macrocode}
 %
 % \section{Catcode defenses}
@@ -1162,7 +1161,7 @@
 %    \begin{macrocode}
              \@xp\Umathch@\meaning@"0"\Umathch@
              \ifgtest@ % if \Umathchar
-             \else % else not \Umathcar
+             \else % else not \Umathchar
 %    \end{macrocode}
 %    \begin{macrocode}
            \@xp\macro@\meaning@@\macro@
@@ -4153,6 +4152,12 @@
 %    cause \cs{row@} to be advanced twice instead of once.
 %    \begin{macrocode}
     \global\advance\row@\@ne
+%    \end{macrocode}
+%    Also reset \cs{lineht@} to avoid that this is incorrectly picked
+%    up by a following environment, such as \env{align}.
+% \changes{v2.17p}{2024/03/11}{Reset \cs{lineht@} (gh/1289)}
+%    \begin{macrocode}
+    \global\lineht@\z@
     \cr
 }
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/amsmath/amsmath.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/amsmath/amsmath.ins	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/amsmath/amsmath.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 %%
 %% Copyright (C) 2010 American Mathematical Society.
-%% Copyright (C) 2016-2023  LaTeX Project and American Mathematical Society.
+%% Copyright (C) 2016-2024  LaTeX Project and American Mathematical Society.
 %%
 %% This work may be distributed and/or modified under the
 %% conditions of the LaTeX Project Public License, either version 1.3c
@@ -25,7 +25,7 @@
 \preamble
 
 Copyright (C) 1995, 1999, 2000, 2013 American Mathematical Society.
-Copyright (C) 2016-2023  LaTeX Project and American Mathematical Society.
+Copyright (C) 2016-2024  LaTeX Project and American Mathematical Society.
 
 This work may be distributed and/or modified under the
 conditions of the LaTeX Project Public License, either version 1.3c

Modified: trunk/Master/texmf-dist/source/latex/amsmath/amsopn.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/amsmath/amsopn.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/amsmath/amsopn.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -2,7 +2,7 @@
 % \iffalse meta-comment
 %
 % Copyright (C) 1995, 1999 American Mathematical Society.
-% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society.
+% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society.
 %
 % This work may be distributed and/or modified under the
 % conditions of the LaTeX Project Public License, either version 1.3c

Modified: trunk/Master/texmf-dist/source/latex/amsmath/amsopn.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/amsmath/amsopn.ins	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/amsmath/amsopn.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 %%
 %% Copyright (C) 2010 American Mathematical Society.
-%% Copyright (C) 2016-2023  LaTeX Project and American Mathematical Society.
+%% Copyright (C) 2016-2024  LaTeX Project and American Mathematical Society.
 %%
 %% This work may be distributed and/or modified under the
 %% conditions of the LaTeX Project Public License, either version 1.3c
@@ -25,7 +25,7 @@
 \preamble
 
 Copyright (C) 1995, 1999 American Mathematical Society.
-Copyright (C) 2016-2023  LaTeX Project and American Mathematical Society.
+Copyright (C) 2016-2024  LaTeX Project and American Mathematical Society.
 
 This work may be distributed and/or modified under the
 conditions of the LaTeX Project Public License, either version 1.3c

Modified: trunk/Master/texmf-dist/source/latex/amsmath/amstext.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/amsmath/amstext.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/amsmath/amstext.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -2,7 +2,7 @@
 % \iffalse meta-comment
 %
 % Copyright (C) 1995, 1999 American Mathematical Society.
-% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society.
+% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society.
 %
 % This work may be distributed and/or modified under the
 % conditions of the LaTeX Project Public License, either version 1.3c

Modified: trunk/Master/texmf-dist/source/latex/amsmath/amstext.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/amsmath/amstext.ins	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/amsmath/amstext.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 %%
 %% Copyright (C) 2010 American Mathematical Society.
-%% Copyright (C) 2016-2023  LaTeX Project and American Mathematical Society.
+%% Copyright (C) 2016-2024  LaTeX Project and American Mathematical Society.
 %%
 %% This work may be distributed and/or modified under the
 %% conditions of the LaTeX Project Public License, either version 1.3c
@@ -25,7 +25,7 @@
 \preamble
 
 Copyright (C) 1995, 1999 American Mathematical Society.
-Copyright (C) 2016-2023  LaTeX Project and American Mathematical Society.
+Copyright (C) 2016-2024  LaTeX Project and American Mathematical Society.
 
 This work may be distributed and/or modified under the
 conditions of the LaTeX Project Public License, either version 1.3c

Modified: trunk/Master/texmf-dist/source/latex/amsmath/amsxtra.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/amsmath/amsxtra.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/amsmath/amsxtra.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -2,7 +2,7 @@
 % \iffalse meta-comment
 %
 % Copyright (C) 1995, 1999 American Mathematical Society.
-% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society.
+% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society.
 %
 % This work may be distributed and/or modified under the
 % conditions of the LaTeX Project Public License, either version 1.3c

Modified: trunk/Master/texmf-dist/source/latex/amsmath/amsxtra.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/amsmath/amsxtra.ins	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/amsmath/amsxtra.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 %%
 %% Copyright (C) 2010 American Mathematical Society.
-%% Copyright (C) 2016-2023  LaTeX Project and American Mathematical Society.
+%% Copyright (C) 2016-2024  LaTeX Project and American Mathematical Society.
 %%
 %% This work may be distributed and/or modified under the
 %% conditions of the LaTeX Project Public License, either version 1.3c
@@ -25,7 +25,7 @@
 \preamble
 
 Copyright (C) 1995, 1999 American Mathematical Society.
-Copyright (C) 2016-2023  LaTeX Project and American Mathematical Society.
+Copyright (C) 2016-2024  LaTeX Project and American Mathematical Society.
 
 This work may be distributed and/or modified under the
 conditions of the LaTeX Project Public License, either version 1.3c

Modified: trunk/Master/texmf-dist/source/latex/base/alltt.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/alltt.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/alltt.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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{$}.

Modified: trunk/Master/texmf-dist/source/latex/base/classes.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/classes.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/classes.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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}

Modified: trunk/Master/texmf-dist/source/latex/base/doc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/doc.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/doc.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -34,9 +34,9 @@
 %\catcode`\<=14
 %<+package|shortvrb>\NeedsTeXFormat{LaTeX2e}[1994/12/01]
 %<+package>
-%<+package>\providecommand\DeclareRelease[3]{}
-%<+package>\providecommand\DeclareCurrentRelease[2]{}
-%<+package>
+% Any rollback request before 2016-02-15 we try to fullfil with the 2016 version:
+%<+package>\DeclareRelease{}{1994-06-01}
+%<+package>                      {doc-2016-02-15.sty}
 %<+package>\DeclareRelease{v2.1g}{2016-02-15}
 %<+package>                      {doc-2016-02-15.sty}
 %<+package>\DeclareRelease{v2}{2021-06-01}
@@ -45,7 +45,7 @@
 %<+package>
 %<+package>\ProvidesPackage{doc}
 %<+shortvrb>\ProvidesPackage{shortvrb}
-%<+package|shortvrb>  [2022/11/13 v3.0m
+%<+package|shortvrb>  [2024/04/26 v3.0p
 %<+package|shortvrb>   Standard LaTeX documentation package V3 (FMi)]
 %\catcode`\<=12
 %
@@ -57,7 +57,7 @@
 %
 %
 %% Package `doc' to use with LaTeX 2e
-%% Copyright (C) 1989-2022 Frank Mittelbach, all rights reserved.
+%% Copyright (C) 1989-2023 Frank Mittelbach, all rights reserved.
 %
 %
 % Version:     Date:     Changes:
@@ -143,8 +143,8 @@
 % \MakeShortVerb{\|}
 % \setcounter{StandardModuleDepth}{1}
 %
-% {\catcode`\p=12 \catcode`\t=12 ^^A hack used later on to print
-% \gdef\dimenvalue#1pt{$#1$pt}}  ^^A a register value with a - sign
+% {\catcode`\p=12 \catcode`\t=12 ^^A hack used later on to print a
+% \gdef\dimenvalue#1pt{$#1$pt}}  ^^A register value with a - sign
 %
 % \newcommand{\DOC}{\texttt{doc}\xspace}
 %
@@ -167,7 +167,7 @@
 %\RenewDocElement[macrolike = true ,
 %		 toplevel  = false,
 %                idxtype   = ,
-%                idxgroup  = LaTeX comands\actualchar\LaTeX{} commands ,
+%                idxgroup  = LaTeX commands\actualchar\LaTeX{} commands ,
 %                printtype =
 %               ]{Macro}{macro}
 %
@@ -237,7 +237,7 @@
 % \changes{v1.9t}{1995/05/11}{Use \cs{GetFileInfo}}
 % \GetFileInfo{doc.sty}
 %
-% \CheckSum{0}  ^^A % keep the checksum in this file but not now :-)
+% \CheckSum{0}
 %
 % \title{The \DOC{} and \texttt{shortvrb} Packages\thanks
 %    {This file has version number \fileversion{} dated \filedate{}.}}
@@ -595,8 +595,17 @@
 % 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
 % environment \texttt{environment} which works like the \texttt{macro}
@@ -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 at noligs \verbatim at 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 at font} for NFSS.}
 % \changes{v1.8c}{1993/10/25}{NFSS standard}
 % \changes{v1.9t}{1995/05/26}{Removed \cs{math at fontsfalse} (different
-%                             math setup /pr1622}
+%                             math setup /pr1622)}
 %    \begin{macrocode}
 \@ifundefined{MacroFont}{%
   \if at 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 at 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 at 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 at 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 at 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 at escape@char|) equal
+%          (i.e., the expansion of |\active at escape@char|) equal
 %          |\scan at macro|.
 %    \end{itemize}
 %    The reader might ask why we bother to |\catcode| the
 %    `|\|' first to 12 (at the end of |\macro at 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 at code| would not be found (parameter matching
@@ -2930,7 +2948,7 @@
 %    \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 at crossref{|catcode`|\|active   |let\|bslash
@@ -2937,7 +2955,7 @@
 %    \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 at macro|, i.e.\ fulfill tasks 4)
-%    and 5). Note the use of |\expandafter| to insert the chosen
+%    |\let| it equal |\scan at macro|, i.e., fulfill tasks (4)
+%    and (5). Note the use of |\expandafter| to insert the chosen
 %    escape character saved in |\special at escape@char| and
 %    |\active at escape@char|.
 %    \SpecialEscapechar\|
@@ -2955,7 +2973,7 @@
     |expandafter|let|active at escape@char|scan at 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 at excluded| macro which assumes that the
 %    macro name is saved in |\macro at 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 at 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 at 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 at 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,7 +5959,17 @@
 %    \end{macrocode}
 %  \end{macro}
 %
+%  \begin{macro}{\doc at ignoredinfo}
 %
+%    \begin{macrocode}
+\def\doc at 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 at ignoredinfo
+               }\doc at ignoredinfo
+           }\doc at ignoredinfo
+      }\doc at 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,87 +6259,7 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 
-% \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 at noligs \verbatim at nolig@list
-%    \ttfamily \verb at eol@error \let\do\@makeother \dospecials
-%    \@ifstar{\@sverb}{\@vobeyspaces \frenchspacing \@sverb}}
-%    \end{macrocode}
-% \end{imacro}
-%
-% \begin{macro}{\verb at balance@group}
-% \begin{macro}{\verb at egroup}
-% \begin{macro}{\verb at eol@error}
-% \changes{v1.8b}{1993/09/21}{Renamed \cs{verb at err} to
-%                   \cs{verb at eol@error}, as in new LaTeX verbatim.}
-%    \begin{macrocode}
-%\let\verb at balance@group\@empty
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-%\def\verb at egroup{\global\let\verb at balance@group\@empty\egroup}
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-%\begingroup
-%  \obeylines%
-%  \gdef\verb at eol@error{\obeylines%
-%    \def^^M{\verb at egroup\@latex at 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 at balance@group{\verb at egroup
-%     \@latex at error{Illegal use of \noexpand\verb command}\@ehc}%
-%  \aftergroup\verb at balance@group
-%  \lowercase{\let~\verb at egroup}}
-%    \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{\verbatim at nolig@list}
-% \begin{macro}{\do at noligs}
-%     These macros replace the old |\@noligs| mechanism by an
-%     extensible version to allow more ligatures to be added.
-%    \begin{macrocode}
-%\def\verbatim at nolig@list{\do\`\do\<\do\>\do\,\do\'\do\-}
-%\def\do at 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
 ^^A  Local Variables: 

Modified: trunk/Master/texmf-dist/source/latex/base/docstrip.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/docstrip.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/docstrip.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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 @@
 %    \end{macrocode}
 %
 %  \begin{macro}{\quote at 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 @@
 %    \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 @@
 %    \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 @@
 %      {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 at first@batchfile{%
   \processbatchFile

Modified: trunk/Master/texmf-dist/source/latex/base/fontdef.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/fontdef.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/fontdef.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -27,7 +27,8 @@
 %
 % \fi
 % \iffalse
-%%% From File: fontdef.dtx
+%%%   From File: fontdef.dtx
+%<*!latexrelease>
 %<*dtx>
            \ProvidesFile{fontdef.dtx}
 %</dtx>
@@ -38,18 +39,25 @@
 %<+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
 %
 % File `fontdef.dtx'.

Modified: trunk/Master/texmf-dist/source/latex/base/format.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/format.ins	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/format.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -170,6 +170,7 @@
           \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 @@
           \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 @@
           \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}{%

Modified: trunk/Master/texmf-dist/source/latex/base/ifthen.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ifthen.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ifthen.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -30,7 +30,7 @@
 %%
 %% File `ifthen.dtx'.
 %% Copyright (C) 1991 by Leslie Lamport
-%% Copyright (C) 1994-2001 LaTeX project, David Carlisle
+%% Copyright (C) 1994-2024 LaTeX project, David Carlisle
 %%                       all rights reserved.
 %%
 %
@@ -42,7 +42,7 @@
 %<driver>\ProvidesFile{ifthen.drv}
 % \fi
 %         \ProvidesFile{ifthen.dtx}
-          [2022/04/13 v1.1d Standard LaTeX ifthen package (DPC)]
+          [2024/03/16 v1.1e Standard LaTeX ifthen package (DPC)]
 %
 % \iffalse
 %<*driver>
@@ -273,9 +273,26 @@
          \ifx##1\relax\z@\else\expandafter##2##1\fi}}}
 %    \end{macrocode}
 %    \begin{macrocode}
+\begingroup
+\lccode`\~`\> %
+\catcode`\+\active
+\lccode`\+`\< %
+\catcode`\!\active
+\lccode`\!`\= %
+\lowercase{\endgroup
+%    \end{macrocode}
+%    \begin{macrocode}
+\def\TE at repl@active{%
+  \TE at repl~>%
+  \TE at repl+<%
+  \TE at repl!=%
+}
+%    \end{macrocode}
+%    \begin{macrocode}
 \long\def\ifthenelse#1{%
 %    \end{macrocode}
 % \changes{v1.0h}{1994/05/14}{Use \cs{TE at repl}}
+% \changes{v1.1e}{2024/03/16}{replace active \cs{ifnum} syntax}
 %    \begin{macrocode}
   \toks@{#1}%
   \TE at repl\or\TE at or
@@ -282,6 +299,9 @@
   \TE at repl\and\TE at and
   \TE at repl\not\TE at neg
 %    \end{macrocode}
+%    \begin{macrocode}
+  \TE at repl@active
+%    \end{macrocode}
 %
 % \changes{v1.1c}{2001/05/25}{Added \cs{AND}, \cs{OR} and \cs{NOT} as
 %    boolean operators as alternative to the lower case versions
@@ -353,8 +373,11 @@
           \expandafter\@firstoftwo
         \else
           \expandafter\@secondoftwo
-        \fi}
+        \fi}%
 %    \end{macrocode}
+%    \begin{macrocode}
+}
+%    \end{macrocode}
 % \end{macro}
 %
 % \begin{macro}{\TE at eval}

Modified: trunk/Master/texmf-dist/source/latex/base/inputenc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/inputenc.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/inputenc.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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

Modified: trunk/Master/texmf-dist/source/latex/base/latexrelease.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/latexrelease.ins	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/latexrelease.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -97,6 +97,7 @@
   \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

Modified: trunk/Master/texmf-dist/source/latex/base/ltboxes.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltboxes.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltboxes.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -33,7 +33,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltboxes.dtx}
-             [2023/10/26 v1.4e LaTeX Kernel (Box Commands)]
+             [2024/04/22 v1.4f LaTeX Kernel (Box Commands)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltboxes.dtx}
@@ -87,7 +87,7 @@
 % Note that in this picture mode version of |\makebox| a [b] aligns on
 % the \emph{bottom} of the text as documented. If you want to align on
 % the \emph{baseline} use
-%  |\makebox( , )[b]{\raisebox{0pt}[\height][0pt]{xyz}}}|
+%  |\makebox( , )[b]{\raisebox{0pt}[\height][0pt]{xyz}}|
 %  or |\makebox( , )[b]{\smash{xyz}}|
 %
 % \DescribeMacro\mbox
@@ -235,7 +235,8 @@
 % \begin{macro}{\makebox}
 % \changes{v0.1a}{1993/12/03}
 %         {modified}
-% |\makebox| User level command just looks for optional |[| or |(|.
+% |\makebox| User level command just looks for optional
+% |[| or |(|. \iffalse)]\fi
 % \changes{v1.1h}{2015/01/08}{Make Robust (latexrelease)}
 %    \begin{macrocode}
 %</2ekernel>
@@ -1010,7 +1011,7 @@
 % set globally to false when they are definitely true.
 %
 % If anyone is unhappy with this argument then both flags should be
-% treated as in |\set at nobreak|; otherwise this command will be
+% treated as in |\@setnobreak|; otherwise this command will be
 % redundant.
 % \changes{v1.1a}{1996/10/24}{Added local settings of flags: dangerous!!}
 %    \begin{macrocode}
@@ -1486,9 +1487,40 @@
 %
 % The |\nobreak| was added (1995/10/31) to allow hyphenation of the
 % final word of the paragraph.
+%
+%    In 2024 we changed the macro to account for vertical mode. In
+%    that case we use a strut produced with \cs{hrule} to avoid
+%    starting a new paragraph (resulting in spurious extra line) and
+%    also account for the \cs{prevdepth} of the previous line.
+% \changes{v1.4f}{2024/04/18}
+%         {Use a \cs{hrule} strut not a \cs{vrule} if already in
+%          vertical mode (bug seen first with footmisc/14)}
 %    \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2024/06/01}%
+%<latexrelease>                 {\@finalstrut}{final strut correction}%
 \def\@finalstrut#1{%
-  \unskip\ifhmode\nobreak\fi\vrule\@width\z@\@height\z@\@depth\dp#1}
+  \unskip
+  \ifhmode \nobreak \vrule
+  \else
+    \ifdim \prevdepth=-\@m\p@
+    \else
+      \vskip-\prevdepth
+    \fi
+    \hrule
+  \fi
+  \@width\z@\@height\z@\@depth\dp#1}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\@finalstrut}{final strut correction}%
+%<latexrelease>\def\@finalstrut#1{%
+%<latexrelease>  \unskip\ifhmode\nobreak\fi
+%<latexrelease>  \vrule\@width\z@\@height\z@\@depth\dp#1}
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
 %    \end{macrocode}
 %  \end{macro}
 %

Modified: trunk/Master/texmf-dist/source/latex/base/ltclass.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltclass.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltclass.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -33,7 +33,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltclass.dtx}
-             [2023/04/14 v1.5h LaTeX Kernel (Class & Package Interface)]
+             [2024/04/10 v1.5k LaTeX Kernel (Class & Package Interface)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltclass.dtx}
@@ -390,7 +390,7 @@
 %       package files.)
 %
 % |\DeclareOption*{\PassOptionsToPackage{\CurrentOption}|^^A
-%                                     |{|\meta{pkg-name}|}|\\
+%                                     |{|\meta{pkg-name}|}}|\\
 % Handle the current option by passing it on to the package
 % \meta{pkg-name}, which will presumably be loaded via
 % |\RequirePackage| later in the file. This is useful for building
@@ -1075,19 +1075,20 @@
 %    \begin{macrocode}
 %</2ekernel>
 %<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2021/11/15}%
-%<latexrelease>                 {\IfPackageLoadedtTF}{Test package loading}%
+%<latexrelease>\IncludeInRelease{2024/06/01}%
+%<latexrelease>                 {\IfPackageLoadedTF}{Test package loading}%
 \let \IfPackageLoadedTF            \@ifpackageloaded
 \let \IfClassLoadedTF              \@ifclassloaded
 \let \IfPackageLoadedWithOptionsTF \@ifpackagewith
 \let \IfClassLoadedWithOptionsTF   \@ifclasswith
 %    \end{macrocode}
-%    For rollback pretend it was available since the beginning of dawn.
+%    For rollback/rollforward pretend everything was available since
+%    the beginning of dawn.
 %    \begin{macrocode}
 %</2ekernel|latexrelease>
 %<latexrelease>\EndIncludeInRelease
 %<latexrelease>\IncludeInRelease{0000/00/00}%
-%<latexrelease>                 {\IfPackageLoadedtTF}{Test package loading}%
+%<latexrelease>                 {\IfPackageLoadedTF}{Test package loading}%
 %<latexrelease>
 %<latexrelease>\let \IfPackageLoadedTF            \@ifpackageloaded
 %<latexrelease>\let \IfClassLoadedTF              \@ifclassloaded
@@ -1102,6 +1103,99 @@
 %
 %
 %
+%  \begin{macro}{
+%    \IfPackageLoadedT,\IfPackageLoadedF,
+%    \IfPackageAtLeastT,\IfPackageAtLeastF,
+%    \IfClassAtLeastT,\IfClassAtLeastF,
+%    \IfFileAtLeastT,\IfFileAtLeastF,
+%    \IfFormatAtLeastT,\IfFormatAtLeastF,
+%    \IfPackageLoadedWithOptionsT,\IfPackageLoadedWithOptionsF,
+%    \IfClassLoadedT,\IfClassLoadedF,
+%    \IfClassLoadedWithOptionsF,\IfClassLoadedWithOptionTF
+%   }
+%    A few more conditionals for convenience
+% \changes{v1.5k}{2024/04/10}{Provide T and F conditionals not just TF
+%    (gh/1262)}
+%    \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2024/06/01}%
+%<latexrelease>                 {\IfPackageLoadedT}{More conditionals}%
+\def\IfPackageLoadedT #1#2{\IfPackageLoadedTF{#1}{#2}{}}
+\def\IfPackageLoadedF   #1{\IfPackageLoadedTF{#1}{}}
+\def\IfClassLoadedT   #1#2{\IfClassLoadedTF{#1}{#2}{}}
+\def\IfClassLoadedF     #1{\IfClassLoadedTF{#1}{}}
+\def\IfPackageAtLeastT#1#2#3{\IfPackageAtLeastTF{#1}{#2}{#3}{}}
+\def\IfPackageAtLeastF  #1#2{\IfPackageAtLeastTF{#1}{#2}{}}
+\def\IfClassAtLeastT  #1#2#3{\IfClassAtLeastTF{#1}{#2}{#3}{}}
+\def\IfClassAtLeastF    #1#2{\IfClassAtLeastTF{#1}{#2}{}}
+\def\IfFileAtLeastT   #1#2#3{\IfFileAtLeastTF{#1}{#2}{#3}{}}
+\def\IfFileAtLeastF     #1#2{\IfFileAtLeastTF{#1}{#2}{}}
+\def\IfFormatAtLeastT   #1#2{\IfFormatAtLeastTF{#1}{#2}{}}
+\def\IfFormatAtLeastF     #1{\IfFormatAtLeastTF{#1}{}}
+\def\IfPackageLoadedWithOptionsT #1#2#3{\IfPackageLoadedWithOptionsTF{#1}{#2}{#3}{}}
+\def\IfPackageLoadedWithOptionsF   #1#2{\IfPackageLoadedWithOptionsTF{#1}{#2}{}}
+\def\IfClassLoadedWithOptionsT #1#2#3{\IfClassLoadedWithOptionsTF{#1}{#2}{#3}{}}
+\def\IfClassLoadedWithOptionsF   #1#2{\IfClassLoadedWithOptionsTF{#1}{#2}{}}
+%    \end{macrocode}
+%    
+%  \begin{macro}{\IfFileLoadedTF,\IfFileLoadedT,\IfFileLoadedF}
+%    These three commands haven't been there at all in the past.
+% \changes{v1.5k}{2024/04/10}{Provide \cs{IfFileLoadedTF} and variants
+%    (gh/1222)}
+%    \begin{macrocode}
+\def\IfFileLoadedTF#1{%
+  \expandafter\ifx\csname ver@#1\endcsname\relax
+    \expandafter\@secondoftwo
+  \else
+    \expandafter\@firstoftwo
+  \fi}
+\def\IfFileLoadedT#1#2{\IfFileLoadedTF{#1}{#2}{}}
+\def\IfFileLoadedF  #1{\IfFileLoadedTF{#1}{}}
+%    \end{macrocode}
+%    For rollback/rollforward pretend everything was available since
+%    the beginning of dawn.
+%    \begin{macrocode}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\IfPackageLoadedT}{More conditionals}%
+%<latexrelease>
+%<latexrelease>\def\IfPackageLoadedT #1#2{\IfPackageLoadedTF{#1}{#2}{}}
+%<latexrelease>\def\IfPackageLoadedF   #1{\IfPackageLoadedTF{#1}{}}
+%<latexrelease>\def\IfClassLoadedT   #1#2{\IfClassLoadedTF{#1}{#2}{}}
+%<latexrelease>\def\IfClassLoadedF     #1{\IfClassLoadedTF{#1}{}}
+%<latexrelease>\def\IfPackageAtLeastT#1#2#3{\IfPackageAtLeastTF{#1}{#2}{#3}{}}
+%<latexrelease>\def\IfPackageAtLeastF  #1#2{\IfPackageAtLeastTF{#1}{#2}{}}
+%<latexrelease>\def\IfClassAtLeastT  #1#2#3{\IfClassAtLeastTF{#1}{#2}{#3}{}}
+%<latexrelease>\def\IfClassAtLeastF    #1#2{\IfClassAtLeastTF{#1}{#2}{}}
+%<latexrelease>\def\IfFileAtLeastT   #1#2#3{\IfFileAtLeastTF{#1}{#2}{#3}{}}
+%<latexrelease>\def\IfFileAtLeastF     #1#2{\IfFileAtLeastTF{#1}{#2}{}}
+%<latexrelease>\def\IfFormatAtLeastT   #1#2{\IfFormatAtLeastTF{#1}{#2}{}}
+%<latexrelease>\def\IfFormatAtLeastF     #1{\IfFormatAtLeastTF{#1}{}}
+%<latexrelease>\def\IfPackageLoadedWithOptionsT #1#2#3{\IfPackageLoadedWithOptionsTF{#1}{#2}{#3}{}}
+%<latexrelease>\def\IfPackageLoadedWithOptionsF   #1#2{\IfPackageLoadedWithOptionsTF{#1}{#2}{}}
+%<latexrelease>\def\IfClassLoadedWithOptionsT #1#2#3{\IfClassLoadedWithOptionsTF{#1}{#2}{#3}{}}
+%<latexrelease>\def\IfClassLoadedWithOptionsF   #1#2{\IfClassLoadedWithOptionsTF{#1}{#2}{}}
+%<latexrelease>
+%<latexrelease>\def\IfFileLoadedTF#1{%
+%<latexrelease>  \expandafter\ifx\csname ver@#1\endcsname\relax
+%<latexrelease>    \expandafter\@secondoftwo
+%<latexrelease>  \else
+%<latexrelease>    \expandafter\@firstoftwo
+%<latexrelease>  \fi}
+%<latexrelease>\def\IfFileLoadedT#1#2{\IfFileLoadedTF{#1}{#2}{}}
+%<latexrelease>\def\IfFileLoadedF  #1{\IfFileLoadedTF{#1}{}}
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%
+%
+%
+%
 % \begin{macro}{\ProvidesPackage}
 %    Checks that the current filename is correct, and defines
 %    |\ver at filename|.
@@ -1327,11 +1421,11 @@
 % \changes{v1.4c}{2021/06/06}
 %         {apply \cs{expandafter} to raw options for gh/580}
 %    \begin{macrocode}
-    \@ifundefined{@raw at opt@#3.#1}%
-      {\expandafter\gdef\csname @raw at opt@#3.#1\expandafter\endcsname
-                \expandafter{#2}}%
-      {\expandafter\g at addto@macro\csname @raw at opt@#3.#1\expandafter\endcsname
-                \expandafter{\expandafter,#2}}%
+  \@ifundefined{@raw at opt@#3.#1}%
+    {\expandafter\gdef\csname @raw at opt@#3.#1\expandafter\endcsname
+              \expandafter{#2}}%
+    {\expandafter\g at addto@macro\csname @raw at opt@#3.#1\expandafter\endcsname
+              \expandafter{\expandafter,#2}}%
 }
 %</2ekernel|latexrelease>
 %<latexrelease>\EndIncludeInRelease
@@ -1950,12 +2044,34 @@
 % \end{macro}
 %
 % \begin{macro}{\@fileswithoptions}
+% \changes{v1.5i}{2024/01/30}{Test group level}
 % The common part of |\documentclass| and |\usepackage|.
 %    \begin{macrocode}
+%</2ekernel>
+%<latexrelease>\IncludeInRelease{2024/06/01}%
+%<latexrelease>                 {\@fileswithoptions}{Check Group}%
+%<*2ekernel|latexrelease>
 \def\@fileswithoptions#1{%
+    \ifnum\currentgrouplevel>\z@
+     \@latex at error
+      {Loading a class or package in a group}%
+      {Classes and packages should only be loaded at the top level}%
+  \fi
   \@ifnextchar[%]
     {\@fileswith at ptions#1}%
     {\@fileswith at ptions#1[]}}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\@fileswithoptions}{Check Group}%
+%<latexrelease>\def\@fileswithoptions#1{%
+%<latexrelease>  \@ifnextchar[%]
+%<latexrelease>    {\@fileswith at ptions#1}%
+%<latexrelease>    {\@fileswith at ptions#1[]}}
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+%    \end{macrocode}
+%    \begin{macrocode}
 \@onlypreamble\@fileswithoptions
 %    \end{macrocode}
 %
@@ -2221,9 +2337,17 @@
 %    \end{macrocode}
 % \changes{v1.5d}{2022/10/10}{Use \cs{protected at edef}.}
 %    \begin{macrocode}
-          \expandafter\protected at edef\csname opt@\@currname.\@currext\endcsname
+          \expandafter\protected at edef
+            \csname opt@\@currname.\@currext\endcsname
             {\zap at space#2 \@empty}%
-          \@namedef{@raw at opt@\@currname.\@currext}{#2}%
+%    \end{macrocode}
+% \changes{v1.5j}{2024/03/22}
+%         {Apply one-step expansion to raw option list,
+%          to be consistent with change for gh/580 (gh/1298).}
+%    \begin{macrocode}
+          \expandafter\def
+            \csname @raw at opt@\@currname.\@currext\expandafter\endcsname
+            \expandafter{#2}%
           \@nameuse{opt at handler@\@currname.\@currext}%
         }%
     }%
@@ -2624,8 +2748,8 @@
 %
 % Allow code to be saved to be executed at specific later times.
 %
-% Save things in macros, I considered using toks registers, (and
-% |\addto at hook| from the NFSS code, that would require stacking the
+% Here we save things in macros. I considered using toks registers (and
+% |\addto at hook| from the NFSS code), but that would require stacking the
 % contents in the case of required packages, so just generate a new
 % macro for each package.
 % \begin{macro}{\@begindocumenthook}
@@ -2997,7 +3121,7 @@
   \let\do\@makeother\dospecials%
 %    \end{macrocode}
 %    If there are active characters in the upper half (e.g., from
-%    \texttt{inputenc} there would be confusion so we render everything
+%    \texttt{inputenc}) there would be confusion so we render everything
 %    harmless.
 % \changes{v1.2f}{2018/03/27}
 %         {Use full file name for old release}
@@ -3585,7 +3709,7 @@
 %    and therefore we can now test its value. If the value is zero we
 %    assume that the remaining argument string represents a version
 %    and change |\pkgcls at targetdate| and set |\pkgcls at targetlabel| to
-%    the version name (after stripping off the trailing \texttt{=}.
+%    the version name (after stripping off the trailing \texttt{=}).
 %    \begin{macrocode}
       \ifnum \pkgcls at targetdate=\z@
         \pkgcls at targetdate\@ne
@@ -3695,7 +3819,7 @@
 %    late, but if there wasn't one (i.e., if current release is the
 %    oldest that exists) we use it as the best choice. However in
 %    that case something is wrong (as there shouldn't be a rollback to
-%    a date where a package used doesn't yet exists. So we make a
+%    a date when a package used didn't yet exists). So we make a
 %    complained to the user.
 %    \begin{macrocode}
           \ifx\pkgcls at candidate\@empty

Modified: trunk/Master/texmf-dist/source/latex/base/ltcmd.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltcmd.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltcmd.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -34,8 +34,8 @@
 %%% From File: ltcmd.dtx
 %
 %    \begin{macrocode}
-\def\ltcmdversion{v1.2a}
-\def\ltcmddate{2023-08-19}
+\def\ltcmdversion{v1.2e}
+\def\ltcmddate{2024-04-17}
 %    \end{macrocode}
 %
 %<*driver>
@@ -415,8 +415,6 @@
 \cs_new_protected:Npn \@@_declare_cmd_internal:Nnnn #1#2#3#4
   {
     \tl_set:Nx \l_@@_function_tl { \cs_to_str:N #1 }
-    \tl_set:Nx \l_@@_fn_tl
-      { \exp_not:c { \l_@@_function_tl \c_space_tl } }
     \@@_normalize_arg_spec:n {#2}
     \exp_args:No \@@_prepare_signature:n \l_@@_arg_spec_tl
     \@@_declare_cmd_code:Nnn #1 {#2} {#3}
@@ -435,18 +433,94 @@
 %    \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
+\cs_new_protected:Npn \@@_declare_cmd_code:Nnn #1#2
   {
-    \bool_if:NTF \l_@@_grab_expandably_bool
-      { \@@_declare_cmd_code_expandable:Nnn }
-      { \@@_declare_cmd_code_aux:Nnn }
+    \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_optimized:Nnn #1#2#3
+  {
+    \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
 %   grabbing arguments, an auxiliary containing the code, and then the
@@ -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,7 +2272,25 @@
 %<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}
 %    \end{macrocode}
@@ -2423,7 +2527,7 @@
 %
 % \begin{macro}{\@@_show:N}
 %   This macro just branches to the proper showing command by using
-%   \cs{@@_cmd_type_cases:NnnnnF}.  The showing command takes the command
+%   \cs{@@_cmd_type_cases:NnnnnnF}.  The showing command takes the command
 %   to be shown as argument.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_show:N #1
@@ -2431,9 +2535,10 @@
     \use:x
       {
         \int_set:Nn \tex_escapechar:D { 92 }
-        \exp_not:N \@@_cmd_type_cases:NnnnnF \exp_not:N #1
+        \exp_not:N \@@_cmd_type_cases:NnnnnnF \exp_not:N #1
           { \@@_show_command:N }
           { \@@_show_expandable:N }
+          { \@@_show_optimized:N }
           { \@@_show_environment:N }
           { \@@_show_environment_end:N }
           { \@@_cant_copy:nwn { non-ltcmd } }
@@ -2450,6 +2555,7 @@
 %     \@@_show_command:NnNNwN,
 %     \@@_show_expandable:N,
 %     \@@_show_expandable:NnNNNNnN,
+%     \@@_show_optimized:N,
 %     \@@_show_command_aux:NnNNn,
 %     \@@_show_environment:N,
 %     \@@_show:x,
@@ -2530,6 +2636,48 @@
   }
 %    \end{macrocode}
 %
+% Optimized functions need things done a bit differently as we need to
+% reconstruct the argument spec.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_show_optimized:N #1
+  {
+    \exp_args:Nc \@@_show_optimized:NN
+      { \cs_to_str:N #1 \c_space_tl code }
+      #1
+  }
+\cs_new_protected:Npn \@@_show_optimized:NN #1#2
+  {
+    \cs_set:Npe \@@_show_optimized_aux:N ##1
+      {
+        \c_space_tl \c_space_tl \c_hash_str ##1 :
+        \bool_lazy_or:nnT
+          { \token_if_long_macro_p:N #1 }
+          { \token_if_protected_long_macro_p:N #1 }
+            { + } m
+         \iow_newline:
+      }
+    \tl_show:e
+      {
+        \token_to_str:N #2 =
+          \bool_lazy_or:nnF
+            { \token_if_protected_macro_p:N #1 }
+            { \token_if_protected_long_macro_p:N #1 }
+              { expandable ~ } document~command:
+        \iow_newline:
+        \int_step_function:nN
+          {
+            \int_div_truncate:nn
+              { \tl_count:e { \cs_parameter_spec:N #1 } }
+              { 2 }
+          }
+          \@@_show_optimized_aux:N
+        ->
+        \cs_replacement_spec:N #1
+      }
+  }
+\cs_generate_variant:Nn \tl_count:n { e }
+%    \end{macrocode}
+%
 %   We can reuse most of the above to show an environment, except that
 %   we need to ensure that the proper \cs[no-index]{environment~\ldots}
 %   are passed to \cs{@@_show_command_aux:NnNNn}.  Additionally, when
@@ -3533,18 +3681,38 @@
 % \end{macro}
 %
 % \begin{macro}{\@@_grab_v_aux_put:N}
+% \changes{v1.2d}{2024/03/21}{Collect \cs{endlinechar} as \cs{obeyedline}}
 %   Storing one token in the collected argument. Most tokens are
 %   converted to category code $12$, with the exception of active
 %   characters, and spaces (not sure what should be done for those).
 %    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{2024/06/01}{\@@_grab_v_aux_put:N}%
+%<latexrelease>  {Endlines~as~\obeyedline}
 \cs_new_protected:Npn \@@_grab_v_aux_put:N #1
   {
     \tl_put_right:Nx \l_@@_v_arg_tl
       {
         \token_if_active:NTF #1
-          { \exp_not:N #1 } { \token_to_str:N #1 }
+          { \exp_not:N #1 }
+          {
+            \int_compare:nNnTF {`#1} = \tex_endlinechar:D
+              { \exp_not:N \obeyedline }
+              { \token_to_str:N #1 }
+          }
       }
   }
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_grab_v_aux_put:N}%
+%<latexrelease>  {Endlines~as~\obeyedline}
+%<latexrelease>\cs_new_protected:Npn \@@_grab_v_aux_put:N #1
+%<latexrelease>  {
+%<latexrelease>    \tl_put_right:Nx \l_@@_v_arg_tl
+%<latexrelease>      {
+%<latexrelease>        \token_if_active:NTF #1
+%<latexrelease>          { \exp_not:N #1 } { \token_to_str:N #1 }
+%<latexrelease>      }
+%<latexrelease>  }
+%<latexrelease>\EndIncludeInRelease
 %    \end{macrocode}
 % \end{macro}
 %
@@ -4376,13 +4544,16 @@
 % \end{macro}
 %
 % \begin{macro}{\__kernel_cmd_if_xparse:NTF}
-% \begin{macro}{\@@_cmd_type_cases:Nnnnn}
+% \begin{macro}{\@@_cmd_type_cases:NnnnnnF}
 % \changes{v1.0d}{2021/04/19}{Renamed \cs{__cmd_cmd_if_xparse:NTF} to
 %      \cs{__kernel_cmd_if_xparse:NTF} for cross-module usage}
 % \changes{v1.0d}{2021/07/30}{Added \cs{@@_cmd_type_cases:NnnnnF} for
 %      \cs{NewCommandCopy} and \cs{ShowCommand} support}
 % \changes{v1.0l}{2022/03/18}{Fix \cs{@@_cmd_type_cases:NnnnnF}
-%"     prematurely expanding macros (gh/795)}
+%      prematurely expanding macros (gh/795)}
+% \changes{v1.2b}{2023/12/01}{Extend for optimized commands}
+% \changes{v1.2e}{2024/04/17}{Use \cs{__kernel_cs_parameter_spec:N} instead
+%   of \cs{cs_argument_spec:N}/\cs{cs_parameter_spec:N}}
 % \begin{macro}{\@@_cmd_if_xparse_aux:N}
 %
 %    To determine whether the command is an \pkg{xparse} command check
@@ -4390,6 +4561,7 @@
 %    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).
 %
@@ -4396,30 +4568,31 @@
 %    This conditional is needed in several kernel modules and is
 %    therefore has a kernel-internal name.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_cmd_type_cases:NnnnnF #1 #2 #3 #4 #5 #6
+\cs_new_protected:Npn \@@_cmd_type_cases:NnnnnnF #1 #2 #3 #4 #5 #6 #7
   {
     \exp_args:Ne \str_case_e:nnF
       {
-        \exp_args:Nf \tl_if_empty:nT { \cs_argument_spec:N #1 }
+        \exp_args:Nf \tl_if_empty:nT { \__kernel_cs_parameter_spec:N #1 }
           { \exp_not:N \exp_not:n { \exp_not:e { \tl_head:N #1 } } }
       }
       {
         { \exp_not:N \@@_start:nNNnnn } {#2}
         { \exp_not:N \@@_start_expandable:nNNNNn } {#3}
-        { \exp_not:N \@@_start_env:nnnnn } {#4}
+        { \exp_not:N \@@_start_optimized: } {#4}
+        { \exp_not:N \@@_start_env:nnnnn } {#5}
         {
           \exp_after:wN \exp_not:N
             \cs:w environment~
               \exp_last_unbraced:Ne \use_none:nnn
                 { \cs_to_str:N #1 } ~end~aux \cs_end:
-        } {#5}
+        } {#6}
       }
-      {#6}
+      {#7}
   }
 \cs_new_protected:Npn \__kernel_cmd_if_xparse:NTF #1
   {
-    \@@_cmd_type_cases:NnnnnF #1
-      { } { } { } { } { \use_iii:nnn }
+    \@@_cmd_type_cases:NnnnnnF #1
+      { } { } { } { } { } { \use_iii:nnn }
     \use_i:nn
   }
 %    \end{macrocode}
@@ -4511,10 +4684,8 @@
     \bool_if:NTF \l_@@_environment_bool
       { environment ~ ' \l_@@_environment_str ' }
       {
-        command ~ '
-        \exp_args:Nf \tl_trim_spaces:n
-          { \exp_after:wN \token_to_str:N \l_@@_fn_tl }
-        '
+        command ~
+          ' \c_backslash_str \tl_to_str:N \l_@@_function_tl '
       }
   }
 %    \end{macrocode}
@@ -4522,6 +4693,8 @@
 %
 % Some messages intended as errors when defining commands/environments.
 % \changes{v1.0f}{2021/06/04}{Normalize various error messages}
+% \changes{v1.2c}{2023/12/22}
+%         {Generalize message \texttt{invalid-bang} (gh/1198)}
 %    \begin{macrocode}
 \msg_new:nnnn { cmd } { arg-after-body }
   { Argument~type~'b'~must~be~last~in~#1. }
@@ -4612,7 +4785,7 @@
   { Invalid~argument~prefix~'!'~in~#1. }
   {
     The~prefix~'!'~is~only~allowed~for~trailing~optional~arguments.~
-    You~tried~to~apply~it~to~'#2'.
+    You~tried~to~apply~it~to~#2.
     \c_@@_ignore_def_tl
   }
 \msg_new:nnnn { cmd } { not-definable }

Modified: trunk/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-%% File: ltcmdhooks.dtx
+%% From File: ltcmdhooks.dtx
 %% Copyright (C) 2020-2024
 %% Frank Mittelbach, Phelype Oleinik, The LaTeX Project
 %
@@ -12,16 +12,20 @@
 %    https://www.latex-project.org/lppl.txt
 %
 %
-%%% From File: ltcmdhooks.dtx
+% \fi
 %
-\def\ltcmdhooksversion{v1.0i}
-\def\ltcmdhooksdate{2023/06/16}
+% \iffalse
+%%% From File: lthooks.dtx
 %
+%<*driver>
+% \fi
+\ProvidesFile{ltcmdhooks.dtx}
+             [2024/04/17 v1.0j LaTeX Kernel (Command hooks)]
+% \iffalse
 %
-%
-%<*driver>
 \documentclass{l3doc}
-%\usepackage{ltcmdhooks}
+\GetFileInfo{ltcmdhooks.dtx}
+% \usepackage{ltcmdhooks}
 \EnableCrossrefs
 \CodelineIndex
 \begin{document}
@@ -38,7 +42,7 @@
 % \providecommand\phoinline[1]{\begin{quote}\itshape\footnotesize PhO: #1\end{quote}}
 %
 % \title{The \texttt{ltcmdhooks} module\thanks{This file has version
-%    \ltcmdhooksversion\ dated \ltcmdhooksdate, \copyright\ \LaTeX\
+%    \fileversion\ dated \filedate, \copyright\ \LaTeX\
 %    Project.}}
 % \author{Frank Mittelbach \and Phelype Oleinik}
 %
@@ -125,8 +129,8 @@
 %    \item
 %
 %      that code can be prepended or appended (i.e., added to the
-%      hooks) even if the command itself is not defined, because the
-%      defining package has not yet been loaded;
+%      hooks) even if the command itself is not (yet) defined, because the
+%      defining package has not been loaded at this point;
 %
 %    \item
 %
@@ -214,6 +218,14 @@
 % optional and mandatory arguments.  By adding code to the
 % \hook{cmd/section/after} hook, you get in the way of that scanning.
 %
+% In such a case, where it is known that a specific generic command
+% hook does not work if code is added to it, the package author can
+% add a \cs{DisableGenericHook}\footnote{Please use
+% \cs{DisableGenericHook} if at all, only on hooks that you
+% \enquote{own}, i.e., for commands your package or class defines and
+% not second guess whether or not hooks of other packages should get
+% disabled!} declaration to prevent this from happening in user
+% documents and thereby avoiding obscure errors.
 %
 %
 % \section{Package Author Interface}
@@ -394,6 +406,8 @@
 %    \end{macrocode}
 %
 % \changes{v1.0b}{2021/05/24}{Use \cs{msg_...} instead of \cs{__kernel_msg...}}
+% \changes{v1.0j}{2024/04/17}{Use \cs{__kernel_cs_parameter_spec:N} instead
+%   of \cs{cs_argument_spec:N}/\cs{cs_parameter_spec:N}}
 %
 %    \begin{macrocode}
 %<*2ekernel|latexrelease>
@@ -643,7 +657,7 @@
       }
   }
 %    \end{macrocode}
-%   and a conditional \cs{@@_if_public_command:N} to check if a command
+%   and a conditional \cs{@@_if_public_command:NTF} to check if a command
 %   has |__| in its name (no other checking is performed).  Primitives
 %   with |:D| in their name could be included here, but they are already
 %   discarded in the \cs{token_if_macro:NTF} test above.
@@ -838,7 +852,7 @@
     \@@_patch_debug:x { ++~command~can~be~patched~without~rescanning }
 %    \end{macrocode}
 %   We'll start by counting the number of arguments in the command by
-%   counting the number of characters in the \cs{cs_argument_spec:N} of
+%   counting the number of characters in the \cs{cs_parameter_spec:N} of
 %   the macro, divided by two, and subtracting one if the command has an
 %   optional argument (that is, an extra |[]| in its
 %   \meta{parameter text}).
@@ -845,7 +859,7 @@
 %    \begin{macrocode}
     \int_set:Nn \l_@@_patch_num_args_int
       {
-        \exp_args:Nf \str_count:n { \cs_argument_spec:N #2 } / 2
+        \exp_args:Nf \str_count:n { \__kernel_cs_parameter_spec:N #2 } / 2
         \bool_if:NT #1 { -1 }
       }
 %    \end{macrocode}
@@ -998,7 +1012,7 @@
 %<latexrelease>    \@@_patch_debug:x { ++~command~can~be~patched~without~rescanning }
 %<latexrelease>    \int_set:Nn \l_@@_patch_num_args_int
 %<latexrelease>      {
-%<latexrelease>        \exp_args:Nf \str_count:n { \cs_argument_spec:N #2 } / 2
+%<latexrelease>        \exp_args:Nf \str_count:n { \__kernel_cs_parameter_spec:N #2 } / 2
 %<latexrelease>        \bool_if:NT #1 { -1 }
 %<latexrelease>      }
 %<latexrelease>    \int_compare:nNnTF { \l_@@_patch_num_args_int } > { \c_zero_int }
@@ -1248,12 +1262,12 @@
 %   top-level macro with no arguments, so testing this first would
 %   short-circuit \tn{robust at command@act} and the top-level macros would
 %   be incorrectly patched.  In that case, we just check if the
-%   \cs{cs_argument_spec:N} is empty, and call
+%   \cs{cs_parameter_spec:N} is empty, and call
 %   \cs{@@_patch_expand_redefine:NNnn}.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_retokenize_patch:Nnn #1 #2 #3
   {
-    \str_if_eq:eeTF { \cs_argument_spec:N #1 } { }
+    \str_if_eq:eeTF { \__kernel_cs_parameter_spec:N #1 } { }
       { \@@_patch_expand_redefine:NNnn \c_false_bool #1 {#2} {#3} }
       {
         \@@_patch_debug:x { ..~command~can~only~be~patched~by~rescanning }

Modified: trunk/Master/texmf-dist/source/latex/base/ltcounts.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltcounts.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltcounts.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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 at warning{Command `\string\the#1' already
+                       defined -- not changed}%
+     \fi}
 %    \end{macrocode}
 %  \end{macro}
 %

Modified: trunk/Master/texmf-dist/source/latex/base/ltdefns.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltdefns.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltdefns.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -32,7 +32,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltdefns.dtx}
-             [2022/11/24 v1.5s LaTeX Kernel (definition commands)]
+             [2024/04/17 v1.5t LaTeX Kernel (definition commands)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltdefns.dtx}
@@ -91,6 +91,9 @@
 % \changes{v1.4b}{2015/02/21}
 %         {Removed autoload support}
 % \changes{v1.5l}{2020/08/21}{Integration of new hook management interface}
+% \changes{v1.5t}{2024/04/17}
+%         {Rename \cs{@expl at cs@argument at spec@@N} to
+%          \cs{@expl at cs@parameter at spec@@N} (gh/1014)}
 %
 % \section{Definitions}
 %
@@ -215,12 +218,12 @@
 % This section defines the following commands:
 %
 % \DescribeMacro
-%  {\@namedef}\marg{NAME}\\ Expands to |\def\|\marg{NAME},
+%  {\@namedef}\marg{NAME}\\ Expands to |\def\|\meta{NAME},
 %   except name can contain any characters.
 %
 % \DescribeMacro
 %  {\@nameuse}\marg{NAME}\\
-%   Expands to |\|\marg{NAME}.
+%   Expands to |\|\meta{NAME}.
 %
 % \DescribeMacro
 %  {\@ifnextchar} X\marg{YES}\marg{NO}\\
@@ -530,9 +533,11 @@
 % This macro encapsulates the most common call to |\@ifnextchar|, saving
 % several tokens each time it is used in the definition of a command
 % with an optional argument.
-% |#1| The code to execute in the case that there is a |[| need not be
+% |#1| The code to execute in the case that there is a |[| \iffalse]\fi
+% need not be
 % a single token but can be any sequence of commands that `expects' to
-% be followed by |[|. If this command were only used in |\newcommand|
+% be followed by |[|. \iffalse]\fi
+% If this command were only used in |\newcommand|
 % definitions then |#1| would be a single token and the braces could
 % be omitted from |{#1}| in the definition below, saving a bit of
 % memory.
@@ -595,7 +600,7 @@
 %    required argument spec by using a delimited argument (delimited
 %    by the digit).  This is faster and uses less tokens. The coding
 %    is slightly odd to preserve the old interface (using |#2| =
-%    |\tw@| as the flag to surround the first argument with |[]|.  But
+%    |\tw@| as the flag to surround the first argument with |[]|).  But
 %    the new method did not allow for the number of arguments |#3| not
 %    being given as an explicit digit; hence (further expansion of
 %    this argument and use of) |\number| was added later in 1999.
@@ -706,13 +711,14 @@
 % \begin{macro}{\newenvironment}
 %    Define a new user environment.
 %    |#1| is the environment name. |#2#| Grabs all the tokens up to
-%    the first |{|. These will be any optional arguments. They are not
+%    the first |{|. \iffalse}\fi
+%    These will be any optional arguments. They are not
 %    parsed at this point, but are just passed to |\@newenv| which
 %    will eventually call |\newcommand|. Any optional arguments will
 %    then be parsed by |\newcommand| as it defines the command that
 %    executes the `begin code' of the environment.
 %
-% This |#2#| trick removed with version 1.2i as it fails if a |{|
+% This |#2#| trick removed with version 1.2i as it fails if a |{| \iffalse}\fi
 % occurs in the optional argument. Now use |\@ifnextchar| directly.
 %    \begin{macrocode}
 \def\newenvironment{\@star at or@long\new at environment}
@@ -888,7 +894,8 @@
 % \begin{macro}{\@check at 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 at a|. If |\\reserved at a| is then defined, compare it
 %    with the ``|\#1|' otherwise compare |\reserved at a| with |#1|.
 %    \begin{macrocode}
@@ -2016,7 +2023,7 @@
 \long\def\@show at newcommand@aux#1#2#3{%
   \typeout{> \string#1=\@expl at cs@prefix at spec@@N#1macro:}%
   #3{default \string##1=\expandafter\detokenize\@gobblethree#2.^^J%
-    \@expl at cs@argument at spec@@N#1->\@expl at cs@replacement at spec@@N#1}}
+    \@expl at cs@parameter at spec@@N#1->\@expl at cs@replacement at spec@@N#1}}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -2117,7 +2124,7 @@
   \@show at environment@end#1}
 \long\def\@show at environment@begin#1{%
   \typeout{> \string\begin{\@expl at cs@to at str@@N#1}=environment:}%
-  \typeout{\@expl at cs@argument at spec@@N#1->%
+  \typeout{\@expl at cs@parameter at spec@@N#1->%
            \@expl at cs@replacement at spec@@N#1.^^J}}
 %    \end{macrocode}
 % \end{macro}
@@ -2139,7 +2146,7 @@
 \long\def\@show at environment@end at aux#1#2{%
   \@show at tokens{\string\end{\@expl at cs@to at str@@N#2}%
     \ifx\relax#1=undefined%
-    \else:^^J\@expl at cs@argument at spec@@N#1->%
+    \else:^^J\@expl at cs@parameter at spec@@N#1->%
              \@expl at cs@replacement at spec@@N#1%
     \fi}}
 %    \end{macrocode}
@@ -2158,7 +2165,7 @@
 %    \begin{macrocode}
 \def\@show at nonstop#1{%
   \typeout{> \string#1=\@expl at cs@prefix at spec@@N#1macro:^^J%
-   \@expl at cs@argument at spec@@N#1->\@expl at cs@replacement at spec@@N#1.}}
+   \@expl at cs@parameter at spec@@N#1->\@expl at cs@replacement at spec@@N#1.}}
 \def\@show at typeout#1{\typeout{> #1.^^J}}
 %    \end{macrocode}
 % \end{macro}
@@ -2296,7 +2303,7 @@
 % \changes{v1.3g}{2004/01/23}{Added macro (pr/3501)}
 %    This macro is the kernel version of |\@ifnextchar| which is used
 %    in a couple of places to prevent the AMS variant from being used
-%    since in some places this produced chaos (for example
+%    since in some places this produced chaos. For example,
 %    if an \texttt{fd} file
 %    is loaded in a random place then the optional argument to
 %    |\ProvidesFile| could get printed there instead of being written

Modified: trunk/Master/texmf-dist/source/latex/base/ltdirchk.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltdirchk.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltdirchk.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -36,9 +36,11 @@
 %</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}
 \title{\filename\thanks{%
@@ -261,6 +263,10 @@
 % In current formats enable primitives with unprefixed names.
 % the \textsf{latexrelease} guards allow the primitives to be
 % defined with a |\luatex| prefix if older formats are specified.
+%
+% The unprefixed forms are \emph{not} undefined for improved
+% compatibility with external packages when rolling back
+% the format.
 %    \begin{macrocode}
 %</initex>
 %</dircheck>
@@ -278,25 +284,6 @@
 %<latexrelease>    "luatex",
 %<latexrelease>    tex.extraprimitives("core","omega", "aleph", "luatex")
 %<latexrelease>  )
-%<latexrelease>  local i
-%<latexrelease>  local t = { }
-%<latexrelease>  for _,i in pairs(tex.extraprimitives("luatex")) do
-%<latexrelease>    if not string.match(i,"^U") then
-%<latexrelease>      if not string.match(i, "^luatex") then
-%<latexrelease>        table.insert(t,i)
-%<latexrelease>      end
-%<latexrelease>    else
-%<latexrelease>      if string.match(i,"^Uchar$") then
-%<latexrelease>        table.insert(t,i)
-%<latexrelease>      end
-%<latexrelease>    end
-%<latexrelease>  end
-%<latexrelease>  for _,i in pairs(t) do
-%<latexrelease>    tex.print(
-%<latexrelease>      "\noexpand\\let\noexpand\\" .. i
-%<latexrelease>        .. "\noexpand\\undefined"
-%<latexrelease>    )
-%<latexrelease>  end
 %<latexrelease>}
 %<latexrelease>\EndIncludeInRelease
 %<latexrelease>\fi
@@ -1000,8 +987,8 @@
 % \begin{macro}{\@TeXversion}
 % \TeX\ versions older than 3.141 require |\@TeXversion| to be
 % set. This can be determined automatically due to a trick suggested
-% by Bernd Raichle. (Actually this will not always get the correct
-% version number, eg \TeX3.14 would be detected as \TeX3, but \LaTeX\
+% by Bernd Raichle. Actually this will not always get the correct
+% version number, e.g., \TeX3.14 would be detected as \TeX3, but \LaTeX\
 % only needs to take account of \TeX's older than 3, or between 3 and
 % 3.14.
 % \changes{v1.0h}{1994/10/11}

Modified: trunk/Master/texmf-dist/source/latex/base/ltexpl.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltexpl.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltexpl.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -33,7 +33,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltexpl.dtx}
-             [2023/10/13 v1.3g LaTeX Kernel (expl3-dependent code)]
+             [2024/04/17 v1.3h LaTeX Kernel (expl3-dependent code)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltexpl.dtx}
@@ -356,9 +356,19 @@
 % \changes{v1.2e}{2020/08/19}
 %         {Add \cs{@expl at cs@\meta{thing}@spec@@N}
 %          for \cs{ShowCommand} (gh/373)}
+% \changes{v1.3h}{2024/04/17}
+%         {Rename \cs{@expl at cs@argument at spec@@N} to
+%          \cs{@expl at cs@parameter at spec@@N} (gh/1014)}
+% \changes{v1.3h}{2024/04/17}
+%         {Update name of \pkg{expl3} function}
+% \changes{v1.3h}{2024/04/17}
+%         {Add a kernel-level copy of \cs{cs_parameter_spec:N}}
 %    \begin{macrocode}
 \cs_gset_eq:NN \@expl at cs@prefix at spec@@N \cs_prefix_spec:N
-\cs_gset_eq:NN \@expl at cs@argument at spec@@N \cs_argument_spec:N
+\cs_if_exist:NTF \cs_parameter_spec:N
+  { \cs_gset_eq:NN \@expl at cs@parameter at spec@@N \cs_parameter_spec:N }
+  { \cs_gset_eq:NN \@expl at cs@parameter at spec@@N \cs_argument_spec:N }
+\cs_gset_eq:NN \__kernel_cs_parameter_spec:N \@expl at cs@parameter at spec@@N
 \cs_gset_eq:NN \@expl at cs@replacement at spec@@N \cs_replacement_spec:N
 %    \end{macrocode}
 %
@@ -387,7 +397,7 @@
 %<latexrelease>\let \@expl at cs@to at str@@N \@undefined
 %<latexrelease>\let \@expl at str@if at eq@@nnTF \@undefined
 %<latexrelease>\let \@expl at cs@prefix at spec@@N \@undefined
-%<latexrelease>\let \@expl at cs@argument at spec@@N \@undefined
+%<latexrelease>\let \@expl at cs@parameter at spec@@N \@undefined
 %<latexrelease>\let \@expl at cs@replacement at spec@@N \@undefined
 %<latexrelease>\let \@expl at str@map at function@@NN \@undefined
 %<latexrelease>\EndIncludeInRelease

Modified: trunk/Master/texmf-dist/source/latex/base/ltfilehook.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfilehook.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltfilehook.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -30,16 +30,22 @@
 %
 %%% From File: ltfilehook.dtx
 %
-%    \begin{macrocode}
-\providecommand\ltfilehookversion{v1.0o}
-\providecommand\ltfilehookdate{2023/07/10}
-%    \end{macrocode}
+% \fi
+%\iffalse
+%<*driver,structuredlog>
+%\fi
+\def\ltfilehookdate{2024/03/13}
+\def\ltfilehookversion{v1.0o}
+%\iffalse
+%</driver,structuredlog>
+%<*driver>
+%\fi
+\expanded{\noexpand\ProvidesFile{ltfilehook.dtx}
+[\ltfilehookdate\space \ltfilehookversion\space LaTeX Kernel (hooks)]}
+% \iffalse
 %
-%<*driver>
-
 \documentclass{l3doc}
 
-
 \providecommand\InternalDetectionOff{}
 \providecommand\InternalDetectionOn{}
 
@@ -375,7 +381,7 @@
 %
 %
 %
-% \subsection{Internal interfaces for \LaTeX{}}
+% \subsection{Kernel, class, and package interfaces for \LaTeX{}}
 %
 % \begin{function}{\declare at file@substitution,\undeclare at file@substitution}
 %   \begin{syntax}
@@ -393,6 +399,8 @@
 %    example, or to provide a version that makes use of new kernel
 %    functionality while the original package remains available for
 %    use with older releases.
+%    As such it is mainly meant for use in the \LaTeX{} kernel but
+%    other use cases are conceivable.
 %
 %    The \cs{undeclare at file@substitution} declaration undoes a
 %    substitution made earlier.
@@ -407,10 +415,10 @@
 %
 % \begin{function}{\disable at package@load,\reenable at package@load}
 %   \begin{syntax}
-%     \cs{disable at package@load}  \Arg{package}  \Arg{alternate-code}
+%     \cs{disable at package@load}  \Arg{package} \Arg{alternate-code}
 %     \cs{reenable at package@load} \Arg{package}
 %   \end{syntax}
-%    If \meta{package} is requested do not load it but instead run
+%    If \meta{package} is requested, do not load it but instead run
 %    \meta{alternate-code} which could issue a warning, error or any
 %    other code.
 %
@@ -421,7 +429,9 @@
 %    are not available.
 %
 %    The function is only implemented for packages not for arbitrary
-%    files.
+%    files and again it should only be applied if there are good
+%    reasons for doing this.\footnote{Just to be sure: \enquote{I don't
+%    like this package by somebody else} is not a good one :-)}
 %  \end{function}
 %
 %
@@ -1328,7 +1338,7 @@
 % \end{macro}
 % \end{macro}
 %
-% \begin{macro}{flag @@_file_replaced}
+% \begin{macro}{@@_file_replaced}
 % \begin{macro}{\@@_if_file_replaced:TF}
 % \begin{macro}{\@@_clear_replacement_flag:}
 %   Since the file replacement is done expandably in a \cs{csname}, use

Modified: trunk/Master/texmf-dist/source/latex/base/ltfiles.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfiles.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltfiles.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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 at listfiles@hashes}
+% \changes{v1.2v}{2023/11/15}{Extend file list information}
+% \begin{macro}{\if at 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 at hashes ,
+    sizes .legacy_if_set:n  = @listfiles at 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 at d{\\}%
@@ -1730,9 +1748,40 @@
              \filename at area\filename at base\\\\\\\\\\\\\\\\\\\@@
        \typeout{%
          \filename at area\reserved at a
-         \ifx\reserved at b\relax\else\@spaces\reserved at b\fi}}%
+         \ifx\reserved at b\relax\else\@spaces\reserved at b\fi
+%    \end{macrocode}
+%   Now we add the additional information if requested.
+%    \begin{macrocode}
+         \ifnum0%
+           \if at listfiles@hashes1\fi
+           \if at listfiles@sizes1\fi
+             >0 %
+             ^^J\@spaces
+             (%
+               \if at listfiles@sizes
+                 size \@dofilelist at size\@currname
+                 \if at listfiles@hashes
+                   , %
+                 \fi
+               \fi
+               \if at listfiles@hashes
+                 hash \@dofilelist at hash\@currname
+               \fi
+             )%
+         \fi
+      }}%
      \typeout{ ***********^^J}}}
 %    \end{macrocode}
+% \begin{macro}{\@dofilelist at hash}
+% \begin{macro}{\@dofilelist at size}
+%    \begin{macrocode}
+\ExplSyntaxOn
+\cs_new_eq:NN \@dofilelist at hash \file_mdfive_hash:n
+\cs_new_eq:NN \@dofilelist at size \file_size:n
+\ExplSyntaxOff
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
 %
 % \changes{LaTeX2e}{1994/03/13}
 %         {Reset \cs{@addtofilelist} at begin document}

Modified: trunk/Master/texmf-dist/source/latex/base/ltfinal.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfinal.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltfinal.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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 at a} setting:-)}
+% \changes{v1.0w}{1995/10/19}{Move after \cs{reserved at 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

Modified: trunk/Master/texmf-dist/source/latex/base/ltfloat.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfloat.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltfloat.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -31,7 +31,7 @@
 %
 %<*driver>
 % \fi
-\ProvidesFile{ltfloat.dtx}[2021/10/14 v1.2g LaTeX Kernel (Floats)]
+\ProvidesFile{ltfloat.dtx}[2024/04/22 v1.2g LaTeX Kernel (Floats)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltfloat.dtx}
@@ -559,7 +559,7 @@
 % set globally to false when they are definitely true.
 %
 % If anyone is unhappy with this argument then both flags should be
-% treated as in |\set at nobreak|; otherwise this command will be
+% treated as in |\@setnobreak|; otherwise this command will be
 % redundant.
 % \changes{v1.1p}{1996/10/24}
 %     {Added local settings of flags: dangerous!!}
@@ -1061,7 +1061,7 @@
 % set globally to false when they are definitely true.
 %
 % If anyone is unhappy with this argument then both flags should be
-% treated as in |\set at nobreak|; otherwise this command will be
+% treated as in |\@setnobreak|; otherwise this command will be
 % redundant.
 % \changes{v1.1p}{1996/10/24}
 %     {Added local settings of flags: dangerous!!}

Modified: trunk/Master/texmf-dist/source/latex/base/ltfntcmd.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfntcmd.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltfntcmd.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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}

Modified: trunk/Master/texmf-dist/source/latex/base/ltfssaxes.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfssaxes.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltfssaxes.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -28,7 +28,7 @@
 % \fi
 % \iffalse
 %%% From File: ltfssaxes.dtx
-%% Copyright (C) 1999-2020 Frank Mittelbach
+%% Copyright (C) 2019-2020 Frank Mittelbach
 %
 %<*driver>
 % \fi
@@ -35,7 +35,7 @@
 %
 %
 \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.
 %

Modified: trunk/Master/texmf-dist/source/latex/base/ltfssbas.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfssbas.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltfssbas.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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 at 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 at linespread| such a change would be
 %    effectively overwritten by a size change.

Modified: trunk/Master/texmf-dist/source/latex/base/ltfssini.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfssini.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltfssini.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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 at 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 at previous\bfdefault
 %    \end{macrocode}
 %    And we reset the meta family defaults (\cs{bfdef at ult} is an
-%    expanded version of \cs{bfdefault}.
+%    expanded version of \cs{bfdefault}).
 %    \begin{macrocode}
     \let\bfseries at rm\bfdef at ult
     \let\bfseries at sf\bfdef at ult
@@ -1661,8 +1661,8 @@
 %    \begin{macrocode}
   \def\emfontdeclare at 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

Modified: trunk/Master/texmf-dist/source/latex/base/ltfsstrc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfsstrc.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltfsstrc.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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 at shape@saved\f at shape
       \let\f at series@saved\f at series      
 %    \end{macrocode}
-%    The we run the delayed adjustments (which is using the
-%    \cs{.. at without@substitution} commands
+%    Then we run the delayed adjustments (which use the
+%    \cs{.. at without@substitution} commands):
 %    \begin{macrocode}
       \delayed at f@adjustment
 %    \end{macrocode}
@@ -863,7 +863,7 @@
 %
 % \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}
@@ -870,7 +870,8 @@
 % $ 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 at 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 at bgroup| we change the
+%    looking at the definition of |\math at bgroup|) we change the
 %    |\math at 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 at 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 at rangefontinfo#1<#2>{%
@@ -1402,7 +1403,7 @@
 %
 %    From the way |\is at range| is called inside |\extract at 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 at rangefontinfo|
 %    called again. Note that the extra tokens inserted after the
 %    |\@nil| in the call to |\is at range| appear at the beginning of

Modified: trunk/Master/texmf-dist/source/latex/base/lthooks.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/lthooks.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/lthooks.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -27,18 +27,17 @@
 % \fi
 %
 % \iffalse
-%
 %%% From File: lthooks.dtx
 %
-%    \begin{macrocode}
-\def\lthooksversion{v1.1f}
-\def\lthooksdate{2023/10/02}
-%    \end{macrocode}
+%<*driver>
+% \fi
+\ProvidesFile{lthooks.dtx}
+             [2024/04/22 v1.1h LaTeX Kernel (hooks)]
+% \iffalse
 %
-%<*driver>
 \documentclass{l3doc}
+\GetFileInfo{lthooks.dtx}
 
-
 \providecommand\InternalDetectionOff{}
 \providecommand\InternalDetectionOn{}
 
@@ -62,7 +61,7 @@
 %
 %
 % \title{\LaTeX{}'s hook management\thanks{This module has version
-%    \lthooksversion\ dated \lthooksdate, \copyright\ \LaTeX\
+%    \fileversion\ dated \filedate, \copyright\ \LaTeX\
 %    Project.}}
 %
 % \author{Frank Mittelbach\thanks{Code improvements for speed and other goodies by Phelype Oleinik}}
@@ -160,7 +159,7 @@
 % \end{function}
 %
 %
-% \begin{function}{\NewHookWithArguments}
+% \begin{function}[added=2023-06-01]{\NewHookWithArguments}
 %   \begin{syntax}
 %     \cs{NewHookWithArguments} \Arg{hook} \Arg{number}
 %   \end{syntax}
@@ -172,7 +171,7 @@
 %    the current package name. See section~\ref{sec:default-label}.
 % \end{function}
 %
-% \begin{function}{\NewReversedHookWithArguments}
+% \begin{function}[added=2023-06-01]{\NewReversedHookWithArguments}
 %   \begin{syntax}
 %     \cs{NewReversedHookWithArguments} \Arg{hook} \Arg{number}
 %   \end{syntax}
@@ -184,7 +183,7 @@
 %    the current package name. See section~\ref{sec:default-label}.
 % \end{function}
 %
-% \begin{function}{\NewMirroredHookPairWithArguments}
+% \begin{function}[added=2023-06-01]{\NewMirroredHookPairWithArguments}
 %   \begin{syntax}
 %     \cs{NewMirroredHookPairWithArguments} \Arg{hook-1} \Arg{hook-2} \Arg{number}
 %   \end{syntax}
@@ -234,9 +233,9 @@
 %    (e.g., one used in code with \cs{UseHook} or
 %    \cs{UseOneTimeHook}) without it being explicitly declared with
 %    \cs{NewHook}).
-%    This command undoes the effect of \cs{DisableGenericHook}.
 %    If the hook is already activated, this command does nothing.
 %
+%    Note that this command does not undo the effect of \cs{DisableGenericHook}.
 %    See section~\ref{sec:generic-hooks} for a discussion of when this
 %    declaration is appropriate.
 % \end{function}
@@ -264,7 +263,7 @@
 %    A leading |.| is treated literally.
 % \end{function}
 %
-% \begin{function}{\UseHookWithArguments}
+% \begin{function}[added=2023-06-01]{\UseHookWithArguments}
 %   \begin{syntax}
 %     \cs{UseHookWithArguments} \Arg{hook} \Arg{number} \Arg{arg_1} \ldots \Arg{arg_n}
 %   \end{syntax}
@@ -314,7 +313,7 @@
 %
 % \end{function}
 %
-% \begin{function}{\UseOneTimeHookWithArguments}
+% \begin{function}[added=2023-06-01]{\UseOneTimeHookWithArguments}
 %   \begin{syntax}
 %     \cs{UseOneTimeHookWithArguments} \Arg{hook} \Arg{number} \Arg{arg_1} \ldots \Arg{arg_n}
 %   \end{syntax}
@@ -340,7 +339,7 @@
 %
 % \begin{function}{\AddToHook}
 %   \begin{syntax}
-%     \cs{AddToHook} \Arg{hook}\oarg{label}\Arg{code}
+%     \cs{AddToHook} \Arg{hook} \oarg{label} \Arg{code}
 %   \end{syntax}
 %    Adds \meta{code} to the \meta{hook} labeled by \meta{label}.
 %    When the optional argument \meta{label} is not provided, the
@@ -368,9 +367,9 @@
 %    See section~\ref{sec:default-label}.
 % \end{function}
 %
-% \begin{function}{\AddToHookWithArguments}
+% \begin{function}[added=2023-06-01]{\AddToHookWithArguments}
 %   \begin{syntax}
-%     \cs{AddToHookWithArguments} \Arg{hook}\oarg{label}\Arg{code}
+%     \cs{AddToHookWithArguments} \Arg{hook} \oarg{label} \Arg{code}
 %   \end{syntax}
 %    Works exactly like \cs{AddToHook}, except that the \meta{code} can
 %    access the arguments passed to the hook using \verb|#1|, \verb|#2|,
@@ -398,7 +397,7 @@
 %
 % \begin{function}{\RemoveFromHook}
 %   \begin{syntax}
-%     \cs{RemoveFromHook} \Arg{hook}\oarg{label}
+%     \cs{RemoveFromHook} \Arg{hook} \oarg{label}
 %   \end{syntax}
 %    Removes any code labeled by \meta{label} from the \meta{hook}.
 %    When the optional argument \meta{label} is not provided, the
@@ -459,7 +458,7 @@
 %
 % \begin{function}{\AddToHookNext}
 %   \begin{syntax}
-%     \cs{AddToHookNext} \Arg{hook}\Arg{code}
+%     \cs{AddToHookNext} \Arg{hook} \Arg{code}
 %   \end{syntax}
 %    Adds \meta{code} to the next invocation of the \meta{hook}.
 %    The code is executed after the normal hook code has finished and
@@ -505,9 +504,9 @@
 % \end{function}\footnotetext{There is
 %    no mechanism to reorder such code chunks (or delete them).}
 %
-% \begin{function}{\AddToHookNextWithArguments}
+% \begin{function}[added=2023-06-01]{\AddToHookNextWithArguments}
 %   \begin{syntax}
-%     \cs{AddToHookNextWithArguments} \Arg{hook}\Arg{code}
+%     \cs{AddToHookNextWithArguments} \Arg{hook} \Arg{code}
 %   \end{syntax}
 %    Works exactly like \cs{AddToHookNext}, but the \meta{code} can
 %    contain references to the arguments of the \meta{hook} as described
@@ -522,7 +521,7 @@
 %
 % \begin{function}{\ClearHookNext}
 %   \begin{syntax}
-%     \cs{ClearHookNext}\Arg{hook}
+%     \cs{ClearHookNext} \Arg{hook}
 %   \end{syntax}
 %    Normally \cs{AddToHookNext} is only used when you know precisely
 %    where it will apply and why you want some extra code at that
@@ -746,7 +745,7 @@
 %
 % \begin{function}{\DeclareHookRule}
 %   \begin{syntax}
-%     \cs{DeclareHookRule} \Arg{hook}\Arg{label1}\Arg{relation}\Arg{label2}
+%     \cs{DeclareHookRule} \Arg{hook} \Arg{label1} \Arg{relation} \Arg{label2}
 %   \end{syntax}
 %    Defines a relation between \meta{label1} and \meta{label2} for a
 %    given \meta{hook}. If \meta{hook} is \texttt{??} this defines a default
@@ -807,7 +806,7 @@
 %
 % \begin{function}{\ClearHookRule}
 %   \begin{syntax}
-%     \cs{ClearHookRule}\Arg{hook}\Arg{label1}\Arg{label2}
+%     \cs{ClearHookRule} \Arg{hook} \Arg{label1} \Arg{label2}
 %   \end{syntax}
 %    Syntactic sugar for saying that \meta{label1} and \meta{label2}
 %    are unrelated for the given \meta{hook}.
@@ -817,7 +816,7 @@
 %
 % \begin{function}{\DeclareDefaultHookRule}
 %   \begin{syntax}
-%     \cs{DeclareDefaultHookRule}\Arg{label1}\Arg{relation}\Arg{label2}
+%     \cs{DeclareDefaultHookRule} \Arg{label1} \Arg{relation} \Arg{label2}
 %   \end{syntax}
 %   This sets up a relation between \meta{label1} and \meta{label2}
 %    for all hooks unless overwritten by a specific rule for a hook.
@@ -1004,7 +1003,7 @@
 %
 % \begin{function}{\DebugHooksOn,\DebugHooksOff}
 %   \begin{syntax}
-%     \cs{DebugHooksOn}
+%     \cs{DebugHooksOn} \ldots\ \cs{DebugHooksOff}
 %   \end{syntax}
 %    Turn the debugging of hook code on or off. This displays most changes
 %    made to the hook data structures. The output is rather coarse and
@@ -1044,7 +1043,7 @@
 %    the current package name. See section~\ref{sec:default-label}.
 % \end{function}
 %
-% \begin{function}{
+% \begin{function}[added=2023-06-01]{
 %     \hook_new_with_args:nn,
 %     \hook_new_reversed_with_args:nn,
 %     \hook_new_pair_with_args:nnn
@@ -1100,9 +1099,14 @@
 %
 %
 %
-% \begin{function}{\hook_use:n,\hook_use:nnw}
+% \begin{function}{\hook_use:n}
 %   \begin{syntax}
-%     \cs{hook_use:n} \Arg{hook}
+%     ~~\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:nnw} \Arg{hook} \Arg{number} \Arg{arg_1} \ldots \Arg{arg_n}
 %   \end{syntax}
 %    Executes the \Arg{hook} code followed (if set up) by the code for next
@@ -1118,9 +1122,14 @@
 %    A leading |.| is treated literally.
 % \end{function}
 %
-% \begin{function}{\hook_use_once:n,\hook_use_once:nnw}
+% \begin{function}{\hook_use_once:n}
 %   \begin{syntax}
 %     \cs{hook_use_once:n} \Arg{hook}
+%   \end{syntax}
+% \end{function}
+% \vskip-1.2\baselineskip
+% \begin{function}[added=2023-06-01]{\hook_use_once:nnw}
+%   \begin{syntax}
 %     \cs{hook_use_once:nnw} \Arg{hook} \Arg{number} \Arg{arg_1} \ldots \Arg{arg_n}
 %   \end{syntax}
 %     Changes the \Arg{hook} status so that from now on any addition to
@@ -1139,10 +1148,16 @@
 %
 % \begin{function}{
 %     \hook_gput_code:nnn,
+%   }
+%   \begin{syntax}
+%     ~~~~~~~~~\cs{hook_gput_code:nnn} \Arg{hook} \Arg{label} \Arg{code}
+%   \end{syntax}
+% \end{function}
+% \vskip -1.2\baselineskip
+% \begin{function}[added=2023-06-01]{
 %     \hook_gput_code_with_args:nnn
 %   }
 %   \begin{syntax}
-%     \cs{hook_gput_code:nnn} \Arg{hook} \Arg{label} \Arg{code}
 %     \cs{hook_gput_code_with_args:nnn} \Arg{hook} \Arg{label} \Arg{code}
 %   \end{syntax}
 %    Adds a chunk of \meta{code} to the \meta{hook} labeled
@@ -1168,10 +1183,17 @@
 %
 % \begin{function}{
 %     \hook_gput_next_code:nn,
+%   }
+%   \begin{syntax}
+%     ~~~~~~~~~~~~~\cs{hook_gput_next_code:nn} \Arg{hook} \Arg{code}
+%   \end{syntax}
+% \end{function}
+% \vskip-1.2\baselineskip
+% \begin{function}[added=2023-06-01]{
 %     \hook_gput_next_code_with_args:nn,
 %   }
 %   \begin{syntax}
-%     \cs{hook_gput_next_code:nn} \Arg{hook} \Arg{code}
+%     \cs{hook_gput_next_code_with_args:nn} \Arg{hook} \Arg{code}
 %   \end{syntax}
 %    Adds a chunk of \meta{code} for use only in the next invocation of the
 %    \meta{hook}. Once used it is gone.
@@ -1183,6 +1205,7 @@
 %    In that case, if an actual parameter token should be added to the
 %    code, it should be doubled.
 %
+% \end{function}
 %    This is simpler than \cs{hook_gput_code:nnn}, the code is simply
 %    appended to the hook in the order of declaration at the very end,
 %    i.e., after all standard code for the hook got executed.
@@ -1191,7 +1214,6 @@
 %
 %    The \meta{hook} can be specified using the dot-syntax to denote
 %    the current package name. See section~\ref{sec:default-label}.
-% \end{function}
 %
 %
 % \begin{function}{\hook_gclear_next_code:n}
@@ -1527,7 +1549,7 @@
 %    \hook{cmd},
 %    \hook{env},
 %    \hook{file},
-%    \hook{include}
+%    \hook{include},
 %    \hook{package}, and
 %    \hook{class},
 %    and all these are available out of the box: you only have to 
@@ -1862,15 +1884,17 @@
 %    \item[\hook{env/\meta{env}/begin}]
 %
 %       This hook is executed as part of \cs{begin} directly in front
-%       of the code specific to the environment start (e.g., the
-%       second argument of \cs{newenvironment}).  Its scope is the
-%       environment body.
+%       of the code specific to the environment start (e.g.,
+%       the third argument of \cs{NewDocumentEnvironment} and
+%       the second argument of \cs{newenvironment}).
+%       Its scope is the environment body.
 %
 %    \item[\hook{env/\meta{env}/end}]
 %
 %       This hook is executed as part of \cs{end} directly in front of the
-%       code specific to the end of the environment (e.g., the third
-%       argument of \cs{newenvironment}).
+%       code specific to the end of the environment (e.g.,
+%       the forth argument of \cs{NewDocumentEnvironment} and
+%       the third argument of \cs{newenvironment}).
 %
 %    \item[\hook{env/\meta{env}/after}]
 %
@@ -2701,7 +2725,7 @@
 %    \hook_new:n,
 %    \hook_new_with_args:nn
 %  }
-%  \begin{macro}{@@_new:nn}
+%  \begin{macro}{\@@_new:nn}
 %    The \cs{hook_new:n} declaration declares a new hook and expects
 %    the hook \meta{name} as its argument, e.g.,
 %    \hook{begindocument}.
@@ -3509,7 +3533,8 @@
         \msg_error:nnnnn { hooks } { set-top-level }
           { for } { SetDefaultHookLabel } {#1}
       }
-      { \exp_args:Nx \@@_set_default_label:n { \@@_make_name:n {#1} } }
+      { \exp_args:Nx
+        \@@_set_default_label:n { \@@_make_name:n {#1} } }
   }
 \cs_new_protected:Npn \@@_set_default_label:n #1
   {
@@ -3722,7 +3747,8 @@
 %<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 at 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 at line :^^J } }
+%<latexrelease>      { \iow_term:x { ^^J Update~code~for~hook~'#1'
+%<latexrelease>                      \on at 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,19 +6273,22 @@
 %<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
@@ -6196,7 +6295,8 @@
 %<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,7 +6332,8 @@
 %<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>          {
@@ -6238,9 +6340,11 @@
 %<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>      }

Modified: trunk/Master/texmf-dist/source/latex/base/ltkeys.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltkeys.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltkeys.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -100,7 +100,7 @@
 %   \texttt{second-name} can be given anywhere, and will save its value in
 %   \cs{@mypkg at other@name}.
 %
-%   Keys created \emph{before} the use of \cs{ProcessKeyOptions}act as
+%   Keys created \emph{before} the use of \cs{ProcessKeyOptions} act as
 %   package options.
 % \end{function}
 %

Modified: trunk/Master/texmf-dist/source/latex/base/ltluatex.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltluatex.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltluatex.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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>
+%</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>
-[2023/08/03 v1.2c
-%</tex>
-%<plain>  LuaTeX support for plain TeX (core)
-%<*tex>
-]
 \edef\etatcatcode{\the\catcode`\@}
 \catcode`\@=11
 %</tex>
@@ -541,9 +547,9 @@
                 \csname globbox\endcsname
 %    \end{macrocode}
 %
-% Define|\e at alloc| as in latex (the existing macros in |etex.src|
+% Define|\e at 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}

Modified: trunk/Master/texmf-dist/source/latex/base/ltmarks.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltmarks.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltmarks.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -14,22 +14,15 @@
 %
 %%% From File: ltmarks.dtx
 %
-%    \begin{macrocode}
-\def\ltmarksversion{v1.0d}
-\def\ltmarksdate{2022/06/01}
-%    \end{macrocode}
 %<*driver>
+% \fi
+\ProvidesFile{ltmarks.dtx}
+             [2024/05/31 v1.0g LaTeX Kernel (Marks)]
+% \iffalse
+%
 \documentclass{l3doc}
+\GetFileInfo{ltmarks.dtx}
 
-%\usepackage{ltmarks}
-
-% Fixing footnotes in  functions and variables: this should be in l3doc!
-
-\newcommand\fixfootnote[2]{\footnotemark
-  \AddToHookNext{env/#1/after}{\footnotetext{#2}}}
-\AddToHook{env/function/begin}{\def\footnote{\fixfootnote{function}}}
-\AddToHook{env/variable/begin}{\def\footnote{\fixfootnote{variable}}}
-
 \EnableCrossrefs
 \CodelineIndex
 \begin{document}
@@ -45,7 +38,7 @@
 %
 %
 % \title{The \texttt{ltmarks.dtx} code\thanks{This file has version
-%    \ltmarksversion\ dated \ltmarksdate, \copyright\ \LaTeX\
+%    \fileversion\ dated \filedate, \copyright\ \LaTeX\
 %    Project.}}
 % \author{^^A
 %  Frank Mittelbach, \LaTeX{} Project\thanks
@@ -156,7 +149,7 @@
 % \begin{function}{\InsertMark,\mark_insert:nn}
 %   \begin{syntax}
 %     \cs{InsertMark} \Arg{class} \Arg{text}
-%     \cs{mark_insert:nn}  \Arg{class} \Arg{text}
+%     \cs{mark_insert:nn} \Arg{class} \Arg{text}
 %   \end{syntax}
 %   Adds a mark to the current galley for the \meta{class}, containing the
 %   \meta{text}.
@@ -291,6 +284,11 @@
 %    The \meta{pos\textsubscript{\itshape i}} argument can be either
 %    \texttt{top}, \texttt{first}, or \texttt{last}.
 %
+%    Important to note is that the comparison is not with respect to
+%    the textual content of the marks but whether or not they
+%    originated from the same \cs{InsertMark} command (or the L3 layer
+%    version \cs{mark_insert:nn}).
+%
 %    If you wish to compare marks across different regions or across
 %    different classes, you have to do it using the generic test only
 %    available in the L3 programming layer or do it manually, i.e.,
@@ -299,6 +297,8 @@
 %    \emph{true}; if a declared and an undeclared mark class is used
 %    it is always \emph{false}.}
 %
+% \subsection{Use cases for conditionals}
+%
 %   However, the basic version is enough for the following typical use cases:
 %   \begin{description}
 %   \item[Test for at most one mark of class \texttt{myclass} on current
@@ -353,7 +353,7 @@
 % \begin{function}{\DebugMarksOn,\DebugMarksOff,
 %                  \mark_debug_on:,\mark_debug_off:}
 %   \begin{syntax}
-%     \cs{DebugMarksOn} ...  \cs{DebugMarksOff}
+%     \cs{DebugMarksOn} \ldots\ \cs{DebugMarksOff}
 %   \end{syntax}
 %
 %    Commands to turn the debugging of mark code on or off. The
@@ -397,8 +397,8 @@
 %
 % \begin{function}{\markboth, \markright}
 %   \begin{syntax}
-%     \cs{markboth}   \Arg{left} \Arg{right}
-%     \cs{markright}  \Arg{right}
+%     \cs{markboth}  \Arg{left} \Arg{right}
+%     \cs{markright} \Arg{right}
 %   \end{syntax}
 % \LaTeXe{} uses two marks which aren't fully independent. A
 %   \enquote{left} mark generated by the first argument of \cs{markboth}
@@ -610,9 +610,9 @@
 %   marks. It too is called as part of \cs{@opcol}.
 % \end{function}
 %
-% \begin{function}{\@@_update_structure:nn}
+% \begin{function}{\@@_update_structure_from_material:nn}
 %   \begin{syntax}
-%     \cs{@@_update_structure:nn}  \Arg{region} \Arg{material with marks}
+%     \cs{@@_update_structure_from_material:nn} \Arg{region} \Arg{material with marks}
 %   \end{syntax}
 %   Helper function that inspects the marks
 %   inside the second argument and assigns new mark values based on
@@ -627,8 +627,8 @@
 %   \texttt{page} and \texttt{column} because only they have
 %   \texttt{previous-...} counterparts.
 %
-%   Another important part to keep in mind is that marks are only
-%   recognized if they appear on top-level, e.g., if we want to
+%   Another important aspect to keep in mind is that marks are recognized
+%   only if they appear on the top level, e.g., if we want to
 %   process material stored in boxes we need to put it unboxed (using
 %   \cs{unvcopy} etc.)\ into the second argument.
 % \end{function}
@@ -642,7 +642,7 @@
 %   Helper function that copies all mark values in the \meta{source}
 %   region to \meta{alias}, i.e., make the structures identical. Used
 %   to update the \texttt{previous-...} structures inside
-%   \cs{@@_update_structure:nn} and \texttt{first-column} and
+%   \cs{@@_update_structure_from_material:nn} and \texttt{first-column} and
 %   \texttt{last-column} structures inside
 %   \cs{@@_update_singlecol_structures:} or
 %   \cs{@@_update_dblcol_structures:}.
@@ -650,7 +650,6 @@
 %
 %
 %
-%
 % \begin{function}{\@@_update_structure_to_err:n}
 %   \begin{syntax}
 %     \cs{@@_update_structure_to_err:n} \Arg{region}
@@ -662,7 +661,38 @@
 % \end{function}
 %
 %
+% \begin{function}{\@@_get_marks_for_reinsertion:nNN}
+%   \begin{syntax}
+%     \cs{@@_get_marks_for_reinsertion:nNN} \Arg{source}
+%           \qquad \meta{token-list-var for collecting first marks}
+%           \qquad \meta{token-list-var for collecting last marks}
+%   \end{syntax}
+%   Helper function for extracting marks that would otherwise get
+%    lost, for example when they are hidden inside a box. This helper
+%    does not update mark structures and can therefore be used outside
+%    the output routine as well.
 %
+%    It collect all the top-level marks from inside the \meta{source}
+%    and adds suitable \cs{mark_insert:nn} in the two token
+%    lists. These token lists can then be executed at the right place
+%    to reinsert the marks, e.g., directly after the box. This is, for
+%    example, used by \pkg{multicol} when a short balanced
+%    \env{multicols} is returned to the galley for typesetting.
+%
+%    If the \meta{source} consists of a single vertical box (plus
+%    possibly followed by some glue but nothing else) then the box is
+%    unpacked and the top-level marks are collected from its
+%    content. However, if it is not a vertical box or there are are
+%    other data then nothing is unpacked and you have to do the
+%    unpacking yourself to get at the marks inside.
+%
+%    It is quite likely that one only needs a single token list for
+%    returning the \cs{mark_insert:nn} statements. If that is the case
+%    this command may change to take only two arguments.
+% \end{function}
+%
+%
+%
 % ^^A \end{documentation}
 %
 %
@@ -703,12 +733,13 @@
 %
 %
 % \begin{macro}{\mark_new_class:n,\@@_new_class:nn}
+%    
 %    A mark class is created by initializing a number of data
-%    structures.  First, we get a register number to refer to the mark class.
-%    The new mark class is then added to the \cs{g_@@_classes_seq}
-%    sequence to be able to easily loop over all classes.  Finally a
-%    number of top-level global token lists are declared that hold
-%    various versions of the mark for access.
+%    structures.  First, we get a register number to refer to the mark
+%    class.  The new mark class is then added to the
+%    \cs{g_@@_classes_seq} sequence to be able to easily loop over all
+%    classes.  Finally a number of top-level global token lists are
+%    declared that hold various versions of the mark for access.
 %    \begin{macrocode}
 \cs_new_protected:Npn \mark_new_class:n #1
 {
@@ -774,6 +805,32 @@
   \tl_new:c   { g_@@_last-column_top_    #1 _tl }
   \tl_new:c   { g_@@_last-column_first_  #1 _tl }
   \tl_new:c   { g_@@_last-column_last_   #1 _tl }
+%    \end{macrocode}
+%    All marks will have an identication at the beginning of the form
+%    \cs{@@_id:n}\texttt\{\meta{number}\texttt\} and therefore the
+%    initial empty values should have that too, so that data extraction
+%    is going to be uniform.
+% \changes{v1.0g}{2024/05/31}{Initialize all marks with an id, use 0
+%    when a new class is made (gh/1359)}
+%    \begin{macrocode}
+  \tl_set:cn   { g_@@_page_top_   #1 _tl }{ \@@_id:n{0} }
+  \tl_set:cn   { g_@@_page_first_ #1 _tl }{ \@@_id:n{0} }
+  \tl_set:cn   { g_@@_page_last_  #1 _tl }{ \@@_id:n{0} }
+  \tl_set:cn   { g_@@_previous-page_top_   #1 _tl }{ \@@_id:n{0} }
+  \tl_set:cn   { g_@@_previous-page_first_ #1 _tl }{ \@@_id:n{0} }
+  \tl_set:cn   { g_@@_previous-page_last_  #1 _tl }{ \@@_id:n{0} }
+  \tl_set:cn   { g_@@_column_top_   #1 _tl }{ \@@_id:n{0} }
+  \tl_set:cn   { g_@@_column_first_ #1 _tl }{ \@@_id:n{0} }
+  \tl_set:cn   { g_@@_column_last_  #1 _tl }{ \@@_id:n{0} }
+  \tl_set:cn   { g_@@_previous-column_top_   #1 _tl }{ \@@_id:n{0} }
+  \tl_set:cn   { g_@@_previous-column_first_ #1 _tl }{ \@@_id:n{0} }
+  \tl_set:cn   { g_@@_previous-column_last_  #1 _tl }{ \@@_id:n{0} }
+  \tl_set:cn   { g_@@_first-column_top_   #1 _tl }{ \@@_id:n{0} }
+  \tl_set:cn   { g_@@_first-column_first_ #1 _tl }{ \@@_id:n{0} }
+  \tl_set:cn   { g_@@_first-column_last_  #1 _tl }{ \@@_id:n{0} }
+  \tl_set:cn   { g_@@_last-column_top_    #1 _tl }{ \@@_id:n{0} }
+  \tl_set:cn   { g_@@_last-column_first_  #1 _tl }{ \@@_id:n{0} }
+  \tl_set:cn   { g_@@_last-column_last_   #1 _tl }{ \@@_id:n{0} }
 }
 %    \end{macrocode}
 % \end{macro}
@@ -784,11 +841,12 @@
 % \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}
@@ -795,46 +853,62 @@
 %  \end{macro}
 %
 %
-%  \begin{macro}{\@@_update_structure:nn}
 %
-%    This function updates the mark structures. The first argument is
-%    the region to update and second argument receives the material
-%    that holds the marks. Out of this material we extract the first
-%    and last marks for all classes (if there are any) to do the
-%    assignments.
-%
+%  \begin{macro}{\@@_extract_and_handle_marks:nn}
+% \changes{v1.0e}{2024/01/29}{Macro added}
+%    
+%    This is the main macro to extract and handle marks inside some
+%    vertical material. It is used by
+%    \cs{@@_update_structure_from_material:nn} (for updating the mark
+%    structure for a region based on the marks found) and by
+%    \cs{@@_get_marks_for_reinsertion:nNN} (for extracting marks from
+%    some material and prepare for reinserting them later (e.g., out
+%    of a box that is placed as a box into the main galley).
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_update_structure:nn #1#2
-  {
+\cs_new_protected:Npn \@@_extract_and_handle_marks:nn #1#2 {
 %    \end{macrocode}
-%    First thing we do is copying the current structure to
-%    \texttt{previous-...}; this leaves the current structure
-%    untouched so we can update it class by class (which is necessary).
+%    This macro expects code to handle extracted marks in its first argument and
+%    vertical material (not boxed or just consisting of a single
+%    vertical box) as its second. It
+%    extracts top-level mark information from \verb/#2/, stores them
+%    as split marks and then calls
+%    \verb/#1/ to make use of this information.
+%  
+%    If it finds a forced break in the material it removes it and then
+%    restarts the attempt without it.
+%
+%    We start with a group to keep most changes local.
 %    \begin{macrocode}
-    \@@_update_structure_alias:nn { previous-#1 } {#1}
+    \group_begin:
 %    \end{macrocode}
+%    
 %    Getting the first and last marks out of the material in \verb=#2=
-%    is done by putting the material in a box and then doing a
-%    split operation to the maximum size possible (which hopefully
-%    means all of the content).\footnote{We could verify this, maybe we
-%    should.} Because this is an action only for the sake of getting
-%    at the mark values we don't want any underfull
-%    box warnings so we turn those (locally) off.
+%    is done by putting the material in a box and then doing a split
+%    operation to the maximum size possible (which hopefully gets us
+%    all of the content).\footnote{With normal column material cut
+%    from the main galley we should always get all material in one go,
+%    but in certain situations, for example, in a \pkg{multicols}
+%    environment that contains some \cs{columnbreak}s a single split
+%    operation will not be enough. Thus, this is something we need to
+%    handle.}  Because this action is used only to get the mark
+%    values, we don't want any underfull box warnings so we (locally)
+%    turn those off.
+%
 %    \begin{macrocode}
-    \group_begin:
       \dim_set_eq:NN \tex_splitmaxdepth:D \c_max_dim
       \int_set_eq:NN \tex_vbadness:D      \c_max_int
       \dim_set_eq:NN \tex_vfuzz:D         \c_max_dim
 %    \end{macrocode}
-%    There is a further complication: if the region contains infinite
+%    
+%    There is a further complication: if the material contains infinite
 %    shrinking glue then a \tn{vsplit} operation will balk with a
-%    low-level error. Now pages or columns, which are our main concern here, can't
-%    have such infinite shrinkage if they are cut straight from the
-%    galley, however the use of \tn{enlargethispage} actually does add
-%    some at the very bottom (and also wraps the whole page into a box
-%    by itself, so if we leave it this way then a) we get this error
-%    and b) we don't see any marks because they are hidden one level
-%    down).
+%    low-level error. Now pages or columns, which are our main concern
+%    here, can't have such infinite shrinkage if they are cut straight
+%    from the galley, however the use of \tn{enlargethispage} actually
+%    does add some at the very bottom (and also wraps the whole page
+%    into a box by itself, so if we leave it this way then a) we get
+%    this error and b) we don't see any marks because they are hidden
+%    one level down).
 %      
 %    Another possible issue are packages or user code that place stray
 %    \tn{vbox}es directly into the main galley (an example is
@@ -842,93 +916,236 @@
 %    boxes end up as the last item on the page we should not unpack
 %    them.
 %
-%    We therefore do an \tn{unskip} to get rid of that glue if present and
-%    also check if we have then a \tn{vbox} as the last item and if so
-%    unpack that too, but only under certain conditions, see
-%    below. All this is temporary, just for getting the
-%    marks out, so it doesn't affect the final page production.
+%    All these issues need to be handled, which is done in
+%    \cs{@@_prepare_and_extract:nn}.     
 %
-%    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
+      \@@_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
-                {
+      \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.
+%    If it is, we unpack the box.
 %    \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
-                    }
+            { \vbox_unpack:N \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}.
-%    \begin{macrocode}
-                    \int_compare:nNnT \tex_badness:D > 0
-                      { \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).
+%    it back in that case.
 %    \begin{macrocode}
-          \tex_kern:D \c_zero_dim
-        }
-      \int_compare:nNnTF \tex_badness:D > 0
+    }
 %    \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 +1167,14 @@
               \tl_gset:No \g_@@_tmp_tl
                 { \tex_splitbotmarks:D \use:c { c_@@_class_##1_mark } }
 %    \end{macrocode}
-%    If this mark doesn't exist then obviously first mark does
-%    neither, so both become the last mark from the previous region. We
+%    If this mark doesn't exist then obviously neither does the first mark,
+%    so both become the last mark from the previous region. We
 %    have to be a little careful here: something like
 %    \verb=\mark_insert:nn{foo}{}= adds an \enquote{empty} mark that should
 %    not be confused with no mark at all. But no mark in our material
 %    will result in \cs{g_@@_tmp_tl} being fully empty. This is why we
 %    have to make sure that \enquote{empty} from \cs{mark_insert:nn} only
-%    appears to be empty but fails the next test (see below how this
+%    appears to be empty when typeset but fails the next test (see below how this
 %    is done).
 %    \begin{macrocode}
               \tl_if_empty:NTF \g_@@_tmp_tl
@@ -987,29 +1204,144 @@
                     }
                 }
             }
-        }
+}
 %    \end{macrocode}
-%    If the badness was zero (we actually tested for${}>0$ but it
-%    can't get negative) then we had infinite shrinkage, so we report
-%    that and set all marks to the value the last mark had before.
+%  \end{macro}
+%
+%
+%
+%  \begin{macro}{\@@_get_marks_for_reinsertion:nNN}
+%
+%    This function extracts the marks from the material in the first
+%    argument but it does not update any the mark structures. Instead,
+%    it collects the marks in the token lists given as the second and
+%    third argument, in such a way that they can be reinserted by just
+%    executing the token lists.\footnote{It is probably enough to
+%    collect everything in a single token list as long as we put the
+%    first marks first and the last marks last). But for extra
+%    flexibility, I currently use 2 token lists. This might change when it is
+%    really clear that this is never needed.}
+%
 %    \begin{macrocode}
-        {
-          \msg_error:nnn { mark } { infinite-shrinkage } {#1}
-          \seq_map_inline:Nn \g_@@_classes_seq
+\cs_new_protected:Npn \@@_get_marks_for_reinsertion:nNN #1#2#3 {
+%    \end{macrocode}
+%    First we clear the temporary token lists as we haven't seen any marks yet.
+%    \begin{macrocode}
+  \tl_clear:N \g_@@_first_marks_tl
+  \tl_clear:N \g_@@_last_marks_tl
+%    \end{macrocode}
+%    Then we  extract all top-level marks, thereby filling the token lists
+%    with suitable \cs{mark_insert:nn} calls.
+%    \begin{macrocode}
+  \@@_extract_and_handle_marks:nn
+%    \end{macrocode}
+%    The first argument holds the code for fill the token lists and
+%    the second is the material we extract from.
+%    \begin{macrocode}
+     \@@_get_from_splitmarks:
+     { #1 }
+%    \end{macrocode}
+%    
+%    Finally, we copy the updated (or not updated) temporary token
+%    lists to the two that have been supplied when the function was
+%    called.  By convention \enquote{get} operations return their
+%    values in local variables and \cs{@@_extract_and_handle_marks:nn}
+%    runs in a group, which is why we have to use global temporary
+%    variables for collecting.
+%    \begin{macrocode}
+  \tl_set_eq:NN #2 \g_@@_first_marks_tl
+  \tl_set_eq:NN #3 \g_@@_last_marks_tl
+}
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%  \begin{macro}{\@@_get_from_splitmarks:}
+%    This function is called after we have done a \cs{vsplit} to
+%    update the split marks. It loops through all mark classes to find
+%    out if there are marks for this class and if so updates the
+%    global tls used for collecting.
+%    \begin{macrocode}
+\cs_new_protected:Npn  \@@_get_from_splitmarks:  {
+  \seq_map_inline:Nn \g_@@_classes_seq
             {
-              \tl_gset_eq:cc { g_@@_#1_top_  ##1_tl }
-                             { g_@@_#1_last_ ##1_tl }
-              \tl_gset_eq:cc { g_@@_#1_first_##1_tl }
-                             { g_@@_#1_last_ ##1_tl }
+%    \end{macrocode}
+%    First we to get the last mark for the current class from the
+%    material supplied.
+%    \begin{macrocode}
+              \tl_gset:No \g_@@_tmp_tl
+                { \tex_splitbotmarks:D \use:c { c_@@_class_##1_mark } }
+%    \end{macrocode}
+%    
+%    If this mark doesn't exist then obviously first mark doesn't
+%    either, so we do nothing (other than issuing some debugging
+%    info).
+
+%    We have to be a little careful here: something like
+%    \verb=\mark_insert:nn{foo}{}= adds an \enquote{empty} mark that
+%    we should not confuse with the case where there is no mark at
+%    all.
+%
+%    When there is no mark at all we get a truly empty
+%    \cs{g_@@_tmp_tl} as a result. This is why we have to make sure
+%    that an \enquote{empty} mark generated with \cs{mark_insert:nn}
+%    only appears to be empty when it is typeset, but fails the next
+%    test (see below how this is done).
+%    \begin{macrocode}
+              \tl_if_empty:NTF \g_@@_tmp_tl
+                {
+%<*trace>
+                  \@@_debug:n { \iow_term:x { Marks:~no~ marks~
+                      for~ class~ '##1'~\msg_line_context: } }
+%</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}
 %
@@ -1098,7 +1430,18 @@
 %    \begin{macrocode}
           \@kernel at before@insertmark
           \hook_use:n { insertmark }
-          \unrestored at protected@xdef \g_@@_tmp_tl {#2}
+          \unrestored at protected@xdef \g_@@_tmp_tl
+               {
+%    \end{macrocode}
+%    To ensure that marks are unique we insert a hidden sequence
+%    marker at the beginning of the content of the mark containing the
+%    sequence number of the mark.
+% \changes{v1.0f}{2024/05/30}{Use sequence marker to make all marks
+%    unique on nearby regions (gh/1359)}
+%    \begin{macrocode}
+                 \@@_id:n{ \int_use:N\g_@@_int }
+                 #2
+               }
 %<*trace>
           \@@_debug:n{ \iow_term:x { Marks:~ set~#1~<-~
               '\tl_to_str:V \g_@@_tmp_tl' ~ \msg_line_context: } }
@@ -1111,9 +1454,11 @@
 %    becomes empty, but not immediately; otherwise we just put
 %    \cs{g_@@_tmp_tl} in.
 %    \begin{macrocode}
-              \tl_if_empty:NTF \g_@@_tmp_tl
-                { \exp_not:n { \prg_do_nothing: } }
-                { \exp_not:o { \g_@@_tmp_tl } }
+% this is no longer needed with 1.0f
+%              \tl_if_empty:NTF \g_@@_tmp_tl
+%                { \exp_not:n { \prg_do_nothing: } }
+%                { \exp_not:o { \g_@@_tmp_tl } }
+              \exp_not:o { \g_@@_tmp_tl }
             }
         \group_end:
 %    \end{macrocode}
@@ -1135,15 +1480,43 @@
 %  \end{macro}
 %
 %
+%  \begin{macro}{\@@_id:n}
+%    A hidden marker is placed into every mark added by
+%    \cs{mark_insert:nn}. It will will not show up in the output but
+%    its argument (a counter value that is incremented) makes all
+%    marks unique so the test for \enquote{equal} is not fooled by two
+%    different marks having the same mark text.
+% \changes{v1.0f}{2024/05/30}{Use sequence marker to make all marks
+%    unique on nearby regions (gh/1359)}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_id:n #1 { }
+%    \end{macrocode}
+%  \end{macro}
+%
+%
 % \begin{macro}[int]{\@kernel at before@insertmark}
 % \begin{macro}{insertmark}
 %    By default \cs{label}, \cs{index}, and \cs{glossary} do nothing
 %    when the mark is inserted.
 %    \begin{macrocode}
+\int_new:N \g_@@_int
 \cs_new:Npn \@kernel at before@insertmark {
           \cs_set_eq:NN \label    \scan_stop:
           \cs_set_eq:NN \index    \scan_stop:
           \cs_set_eq:NN \glossary \scan_stop:
+%    \end{macrocode}
+%    We count each mark and use that to place a hidden marker in front
+%    of the mark text. To ensure that there is no overflow (very
+%    unlikely but you never know) we restart every 100000 marks. Thus,
+%    if somebody puts more than that number of marks on a single page
+%    you could construct a scenario in which that approach fails.
+% \changes{v1.0f}{2024/05/30}{Use sequence marker to make all marks
+%    unique on nearby regions (gh/1359)}
+%    \begin{macrocode}
+          \int_compare:nNnTF \g_@@_int < {99999}
+              { \int_gincr:N \g_@@_int }
+              { \int_gzero:N \g_@@_int }
+                
 }
 %    \end{macrocode}
 %    The public hook to augment the setup.
@@ -1158,16 +1531,26 @@
 %    To retrieve the first, last or top region mark, we grab the
 %    appropriate value stored in the corresponding token list variable
 %    and pass its contents back. These functions should be used only
-%    in output routines after \cs{@@_update_structure:nn} has acted,
+%    in output routines and only after \cs{@@_update_structure_from_material:nn} has acted,
 %    otherwise their value will be wrong.
 %
 %    If used with an unknown class or region they generate an error
 %    (fairly low-level because we are in an expandable context).
+%
+%    Each mark starts with an id and while the id does not print it is
+%    nevertheless better to remove it when returning the mark, so that
+%    downstream manipulation of the data doesn't have to deal with it.
+% \changes{v1.0g}{2024/05/31}{Remove the id when returning the mark value (gh/1359)}
 %    \begin{macrocode}
-\cs_new:Npn \mark_use_first:nn #1#2 { \exp_not:v { g_@@_#1_first_#2_tl } }
-\cs_new:Npn \mark_use_last:nn #1#2  { \exp_not:v { g_@@_#1_last_#2_tl }  }
-\cs_new:Npn \mark_use_top:nn #1#2   { \exp_not:v { g_@@_#1_top_#2_tl }   }
+\cs_new:Npn \mark_use_first:nn #1#2 { \@@_use:v { g_@@_#1_first_#2_tl } }
+\cs_new:Npn \mark_use_last:nn #1#2  { \@@_use:v { g_@@_#1_last_#2_tl }  }
+\cs_new:Npn \mark_use_top:nn #1#2   { \@@_use:v { g_@@_#1_top_#2_tl }   }
 %    \end{macrocode}
+%    This is what the \cs{use_none:nn} accomplishes.
+%    \begin{macrocode}
+\cs_new:Npn \@@_use:n #1 { \exp_not:o { \use_none:nn #1 } }
+\cs_generate_variant:Nn \@@_use:n { v }
+%    \end{macrocode}
 % \end{macro}
 %
 %
@@ -1207,7 +1590,7 @@
 %
 % \subsection{Messages}
 %
-%    Mark errors are LaTeX kernel errors:
+%    Mark errors are \LaTeX{} kernel errors:
 % \changes{v1.0d}{2022/06/01}{Marks are kernel errors}
 %    \begin{macrocode}
 \prop_gput:Nnn \g_msg_module_type_prop { mark } { LaTeX }
@@ -1247,20 +1630,10 @@
   }
 %    \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}
 %
 %
 %
+%
 % \subsection{Debugging the mark structures}
 %
 %  Code and commands in this section are not final, it needs more
@@ -1358,7 +1731,7 @@
 %
 %
 %  \begin{macro}{\@@_status:n}
-%    Show all mark class values across all regions.
+%    Show a snapshot of all mark class values across all regions.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_status:n #1
   {
@@ -1370,8 +1743,24 @@
 %  \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 +1814,9 @@
 %
 %
 %
-%  \section{\LaTeXe{} integration}
+% \section{\LaTeXe{} integration}
 %
-%  \subsection{Core \LaTeXe{} integration}
+% \subsection{Core \LaTeXe{} integration}
 %
 %  \begin{macro}{\@@_update_singlecol_structures:}
 %    This command updates the mark structures if we are producing a
@@ -1445,11 +1834,11 @@
 %    \begin{macrocode}
   \box_if_vertical:NTF \@outputbox
       {
-        \@@_update_structure:nn {page}
+        \@@_update_structure_from_material:nn {page}
            { \vbox_unpack:N  \@outputbox }
       }
       {
-        \@@_update_structure:nn {page}
+        \@@_update_structure_from_material:nn {page}
            { \hbox_unpack:N  \@outputbox }
       }
 %    \end{macrocode}
@@ -1489,11 +1878,11 @@
 %    \begin{macrocode}
   \box_if_vertical:NTF \@outputbox
       {
-        \@@_update_structure:nn {column}
+        \@@_update_structure_from_material:nn {column}
            { \vbox_unpack:N  \@outputbox }
       }
       {
-        \@@_update_structure:nn {column}
+        \@@_update_structure_from_material:nn {column}
            { \hbox_unpack:N  \@outputbox }
       }
 %    \end{macrocode}
@@ -1538,6 +1927,12 @@
 %    \begin{macrocode}
       \seq_map_inline:Nn \g_@@_classes_seq
         {
+%    \end{macrocode}
+%    The \texttt{previous-page} updates need to come before the
+%    updates for \texttt{page} region because otherwise the values
+%    to copy are already overwritten.
+%    necessary values.
+%    \begin{macrocode}
           \tl_gset_eq:cc { g_@@_previous-page_top_   ##1 _tl }
                          { g_@@_page_top_            ##1 _tl }
           \tl_gset_eq:cc { g_@@_previous-page_first_ ##1 _tl }
@@ -1545,16 +1940,48 @@
           \tl_gset_eq:cc { g_@@_previous-page_last_  ##1 _tl }
                          { g_@@_page_last_           ##1 _tl }
 %    \end{macrocode}
-%    The \texttt{page} updates need to come after the corresponding
-%    updates for \texttt{previous-page} otherwise we loose the
-%    necessary value.
+%    To update the \texttt{top} we only have to copy what is in
+%    \texttt{first-column}:                      
 %    \begin{macrocode}
           \tl_gset_eq:cc { g_@@_page_top_           ##1 _tl }
                          { g_@@_first-column_top_   ##1 _tl }
-          \tl_gset_eq:cc { g_@@_ page_first_        ##1 _tl }
-                         { g_@@_first-column_first_ ##1 _tl }
-          \tl_gset_eq:cc { g_@@_page_last_          ##1 _tl }
-                         { g_@@_last-column_last_   ##1 _tl }
+             
+%    \end{macrocode}
+%    Updating the \texttt{first} mark for the \texttt{page} region is
+%    more complicated. We first have to find out of there is any mark
+%    in the first column (this can be done by comparing the \texttt{top} and
+%    the \texttt{first} mark of of that region). 
+% \changes{v1.0f}{2024/05/30}{Correct logic for first mark in page
+%    region if first column contains no marks (gh/1359)}
+%    \begin{macrocode}
+          \tl_if_eq:ccTF { g__@@_first-column_top_   ##1 _tl }
+                         { g__@@_first-column_first_ ##1 _tl }
+             {
+%    \end{macrocode}
+%    If there is no mark in the first column we copy the first mark of
+%    the last column. If that doesn't contain a mark we still get the
+%    right result because the first mark is then equal to the top mark.
+%    \begin{macrocode}
+               \tl_gset_eq:cc { g_@@_page_first_        ##1 _tl }
+                              { g_@@_last-column_first_ ##1 _tl }
+             }
+             {
+%    \end{macrocode}
+%    On the other hand, if there is a mark in the first column we copy
+%    over the \texttt{first} mark from that column.
+%    \begin{macrocode}
+               \tl_gset_eq:cc { g_@@_page_first_         ##1 _tl }
+                              { g_@@_first-column_first_ ##1 _tl }
+             }
+%    \end{macrocode}
+%    The logic for the \texttt{last} page mark is again simple, we can
+%    just copy the value in the \texttt{last} mark of the last column.
+%    If that column doesn't contain any marks, then the value in
+%    \texttt{last} will be automatically the same as the \texttt{last}
+%    from the first column.
+%    \begin{macrocode}
+          \tl_gset_eq:cc { g_@@_page_last_        ##1 _tl }
+                         { g_@@_last-column_last_ ##1 _tl }
         }
     }
 %<*trace>
@@ -1583,18 +2010,27 @@
 %<@@=>
 %    \end{macrocode}
 %
-%  \begin{macro}[int]{\@expl@@@mark at update@singlecol at structures@@,
-%                \@expl@@@mark at update@dblcol at structures@@}
+%  \begin{macro}[int]{\@expl@@@mark at update@singlecol at structures@@}
 %    \begin{macrocode}
 \cs_new_eq:NN  \@expl@@@mark at update@singlecol at structures@@
                \__mark_update_singlecol_structures:
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%    
+%  \begin{macro}[int]{\@expl@@@mark at update@dblcol at structures@@}
+%    \begin{macrocode}
 \cs_new_eq:NN  \@expl@@@mark at update@dblcol at structures@@
                \__mark_update_dblcol_structures:
 %    \end{macrocode}
 %  \end{macro}
 %
-%  \subsection{Other \LaTeXe{} output routines}
 %
+%
+%
+% \subsection{Other \LaTeXe{} output routines}
+%
 %  This section will cover \pkg{multicol} and other packages altering
 %  or providing their own output routine. Not done yet.
 %
@@ -1601,6 +2037,9 @@
 %
 %
 %
+% \subsection{Rollback information}
+%
+%
 %    \begin{macrocode}
 %<latexrelease>\IncludeInRelease{0000/00/00}{ltmarks}%
 %<latexrelease>                 {Undo~Marks~handling}
@@ -1609,7 +2048,7 @@
 %    We keep the interface commands around even if we roll back in
 %    case they are used in packages that don't roll back. Not likely
 %    to do a lot of good, but then there is not much we can do, but
-%    this at least then doesn't give errors.
+%    this at least they won't give unknown csname errors.
 %    \begin{macrocode}
 %<latexrelease>\DeclareRobustCommand \NewMarkClass[1]{}
 %<latexrelease>\DeclareRobustCommand \InsertMark[2]{}

Modified: trunk/Master/texmf-dist/source/latex/base/ltmeta.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltmeta.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltmeta.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -13,21 +13,15 @@
 %
 %
 %%% From File: ltmeta.dtx
+%<*driver>
+% \fi
+\ProvidesFile{ltmeta.dtx}
+             [2024/05/16 v1.0b LaTeX Kernel (Document Metadata)]
+% \iffalse
 %
-%    \begin{macrocode}
-\def\ltmetaversion{v1.0b}
-\def\ltmetadate{2022/05/18}
-%    \end{macrocode}
-%<*driver>
 \documentclass{l3doc}
+\GetFileInfo{ltmeta.dtx}
 
-% Fixing footnotes in  functions and variables: this should be in l3doc!
-
-\newcommand\fixfootnote[2]{\footnotemark
-  \AddToHookNext{env/#1/after}{\footnotetext{#2}}}
-\AddToHook{env/function/begin}{\def\footnote{\fixfootnote{function}}}
-\AddToHook{env/variable/begin}{\def\footnote{\fixfootnote{variable}}}
-
 \EnableCrossrefs
 \CodelineIndex
 \begin{document}
@@ -43,7 +37,7 @@
 %
 %
 % \title{The \texttt{ltmeta.dtx} code\thanks{This file has version
-%    \ltmetaversion\ dated \ltmetadate, \copyright\ \LaTeX\
+%    \fileversion\ dated \filedate, \copyright\ \LaTeX\
 %    Project.}}
 % \author{Frank Mittelbach}
 %

Modified: trunk/Master/texmf-dist/source/latex/base/ltmiscen.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltmiscen.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltmiscen.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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}

Modified: trunk/Master/texmf-dist/source/latex/base/ltoutenc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltoutenc.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltoutenc.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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 at 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 at tempswa
 %    \end{macrocode}
 %
+% \changes{v2.1a}{2023/11/07}{Add more explanation to error message (gh/1102)}
 %    \begin{macrocode}
      \edef\reserved at f{%
        \lowercase{\def\noexpand\reserved at f{\CurrentOption enc.def}}}%
@@ -3685,7 +3686,11 @@
           {}{\PackageError{fontenc}%
            {Encoding file `\reserved at 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 at shape|, e.g., \texttt{LY1} is not defined for
+%    specified in the option list). But this encoding may not work with
+%    the current |\f at 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

Modified: trunk/Master/texmf-dist/source/latex/base/ltoutput.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltoutput.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltoutput.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -37,7 +37,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltoutput.dtx}
-             [2023/05/26 v1.4j LaTeX Kernel (Output Routine)]
+             [2024/03/16 v1.4j LaTeX Kernel (Output Routine)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltoutput.dtx}
@@ -847,7 +847,7 @@
 % \begin{macro}{\if at firstcolumn}
 % \begin{macro}{\if at twocolumn}
 % \begin{macro}{\if at twoside}
-% \begin{macro}{\if at reversemarginpar}
+% \begin{macro}{\if at reversemargin}
 % \begin{macro}{\if at mparswitch}
 % \begin{macro}{\col at number}
 % \changes{v1.0n}{1994/04/30}{Added \cs{col at number}}

Modified: trunk/Master/texmf-dist/source/latex/base/ltpara.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltpara.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltpara.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -14,22 +14,15 @@
 %
 %%% From File: ltpara.dtx
 %
-%    \begin{macrocode}
-\def\ltparaversion{v1.0l}
-\def\ltparadate{2023/01/30}
-%    \end{macrocode}
 %<*driver>
+% \fi
+\ProvidesFile{ltpara.dtx}
+             [2024/05/16 v1.0m LaTeX Kernel (paragraph hooks)]
+% \iffalse
+%
 \documentclass{l3doc}
+\GetFileInfo{ltpara.dtx}
 
-%\usepackage{ltpara}
-
-% Fixing footnotes in  functions and variables: this should be in l3doc!
-
-\newcommand\fixfootnote[2]{\footnotemark
-  \AddToHookNext{env/#1/after}{\footnotetext{#2}}}
-\AddToHook{env/function/begin}{\def\footnote{\fixfootnote{function}}}
-\AddToHook{env/variable/begin}{\def\footnote{\fixfootnote{variable}}}
-
 \EnableCrossrefs
 \CodelineIndex
 \begin{document}
@@ -45,7 +38,7 @@
 %
 %
 % \title{The \texttt{ltpara.dtx} code\thanks{This file has version
-%    \ltparaversion\ dated \ltparadate, \copyright\ \LaTeX\
+%    \fileversion\ dated \filedate, \copyright\ \LaTeX\
 %    Project.}}
 % \author{Frank Mittelbach}
 %
@@ -811,9 +804,11 @@
   \hook_use:n {para/begin}
 %    \end{macrocode}
 %    If we aren't in horizontal mode any longer the hooks above misbehaved.
+% \changes{v1.0m}{2023/11/16}{Correct error message: hook
+%          left horizontal not vertical mode (gh/1182)}
 %    \begin{macrocode}
   \if_mode_horizontal: \else:
-    \msg_error:nnnn { hooks }{ para-mode }{begin}{vertical} \fi:
+    \msg_error:nnnn { hooks }{ para-mode }{begin}{horizontal} \fi:
 %    \end{macrocode}
 %    Finally we reinsert the indentation box (unless suppressed) and
 %    then call \cs{everypar} the way legacy \LaTeX\ code expects it.
@@ -845,7 +840,7 @@
 %<latexrelease>  \@kernel at before@para at 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}
@@ -1261,7 +1256,7 @@
 %    redo the \cs{everypar} setting from the kernel, otherwise that
 %    gets lost (as it happens before that file is loaded).
 %    \begin{macrocode}
-\everypar{\@nodocument} %% To get an error if text appears before the
+\everypar{\@nodocument} %% To get an error if text appears before the \document
 %    \end{macrocode}
 %
 %

Modified: trunk/Master/texmf-dist/source/latex/base/ltplain.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltplain.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltplain.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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@
 }%

Modified: trunk/Master/texmf-dist/source/latex/base/ltproperties.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltproperties.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltproperties.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-%% File: ltproperties.dtx
+% File: ltproperties.dtx
 %
-% Copyright (C) 2021-2023 The LaTeX Project
+% Copyright (C) 2023-2024 The LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -21,13 +21,21 @@
 %    https://github.com/latex3/latex2e
 %
 % for those people who are interested.
-%    \begin{macrocode}
-\def\ltpropertiesversion{1.0c}
-\def\ltpropertiesdate{2023-10-15}
-%    \end{macrocode}
+%
+% \fi
+%
+% \iffalse
+%%% From File: ltproperties.dtx
+%
+%<*driver> 
+% \fi
+\ProvidesFile{ltproperties.dtx}
+             [2024/04/17 v1.0e LaTeX Kernel (Properties)]
+% \iffalse
+%
+\documentclass[full]{l3doc}
+\GetFileInfo{ltproperties.dtx}
 
-%<*driver>
-\documentclass[full]{l3doc}
 \EnableCrossrefs
 \CodelineIndex
 \begin{document}
@@ -39,7 +47,7 @@
 % \title{^^A
 %   Recording and cross-referencing document properties^^A
 %  \thanks{This module has version
-%    \ltpropertiesversion\ dated \ltpropertiesdate, \copyright\ The \LaTeX\
+%    \fileversion\ dated \filedate, \copyright\ The \LaTeX\
 %    Project.}
 % }
 %
@@ -157,8 +165,8 @@
 %
 % \begin{function}{\property_new:nnnn,\property_gset:nnnn}
 %   \begin{syntax}
-%     \cs{property_new:nnnn} \Arg{property} \Arg{setpoint} \Arg{default}  \Arg{code}
-%     \cs{property_gset:nnnn} \Arg{property}\Arg{setpoint} \Arg{default}  \Arg{code}
+%     \cs{property_new:nnnn}  \Arg{property} \Arg{setpoint} \Arg{default} \Arg{code}
+%     \cs{property_gset:nnnn} \Arg{property} \Arg{setpoint} \Arg{default} \Arg{code}
 %   \end{syntax}
 %  \LaTeXe-interface: see \cs{NewProperty}, \cs{SetProperty}.\\ 
 %   Sets the \meta{property} to have the \meta{default} specified, and at the
@@ -180,7 +188,7 @@
 %     \property_record:nn, \property_record:nV, \property_record:ee
 %   }
 %   \begin{syntax}
-%      \cs{property_record:nN} \Arg{label} \Arg{clist var}
+%      \cs{property_record:nN} \Arg{label} \meta{clist var}
 %      \cs{property_record:nn} \Arg{label} \Arg{clist}
 %   \end{syntax}
 %   \LaTeXe{}-interface: see \cs{RecordProperties}.\\  
@@ -266,7 +274,7 @@
 %     \cs{property_if_exist_p:n} \Arg{property}
 %     \cs{property_if_exist:nTF} \Arg{property} \Arg{true code} \Arg{false code}
 %   \end{syntax}
-%  \LaTeXe{}-interface: \cs{IfPropertyExistTF}.\\   
+%  \LaTeXe{}-interface: \cs{IfPropertyExistsTF}.\\   
 %   Tests if the \meta{property} has been declared.
 % \end{function}
 %
@@ -275,7 +283,7 @@
 %     \cs{property_if_recorded_p:n} \Arg{label} 
 %     \cs{property_if_recorded:nTF} \Arg{label} \Arg{true code} \Arg{false code}
 %   \end{syntax}
-%  \LaTeXe{}-interface: \cs{IfLabelExistTF}\\
+%  \LaTeXe{}-interface: \cs{IfLabelExistsTF}\\
 %   Tests if the \meta{label} is known. This is also true if the label has been
 %   set with the standard \cs{label} command.
 % \end{function}
@@ -307,8 +315,8 @@
 % 
 % \begin{function}{\NewProperty,\SetProperty}
 %   \begin{syntax}
-%     \cs{NewProperty} \Arg{property} \Arg{setpoint} \Arg{default}  \Arg{code}
-%     \cs{SetProperty} \Arg{property} \Arg{setpoint} \Arg{default}  \Arg{code}
+%     \cs{NewProperty} \Arg{property} \Arg{setpoint} \Arg{default} \Arg{code}
+%     \cs{SetProperty} \Arg{property} \Arg{setpoint} \Arg{default} \Arg{code}
 %   \end{syntax}
 %   Sets the \meta{property} to have the \meta{default} specified, and at the
 %   \meta{setpoint} (either |now| or |shipout|) to write the result of the
@@ -329,7 +337,7 @@
 %   of properties. Also similar to the standard \cs{label} command, the command is surrounded
 %   by an \cs{@bsphack}/\cs{@esphack} pair to preserve spacing.
 % \end{function}
-
+%
 % \begin{function}[EXP]{\RefProperty}
 %   \begin{syntax}
 %      \cs{RefProperty} \oarg{local default} \Arg{label} \Arg{property}
@@ -340,16 +348,16 @@
 %   If \Arg{property} has not been declared an error is issued.
 % \end{function}
 % 
-% \begin{function}{\IfPropertyExistTF}
+% \begin{function}{\IfPropertyExistsTF,\IfPropertyExistsT,\IfPropertyExistsF}
 %   \begin{syntax}
-%     \cs{IfPropertyExistTF}  \Arg{property} \Arg{true code} \Arg{false code}
+%     \cs{IfPropertyExistsTF} \Arg{property} \Arg{true code} \Arg{false code}
 %   \end{syntax}
 %   Tests if the \meta{property} has been declared.
 % \end{function}
 %
-% \begin{function}{\IfLabelExistTF}
+% \begin{function}{\IfLabelExistsTF,\IfLabelExistsT,\IfLabelExistsF}
 %   \begin{syntax}
-%     \cs{IfLabelExistTF} \Arg{label} \Arg{true code} \Arg{false code}
+%     \cs{IfLabelExistsTF} \Arg{label} \Arg{true code} \Arg{false code}
 %   \end{syntax}
 %   Tests if the \meta{label} has been recorded. This is also true if a label
 %   has been set with the standard \cs{label} command.
@@ -361,7 +369,7 @@
 %   \end{syntax}
 %   Tests if the label and a value of the \meta{property} for the \meta{label} are both known.
 % \end{function}
-
+%
 % \begin{function}{\RefUndefinedWarn}
 %   \begin{syntax}
 %      \cs{RefUndefinedWarn} \Arg{label} \Arg{property}
@@ -551,6 +559,7 @@
 %   later too. That is all pretty easy using \pkg{expl3}: we accept a stray
 %   comma at the end of the list as that is easier to deal with than trying
 %   to tidy up, and there is no real downside.
+% \changes{v1.0d}{2024-01-17}{Use \cs{protected at 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 at write \@auxout {}
           {
             \token_to_str:N \new at label@record 
               {#1}
@@ -737,9 +746,13 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{IfPropertyExistTF}
+% \begin{macro}{\IfPropertyExistsTF,\IfPropertyExistsT,\IfPropertyExistsF}
+% \changes{v1.0e}{2024-04-17}{Renamed \cs{IfPropertyExistTF} to
+%                             \cs{IfPropertyExistsTF} (gh/1262)} 
 %    \begin{macrocode}
-\cs_new_eq:NN \IfPropertyExistTF \property_if_exist:eTF  
+\cs_new_eq:NN \IfPropertyExistsTF \property_if_exist:eTF  
+\cs_new:Npn   \IfPropertyExistsT #1#2 {\property_if_exist:eTF {#1}{#2}{} }  
+\cs_new:Npn   \IfPropertyExistsF #1   {\property_if_exist:eTF {#1}{} }  
 %    \end{macrocode}
 % \end{macro}
 % 
@@ -762,9 +775,13 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\IfLabelExistTF}
+% \begin{macro}{\IfLabelExistsTF,\IfLabelExistsT,\IfLabelExistsF}
+% \changes{v1.0e}{2024-04-17}{Renamed \cs{IfLabelExistTF} to
+%                             \cs{IfLabelExistsTF} (gh/1262)} 
 %    \begin{macrocode}
-\cs_new_eq:NN \IfLabelExistTF \property_if_recorded:eTF  
+\cs_new_eq:NN \IfLabelExistsTF \property_if_recorded:eTF  
+\cs_new:Npn   \IfLabelExistsT #1#2 {\property_if_exist:eTF {#1}{#2}{} }  
+\cs_new:Npn   \IfLabelExistsF #1   {\property_if_exist:eTF {#1}{} }  
 %    \end{macrocode}
 % \end{macro} 
 %
@@ -938,8 +955,8 @@
 %<latexrelease>\let \RefProperty \@undefined
 %<latexrelease>\let \RefUndefinedWarn  \@undefined
 %<latexrelease>
-%<latexrelease>\let \IfPropertyExistTF \@undefined
-%<latexrelease>\let \IfLabelExistTF \@undefined
+%<latexrelease>\let \IfPropertyExistsTF \@undefined
+%<latexrelease>\let \IfLabelExistsTF \@undefined
 %<latexrelease>\let \IfPropertyRecordedTF  \@undefined
 %<latexrelease>
 %<latexrelease>\let\new at label@record \@undefined

Modified: trunk/Master/texmf-dist/source/latex/base/ltsect.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltsect.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltsect.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -31,7 +31,7 @@
 %%% From File: ltsect.dtx
 %<*driver>
 % \fi
-\ProvidesFile{ltsect.dtx}[2021/07/28 v1.1f LaTeX Kernel (Sectioning)]
+\ProvidesFile{ltsect.dtx}[2024/03/25 v1.1f LaTeX Kernel (Sectioning)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltsect.dtx}
@@ -835,13 +835,13 @@
 % \begin{macro}{\contentsline}
 % The |\contentsline{|\meta{type}|}{|\meta{entry}|}{|\meta{page}|}{}|
 % macro produces a \meta{type} entry in a table of contents, etc.
-% It will appear in the |.toc| or other file.  For example,
-% The entry for subsection 1.4.3 in the table of contents for
-% example, might be produced by:
+% It will appear in the |.toc| or other file.
+% For example, the entry for subsection 1.4.3 in the table of contents,
+% might be produced by:
 %
 %  \begin{verbatim}
 %       \contentsline{subsection}
-%           {\makebox{30pt}[r]{1.4.3} Gnats and Gnus}{22}
+%           {\numberline{1.4.3}Gnats and Gnus}{22}{}
 %  \end{verbatim}
 %
 %  The |\protect| command causes command sequences to be written

Modified: trunk/Master/texmf-dist/source/latex/base/ltshipout.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltshipout.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltshipout.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -31,31 +31,15 @@
 %
 %%% 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
 %
-%<*driver>
-
 \documentclass{l3doc}
+\GetFileInfo{ltshipout.dtx}
 
-% 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
-
 \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} }

Modified: trunk/Master/texmf-dist/source/latex/base/ltsockets.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltsockets.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltsockets.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -30,15 +30,15 @@
 %
 %%% 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

Modified: trunk/Master/texmf-dist/source/latex/base/ltspace.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltspace.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltspace.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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 }.

Added: trunk/Master/texmf-dist/source/latex/base/lttagging.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/lttagging.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/base/lttagging.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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 at 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 at refstepcounter\refstepcounter
+%    \end{macrocode}
+%    Prevent longtable patching by hyperref until hyperref does so automatically:
+%    \begin{macrocode}
+\def\hyper at 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
+%


Property changes on: trunk/Master/texmf-dist/source/latex/base/lttagging.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/base/lttemplates.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/lttemplates.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/base/lttemplates.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -0,0 +1,2634 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 1999 Frank Mittelbach, Chris Rowley, David Carlisle
+% Copyright (C) 2004-2010 Frank Mittelbach, The LaTeX Project
+% Copyright (C) 2011-2024
+% The LaTeX Project and any individual authors listed elsewhere
+% in this file.
+%
+% This file is part of the LaTeX base system.
+% -------------------------------------------
+%
+% It may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3c
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+%    https://www.latex-project.org/lppl.txt
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2008 or later.
+%
+% This file has the LPPL maintenance status "maintained".
+%
+% The list of all files belonging to the LaTeX base distribution is
+% given in the file `manifest.txt'. See also `legal.txt' for additional
+% information.
+%
+% The list of derived (unpacked) files belonging to the distribution
+% and covered by LPPL is defined by the unpacking scripts (with
+% extension .ins) which are part of the distribution.
+%
+% \fi
+%
+% \iffalse
+%
+%%% From File: lttemplates.dtx
+%
+%<*driver>
+% \fi
+\ProvidesFile{lttemplates.dtx}
+  [2024-04-17 v1.0c LaTeX Kernel (Prototype document functions)]
+% \iffalse
+\documentclass{l3doc}
+\GetFileInfo{lttemplates.dtx}
+\begin{document}
+  \DocInput{lttemplates.dtx}
+\end{document}
+%</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 at latex-project.org}
+%          {latex-team at latex-project.org}^^A
+%    }^^A
+% }
+%
+% \maketitle
+%
+% \section{Introduction}
+%
+% There are three broad \enquote{layers} between putting down ideas into
+% a source file and ending up with a typeset document. These layers of
+% document writing are
+% \begin{enumerate}
+%   \item authoring of the text with mark-up;
+%   \item document layout design;
+%   \item implementation (with \TeX{} programming) of the design.
+% \end{enumerate}
+% We write the text as an author, and we see the visual output of the design
+% after the document is generated; the \TeX{} implementation in the middle is
+% the glue between the two.
+%
+% \LaTeX{}'s greatest success has been to standardise a system of mark-up that
+% balances the trade-off between ease of reading and ease of writing to suit
+% almost all forms of technical writing. It's
+% other original strength was a good background in typographical design; while
+% the standard \LaTeXe{} classes look somewhat dated now in terms of their
+% visual design, their typography is generally sound (barring the occasional
+% minor faults).
+%
+% However, \LaTeXe{} has always lacked a standard approach to customising
+% the visual design of a document. Changing the looks of the standard classes
+% involved either:
+% \begin{itemize}
+%   \item Creating a new version of the implementation code of the class and
+%     editing it.
+%   \item Loading one of the many packages to customise certain elements of
+%     the standard classes.
+%   \item Loading a completely different document class, such as
+%     \textsf{KOMA-Script} or \textsf{memoir}, that allows easy customisation.
+% \end{itemize}
+% All three of these approaches have their drawbacks and learning curves.
+%
+% The idea behind \pkg{lttemplates} is to cleanly separate the three layers
+% introduced at the beginning of this section, so that document authors who
+% are not programmers can easily change the design of their documents.
+% \pkg{lttemplates} also makes it easier for \LaTeX{} programmers to provide
+% their own customisations on top of a pre-existing class.
+%
+% \section{What is a document?}
+%
+% Besides the textual content of the words themselves, the source file
+% of a document contains mark-up elements that add structure to the
+% document. These elements include sectional divisions, figure/table
+% captions, lists of various sorts, theorems/proofs, and so on.
+% The list will be different for every document that can be written.
+%
+% Each element can be represented logically without worrying about the
+% formatting, with mark-up such as \cs{section}, \cs{caption},
+% |\begin{enumerate}| and so on. The output of each one of these
+% document elements will be a typeset representation of the information
+% marked up, and the visual arrangement and design of these elements
+% can vary widely in producing a variety of desired outcomes.
+%
+% For each type of document element, there may be design variations that
+% contain the same sort of information but present it in slightly
+% different ways. For example, the difference between a numbered and an
+% unnumbered section, \cs{section} and |\section*|, or the difference
+% between an itemised list or an enumerated list.
+%
+% There are three distinct layers in the definition of
+% \enquote{a document} at this level
+% \begin{enumerate}
+%   \item semantic elements such as the ideas of sections and lists;
+%   \item a set of design solutions for representing these elements
+%     visually;
+%   \item specific variations for these designs that represent the
+%     elements in the document.
+% \end{enumerate}
+% In the parlance of the template system, these are called types,
+% templates, and instances, and they are discussed below in sections
+% \ref{sec:types}, \ref{sec:templates}, and~\ref{sec:instances},
+% respectively.
+%
+% \section {Types, templates, and instances}
+%
+% By formally declaring documents to be composed of mark-up elements
+% grouped into types, which are interpreted and typeset with a set of
+% templates, each of which has one or more instances with which to
+% compose each and every semantic unit of the text, we can cleanly
+% separate the components of document construction.
+%
+% All of the structures provided by the template system are global,
+% and do not respect \TeX{} grouping.
+%
+% \section{Template types}
+% \label{sec:types}
+%
+% An \emph{template type} (sometimes just \enquote{type}) is an
+% abstract idea of a document element that takes a fixed number of
+% arguments corresponding to the information from the document author
+% that it is representing. A sectioning type, for example, might take
+% three inputs: \enquote{title}, \enquote{short title}, and
+% \enquote{label}.
+%
+% Any given document class will define which types are to be
+% used in the document, and any template of a given type can be
+% used to generate an instance for the type. (Of course, different
+% templates will produce different typeset representations, but the
+% underlying content will be the same.)
+%
+% \begin{function}{\NewTemplateType}
+%   \begin{syntax}
+%     \cs{NewTemplateType} \Arg{template type} \Arg{no. of args}
+%   \end{syntax}
+%  This function defines an \meta{template type} taking
+%  \meta{number of arguments}, where the \meta{type} is an
+%  abstraction as discussed above. For example,
+%   \begin{verbatim}
+%     \NewTemplateType{sectioning}{3}
+%   \end{verbatim}
+%  creates a type \enquote{sectioning}, where each use of that
+%  type will need three arguments.
+% \end{function}
+%
+% \section{Templates}
+% \label{sec:templates}
+%
+% A \emph{template} is a generalised design solution for representing
+% the information of a specified type. Templates that do the same
+% thing, but in different ways, are grouped together by their type
+% and given separate names. There are two important parts to a template:
+% \begin{itemize}
+%   \item the parameters it takes to vary the design it is producing;
+%   \item the implementation of the design.
+% \end{itemize}
+% As a document author or designer does not care about the
+% implementation but rather only the interface to the template, these two
+% aspects of the template definition are split into two independent
+% declarations, \cs{DeclareTemplateInterface} and
+% \cs{DeclareTemplateCode}.
+%
+% \begin{function}{\DeclareTemplateInterface}
+%   \begin{syntax}
+%     \cs{DeclareTemplateInterface}
+%     ~~\Arg{type} \Arg{template} \Arg{no.~of args}
+%     ~~\Arg{key list}
+%   \end{syntax}
+%   A \meta{template} interface is declared for a particular
+%   \meta{type}, where the \meta{number of arguments} must
+%   agree with the type declaration. The interface itself is
+%   defined by the \meta{key list}, which is itself a key--value list
+%   taking a specialized format:
+%   \begin{quotation}
+%     \obeylines
+%     \noindent
+%      \meta{key1}~":"~\meta{key type1}~","
+%      \meta{key2}~":"~\meta{key type2}~","
+%      \meta{key3}~":"~\meta{key type3}~"="~\meta{default3}~","
+%      \meta{key4}~":"~\meta{key type4}~"="~\meta{default4}~","
+%      \ldots
+%    \end{quotation}
+%   Each \meta{key} name should consist of \textsc{ascii} characters,
+%   with the exception of |,|, |=| and \verb*| |. The recommended form
+%   for key names is to use lower case letters, with dashes to separate
+%   out different parts. Spaces are ignored in key names, so they can be
+%   included or missed out at will. Each \meta{key} must have a
+%   \meta{key type}, which defined the type of input that the \meta{key}
+%   requires. A full list of key types is given in
+%   Table~\ref{tab:key-types}.  Each key may have a \meta{default}
+%   value, which will be used in by the template if the \meta{key} is
+%   not set explicitly. The \meta{default} should be of the correct
+%   form to be accepted by the \meta{key type} of the \meta{key}: this
+%   is not checked by the code. Expressions for numerical values are
+%   evaluated when the template is used, thus for example values given
+%   in terms of |em| or |ex| will be set respecting the prevailing font.
+% \end{function}
+%
+%   \begin{table}
+%     \centering
+%     \begin{tabular}{>{\ttfamily}ll}
+%       \toprule
+%       \multicolumn{1}{l}{Key-type} & Description of input \\
+%       \midrule
+%       boolean    & \texttt{true} or \texttt{false}            \\
+%       choice\Arg{choices}
+%         & A list of pre-defined \meta{choices} \\
+%       commalist  & A comma-separated list                        \\
+%       function\Arg{$N$}
+%         & A function definition with $N$ arguments
+%          ($N$ from $0$ to $9$) \\
+%       instance\Arg{name}
+%         & An instance of type \meta{name} \\
+%       integer    & An integer or integer expression            \\
+%       length     & A fixed length                              \\
+%       muskip     & A math length with shrink and stretch components \\
+%       real       & A real (floating point) value               \\
+%       skip       & A length with shrink and stretch components \\
+%       tokenlist  & A token list: any text or commands          \\
+%       \bottomrule
+%     \end{tabular}
+%     \caption{Key-types for defining template interfaces with
+%       \cs{DeclareTemplateInterface}.}
+%     \label{tab:key-types}
+%   \end{table}
+%
+% \begin{function}{\KeyValue}
+%   \begin{syntax}
+%     \cs{KeyValue} \Arg{key name}
+%   \end{syntax}
+%   There are occasions where the default (or value) for one key
+%   should be taken from another. The \cs{KeyValue} function can be
+%   used to transfer this information without needing to know the
+%   internal implementation of the key:
+%   \begin{verbatim}
+%     \DeclareTemplateInterface { type } { template } { no. of args }
+%       {
+%         key-name-1 : key-type = value ,
+%         key-name-2 : key-type = \KeyValue { key-name-1 },
+%         ...
+%       }
+%   \end{verbatim}
+% \end{function}
+%
+% \begin{function}{\DeclareTemplateCode}
+%   \begin{syntax}
+%     \cs{DeclareTemplateCode}
+%     ~~\Arg{type} \Arg{template} \Arg{no.~of args}
+%     ~~\Arg{key bindings} \Arg{code}
+%   \end{syntax}
+%   The relationship between a templates keys and the internal
+%   implementation is created using the \cs{DeclareTemplateCode}
+%   function. As with \cs{DeclareTemplateInterface}, the
+%   \meta{template} name is given along with the \meta{type}
+%   and \meta{number of arguments} required. The \meta{key bindings}
+%   argument is a key--value list which specifies the relationship
+%   between each \meta{key} of the template interface with an
+%   underlying\meta{variable}.
+%
+%   \begin{quotation}
+%     \obeylines
+%     \noindent
+%     \meta{key1}~"="~\meta{variable1},
+%     \meta{key2}~"="~\meta{variable2},
+%     \meta{key3}~"="~global~\meta{variable3},
+%     \meta{key4}~"="~global~\meta{variable4},
+%     \ldots
+%   \end{quotation}
+%   With the exception of the choice, code and function key types,
+%   the \meta{variable} here should be the name of an existing
+%   \LaTeX3 register. As illustrated, the key word \enquote{global}
+%   may be included in the listing to indicate that the \meta{variable}
+%   should be assigned globally. A full list of variable bindings is
+%   given in Table~\ref{tab:key-vars}.
+%
+%   The \meta{code} argument of \cs{DeclareTemplateCode} is used
+%   as the replacement text for the template when it is used, either
+%   directly or as an instance. This may therefore accept arguments
+%   |#1|, |#2|, \emph{etc}.~as detailed by the \meta{number of arguments}
+%   taken by the type.
+% \end{function}
+%
+%   \begin{table}
+%     \centering
+%     \begin{tabular}{>{\ttfamily}ll}
+%       \toprule
+%       \multicolumn{1}{l}{Key-type} & Description of binding \\
+%       \midrule
+%       \    & Boolean variable, \emph{e.g}.~\cs{l_tmpa_bool}      \\
+%       choice
+%         & List of choice implementations
+%         (see Section~\ref{sec:choices-key}) \\
+%       commalist  & Comma list, \emph{e.g}.~\cs{l_tmpa_clist}           \\
+%       function
+%         & Function taking $N$ arguments, \emph{e.g}.~\cs{use_i:nn}     \\
+%       instance \\
+%       integer    & Integer variable, \emph{e.g}.~\cs{l_tmpa_int}       \\
+%       length     & Dimension variable, \emph{e.g}.~\cs{l_tmpa_dim}     \\
+%       muskip     & Muskip variable, \emph{e.g}.~\cs{l_tmpa_muskip}     \\
+%       real       & Floating-point variable, \emph{e.g}.~\cs{l_tmpa_fp} \\
+%       skip       & Skip variable, \emph{e.g}.~\cs{l_tmpa_skip}         \\
+%       tokenlist  & Token list variable, \emph{e.g}.~\cs{l_tmpa_tl}     \\
+%       \bottomrule
+%     \end{tabular}
+%     \caption{Bindings required for different key types when defining
+%       template implementations with \cs{DeclareTemplateCode}. Apart
+%       from \texttt{code}, \texttt{choice} and \texttt{function}
+%       all of these accept the key word \texttt{global} to carry
+%       out a global assignment.}
+%     \label{tab:key-vars}
+%   \end{table}
+%
+% \begin{function}{\AssignTemplateKeys}
+%   \begin{syntax}
+%     \cs{AssignTemplateKeys}
+%   \end{syntax}
+%   In the final argument of \cs{DeclareTemplateCode} the assignment of
+%   keys defined by the template may be delayed by including the command
+%   \cs{AssignTemplateKeys}. If this is \emph{not} present, keys are assigned
+%   immediately before the template code. If \cs{AssignTemplateKeys} is
+%   present, assignment is delayed until this point. Note that the
+%   command must be \emph{directly} present in the code, not placed
+%   within a nested command/macro.
+% \end{function}
+%
+% \begin{function}{\DeclareTemplateCopy}
+%   \begin{syntax}
+%     \cs{DeclareTemplateCopy}
+%     ~~\Arg{type} \Arg{template2} \Arg{template1}
+%   \end{syntax}
+%   Copies \meta{template1} of \meta{type} to a new name \meta{template2}:
+%   the copy can then be edited independent of teh original.
+% \end{function}
+%
+% \section{Multiple choices}
+% \label{sec:choices-key}
+%
+% The \texttt{choice} key type implements multiple choice input. At the
+% interface level, only the list of valid choices is needed:
+% \begin{verbatim}
+%   \DeclareTemplateInterface { foo } { bar } { 0 }
+%     { key-name : choice { A, B, C } }
+% \end{verbatim}
+% where the choices are given as a comma-list (which must therefore
+% be wrapped in braces). A default value can also be given:
+% \begin{verbatim}
+%   \DeclareTemplateInterface { foo } { bar } { 0 }
+%     { key-name : choice { A, B, C } = A }
+% \end{verbatim}
+%
+% At the implementation level, each choice is associated with code,
+% using a nested key--value list.
+% \begin{verbatim}
+%   \DeclareTemplateCode { foo } { bar } { 0 }
+%     {
+%       key-name =
+%         {
+%           A = Code-A ,
+%           B = Code-B ,
+%           C = Code-C
+%         }
+%      }
+%      { ... }
+% \end{verbatim}
+% The two choice lists should match, but in the implementation a
+% special \texttt{unknown} choice is also available. This can be used
+% to ignore values and implement an \enquote{else} branch:
+% \begin{verbatim}
+%   \DeclareTemplateCode { foo } { bar } { 0 }
+%     {
+%       key-name =
+%         {
+%           A       = Code-A ,
+%           B       = Code-B ,
+%           C       = Code-C ,
+%           unknown = Else-code
+%         }
+%      }
+%      { ... }
+% \end{verbatim}
+% The \texttt{unknown} entry must be the last one given, and should
+% \emph{not} be listed in the interface part of the template.
+%
+% For keys which accept the values \texttt{true} and \texttt{false}
+% both the boolean and choice key types can be used. As template
+% interfaces are intended to prompt clarity at the design level, the
+% boolean key type should be favoured, with the choice type reserved
+% for keys which take arbitrary values.
+%
+% \section{Instances}
+% \label{sec:instances}
+%
+% After a template is defined it still needs to be put to use. The
+% parameters that it expects need to be defined before it can be used in
+% a document. Every time a template has parameters given to it, an
+% \emph{instance} is created, and this is the code that ends up in the
+% document to perform the typesetting of whatever pieces of information
+% are input into it.
+%
+% For example, a template might say \enquote{here is a section with or
+% without a number that might be centred or left aligned and print its
+% contents in a certain font of a certain size, with a bit of a gap
+% before and after it} whereas an instance declares \enquote{this is a
+% section with a number, which is centred and set in $12\,\text{pt}$
+% italic with a $10\,\text{pt}$ skip before and a
+% $12\,\text{pt}$ skip after it}. Therefore, an instance is just a
+% frozen version of a template with specific settings as chosen by the
+% designer.
+%
+% \begin{function}{\DeclareInstance}
+%   \begin{syntax}
+%     \cs{DeclareInstance}
+%     ~~\Arg{type} \Arg{instance} \Arg{template} \Arg{parameters}
+%   \end{syntax}
+%   This function uses a \meta{template} for an \meta{type}
+%   to create an \meta{instance}. The \meta{instance} will be set
+%   up using the \meta{parameters}, which will set some of the
+%   \meta{keys} in the \meta{template}.
+%
+%   As a practical example, consider a type for document sections
+%   (which might include chapters, parts, sections, \emph{etc}.), which
+%   is called \texttt{sectioning}. One possible template for this
+%   type might be called \texttt{basic}, and one instance of this
+%   template would be a numbered section. The instance declaration might
+%   read:
+%   \begin{verbatim}
+%     \DeclareInstance { sectioning } { section-num } { basic }
+%       {
+%         numbered      = true ,
+%         justification = center ,
+%         font          =\normalsize\itshape ,
+%         before-skip   = 10pt ,
+%         after-skip    = 12pt ,
+%       }
+%   \end{verbatim}
+%   Of course, the key names here are entirely imaginary, but illustrate
+%   the general idea of fixing some settings.
+% \end{function}
+%
+% \begin{function}{\IfInstanceExistsT, \IfInstanceExisstF, \IfInstanceExistsTF}
+%   \begin{syntax}
+%     \cs{IfInstanceExistsTF} \Arg{type} \Arg{instance} \Arg{true code} \Arg{false code}
+%   \end{syntax}
+%   Tests if the named \meta{instance} of a \meta{type} exists, and
+%   then inserts the appropriate code into the input stream.
+% \end{function}
+%
+% \begin{function}{\DeclareInstanceCopy}
+%   \begin{syntax}
+%     \cs{DeclareInstanceCopy}
+%     ~~\Arg{type} \Arg{instance2} \Arg{instance1}
+%   \end{syntax}
+%   Copies the \meta{values} for \meta{instance1} for an
+%   \meta{type} to \meta{instance2}.
+% \end{function}
+%
+% \section{Document interface}
+%
+% After the instances have been chosen, document commands must be
+% declared to use those instances in the document. \cs{UseInstance}
+% calls instances directly, and this command should be used internally
+% in document-level mark-up.
+%
+% \begin{function}{\UseInstance}
+%   \begin{syntax}
+%     \cs{UseInstance}
+%     ~~\Arg{type} \Arg{instance} \meta{arguments}
+%   \end{syntax}
+%   Uses an \meta{instance} of the \meta{type}, which will require
+%   \meta{arguments} as determined by the number specified for the
+%   \meta{type}. The \meta{instance} must have been declared
+%   before it can be used, otherwise an error is raised.
+% \end{function}
+%
+% \begin{function}{\UseTemplate}
+%   \begin{syntax}
+%     \cs{UseTemplate} \Arg{type} \Arg{template}
+%     ~~\Arg{settings} \meta{arguments}
+%   \end{syntax}
+%   Uses the \meta{template} of the specified \meta{type},
+%   applying the \meta{settings} and absorbing \meta{arguments} as
+%   detailed by the \meta{type} declaration. This in effect
+%   is the same as creating an instance using \cs{DeclareInstance}
+%   and immediately using it with \cs{UseInstance}, but without the
+%   instance having any further existence. It is therefore useful where
+%   a template needs to be used once.
+%
+%   This function can also be used as the argument to \texttt{instance}
+%   key types:
+%   \begin{verbatim}
+%     \DeclareInstance { type } { template } { instance }
+%       {
+%         instance-key =
+%           \UseTemplate { type2 } { template2 } { <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}
+            \cs_if_exist_use:cF { @@_assign_ \l_@@_keytype_tl : }
+              { \@@_assign_variable: }
+          }
+          { \msg_error:nnn { template } { unknown-attribute } {#1} }
+      }
+  }
+\cs_generate_variant:Nn \@@_convert_to_assignments_aux:nn { nV }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_find_global:}
+% \begin{macro}{\@@_find_global_aux:w}
+%   Global assignments should have the phrase |global| at the front.
+%   This is pretty easy to find: no other error checking, though.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_find_global:
+  {
+    \bool_set_false:N \l_@@_global_bool
+    \tl_if_in:onT \l_@@_var_tl { global }
+      {
+        \exp_after:wN \@@_find_global_aux:w \l_@@_var_tl \s_@@_stop
+      }
+  }
+\cs_new_protected:Npn \@@_find_global_aux:w  #1 global #2 \s_@@_stop
+  {
+    \tl_set:Nn \l_@@_var_tl {#2}
+    \bool_set_true:N \l_@@_global_bool
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Using templates directly}
+%
+% \begin{macro}{\@@_use_template:nnn}
+%   Directly use a template with a particular parameter setting.
+%   This is also picked up if used in a nested fashion inside a parameter
+%   list. The idea is essentially the same as creating an instance,
+%   just with no saving of the result.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_use_template:nnn #1#2#3
+  {
+    \@@_execute_if_code_exist:nnT {#1} {#2}
+      {
+        \@@_recover_defaults:nn {#1} {#2}
+        \@@_recover_vars:nn {#1} {#2}
+        \@@_parse_values:nnn {#1} {#2} {#3}
+        \@@_convert_to_assignments:
+        \use:c { \c_@@_code_root_tl #1 / #2  }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Assigning values to variables}
+%
+% \begin{macro}{\@@_assign_boolean:}
+% \begin{macro}{\@@_assign_boolean_aux:n}
+%   Setting a Boolean value is slightly different to everything else
+%   as the value can be used to work out which \texttt{set} function to
+%   call. As long as there is no need to recover things from another
+%   variable, everything is pretty easy. If there is, then we need to allow
+%   for the fact that the recovered value here will \emph{not} be expandable,
+%   so needs to be converted to something that is.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_assign_boolean:
+  {
+    \bool_if:NTF \l_@@_global_bool
+      { \@@_assign_boolean_aux:n { bool_gset } }
+      { \@@_assign_boolean_aux:n { bool_set } }
+  }
+\cs_new_protected:Npn \@@_assign_boolean_aux:n #1
+  {
+    \@@_if_key_value:VTF \l_@@_value_tl
+      {
+        \@@_key_to_value:
+        \tl_put_right:Ne \l_@@_assignments_tl
+          {
+            \exp_not:c { #1 _eq:NN }
+            \exp_not:V \l_@@_var_tl
+            \exp_not:V \l_@@_value_tl
+          }
+      }
+      {
+        \tl_put_right:Ne \l_@@_assignments_tl
+          {
+            \exp_not:c { #1 _ \l_@@_value_tl :N }
+            \exp_not:V \l_@@_var_tl
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_assign_choice:}
+% \begin{macro}
+%   {\@@_assign_choice_aux:nF, \@@_assign_choice_aux:eF}
+%   The idea here is to find either the choice as-given or else the
+%   special |unknown| choice, and to copy the appropriate code across.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_assign_choice:
+  {
+    \@@_assign_choice_aux:eF
+      { \l_@@_key_name_tl \c_space_tl \l_@@_value_tl }
+      {
+        \@@_assign_choice_aux:eF
+          { \l_@@_key_name_tl \c_space_tl unknown }
+          {
+            \prop_get:NVN \l_@@_keytypes_prop \l_@@_key_name_tl
+              \l_@@_tmp_tl
+            \@@_split_keytype_arg:V \l_@@_tmp_tl
+            \msg_error:nnVV { template } { unknown-choice }
+              \l_@@_key_name_tl
+              \l_@@_value_tl
+          }
+      }
+  }
+\cs_new_protected:Npn \@@_assign_choice_aux:nF #1
+  {
+    \prop_get:NnNTF \l_@@_vars_prop {#1} \l_@@_tmp_tl
+      { \tl_put_right:NV \l_@@_assignments_tl \l_@@_tmp_tl }
+  }
+\cs_generate_variant:Nn \@@_assign_choice_aux:nF { e }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_assign_function:}
+% \begin{macro}{\@@_assign_function_aux:N}
+%   This looks a bit messy but is only actually one function.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_assign_function:
+  {
+    \bool_if:NTF \l_@@_global_bool
+      { \@@_assign_function_aux:N \cs_gset:Npn }
+      { \@@_assign_function_aux:N \cs_set:Npn  }
+  }
+\cs_new_protected:Npn \@@_assign_function_aux:N #1
+  {
+    \tl_put_right:Ne \l_@@_assignments_tl
+      {
+        \cs_generate_from_arg_count:NNnn
+          \exp_not:V \l_@@_var_tl
+          \exp_not:N #1
+          { \exp_not:V \l_@@_keytype_arg_tl }
+          { \exp_not:V \l_@@_value_tl }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_assign_instance:}
+% \begin{macro}{\@@_assign_instance_aux:N}
+%   Using an instance means adding the appropriate function creation to
+%   the tl. No checks are made at this stage, so if the instance is
+%   not valid then errors will arise later.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_assign_instance:
+  {
+    \bool_if:NTF \l_@@_global_bool
+      { \@@_assign_instance_aux:N \cs_gset_protected:Npn }
+      { \@@_assign_instance_aux:N \cs_set_protected:Npn  }
+  }
+\cs_new_protected:Npn \@@_assign_instance_aux:N #1
+  {
+    \tl_put_right:Ne \l_@@_assignments_tl
+      {
+        \exp_not:N #1 \exp_not:V \l_@@_var_tl
+          {
+            \@@_use_instance:nn
+              { \exp_not:V \l_@@_keytype_arg_tl }
+              { \exp_not:V \l_@@_value_tl }
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_assign_variable:}
+% \begin{macro}{\@@_assign_variable:N, \@@_assign_variable:c}
+%   A general-purpose function for all of the other assignments.
+%   As long as the value is not coming from another variable, the stored
+%   value is simply transferred for output.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_assign_variable:
+  {
+    \@@_assign_variable:c
+      {
+        \@@_map_var_type: _
+        \bool_if:NT \l_@@_global_bool { g } set:Nn
+      }
+  }
+\cs_new_protected:Npn \@@_assign_variable:N #1
+  {
+    \@@_if_key_value:VT \l_@@_value_tl
+      { \@@_key_to_value: }
+    \tl_put_right:Ne \l_@@_assignments_tl
+      {
+        #1 \exp_not:V \l_@@_var_tl
+         { \exp_not:V \l_@@_value_tl }
+      }
+  }
+\cs_generate_variant:Nn \@@_assign_variable:N { c }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_key_to_value:}
+% \begin{macro}{\@@_key_to_value_auxi:w}
+% \begin{macro}{\@@_key_to_value_auxii:w}
+%   The idea here is to recover the attribute value of another key. To
+%   do that, the marker is removed and a look up takes place. If this
+%   is successful, then the name of the variable of the attribute is
+%   returned. This assumes that the value will be used in context where
+%   it will be converted to a value, for example when setting a number.
+%   There is also a need to check in case the copied value happens to be
+%   \texttt{global}.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_key_to_value:
+  { \exp_after:wN \@@_key_to_value_auxi:w \l_@@_value_tl }
+\cs_new_protected:Npn \@@_key_to_value_auxi:w \KeyValue #1
+  {
+    \tl_set:Ne \l_@@_tmp_tl { \tl_trim_spaces:e { \tl_to_str:n {#1} } }
+    \prop_get:NVNTF \l_@@_vars_prop \l_@@_tmp_tl
+      \l_@@_value_tl
+      {
+        \exp_after:wN \@@_key_to_value_auxii:w \l_@@_value_tl
+          \s_@@_mark global \q_@@_nil \s_@@_stop
+      }
+      { \msg_error:nnV { template } { unknown-attribute } \l_@@_tmp_tl }
+  }
+\cs_new_protected:Npn \@@_key_to_value_auxii:w #1 global #2#3 \s_@@_stop
+  {
+    \@@_quark_if_nil:NF #2
+      { \tl_set:Nn \l_@@_value_tl {#2} }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Using instances}
+%
+% \begin{macro}{\@@_use_instance:nn}
+% \begin{macro}{\@@_use_instance_aux:nNnnn}
+% \begin{macro}{\@@_use_instance_aux:nn}
+%   Using an instance is just a question of finding the appropriate function.
+%   If nothing is found, an error is raised. One complication is that
+%   if the first token of argument |#2| is \cs{UseTemplate} then that
+%   is also valid. There is an error-test to make sure that the
+%   types agree, and if so the template is used directly.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_use_instance:nn #1#2
+  {
+    \@@_if_use_template:nTF {#2}
+      { \@@_use_instance_aux:nNnnn {#1} #2 }
+      { \@@_use_instance_aux:nn {#1} {#2} }
+  }
+\cs_new_protected:Npn \@@_use_instance_aux:nNnnn #1#2#3#4#5
+  {
+    \str_if_eq:nnTF {#1} {#3}
+      { \@@_use_template:nnn {#3} {#4} {#5} }
+      { \msg_error:nnnn { template } { type-mismatch } {#1} {#3} }
+}
+\cs_new_protected:Npn \@@_use_instance_aux:nn #1#2
+  {
+    \@@_if_instance_exist:nnTF {#1} {#2}
+      { \use:c { \c_@@_instances_root_tl #1 / #2 } }
+      { \msg_error:nnnn { template } { unknown-instance } {#1} {#2} }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%\subsection{Assignment manipulation}
+%
+%  A few functions to transfer assignments about, as this is needed by
+%  \cs{AssignTemplateKeys}.
+%
+% \begin{macro}{\@@_assignments_pop:}
+%   To actually use the assignments.
+%    \begin{macrocode}
+\cs_new:Npn \@@_assignments_pop: { \l_@@_assignments_tl }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_assignments_push:n}
+%   Here, the assignments are stored for later use.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_assignments_push:n #1
+  { \tl_set:Nn \l_@@_assignments_tl {#1} }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Showing templates and instances}
+%
+% \begin{macro}{\@@_show_code:nn}
+%   Showing the code for a template is just a translation of
+%   \cs{cs_show:c}.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_show_code:nn #1#2
+  { \cs_show:c { \c_@@_code_root_tl #1 / #2 } }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {
+%     \@@_show_defaults:nn,
+%     \@@_show_keytypes:nn,
+%     \@@_show_vars:nn
+%   }
+% \begin{macro}{\@@_show:Nnnn}
+%   A modified version of the property-list printing code, such that
+%   the output refers to templates and instances rather than to the
+%   underlying structures.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_show_defaults:nn #1#2
+  {
+    \@@_if_keys_exist:nnT {#1} {#2}
+      {
+        \@@_recover_defaults:nn {#1} {#2}
+        \@@_show:Nnnn \l_@@_values_prop
+          {#1} {#2} { default~values }
+      }
+  }
+\cs_new_protected:Npn \@@_show_keytypes:nn #1#2
+  {
+    \@@_if_keys_exist:nnT {#1} {#2}
+      {
+        \@@_recover_keytypes:nn {#1} {#2}
+        \@@_show:Nnnn \l_@@_keytypes_prop
+          {#1} {#2} { interface }
+      }
+  }
+\cs_new_protected:Npn \@@_show_vars:nn #1#2
+  {
+     \@@_execute_if_code_exist:nnT {#1} {#2}
+      {
+        \@@_recover_vars:nn {#1} {#2}
+        \@@_show:Nnnn \l_@@_vars_prop
+          {#1} {#2} { variable~mapping }
+      }
+  }
+\cs_new_protected:Npn \@@_show:Nnnn #1#2#3#4
+  {
+    \msg_show:nneeee { template } { show-attribute }
+      { \tl_to_str:n {#2} }
+      { \tl_to_str:n {#3} }
+      { \tl_to_str:n {#4} }
+      { \prop_map_function:NN #1 \msg_show_item_unbraced:nn }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_show_values:nn}
+%   Instance values are a little more complex, as is the template to consider.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_show_values:nn #1#2
+  {
+    \@@_if_instance_exist:nnT {#1} {#2}
+      {
+        \@@_recover_values:nn {#1} {#2}
+        \msg_show:nneee { template } { show-values }
+          { \tl_to_str:n {#1} }
+          { \tl_to_str:n {#2} }
+          {
+            \prop_map_function:NN \l_@@_values_prop
+              \msg_show_item_unbraced:nn
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Messages}
+%
+% The text for error messages: short and long text for all of them.
+%    \begin{macrocode}
+\msg_new:nnnn { template } { argument-number-mismatch }
+  { Template~type~'#1'~takes~#2~argument(s). }
+  {
+    Templates~of~type~'#1'~require~#2~argument(s).\\
+    You~have~tried~to~make~a~template~for~'#1'~
+    with~#3~argument(s),~which~is~not~possible:~
+    the~number~of~arguments~must~agree.
+  }
+\msg_new:nnnn { template } { bad-number-of-arguments }
+  { Bad~number~of~arguments~for~template~type~'#1'. }
+  {
+    A~template~may~accept~between~0~and~9~arguments.\\
+    You~asked~to~use~#2~arguments:~this~is~not~supported.
+  }
+\msg_new:nnnn { template } { bad-variable }
+  { Incorrect~variable~description~'#1'. }
+  {
+    The~argument~'#1'~is~not~of~the~form \\
+    ~~'<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}{\IfInstanceExistsT, \IfInstanceExistsF, \IfInstanceExistsTF}
+% \changes{2024-02-15}{v1.0b}{New macros}
+% \changes{2024-04-17}{v1.0c}{Use plural names}
+%   More direct translation.
+%    \begin{macrocode}
+\cs_new:Npn \IfInstanceExistsTF #1#2
+  { \@@_if_instance_exist:nnTF {#1} {#2} }
+\cs_new:Npn \IfInstanceExistsT #1#2
+  { \@@_if_instance_exist:nnT {#1} {#2} }
+\cs_new:Npn \IfInstanceExistsF #1#2
+  { \@@_if_instance_exist:nnF {#1} {#2} }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\KeyValue}
+%   Simply dump the argument when executed: this should not happen.
+%    \begin{macrocode}
+\cs_new_protected:Npn \KeyValue #1 {#1}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\AssignTemplateKeys}
+%   A short call to use a token register by proxy.
+%    \begin{macrocode}
+\cs_new_protected:Npn \AssignTemplateKeys { \@@_assignments_pop: }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\SetTemplateKeys}
+%   A friendly wrapper
+%    \begin{macrocode}
+\cs_new_protected:Npn \SetTemplateKeys #1#2#3
+  { \keys_set_known:nnN { template / #1 / #2 } {#3} \l_@@_tmp_clist }
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+%<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


Property changes on: trunk/Master/texmf-dist/source/latex/base/lttemplates.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/source/latex/base/lttextcomp.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/lttextcomp.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/lttextcomp.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -37,7 +37,7 @@
 %
 %
 \ProvidesFile{lttextcomp.dtx}
-             [2022/08/07 v1.0g LaTeX Kernel (text companion symbols)]
+             [2024/04/24 v1.1c LaTeX Kernel (text companion symbols)]
 % \iffalse
 \documentclass{ltxdoc}
 \begin{document}
@@ -163,11 +163,12 @@
 %
 %  \begin{macro}{\DeclareEncodingSubset}
 %
-%     The declaration takes 3 mandatory arguments: an \emph{encoding}
+%    The declaration takes 3 mandatory arguments: an \emph{encoding}
 %    for which a subsetting is wanted (currently always \texttt{TS1},
 %    and most likely forever), the \emph{font family} for which we
-%    declare the subset and finally the \emph{subset} number (between \texttt{0} (all
-%    of the encoding is supported) and \texttt{9} many glyphs are missing.
+%    declare the subset and finally the \emph{subset} number, with a value between
+%    \texttt{0} (all of the encoding is supported) and \texttt{9} (many
+%    glyphs are missing).
 %
 %    For \texttt{TS1} the numbers have been chosen in a way that most
 %    fonts can be fairly correctly categorized, but the default
@@ -439,7 +440,7 @@
 %    \end{macrocode}
 %
 %    And here are the other \texttt{TS1} glyphs that are implemented
-%    by every font (or nearly every---a few are commented out and
+%    by every font (or nearly every)---a few are commented out and
 %    moved to sub-encoding 9,
 %    because they aren't around in some fonts.
 %    \begin{macrocode}
@@ -950,6 +951,8 @@
 %    This first block contains the fonts that have been already
 %    supported by the \texttt{textcomp} package way back, i.e., the
 %    font families that have \TeX{} support since the mid-nineties.
+% \changes{v1.1a}{2024/01/27}{Adjusted/corrected TS1 sub-encoding
+%    declarations for various families (gh/1257)}
 %    \begin{macrocode}
 \DeclareEncodingSubset{TS1}{ccr}     {0}
 \DeclareEncodingSubset{TS1}{cmbr}    {0}
@@ -981,10 +984,17 @@
 \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}
@@ -991,6 +1001,11 @@
 \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,12 +1171,12 @@
 %    \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}
@@ -1140,10 +1183,9 @@
 \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}
@@ -1150,44 +1192,43 @@
 \DeclareEncodingSubset{TS1}{TheanoModern-TOsF}        {5}
 \DeclareEncodingSubset{TS1}{TheanoOldStyle-TLF}       {5}
 \DeclareEncodingSubset{TS1}{TheanoOldStyle-TOsF}      {5}
+\DeclareEncodingSubset{TS1}{charssil-TLF}             {5}
 %    \end{macrocode}
 %
 %    \begin{macrocode}
 \DeclareEncodingSubset{TS1}{Crimson-TLF}              {6}
-\DeclareEncodingSubset{TS1}{IBMPlexMono-TLF}          {6}
-\DeclareEncodingSubset{TS1}{IBMPlexSerif-TLF}         {6}
-\DeclareEncodingSubset{TS1}{LibertinusMono-TLF}       {6}
 \DeclareEncodingSubset{TS1}{LibertinusSerifDisplay-LF}{6}
 \DeclareEncodingSubset{TS1}{LinuxLibertineDisplayT-*} {6}
 \DeclareEncodingSubset{TS1}{LinuxLibertineMonoT-LF}   {6}
 \DeclareEncodingSubset{TS1}{LinuxLibertineMonoT-TLF}  {6}
-\DeclareEncodingSubset{TS1}{Overlock-LF}              {6}
+\DeclareEncodingSubset{TS1}{Ovrlck-LF}                {6}
 %    \end{macrocode}
 %
 %    \begin{macrocode}
+\DeclareEncodingSubset{TS1}{ComicNeue-TLF}            {7}
+\DeclareEncodingSubset{TS1}{ComicNeueAngular-TLF}     {7}
 \DeclareEncodingSubset{TS1}{CormorantGaramond-*}      {7}
 \DeclareEncodingSubset{TS1}{Heuristica-TLF}           {7}
 \DeclareEncodingSubset{TS1}{Heuristica-TOsF}          {7}
 \DeclareEncodingSubset{TS1}{IMFELLEnglish-TLF}        {7}
-\DeclareEncodingSubset{TS1}{LibreBaskerville-TLF}     {7}
-\DeclareEncodingSubset{TS1}{LibreCaslon-*}            {7}
-\DeclareEncodingSubset{TS1}{Marcellus-LF}             {7}
+\DeclareEncodingSubset{TS1}{LibreBskrvl-TLF}          {7}
+\DeclareEncodingSubset{TS1}{LibreCsln-*}              {7}
+\DeclareEncodingSubset{TS1}{Lbstr-LF}                 {7}
+\DeclareEncodingSubset{TS1}{Mrcls-LF}                 {7}
+%    \end{macrocode}
+%    Strangely enough NotoSerif and NotoSans are sub-encoding 7 as
+%    they are missing \cs{textminus} and several other glyphs. In
+%    contrast the NotoSansMono is far more complete.
+%    \begin{macrocode}
 \DeclareEncodingSubset{TS1}{NotoSans-*}               {7}
-\DeclareEncodingSubset{TS1}{NotoSansMono-TLF}         {7}
-\DeclareEncodingSubset{TS1}{NotoSansMono-TOsF}        {7}
 \DeclareEncodingSubset{TS1}{NotoSerif-*}              {7}
-\DeclareEncodingSubset{TS1}{Quattrocento-TLF}         {7}
-\DeclareEncodingSubset{TS1}{QuattrocentoSans-TLF}     {7}
-\DeclareEncodingSubset{TS1}{XCharter-TLF}             {7}
-\DeclareEncodingSubset{TS1}{XCharter-TOsF}            {7}
-\DeclareEncodingSubset{TS1}{erewhon-*}                {7}
-\DeclareEncodingSubset{TS1}{ComicNeue-TLF}            {7}
-\DeclareEncodingSubset{TS1}{ComicNeueAngular-TLF}     {7}
-\DeclareEncodingSubset{TS1}{Forum-LF}      {7}  % the superiors are missing
+\DeclareEncodingSubset{TS1}{Quattro-LF}               {7}
+\DeclareEncodingSubset{TS1}{QuattroSans-LF}           {7}
+\DeclareEncodingSubset{TS1}{Frm-LF}                   {7}  % the superiors are missing
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\DeclareEncodingSubset{TS1}{Cochineal-*}              {8}
+\DeclareEncodingSubset{TS1}{LibertinusMono-TLF}       {8}
 %    \end{macrocode}
 %
 %    \begin{macrocode}
@@ -1231,7 +1272,7 @@
 %
 %    Here are new names for the legacy symbols that \LaTeX{} used to
 %    pick up from the \texttt{OMS} encoded fonts (and used for itemize
-%    lists or footnote symbols.
+%    lists or footnote symbols).
 %
 %    We go the roundabout way via separate OMS declarations so that
 %\begin{verbatim}
@@ -1481,20 +1522,22 @@
 %
 %
 %
-%
 % \section{The \texttt{textcomp} package}
 %
 %
+%    For any rollback request before 2018-08-11 we make an attempt by
+%    loading the 2018 version.
+% \changes{v2.1b}{2024/04/24}
+%         {Load the 2018 version when rolling back prior to 2018-08-11
+%          (gh/1333)}
 %    \begin{macrocode}
 %<*TS1sty>
-\providecommand\DeclareRelease[3]{}
-\providecommand\DeclareCurrentRelease[2]{}
-
+\DeclareRelease{}{1997-12-01}{textcomp-2018-08-11.sty}
 \DeclareRelease{}{2018-08-11}{textcomp-2018-08-11.sty}
 \DeclareCurrentRelease{}{2020-02-02}
 
 \ProvidesPackage{textcomp}
- [2020/02/02 v2.0n Standard LaTeX package]
+ [2024/04/24 v2.1b Standard LaTeX package]
 %    \end{macrocode}
 %
 %    A precaution in case this is used without rebuilding the format.
@@ -1550,8 +1593,8 @@
 }
 %    \end{macrocode}
 %
+% \changes{v2.1a}{2024/04/22}{Drop default option \texttt{info} (gh/1333)}
 %    \begin{macrocode}
-\ExecuteOptions{info}
 \ProcessOptions\relax
 %    \end{macrocode}
 %
@@ -1706,7 +1749,7 @@
 %    The default is ``almostfull'' which means that old documents will
 %    work except that |\textcircled| and |\t| will use the kernel
 %    defaults (with the advantage that this also works if the current
-%    font (as often the case) doesn't implement these glyphs.
+%    font, as often the case, doesn't implement these glyphs).
 %
 %    The ``force'' option simply sets the switch to true.
 %    \begin{macrocode}
@@ -2301,8 +2344,547 @@
 %    \begin{macrocode}
 %</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
 %
 

Modified: trunk/Master/texmf-dist/source/latex/base/ltthm.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltthm.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltthm.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -32,7 +32,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltthm.dtx}
-             [2014/09/29 v1.0f LaTeX Kernel (Theorems)]
+             [2024/03/18 v1.0g LaTeX Kernel (Theorems)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltthm.dtx}
@@ -237,10 +237,24 @@
 % \end{macro}
 %
 % \begin{macro}{\@thm}
+% \changes{v1.0c}{1994/04/17}{Use new std counter error message (FMi)}
+% \changes{v1.0g}{2024/03/18}{Use \cs{@kernel at refstepcounter} to avoid an unwanted target (UFi)}
 %    \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2024/03/18}%
+%<latexrelease>                 {\@thm}{no link target}%
 \def\@thm#1#2{%
-  \refstepcounter{#1}%
+  \@kernel at refstepcounter{#1}%
   \@ifnextchar[{\@ythm{#1}{#2}}{\@xthm{#1}{#2}}}
+%<latexrelease>\EndIncludeInRelease  
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\@thm}{no link target}%
+%<latexrelease>\def\@thm#1#2{%
+%<latexrelease>  \refstepcounter{#1}%
+%<latexrelease>  \@ifnextchar[{\@ythm{#1}{#2}}{\@xthm{#1}{#2}}}
+%<latexrelease>\EndIncludeInRelease  
+%</2ekernel|latexrelease>
 %    \end{macrocode}
 % \end{macro}
 %
@@ -247,6 +261,7 @@
 % \begin{macro}{\@xthm}
 % \begin{macro}{\@ythm}
 %    \begin{macrocode}
+%<*2ekernel>
 \def\@xthm#1#2{%
   \@begintheorem{#2}{\csname the#1\endcsname}\ignorespaces}
 \def\@ythm#1#2[#3]{%
@@ -273,11 +288,26 @@
 %         NFSS}
 %    Providing theorem defaults.
 %  \task{???}{add `reset at font?}
+%  % \changes{v1.0g}{2024/03/18}{Insert link target in the label (UFi)}
 %    \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2024/03/18}%
+%<latexrelease>                 {\@begintheorem}{add link targets}%
 \def\@begintheorem#1#2{\trivlist
-   \item[\hskip \labelsep{\bfseries #1\ #2}]\itshape}
+   \item[\MakeLinkTarget{\@currentcounter}\hskip \labelsep{\bfseries #1\ #2}]\itshape}
 \def\@opargbegintheorem#1#2#3{\trivlist
-      \item[\hskip \labelsep{\bfseries #1\ #2\ (#3)}]\itshape}
+      \item[\MakeLinkTarget{\@currentcounter}\hskip \labelsep{\bfseries #1\ #2\ (#3)}]\itshape}
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\@begintheorem}{add link targets}%
+%<latexrelease>\def\@begintheorem#1#2{\trivlist
+%<latexrelease>   \item[\hskip \labelsep{\bfseries #1\ #2}]\itshape}
+%<latexrelease>\def\@opargbegintheorem#1#2#3{\trivlist
+%<latexrelease>   \item[\hskip \labelsep{\bfseries #1\ #2\ (#3)}]\itshape}
+%<latexrelease>\EndIncludeInRelease 
+%</2ekernel|latexrelease>     
+%<*2ekernel>
 \def\@endtheorem{\endtrivlist}
 %</2ekernel>
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/base/ltvers.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltvers.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltvers.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -112,10 +112,10 @@
 %</2ekernel>
 %<latexrelease>\edef\latexreleaseversion
 %<*2ekernel|latexrelease>
-   {2023-11-01}
+   {2024-06-01}
 %</2ekernel|latexrelease>
 %<*2ekernel>
-\def\patch at level{1}
+\def\patch at level{0}
 %    \end{macrocode}
 %
 % \begin{macro}{\development at branch@name}

Modified: trunk/Master/texmf-dist/source/latex/base/ltxdoc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltxdoc.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/ltxdoc.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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}

Modified: trunk/Master/texmf-dist/source/latex/base/nfssfont.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/nfssfont.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/nfssfont.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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

Modified: trunk/Master/texmf-dist/source/latex/base/slifonts.fdd
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/slifonts.fdd	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/slifonts.fdd	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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

Modified: trunk/Master/texmf-dist/source/latex/base/syntonly.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/syntonly.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/syntonly.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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 at 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

Modified: trunk/Master/texmf-dist/source/latex/base/utf8ienc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/utf8ienc.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/base/utf8ienc.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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}

Modified: trunk/Master/texmf-dist/source/latex/cyrillic/cyoutenc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/cyrillic/cyoutenc.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/cyrillic/cyoutenc.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-% Copyright 1993-2022
+% Copyright 1993-2023
 % The LaTeX3 Project and any individual authors listed elsewhere
 % in this file.
 %
@@ -65,7 +65,7 @@
 %<T2A>\ProvidesFile{t2aenc.def}
 %<T2B>\ProvidesFile{t2benc.def}
 %<T2C>\ProvidesFile{t2cenc.def}
-  [2022/06/11 v1.0j Cyrillic encoding definition file]
+  [2023/11/07 v1.0k Cyrillic encoding definition file]
 %    \end{macrocode}
 %
 % To assure that |\MakeUppercase| and |\MakeLowercase| will work
@@ -118,8 +118,13 @@
 \DeclareTextCommand{\d}{\LastDeclaredEncoding}[1]
    {\hmode at bgroup
     \o at lign{\relax#1\crcr\hidewidth\ltx at sh@ft{-1ex}.\hidewidth}\egroup}
+%    \end{macrocode}
+%    
+% \changes{v1.0k}{2023/11/07}{Add \cs{hmode at bgroup} to \cs{k} to match
+%            other encoding definitions (gh/1148)}
+%    \begin{macrocode}
 \DeclareTextCommand{\k}{\LastDeclaredEncoding}[1]
-   {\oalign{\null#1\crcr\hidewidth\char12}}
+   {\hmode at bgroup\oalign{\null#1\crcr\hidewidth\char12}\egroup}
 \DeclareTextCommand{\textperthousand}{\LastDeclaredEncoding}
    {\%\char 24 }
 \DeclareTextCommand{\textpertenthousand}{\LastDeclaredEncoding}

Modified: trunk/Master/texmf-dist/source/latex/firstaid/firstaid.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/firstaid/firstaid.ins	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/firstaid/firstaid.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -3,7 +3,7 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 2020-2023
+%% Copyright (C) 2020-2024
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
@@ -44,7 +44,7 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 2020-2023
+Copyright (C) 2020-2024
 The LaTeX Project and any individual authors listed elsewhere
 in this file.
 

Modified: trunk/Master/texmf-dist/source/latex/firstaid/latex2e-first-aid-for-external-files.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/firstaid/latex2e-first-aid-for-external-files.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/firstaid/latex2e-first-aid-for-external-files.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-%% File: latex2e-first-aid-for-external-files.dtx (C) Copyright 2020-2023
+%% File: latex2e-first-aid-for-external-files.dtx (C) Copyright 2020-2024
 %%
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
@@ -111,8 +111,8 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\def\LaTeXFirstAidDate{2024/02/29}
-\def\LaTeXFirstAidVersion{v1.1c}
+\def\LaTeXFirstAidDate{2024/03/20}
+\def\LaTeXFirstAidVersion{v1.1e}
 %    \end{macrocode}
 %
 %    \begin{macrocode}
@@ -612,8 +612,21 @@
 %    routines in \pkg{expl3}.
 %    \begin{macrocode}
 \AddToHook{package/acro/after}[firstaid]{%
-  \FirstAidNeededT{acro}{sty}{2022/04/01 v3.8 typeset acronyms and other abbreviations (CN)}
-    {\UseName{prop_new:c}{l__acro_tmpa_prop}}%
+  \FirstAidNeededT{acro}{sty}{2022/04/01 v3.8 typeset acronyms
+                              and other abbreviations (CN)}
+     {\UseName{prop_new:c}{l__acro_tmpa_prop}%
+%    \end{macrocode}
+%    With the 2024 June release of \LaTeX{} it will also fail to patch
+%    \cs{endlongtable} and therefore errors when loading. However, the
+%    patch it tries never worked (because it was setting a local
+%    boolean at a point where  it was more or less immediately
+%    reset). Thus, rather than fixing the patch approach (which
+%    requires to surround the patch with \cs{ExplSyntaxOn}
+%    \verb*/\catcode`\ =10 / and \cs{ExplSyntaxOff}) we simply disable
+%    the patch for now.
+%    \begin{macrocode}
+       \acsetup{patch/longtable=false}%
+     }%
 }
 %    \end{macrocode}
 %
@@ -636,12 +649,79 @@
 %    routines in \pkg{expl3}.
 %    \begin{macrocode}
 \AddToHook{package/chemnum/after}[firstaid]{%
-  \FirstAidNeededT{chemnum}{sty}{2021/01/21 v1.3a a comprehensive approach for the numbering of chemical compounds (CN)}
+  \FirstAidNeededT{chemnum}{sty}{2021/01/21 v1.3a a comprehensive
+             approach for the numbering of chemical compounds (CN)}
     {\UseName{prop_new:c}{l__chemnum_tmpa_prop}}%
 }
 %    \end{macrocode}
 %
+% \subsection{The \pkg{cleveref} package first aid}
+%
+%    The \pkg{cleveref} package expects only two data containers
+%    for its internal \cs{newlabel} command. This fails if
+%    \pkg{xr-hyper} is used which expands every \cs{newlabel} to 
+%    five data container and puts the file name into the last one.
 %    \begin{macrocode}
+\AddToHook{package/cleveref/after}[firstaid]{%
+  \FirstAidNeededT{cleveref}{sty}{2018/03/27 v0.21.4 Intelligent cross-referencing}
+     {%
+%    \end{macrocode}
+% This are the two commands which retrieve the data from the label info.
+% We change them to expect five arguments.
+%    \begin{macrocode}
+       \def\cref at getref#1#2{%
+         \expandafter\let\expandafter#2\csname r@#1 at cref\endcsname%
+         \expandafter\expandafter\expandafter\def%
+           \expandafter\expandafter\expandafter#2%
+           \expandafter\expandafter\expandafter{%
+             \expandafter\@firstoffive#2}}% <-------- five
+       \def\cpageref at getref#1#2{%
+         \expandafter\let\expandafter#2\csname r@#1 at cref\endcsname%
+         \expandafter\expandafter\expandafter\def%
+           \expandafter\expandafter\expandafter#2%
+           \expandafter\expandafter\expandafter{%
+             \expandafter\@secondoffive#2}}% <----------- five  
+%    \end{macrocode}
+%  We also need to redefine the internal label commands of cleveref.
+%  This must be done after \pkg{cleveref} has made its changes 
+%  in \texttt{begindocument} so we add it to the same hook using 
+%  the hook label used by \pkg{cleveref}. 
+%  This way it is guaranteed to overwrite the definitions.
+%    \begin{macrocode}
+      \AddToHook{begindocument}[cleveref]{%
+         \def\label at noarg#1{%
+          \cref at old@label{#1}%
+          \@bsphack%
+          \edef\@tempa{{page}{\the\c at page}}%
+          \setcounter{page}{1}%
+          \edef\@tempb{\thepage}%
+          \expandafter\setcounter\@tempa%
+          \cref at constructprefix{page}{\cref at result}%
+          \protected at write\@auxout{}%
+            {\string\newlabel{#1 at cref}{{\cref at currentlabel}%
+            {[\@tempb][\arabic{page}][\cref at result]\thepage}{}{}{}}}% <----- five
+          \@esphack}%
+        \def\label at optarg[#1]#2{%
+          \cref at old@label{#2}%
+          \@bsphack%
+          \edef\@tempa{{page}{\the\c at page}}%
+          \setcounter{page}{1}%
+          \edef\@tempb{\thepage}%
+          \expandafter\setcounter\@tempa%
+          \cref at constructprefix{page}{\cref at result}%
+          \protected at edef\cref at currentlabel{%
+            \expandafter\cref at override@label at type%
+              \cref at currentlabel\@nil{#1}}%
+          \protected at write\@auxout{}%
+            {\string\newlabel{#2 at cref}{{\cref at currentlabel}%
+            {[\@tempb][\arabic{page}][\cref at result]\thepage}{}{}{}}}% <------- five
+          \@esphack}%
+          } 
+      }%
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 %</kernel>
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/graphics/color.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/graphics/color.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/graphics/color.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -2,7 +2,7 @@
 % \iffalse
 %
 %% color.dtx Copyright (C) 1994--1999 David Carlisle
-%%           Copyright (C) 2005-2022 LaTeX Project
+%%           Copyright (C) 2005-2024 LaTeX Project
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
@@ -21,7 +21,7 @@
 %<driver> \ProvidesFile{color.drv}
 % \fi
 %         \ProvidesFile{color.dtx}
-          [2022/01/06 v1.3d Standard LaTeX Color (DPC)]
+          [2024/01/14 v1.3d Standard LaTeX Color (DPC)]
 %
 % \iffalse
 %<*driver>
@@ -168,7 +168,7 @@
 %
 % \begin{option}{dvips}
 % \begin{option}{xdvi}
-% Tom Rokicki's dvips driver, and the X Windows previewer, xdvi which uses
+% Tom Rokicki's dvips driver, and the X Windows previewer, xdvi, which uses
 % (a subset of) the same |\specials|.
 %    \begin{macrocode}
 \DeclareOption{dvips}{\def\Gin at driver{dvips.def}%
@@ -248,7 +248,7 @@
 % \changes{v0.3k}{1995/09/07}
 %      {Merge dviwindo and dvipsone options}
 % The drivers of the Y\&Y \TeX\ system.
-% (Which use the same |\specials|).
+% (Which use the same |\specials|.)
 %    \begin{macrocode}
 \DeclareOption{dvipsone}{\def\Gin at driver{dvipsone.def}}
 \DeclareOption{dviwindo}{\ExecuteOptions{dvipsone}}
@@ -360,7 +360,7 @@
 % The |dvipsnames| option predeclares all the names in the colour
 % prologue of dvips. The |dvips| option automatically implies
 % |dvipsnames| unless this choice is overruled with the |nodvipsnames|
-% option. For other drivers, eg |textures| you may use this option to
+% option. For other drivers, eg |textures|, you may use this option to
 % explicitly request that these names be declared.
 %    \begin{macrocode}
 \DeclareOption{dvipsnames}{\def\c at lor@namefile{dvipsnam.def}}
@@ -371,7 +371,7 @@
 %
 % \begin{option}{usenames}
 % The |usenames| option modifies the behaviour of |\DefineNamedColor|
-% So that it declares the same name as a ```user's colour'' for use in
+% so that it declares the same name as a ``user's colour'' for use in
 % a |\color| command, as well as a name in the |named| colour model.
 % The normal behaviour is just to declare the name in the named colour
 % model.
@@ -530,7 +530,7 @@
 % |\color| or |\textcolor| commands to refer to a colour specified by
 % \emph{colour-spec} in the colour model \emph{model}.
 %
-% |\definecolor| associates the \emph{name} the to a  colour in
+% |\definecolor| associates the \emph{name} to a colour in
 % \emph{model}. So |\color{|\emph{name}|}| would check \emph{name}
 % then issue a |\special| for the colour model \emph{model}.
 %
@@ -579,12 +579,12 @@
 % names.
 %
 % The `color1' drivers (dvips) currently ignore the specification of
-% the colour, and once a name is defined, just put the colour name in
-% the dvi file. For dvips, The header file \texttt{color.pro} is used to
+% the colour and, once a name is defined, just put the colour name in
+% the dvi file. For dvips, the header file \texttt{color.pro} is used to
 % give the cmyk equivalents of the names.
 %
 % The `color2' drivers (textures) use a special postscript operator
-% that takes both the name and the cmyk equivalent. so if the names are
+% that takes both the name and the cmyk equivalent, so if the names are
 % not being used, `fall back' definitions in the cmyk model are available.
 % These drivers also allow a numeric value to affect the `density'
 % of the colour to use.
@@ -688,9 +688,9 @@
 %
 % \begin{macro}{\normalcolor}
 % Early versions of this package redefined |\reset at font| to reset the
-% color as well. Current versions do not do this (there are too many
-% |\reset at font| commands hidden in strange places) and so defines a
-% separate command, |\normalcolor| to reset the colour to the colour in
+% color as well. Current versions do not do this (since there are too many
+% |\reset at font| commands hidden in strange places) and so they define a
+% separate command, |\normalcolor|, to reset the colour to the colour in
 % effect at the start of the document.
 %
 % |\normalcolor| is defined (to |\relax|) in the \LaTeX\ kernel, so it
@@ -722,9 +722,9 @@
 % the truth as the `macro layer' of \TeX\ does not know where the output
 % routine is going to re-insert floats. This is why drivers must
 % maintain their own stack of colours in order to fully support these
-% commands.
+% commands.)
 %
-% For dvips, the |\current at color| it is something like `|Black|' or
+% For dvips, the |\current at color| is something like `|Black|' or
 % `|rgb 0 1 0|', but other packages should not rely on any particular
 % format for this macro.
 %
@@ -755,7 +755,7 @@
 % definition of this command. A graphics package may want to define it
 % using a special to produce (for example) a PostScript line. Producing
 % the line in the |\special| has the advantage that on a preview that
-% does not understand |\special|s, the line is automatically omited,
+% does not understand |\special|s, the line is automatically omitted,
 % without needing to modify the source of the document (for instance by
 % adding the |monochrome| option).
 %
@@ -894,7 +894,7 @@
 %  \end{macro}
 %
 %  \begin{macro}{\color at vbox}
-% To be used to open a `coloured hbox'
+% To be used to open a `coloured vbox'
 % \changes{v0.3h}{1994/11/22}
 %     {Macro added}
 %    \begin{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/graphics/drivers.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/graphics/drivers.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/graphics/drivers.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -3,7 +3,7 @@
 %
 %% drivers.dtx Copyright (C) 1994      David Carlisle Sebastian Rahtz
 %%             Copyright (C) 1995 1996 1997 1998 1999 David Carlisle
-%%             Copyright (C) 2000-2022 LaTeX Project
+%%             Copyright (C) 2000-2024 LaTeX Project
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%

Modified: trunk/Master/texmf-dist/source/latex/graphics/epsfig.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/graphics/epsfig.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/graphics/epsfig.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -2,7 +2,7 @@
 % \iffalse
 %
 %% epsfig.dtx Copyright (C) 1994-1996 1999 Sebastian Rahtz
-%%            Copyright (C) 2000-2022 LaTeX Project
+%%            Copyright (C) 2000-2024 LaTeX Project
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
@@ -19,7 +19,7 @@
 %<driver> \ProvidesFile{epsfig.drv}
 % \fi
 %         \ProvidesFile{epsfig.dtx}
-                  [2017/06/25 v1.7b (e)psfig emulation (SPQR)]
+                  [2024/01/14 v1.7b (e)psfig emulation (SPQR)]
 %
 % \iffalse
 %<*driver>
@@ -51,7 +51,7 @@
 \RequirePackage{graphicx}
 %    \end{macrocode}
 % \subsection{Emulation of `psfig' syntax}
-% Emulate "epsfig.sty", and most varieties of psfig
+% Emulate \texttt{epsfig.sty}, and most varieties of psfig
 % \begin{macro}{\psfig,\epsfig}
 %    \begin{macrocode}
 \def\psfig#1{%
@@ -83,7 +83,7 @@
 %    \end{macrocode}
 % \end{macro}
 % \subsection{Emulation of `epsf' syntax}
-% Emulate Rokicki's "epsf.tex" supplied with the ever-popular dvips.
+% Emulate Rokicki's \texttt{epsf.tex}, supplied with the ever-popular dvips.
 % \begin{macro}{\epsfbox,\epsffile}
 %    \begin{macrocode}
 \newdimen\epsfxsize

Modified: trunk/Master/texmf-dist/source/latex/graphics/graphics.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/graphics/graphics.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/graphics/graphics.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -2,7 +2,7 @@
 % \iffalse
 %
 %% graphics.dtx Copyright (C) 1994      David Carlisle Sebastian Rahtz
-%%              Copyright (C) 1995-2022 LaTeX Project
+%%              Copyright (C) 1995-2024 LaTeX Project
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
@@ -17,9 +17,9 @@
           \ProvidesFile{graphics.dtx}
 %</dtx>
 %<+package>\NeedsTeXFormat{LaTeX2e}[1995/12/01]
-%<+package>\providecommand\DeclareRelease[3]{}
-%<+package>\providecommand\DeclareCurrentRelease[2]{}
 %<+package>
+% Try to fulfill rollback requests to early years by using the 2017 version:
+%<+package>\DeclareRelease{}{1994-06-01}{graphics-2017-06-25.sty}
 %<+package>\DeclareRelease{}{2017-06-25}{graphics-2017-06-25.sty}
 %<+package>\DeclareCurrentRelease{}{2019-10-01}
 %<+package>
@@ -27,7 +27,7 @@
 %<driver> \ProvidesFile{graphics.drv}
 % \fi
 %         \ProvidesFile{graphics.dtx}
-          [2022/03/10 v1.4e  Standard LaTeX Graphics (DPC,SPQR)]
+          [2024/05/23 v1.4g  Standard LaTeX Graphics (DPC,SPQR)]
 %
 % \iffalse
 %<*driver>
@@ -69,18 +69,18 @@
 % \section{Introduction}
 %
 % This package implements various `graphics' functions. The main
-% features are a) inclusion of `graphics' files. b) Rotation of sections
-% of the page, c) Scaling of sections of the page.
+% features are: a) inclusion of `graphics' files; b) rotation of sections
+% of the page; c) scaling of sections of the page.
 %
 % The design is split into three `levels'.
 % \begin{itemize}
 % \item The user interface. This is the collection of commands designed
-% to appear in a document text. Actually two separate user interface
+% to appear in a document text. Actually two separate user interfaces
 % have been implemented. The `standard' interface, described here, and a
 % more powerful, and more `user-friendly' interface provided by the
 % |graphicx| package.
 % \item The core functions. These functions, which are also implemented
-% in this file do all the `main work'. The `user-interface functions
+% in this file, do all the `main work'. The `user-interface functions'
 % just collect together the information from any optional-arguments or
 % star-forms, and then call one of these functions.
 % \item The driver files. It is not possible to achieve the
@@ -90,7 +90,7 @@
 % and the syntax required to pass instructions to the drivers is also
 % not standardised. So the `core functions' never access |\special|
 % directly, but rather call a series of commands that must be defined in
-% a special file customised for each driver. The accompanying file,
+% a special file customised for each driver. The accompanying file
 % |drivers.dtx| has suitable files for a range of popular drivers.
 % \end{itemize}
 %
@@ -99,9 +99,9 @@
 % driver that is to be used to print the document. You may wish to set
 % up a configuration file so that this option always takes effect, even
 % if not specified in the document. To do this, produce a file
-% |graphics.cfg| containing the line:\\
+% |graphics.cfg| containing the line\\
 % |\ExecuteOptions{dvips}|\\
-% (or whichever other driver you wish.)
+% (or whichever other driver you wish).
 %
 % Apart from the driver options there are a few other options to control
 % the behaviour of the package.
@@ -166,7 +166,7 @@
 %  |\graphicspath{{eps/}{tiff/}}|
 % would cause the system to look in the subdirectories |eps| and |tiff|
 % of the current directory. The default setting of this path is
-% |\input at path| that is: graphics files will be found wherever \TeX\
+% |\input at path|, so that graphics files will be found wherever \TeX\
 % files are found.
 %
 % \DescribeMacro
@@ -204,7 +204,7 @@
 % \emph{default rule}. For instance the |dvips| driver file declares all
 % files to be of type |eps| unless a more specific rule is declared.
 %
-% Since Version v0.6, extensions should be specified including the |.|
+% Since Version v0.6, extensions should be specified including the |.|,
 % that is, |.eps| not |eps|.
 %
 % \emph{type} is the `type' of file involved. All files of the same type
@@ -241,7 +241,7 @@
 % used to denote the filename. Thus using the dvips driver, one may
 % use\\
 % |\DeclareGraphicsRule{.ps.gz}{eps}{.ps.bb}{`zcat #1}|\\
-% the final argument causes dvips to use the |zcat| command to unzip the
+% The final argument causes dvips to use the |zcat| command to unzip the
 % file before inserting it into the PostScript output.
 %
 % \subsection{Rotation}
@@ -297,9 +297,9 @@
 % \DescribeMacro
 %   {\Gread at eps}\marg{file}\\
 % For each \emph{type} of graphics file supported, the driver file must
-% define |\Ginclude@|\emph{type} and, optionally |\Gread@|\emph{type}.
+% define |\Ginclude@|\emph{type} and, optionally, |\Gread@|\emph{type}.
 % The read command is responsible for obtaining size information from
-% the file specified in the |\DeclareGraphicsRule| command. However the
+% the file specified in the |\DeclareGraphicsRule| command. However, the
 % kernel defines a function, |\Gread at eps|,  which can read PostScript
 % files to find the
 % |%%BoundingBox| comment. This function will be used for any type for
@@ -306,9 +306,9 @@
 % which a specific function has not been declared. |\Gread at eps| accepts
 % a generalised version of the bounding box comment. \TeX\ units may be
 % used (but there must be no space before the unit). If the unit is
-% omitted |bp| is assumed. So\\
+% omitted, |bp| is assumed. So\\
 % |%%BoundingBox 0 0 2in 3in|\\
-% Would be accepted by this function, to produce a 2in wide, by 3in high
+% would be accepted by this function, to produce a 2in wide by 3in high
 % graphic.
 %
 % \subsection{Rotation}
@@ -334,7 +334,7 @@
 % \DescribeMacro
 % {\Gscale at box@dddd}
 %        \marg{dima}\marg{dimb}\marg{dimc}\marg{dimd}\marg{text}\\
-% Scale \emph{text} in horizontally by a factor \emph{dima}/\emph{dimb},
+% Scale \emph{text} horizontally by a factor \emph{dima}/\emph{dimb},
 % and vertically by a factor of  \emph{dimc}/\emph{dimd}.
 %
 % \DescribeMacro
@@ -353,7 +353,7 @@
 % |\Ginclude@|\emph{type}\\
 % The Graphics kernel function will call this driver-defined function
 % with the filename as argument, and certain additional information will
-% be provided as follows.:
+% be provided as follows:
 %
 % \noindent\begin{tabular}{p{.4\textwidth}p{.5\textwidth}}
 % |\Gin at llx|, |\Gin at lly|,\newline
@@ -362,7 +362,7 @@
 %               Registers storing the natural size.\\
 % |\Gin at req@width|\newline |\Gin at req@height| &
 %               Registers storing the required size, after scaling.\\
-% |\Gin at scalex|, |\Gin at scaley| & macros with the scale factors. A value
+% |\Gin at scalex|, |\Gin at scaley| & Macros with the scale factors. A value
 % of |!| means: Scale by the same amount as the other direction.\\
 % |\ifGin at clip| & |\newif| token, true if the graphic should be
 %                 `clipped' to  the bounding box.
@@ -371,11 +371,11 @@
 % Optionally the driver may define a command of the form:\\
 % |\Gread@|\emph{type}\\
 % This is responsible for reading an external file to find the bounding
-% box information. If such a command is not declared, but a read-file is
-% specified the command |\Gread at eps|, which is defined in the Graphics
-% Kernel will be used.
+% box information. If such a command is not declared but a read-file is
+% specified, the command |\Gread at eps|, which is defined in the Graphics
+% Kernel, will be used.
 %
-% \subsection{Literal Postscript}
+% \subsection{Literal PostScript}
 % Drivers that are producing PostScript output may want to define
 % the following macros. They each take one argument which should be
 % passed to an appropriate special. They are not used directly by this
@@ -384,7 +384,7 @@
 % |\Gin at PS@raw|, Literal PostScript special.\\
 % |\Gin at PS@restored|, Literal PostScript special, the driver will
 %                    surround this with a save-restore pair.\\
-% |\Gin at PS@literal at header|, Postscript to be inserted in the header
+% |\Gin at PS@literal at header|, PostScript to be inserted in the header
 %                           section of the PostScript file.\\
 % |\Gin at PS@file at header|, external file to be inserted in the header
 %                           section of the PostScript file.
@@ -550,7 +550,7 @@
 % \changes{v0.3g}{1994/03/15}
 %     {Use dvips def file not development version}
 % \begin{option}{xdvi}
-% Tomas Rockicki's  PostScript driver (unix, MSDOS, VMS\ldots).
+% Tomas Rokicki's  PostScript driver (unix, MSDOS, VMS\ldots).
 % The |X11| previewer |xdvi| supports basically the same set of
 % |\specials|.
 %    \begin{macrocode}
@@ -672,7 +672,7 @@
 % \begin{option}{pctex32}
 % \changes{v1.0b}{1996/10/29}
 %     {pctex32 option added}
-% PC\TeX\ (MSDOS/Windows) .
+% PC\TeX\ (MSDOS/Windows).
 %    \begin{macrocode}
 \DeclareOption{pctexps}{\def\Gin at driver{pctexps.def}}
 \DeclareOption{pctexwin}{\def\Gin at driver{pctexwin.def}}
@@ -913,7 +913,7 @@
 % \end{macro}
 %
 % \begin{macro}{\Gin at iii}
-% Set the coordinates of the {\bfseries l}lower {\bfseries l}eft corner,
+% Set the coordinates of the {\bfseries l}ower {\bfseries l}eft corner,
 % and the coordinates of the {\bfseries u}pper {\bfseries r}ight
 % corner. The coordinates may be any \TeX\ dimension, defaulting to |bp|.
 % \changes{v0.6c}{1994/12/15}
@@ -944,8 +944,8 @@
 % is invisibly small but files conforming to Adobe  DSC should have
 % \emph{integer} Bounding Box Coordinates, and conceivably some drivers
 % might demand integer values.
-% (Although most seem to accept real values (if they accept bounding box
-% coordinates at all) in the |\special|. This is the reason why the
+% Although most seem to accept real values (if they accept bounding box
+% coordinates at all) in the |\special|, this is the reason why the
 % mechanism uses |\def| and not \TeX\ lengths, as in earlier releases of
 % the package.
 %    \begin{macrocode}
@@ -1454,8 +1454,8 @@
 %     {New macro}
 % \begin{macro}{\Gread at generic@aux}
 % \begin{macro}{\Gread at eps}
-% Read an EPS file (|#1|) and search for a line
-% starting with |%%BoundingBox| and returns the result
+% Read an EPS file (|#1|), search for a line
+% starting with |%%BoundingBox|; then return the result
 % by setting four dimension registers
 % |\Gin at llx|, |\Gin at lly|, |\Gin at urx| and |\Gin at ury|.
 % \changes{v0.5e}{1994/11/02}
@@ -1701,7 +1701,7 @@
 % \begin{macro}{\Grot at left}
 % \begin{macro}{\Grot at right}
 % \begin{macro}{\Grot at depth}
-% Final Rotated box dimensions
+% Final rotated box dimensions
 %    \begin{macrocode}
 \let\Grot at height\@ovxx
 \let\Grot at left\@ovyy
@@ -1920,8 +1920,8 @@
 %    \end{macrocode}
 % Now we should translate back by $(O_x,O_y)$, but \TeX\ can not really
 % deal with boxes that do not have the reference point at the left edge.
-% (Everything with a $-$ve $x$-coordinate would over-print earlier
-% text). So we modify the horizontal translation so that the
+% (Everything with a negative $x$-coordinate would over-print earlier
+% text.) So we modify the horizontal translation so that the
 % reference point as understood by \TeX\ \emph{is} at the left edge.
 % This means that the `centre of rotation' is not fixed by |\rotatebox|,
 % but typically moves horizontally. We also need to find the image of
@@ -2157,7 +2157,7 @@
 %    \end{macrocode}
 %  \end{macro}
 %
-% Restore Catcodes
+% Restore catcodes.
 %    \begin{macrocode}
 \Gin at codes
 \let\Gin at codes\relax

Modified: trunk/Master/texmf-dist/source/latex/graphics/graphicx.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/graphics/graphicx.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/graphics/graphicx.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -2,7 +2,7 @@
 % \iffalse
 %
 %% graphicx.dtx Copyright (C) 1994      David Carlisle Sebastian Rahtz
-%%              Copyright (C) 1995-2022 LaTeX Project
+%%              Copyright (C) 1995-2024 LaTeX Project
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%

Modified: trunk/Master/texmf-dist/source/latex/graphics/keyval.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/graphics/keyval.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/graphics/keyval.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,7 +1,7 @@
 %
 % \iffalse
 %% keyval.dtx Copyright (C) 1993 1994 1995 1997 1998 1999 David Carlisle
-%%            Copyright (C) 2000-2022 David Carlisle, LaTeX Project
+%%            Copyright (C) 2000-2024 David Carlisle, LaTeX Project
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%

Modified: trunk/Master/texmf-dist/source/latex/graphics/lscape.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/graphics/lscape.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/graphics/lscape.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -2,7 +2,7 @@
 % \iffalse
 %
 %% lscape.dtx Copyright (C) 1994 1999-2000 David Carlisle
-%%            Copyright (C) 2000-2022 LaTeX Project
+%%            Copyright (C) 2000-2024 LaTeX Project
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%

Modified: trunk/Master/texmf-dist/source/latex/graphics/rotating.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/graphics/rotating.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/graphics/rotating.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -5,7 +5,7 @@
 % File: rotating.dtx
 %% Copyright (C) 1995-1999 Sebastian Rahtz and Leonor Barroca
 %% Copyright (C) 2001-2003,2007-2009 Robin Fairbairns
-%% Copyright (C) 2016-2022 LaTeX Project
+%% Copyright (C) 2016-2024 LaTeX Project
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %

Modified: trunk/Master/texmf-dist/source/latex/graphics/trig.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/graphics/trig.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/graphics/trig.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse
 %% File: trig.dtx Copyright (C) 1993-1999 David Carlisle
-%%                Copyright (C) 2000-2022 LaTeX Project
+%%                Copyright (C) 2000-2024 LaTeX Project
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
@@ -19,7 +19,7 @@
 %<driver>        \ProvidesFile{trig.drv}
 % \fi
 %                \ProvidesFile{trig.dtx}
-                 [2021/08/11 v1.11 sin cos tan (DPC)]
+                 [2023/12/02 v1.11 sin cos tan (DPC)]
 %
 % \iffalse
 %</!plain>
@@ -214,7 +214,7 @@
 % \end{macro}
 %
 % \begin{macro}{\TG at reduce}
-% Repeatedly use one of the the relations
+% Repeatedly use one of the relations
 % $\sin(x)=\sin(180-x)=\sin(-180-x)$ to get $x$ in the range $-90 \leq
 % x\leq 90$. Then call |\TG at series|.
 %    \begin{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/documentmetadata-support.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/documentmetadata-support.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/documentmetadata-support.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
 %% File: documentmetadata-support.dtx
-% Copyright (C) 2021-2023 The LaTeX Project
+% Copyright (C) 2021-2024 The LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -18,8 +18,8 @@
 % for those people who are interested or want to report an issue.
 %
 %    \begin{macrocode}
-\def\documentmetadatasupportversion{1.0f}
-\def\documentmetadatasupportdate{2023-09-01}
+\def\documentmetadatasupportversion{1.0h}
+\def\documentmetadatasupportdate{2024-03-26}
 %    \end{macrocode}
 %
 %
@@ -84,8 +84,17 @@
 %    features developed as part of the multi-year ``Tagged PDF''
 %    project~\cite{blueprint}.
 %
-%
-%
+% \section{The \cs{DocumentMetadata} command}
+%  
+% \begin{function}{\DocumentMetadata}
+% \begin{syntax}
+% \cs{DocumentMetadata}\Arg{key-value list}
+% \end{syntax}
+% 
+% The command should be used as the first command in a document, before
+% \cs{documentclass}. It takes a key-value argument.
+% \end{function}
+
 % \section{Currently supported key/values}
 %
 %
@@ -116,7 +125,8 @@
 %     e.g., \texttt{lang=de-DE}. If not given the default value used is |en-US|.
 %
 %    \item[\texttt{pdfstandard}] Choice key to set the pdf standard.
-%      Currently |A-1b|, |A-2a|, |A-2b|, |A-2u|, |A-3a|, |A-3b|, |A-3u| and |A-4| are accepted as
+%      Currently |A-1b|, |A-2a|, |A-2b|, |A-2u|, |A-3a|, |A-3b|, |A-3u|, |A-4|, |A-4E|
+%      and |A-4F| are accepted as
 %      values. The casing is irrelevant, |a-1b| works too.
 %      Note that using these
 %      key doesn't mean that the document actually follows the standard. \LaTeX{}
@@ -162,12 +172,12 @@
 %    \item[\texttt{phase-I}]
 %       This value loads code implementing the first phase of the project~\cite{blueprint}, i.e., it
 %       will load the tagpdf package. It will also activate tagging by issuing
-%       |\tagpdfsetup{activate,interwordspace}|. This phase
+%       |\tagpdfsetup{activate,activate/spaces}|. This phase
 %       is frozen.
 %    \item[\texttt{phase-II}]
 %       It differs from \texttt{phase-I} only in one point: It will
 %       additionally activate tagging of paragraphs with
-%       |\tagpdfsetup{paratagging}|. In the upcoming months it will
+%       |\tagpdfsetup{para/tagging}|. In the upcoming months it will
 %       also enable automatic tagging of other basic document elements.
 %    \item[\texttt{phase-III}]
 %       This is the current development phase.
@@ -179,7 +189,7 @@
 %       and it supports only a limited number of add-on packages. 
 %   \end{description}
 %   
-%   The various testphase modules can also be loaded individually (and least in theory,
+%   The various testphase modules can also be loaded individually (at least in theory,
 %   there can be hidden dependencies). If loaded like this, the tagpdf package is not
 %   loaded and tagging is not activated! The list of modules will change over time.
 %   \begin{description}           
@@ -213,8 +223,19 @@
 %    \item[\texttt{text}] This module adds tagging support to the \LaTeX{} logo and
 %    to the \cs{emph} command.
 %    This code is also loaded by the \texttt{phase-III} key.
+%    \item[\texttt{marginpar}] This module adds tagging support to the \cs{marginpar}
+%    command. This code is also loaded by the \texttt{phase-III} key.
+%    \item[\texttt{title}] This module add tagging support to the \cs{maketitle}
+%    command if a standard class is used. It also enhances the \cs{title}
+%    and \cs{author} commands to fill the XMP-metadata and set the window title.
+%    It is not compatible with packages and classes which redefine these commands
+%    too. The module is currently not loaded by any \texttt{phase} key.
 %    \item[\texttt{math}] This adapts math for tagging. This is only a prototype. 
 %    The module is currently not loaded by any \texttt{phase} key. 
+%    \item[\texttt{table}] This provides basic tagging for 
+%    \texttt{tabular}, \texttt{longtable} and similar table environments. 
+%    The module is currently not loaded by any \texttt{phase} key. Its use and 
+%    restrictions is documented in \texttt{latex-lab-table.pdf}.%    
 %    \item[\texttt{firstaid}] This contains small adjustments to external packages.
 %    The module is currently not loaded by any \texttt{phase} key.  
 %    \end{description}
@@ -274,8 +295,28 @@
 \ExplSyntaxOn\makeatletter
 %    \end{macrocode}
 
+% \subsection{Variables}
+% These variable definitions are currently also done in ltdocinit.
+% They can be removed from there once latex-lab has been updated to
+% provide them too.
+%  \begin{variable}{\g_@@_firstaidoff_clist}
+%  A list to store the firstaid code which should be disabled
+%    \begin{macrocode}
+\clist_if_exist:NF \g_@@_firstaidoff_clist
+  { \clist_new:N \g_@@_firstaidoff_clist }
+%    \end{macrocode} 
+%  \end{variable}
+%  \begin{variable}{\g_@@_testphase_tl}
+%  a tl to store the testphase loading code so that we can load them at
+%  the end of the command.
+%    \begin{macrocode}
+\tl_if_exist:NF \g_@@_testphase_tl
+ { \tl_new:N \g_@@_testphase_tl }
+%    \end{macrocode}
+% \end{variable}
 
-
+% \subsection{\cs{DocumentMetadata}}
+% 
 %  \begin{macro}{\DocumentMetadata}
 %
 %    \cs{DocumentMetadata} should not be used after
@@ -309,14 +350,35 @@
           \file_input:n {l3backend-testphase-\c_sys_backend_str.def}
         \ExplSyntaxOff\makeatother
 %    \end{macrocode}
-%    Set the default language (this requires that the backend has been loaded),
-%    process the rest of the keys,
-%    and setup the generic driver.
+%
+%    Process the init keys and setup the generic driver.
 %    \begin{macrocode}
-        \keys_set_filter:nnn  { document / metadata } { init } { lang=en-US, #1 }
+        \keys_set_filter:nnn  { document / metadata } { init } { #1 }
         \bool_if:NT \g_@@_active_bool
           {
             \PassOptionsToPackage{customdriver=hgeneric-testphase}{hyperref}
+%    \end{macrocode}
+% Finally we setup the language default. 
+% This is done after the begindocument hook so that it can pick up settings
+% from babel. If the Catalog dictionary already contains a lang value we do nothing,
+% otherwise we use the value stored in \cs{BCPdata}, either the main language
+% (if its exists) or the fall back language.  
+% Note: if babel is loaded without a language this gives the language \texttt{und}.
+%    \begin{macrocode}     
+            \g at addto@macro\@kernel at after@begindocument
+             {       
+               \pdfdict_get:nnN {g__pdf_Core/Catalog}{Lang}\l_@@_tmpa_tl
+               \quark_if_no_value:NT\l_@@_tmpa_tl 
+                {
+                  \tl_if_empty:eTF { \BCPdata{main.language} }
+                   { \tl_set:Ne \l_@@_tmpb_tl { \BCPdata{language} } }
+                   { \tl_set:Ne \l_@@_tmpb_tl { \BCPdata{main.language} } }
+                  \msg_warning:nne { meta } { lang-missing }{ \l_@@_tmpb_tl }
+                  \exp_last_unbraced:Ne
+                   \AddToDocumentProperties{[document]{lang}{\l_@@_tmpb_tl}} 
+                  \pdfmanagement_add:nne {Catalog} {Lang}{(\l_@@_tmpb_tl)}                      
+                }
+             }   
           }
 %    \end{macrocode}
 %    \cs{pdfmanagement_add:nnn} has collected values in this hook.
@@ -348,15 +410,8 @@
 %    \end{macrocode}
 %  \end{macro}
 
-
-
-
+%\subsection{\cs{DocumentMetadata} keys}
 %    \begin{macrocode}
-%FMi defined elsewhere
-%FMi
-%FMi \clist_new:N \g_@@_firstaidoff_clist
-%FMi \tl_new:N \g_@@_testphase_tl
-% UFi should the definition move to here?
 \keys_define:nn { document / metadata }
   {
     backend .choices:nn =
@@ -388,7 +443,7 @@
     % this uses internal command from pdfmeta, it should probably move there ...
     ,pdfstandard .code:n =
       {
-        \exp_args:Nnx
+        \exp_args:Nne
         \keys_set:nn {document / metadata} {_pdfstandard=\str_uppercase:n{#1}}
       }
     ,_pdfstandard .choices:nn =
@@ -400,6 +455,30 @@
           }
         \AddToDocumentProperties [document]{pdfstandard}{#1}
       }
+    ,_pdfstandard / A-4F .code:n = 
+      {
+        \prop_if_exist:cTF { g__pdfmeta_standard_pdf/A-4F_prop }
+          {
+            \prop_gset_eq:Nc \g__pdfmeta_standard_prop { g__pdfmeta_standard_pdf/A-4F_prop }
+          }
+          {
+            \prop_gset_eq:Nc \g__pdfmeta_standard_prop { g__pdfmeta_standard_pdf/A-4_prop }
+            \prop_gput:Nnn   \g__pdfmeta_standard_prop{conformance}{F}
+          }
+        \AddToDocumentProperties [document]{pdfstandard}{A-4F}
+      }
+    ,_pdfstandard / A-4E .code:n = 
+      {
+        \prop_if_exist:cTF { g__pdfmeta_standard_pdf/A-4E_prop }
+          {
+            \prop_gset_eq:Nc \g__pdfmeta_standard_prop { g__pdfmeta_standard_pdf/A-4E_prop }
+          }
+          {
+            \prop_gset_eq:Nc \g__pdfmeta_standard_prop { g__pdfmeta_standard_pdf/A-4_prop }
+            \prop_gput:Nnn   \g__pdfmeta_standard_prop{conformance}{E}
+          }
+        \AddToDocumentProperties [document]{pdfstandard}{A-4E}
+      }         
     ,_pdfstandard / unknown .code:n =
       {
         \msg_warning:nnn{pdf}{unknown-standard}{#1}
@@ -413,7 +492,7 @@
               {
                 \RequirePackage{tagpdf}
                 \AddToDocumentProperties [document]{testphase/tagpdf}{loaded}
-                \tagpdfsetup{activate,paratagging,interwordspace}
+                \tagpdfsetup{activate,para/tagging,activate/spaces}
                 \AddToDocumentProperties [document]{tagging}{active}
                 \AddToDocumentProperties [document]{tagging/para}{active}
                 \AddToDocumentProperties [document]{tagging/interwordspace}{active}
@@ -450,7 +529,7 @@
             package/tagpdf/after
           }
           {
-             \tagpdfsetup{paratagging-show}
+             \tagpdfsetup{debug/show=para}
           }
       }
     ,debug / log .code:n =
@@ -460,7 +539,7 @@
            package/tagpdf/after
           }
           {
-             \tagpdfsetup{log=#1}
+             \tagpdfsetup{debug/log=#1}
           }
       }
     ,debug / tagpdf .code:n =
@@ -498,6 +577,11 @@
              {
                LaTeX-lab~package~'#1'~not~found.
               }
+\msg_new:nnn { meta } { lang-missing }
+             {
+               The~language~has~not~been~set~in~\token_to_str:N 
+               \DocumentMetadata.\\Setting~it~to~'#1'~as~fallback.
+             }       
 %    \end{macrocode}
 %
 %    \begin{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-amsmath.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-amsmath.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-amsmath.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -2,7 +2,7 @@
 %
 %% File: latex-lab-amsmath.dtx
 %
-% Copyright (C) 2022,2023 The LaTeX Project
+% Copyright (C) 2022-2024 The LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -66,7 +66,7 @@
 % \subsection{File declaration}
 %    \begin{macrocode}
 \ProvidesFile{latex-lab-amsmath.ltx}
-        [2023-01-05 v0.1a amsmath adaptions]
+        [2024-02-12 v0.1b amsmath adaptions]
 %    \end{macrocode}
 % \subsection{Tagpdf support}
 % To make the code independent from tagging being loaded and active
@@ -90,7 +90,11 @@
       \def\intertext##1{%
         \ifvmode\else\\\@empty\fi
         \noalign{%
-          \penalty\postdisplaypenalty\vskip\belowdisplayskip
+%    \end{macrocode}
+% we have to flip the sign and use a negative \cs{belowdisplayskip}
+% as we flipped the sign at the outside.
+%    \begin{macrocode}
+          \penalty\postdisplaypenalty\vskip-\belowdisplayskip
           \vbox{
 %    \end{macrocode}
 % Stop tagging when measuring:
@@ -105,9 +109,13 @@
 %    \begin{macrocode}
             \tag_mc_end_push:
 %    \end{macrocode}
-% We are already in a par so we change now to Span:
+% We are already in a par so we change now to text:
 %    \begin{macrocode}
-            \tagpdfsetup{paratag=Span}%
+            \tagpdfsetup{para/tag=P}% 
+%    \end{macrocode}
+% TODO why \cs{tagpdfparaOn} needed? 
+%    \begin{macrocode}
+            \tagpdfparaOn
             \noindent\ignorespaces##1\par
 %    \end{macrocode}
 % Restart the MC
@@ -119,7 +127,111 @@
   }      
 %    \end{macrocode}
 %
+% \subsection{\cs{text}}
+% 
+% The \cs{text} command uses \cs{mathchoice} which \enquote{typesets} the argument
+% four times. This makes it quite problematic for tagging. Without precautions 
+% structure objects would be created four times and would get MC-chunks as kids 
+% that doesn't really exist. amsmath contains a switch that allows to execute code
+% only in the first (displaymath) branch, but that isn't usable here. At first because
+% we don't know if the first branch creates the same structure as the one that is
+% actually used. At second because the engines executes some commands like \cs{label}
+% and \cs{pdfannot} only at shipout from the branch that really was used. So we would
+% get structure data from one \cs{mathchoice}-branch and MC-labels and links from another 
+% one and that gets very messy. 
+% 
+% We therefore have to avoid that tagging is active in unused branches. In pdflatex it
+% is not possible to detect the mathstyle before, so we use a label. With lualatex is
+% is possible to redefine \cs{text} not to use \cs{mathchoice}
+% 
 %    \begin{macrocode}
+\AddToHook{package/amstext/after}
+ {
+%    \end{macrocode}
+% currently amsmath is loaded in a begindocument hook, so this
+% test is fine. If amstext is loaded earlier (in the kernel), this needs perhaps a change.
+%    \begin{macrocode}
+   \tag_if_active:T
+    {
+      \sys_if_engine_luatex:TF
+       {
+         \def\text@#1{{%
+           \ifcase\mathstyle
+           \hbox{{#1}}\or
+           \hbox{{#1}}\or
+           \hbox{{#1}}\or
+           \hbox{{#1}}\or
+           \hbox{{\let\f at size\sf at size\selectfont#1}}\or
+           \hbox{{\let\f at size\sf at size\selectfont#1}}\or
+           \hbox{{\let\f at size\ssf at size\selectfont#1}}\or
+           \hbox{{\let\f at size\ssf at size\selectfont#1}}\or
+           \ERROR
+           \fi
+           \check at mathfonts
+         }}       
+       }
+       {
+         \def\text@#1
+          {{
+           \int_gincr:N\g__math_mathchoice_int
+           \tag_stop:
+           \mathchoice
+            {
+             \@@_tag_if_mathstyle:en{mathchoice-\int_use:N\g__math_mathchoice_int}{0}
+             \textdef@\displaystyle\f at size{#1}
+            }
+            {
+             \@@_tag_if_mathstyle:en{mathchoice-\int_use:N\g__math_mathchoice_int}{2}
+             \textdef@\textstyle\f at size{\firstchoice at false #1}
+            }
+            {
+             \@@_tag_if_mathstyle:en{mathchoice-\int_use:N\g__math_mathchoice_int}{4}
+             \textdef@\textstyle\sf at size{\firstchoice at false #1}
+            }
+            {
+              \@@_tag_if_mathstyle:en{mathchoice-\int_use:N\g__math_mathchoice_int}{6}
+              \textdef@\textstyle \ssf at size{\firstchoice at false #1}
+            }
+            \check at mathfonts
+          }}     
+       }
+    }
+ }
+%    \end{macrocode}
+%
+% \subsection{\cs{pmb}}
+% \cs{pmb} prints is argument three times. For tagging we must mark
+% two of occurences as artifact.
+% For luatex the attributes in the box must be reset, for this
+% we switch to expl3-boxes.
+%    \begin{macrocode}
+\AddToHook{package/amsbsy/after}
+ {
+   \def\pmb@@@@#1#2#3{\leavevmode\hbox_set:Nn\l_@@_tmpa_box{xxx#3}
+      \dimen at -\box_wd:N\l_@@_tmpa_box
+      \kern-.5\ex@\box_use:N\l_@@_tmpa_box      
+      \tag_mc_end:\tag_mc_begin:n{artifact}
+      \tag_mc_reset_box:N\l_@@_tmpa_box
+      \kern\dimen@\kern.25\ex@\raise.4\ex@\box_use:N\l_@@_tmpa_box
+      \kern\dimen@\kern.25\ex@\box_use_drop:N\l_@@_tmpa_box
+      \tag_mc_end:\tag_mc_begin:n{}
+    }
+   \def\pmb@#1#2{\hbox_set:Nn\l_@@_tmpa_box{$\m at th#1{#2}$}
+     \setboxz at h{$\m at th#1\mkern.5mu$}\pmbraise@\wdz@
+     \binrel@{#2}
+     \dimen at -\box_wd:N\l_@@_tmpa_box
+     \binrel@@@@{
+       \mkern-.8mu\box_use:N\l_@@_tmpa_box
+       \tag_mc_end:\tag_mc_begin:n{artifact}
+       \tag_mc_reset_box:N\l_@@_tmpa_box
+       \kern\dimen@\mkern.4mu\raise\pmbraise@\box_use:N\l_@@_tmpa_box
+       \kern\dimen@\mkern.4mu\box_use_drop:N\l_@@_tmpa_box
+       \tag_mc_end:\tag_mc_begin:n{}
+       }
+    }
+  }
+%    \end{macrocode}
+%    \begin{macrocode}
 \ExplSyntaxOff
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-bib.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-bib.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-bib.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -16,8 +16,8 @@
 %
 % for those people who are interested or want to report an issue.
 %
-\def\ltlabbibdate{2023-07-20}
-\def\ltlabbibversion{0.81a}
+\def\ltlabbibdate{2024-02-12}
+\def\ltlabbibversion{0.81b}
 %<*driver>
 \documentclass{l3doc}
 \EnableCrossrefs
@@ -124,7 +124,18 @@
 % but has to test if this anchor is already known.
 % \end{description}
 % 
+% \section{Provided or redefined commands}
+%
+% \begin{function}{\@extra at binfo,\@extra at b@citeb}
 % 
+% These are taken from hyperref, they are for chapterbib compability (and also
+% signal to chapterbib not to change the citation commands)
+% \end{function}
+% 
+% \begin{function}{\@bibitem,\@lbibitem}
+% The internal item commands. 
+% \end{function}
+% 
 % \section{Implementation}
 %    \begin{macrocode}
 %<*package>
@@ -264,7 +275,7 @@
 \AddToHookWithArguments{bibcite/before}
   {
     \tag_mc_end_push:
-    \exp_args:Nx\tagstructbegin{tag=Reference,ref=cite.#1\@extra at b@citeb}
+    \exp_args:Ne\tagstructbegin{tag=Reference,ref=cite.#1\@extra at b@citeb}
     \tagmcbegin{}
   }
 \AddToHookWithArguments{bibcite/after}[tag]
@@ -318,7 +329,7 @@
  {
    \leavevmode
    \tag_mc_end_push:
-   \exp_args:Nx\tag_struct_begin:n{tag=Reference,ref=cite.#1\@extra at b@citeb}
+   \exp_args:Ne\tag_struct_begin:n{tag=Reference,ref=cite.#1\@extra at b@citeb}
    \tag_mc_begin:n{}
  }
 \AddToHook{cmd/hyper at natlinkend/after}

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-block.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-block.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-block.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-%% File: latex-lab-block.dtx (C) Copyright 2021-2023 LaTeX Project
+%% File: latex-lab-block.dtx (C) Copyright 2021-2024 LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -9,10 +9,10 @@
 %
 %    https://www.latex-project.org/lppl.txt
 %
-\def\ltlabblockdate{2023-09-01}
-\def\ltlabblockversion{0.8h}
+\def\ltlabblockdate{2024-03-23}
+\def\ltlabblockversion{0.8n}
 %<*driver>
-\documentclass{l3doc}
+\documentclass[kernel]{l3doc}
 \usepackage{amstext}
 \EnableCrossrefs
 \CodelineIndex
@@ -308,7 +308,7 @@
 % \end{TemplateDescription}
 %
 % The maximum number of \xt{blockenv}s that can be nested into each
-% other is is restricted by the \LaTeX{} counter
+% other is restricted by the \LaTeX{} counter
 % \texttt{maxblocklevels} with a default value of \texttt{6}. If this
 % value is increased then it is necessary to provide additional
 % instances, e.g., \texttt{displayblock-7}, etc. Decreasing is, of
@@ -646,11 +646,59 @@
 %
 % \end{description}
 %
+% \section{Debugging}
+% 
+% \begin{function}{\DebugBlocksOn,\DebugBlocksOff, \block_debug_on:, \block_debug_off:}
+% 
+% These commands enable/disable debugging messages.
+% 
+% \end{function}
 %
+% \section{New and redefined kernel command}
+% 
+% \begin{function}{\@doendpe}
+%   The original \LaTeXe{} command is augmented to allow for tagging.
+% \end{function}
 %
+% \begin{function}{\legacyverbatimsetup,\legacylistsetupcode}
+% \emph{to be documented}
+% \end{function}
+% 
+% \begin{function}{\@setupverbinvisiblespace}
+% A counterpart definition to the kernel command \cs{@setupverbinvisiblespace},
+% needed as we need to handle real space chars in verbatim.
+% \end{function}
 %
+% \begin{function}{endblockenv,\g_block_nesting_depth_int}
+% \emph{to be documented}
+% \end{function}
+% 
+% \begin{function}{\newtheorem,\@thm,\@begintheorem}
+% Redefined to make theorems tagging aware.
+% \end{function}
 %
+% \begin{function}{\item,\@itemlabel}
+% The \cs{item} is redefined.
+% \end{function}
 %
+% \begin{function}{\c at maxblocklevels}
+%    A counter to increase or decrease the number of supported
+%    level. If increased, one needs to supply additional level instances.
+% \end{function}
+% 
+% \begin{function}{\begin}
+% The \cs{begin} is slightly redefine to handle \cs{@doendpe} better.
+% TODO: move to kernel
+% \end{function}
+%
+% \begin{function}{\para_end:}
+% TODO: consider name, document 
+% \end{function}
+% 
+% \begin{function}{para/begin}
+% The para/begin hook is enhanced to support list ends
+% \end{function} 
+%   
 % \end{documentation}
 %
 % \StopEventually{\setlength\IndexMin{200pt}  \PrintIndex  }
@@ -674,10 +722,6 @@
                             blockenv implementation]
 %    \end{macrocode}
 %
-%    We make use of templates:
-%    \begin{macrocode}
-\RequirePackage{xtemplate}
-%    \end{macrocode}
 %   Generell kernel changes, also loaded by the sec and toc code.
 %    \begin{macrocode}
 \RequirePackage{latex-lab-kernel-changes}
@@ -691,7 +735,7 @@
 \tl_new:N \l_@@_item_align_tl
 \tl_new:N\l_@@_legacy_env_params_tl
 %    \end{macrocode}
-
+%
 % \subsection{Handling \cs{par} after the end of the list}
 %
 % An empty line (or a \cs{par}) after a list has semantic meaning as
@@ -767,11 +811,11 @@
 %   given use in the document.  This section is devoted to template
 %   interfaces, and the template code is covered later.
 %    \begin{macrocode}
-\DeclareObjectType{blockenv}{1}
-\DeclareObjectType{block}{1}
-\DeclareObjectType{para}{1}
-\DeclareObjectType{list}{1}
-\DeclareObjectType{item}{1}
+\NewTemplateType{blockenv}{1}
+\NewTemplateType{block}{1}
+\NewTemplateType{para}{1}
+\NewTemplateType{list}{1}
+\NewTemplateType{item}{1}
 %    \end{macrocode}
 % \end{objecttype}
 %
@@ -854,7 +898,7 @@
   item-instance   : instance{item} = basic ,
   item-skip       : skip = \itemsep ,
   item-penalty    : integer = \UseName{@itempenalty} ,
-  item-indent     : length = 0pt ,         % was \itemindent 
+  item-indent     : length = \itemindent ,
   label-width     : length = \labelwidth ,
   label-sep       : length = \labelsep ,
   legacy-support   : boolean = false ,
@@ -893,8 +937,8 @@
 % This section collects \pkg{expl3} commands that will be useful.
 %
 %  \begin{macro}{\@@_skip_set_to_last:N,\@@_skip_remove_last:}
-%    Set a skiip register to  the value of an immediately preceding
-%    skip or zero if there was none
+%    Set a skip register to  the value of an immediately preceding
+%    skip or zero if there was none.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_skip_set_to_last:N #1 {
   \skip_set:Nn #1 { \tex_lastskip:D }
@@ -907,12 +951,9 @@
 %    \end{macrocode}
 %  \end{macro}
 %    
-%  \begin{macro}{\tl_if_novalue:nTF}
-%    
 %    \begin{macrocode}
 \cs_generate_variant:Nn \tl_if_novalue:nTF { o }
 %    \end{macrocode}
-%  \end{macro}
 %    
 %
 % \subsubsection{Debugging}
@@ -1342,7 +1383,7 @@
            \@definecounter {#2}
            \IfNoValueTF {#4}
              {  % @ynthm
-               \tl_gset:cx { the #2 }
+               \tl_gset:ce { the #2 }
                   {
                     \@thmcounter{#2}
                   }
@@ -1349,7 +1390,7 @@
              }
              {  % @xnthm
                \@newctr{#1}[#4]
-               \tl_gset:cx { the #2 }
+               \tl_gset:ce { the #2 }
                   {
                     \expandafter\noexpand\csname the#4\endcsname
                     \@thmcountersep
@@ -1802,7 +1843,7 @@
   fixed-word-spaces = \l__par_fixed_word_spaces_bool ,  % name??
   final-hyphen-demerits = \finalhyphendemerits ,
   cr-cmd                = \\ ,
-  para-class            = \l_tag_para_attr_class_tl ,                          
+  para-class            = \l__tag_para_attr_class_tl ,                          
 }
 {
   \tl_if_empty:nF {#1} { \SetTemplateKeys{para}{std}{#1} }
@@ -2260,6 +2301,9 @@
                 \exp_after:wN \use_ii:nn \l_@@_item_align_tl
               }
           }
+%    \end{macrocode}
+%    Add another box level to the label box:
+%    \begin{macrocode}
        \hbox_set:Nn \l_@@_one_label_box
                     { \box_use_drop:N \l_@@_one_label_box }
       }
@@ -2488,11 +2532,14 @@
     {
       \@inmatherr \item
 %    \end{macrocode}
-%    TODO: Test for being outside of a list needs updating!
+%    TODO: Check if test for being outside of a list is sensible
 %    \begin{macrocode}
-      \tl_if_empty:oTF \@@_item_instance:n %%FMi?
-        { \msg_error:nnn { @@ } { item-in-nonlist } { \item[{#1}] } }
+      \cs_if_free:NTF \@@_item_instance:n
         {
+          \@latex at error{Lonely~\string\item--perhaps~a~missing~
+          list~environment}\@ehc
+        }
+        {
           \legacy_if:nTF { @newlist }
             { \__kernel_list_item_begin: }
             { \@@_inter_item:            }
@@ -2630,7 +2677,7 @@
 %
 %    \item Then open an new (inner) structure (by default
 %    \texttt{Figure} but typically the one specified on the instance).
-%    \item At the end of the block close the the inner structure
+%    \item At the end of the block close the inner structure
 %    (\texttt{Figure} or explicit one)
 %    but leave the \texttt{text-unit} open to be either continued or closed due to a
 %    following \cs{par}.
@@ -3290,6 +3337,7 @@
 \DeclareInstance{item}{description}{std}
   {
     label-format = \normalfont\bfseries #1 ,
+    label-align = left
   }
 %    \end{macrocode}
 %  \end{instance}
@@ -3303,10 +3351,10 @@
 {
   \tagpdfsetup
       {
-        newattribute = {justify}    {/O /Layout /TextAlign/Justify},
-        newattribute = {center}     {/O /Layout /TextAlign/Center},
-        newattribute = {raggedright}{/O /Layout /TextAlign/Start},
-        newattribute = {raggedleft} {/O /Layout /TextAlign/End},
+        role/new-attribute = {justify}    {/O /Layout /TextAlign/Justify},
+        role/new-attribute = {center}     {/O /Layout /TextAlign/Center},
+        role/new-attribute = {raggedright}{/O /Layout /TextAlign/Start},
+        role/new-attribute = {raggedleft} {/O /Layout /TextAlign/End},
       }
 }
 %    \end{macrocode}
@@ -3389,9 +3437,7 @@
 %
 % In this section we provide code to the various kernel hooks to support
 % the tagging of the different displayblock environments. 
-%
-%
-%
+% 
 %    All of the following definitions should only be made if tagging
 %    is active!
 %    \begin{macrocode}
@@ -3424,8 +3470,13 @@
       {
         \int_compare:nNnT \l_@@_flattened_level_int < 2
             {
-              \int_gincr:N \g__tag_para_main_begin_int
-              \tagstructbegin{tag=\l__tag_para_main_tag_tl}
+              \__tag_gincr_para_main_begin_int:
+              \tag_struct_begin:n
+                {
+                  tag=\l__tag_para_main_tag_tl,
+                  attribute-class=\l__tag_para_main_attr_class_tl,
+                }
+              \__tag_para_main_store_struct:  
             }
       }
   }
@@ -3445,7 +3496,7 @@
   \cs_set:Npn \@@_beginpar_hmode:N #1
      {
         \tag_mc_end:
-        \int_gincr:N \g__tag_para_end_int
+        \__tag_gincr_para_end_int:
         \@@_debug_typeout:n{increment~ /P \on at line }
         \bool_if:NT \l__tag_para_show_bool
           { \tag_mc_begin:n{artifact}
@@ -3492,7 +3543,7 @@
                {
                  \@@_debug_typeout:n{Structure-end~
                    \l__tag_para_main_tag_tl\space after~ displayblock \on at line }
-                 \int_gincr:N \g__tag_para_main_end_int      
+                 \__tag_gincr_para_main_end_int:      
                  \tag_struct_end: %text-unit
                }
            }
@@ -3551,16 +3602,21 @@
      {
        \bool_if:NF \l__tag_para_flattened_bool
           {
-            \int_gincr:N \g__tag_para_main_begin_int
-            \tag_struct_begin:n{tag=\l__tag_para_main_tag_tl}
+            \__tag_gincr_para_main_begin_int:
+            \tag_struct_begin:n
+              {
+                tag=\l__tag_para_main_tag_tl,
+                attribute-class=\l__tag_para_main_attr_class_tl,
+              }
+            \__tag_para_main_store_struct:  
           }
       }
-   \int_gincr:N \g__tag_para_begin_int
+   \__tag_gincr_para_begin_int:
    \@@_debug_typeout:n{increment~ P \on at line }
    \tag_struct_begin:n
        {
           tag=\l__tag_para_tag_tl
-         ,attribute-class=\l_tag_para_attr_class_tl
+         ,attribute-class=\l__tag_para_attr_class_tl
        }
    \__tag_check_para_begin_show:nn {green}{#1}    
    \tag_mc_begin:n {}
@@ -3572,15 +3628,20 @@
 \cs_new_protected:Npn \@@_start_para_structure_unconditionally:n #1 {
    \bool_if:NF \l__tag_para_flattened_bool
        {
-         \int_gincr:N \g__tag_para_main_begin_int
-         \tag_struct_begin:n{tag=\l__tag_para_main_tag_tl}
+         \__tag_gincr_para_main_begin_int:
+         \tag_struct_begin:n
+           {
+             tag=\l__tag_para_main_tag_tl,
+             attribute-class=\l__tag_para_main_attr_class_tl,
+           }
+         \__tag_para_main_store_struct:  
        }
-   \int_gincr:N \g__tag_para_begin_int
+   \__tag_gincr_para_begin_int:
    \@@_debug_typeout:n{increment~ P \on at line }
    \tag_struct_begin:n
        {
           tag=\l__tag_para_tag_tl
-         ,attribute-class=\l_tag_para_attr_class_tl
+         ,attribute-class=\l__tag_para_attr_class_tl
        }
    \__tag_check_para_begin_show:nn {green}{#1}    
    \tag_mc_begin:n {}
@@ -3594,7 +3655,7 @@
   {
     \bool_if:NT \l__tag_para_bool
       {
-        \int_gincr:N \g__tag_para_end_int
+        \__tag_gincr_para_end_int:
         \@@_debug_typeout:n{increment~ /P \on at line }
         \tag_mc_end:
         \__tag_check_para_end_show:nn {red}{}
@@ -3601,7 +3662,7 @@
         \tag_struct_end:
         \bool_if:NF \l__tag_para_flattened_bool
          {
-           \int_gincr:N \g__tag_para_main_end_int
+           \__tag_gincr_para_main_end_int:
            \tag_struct_end:
          }
       }
@@ -3657,7 +3718,7 @@
 \DeclareRobustCommand*\begin[1]{%
   \UseHook{env/#1/before}%
   \@ifundefined{#1}%
-    {\def\reserved at a{\@latex at error{Environment #1 undefined}\@eha}}%
+    {\def\reserved at a{\@latex at error{Environment~#1~undefined}\@eha}}%
     {\def\reserved at a{\def\@currenvir{#1}%
         \edef\@currenvline{\on at line}%
         \@execute at begin@hook{#1}%
@@ -3680,7 +3741,7 @@
 	{
 	  \bool_if:NF \l__tag_para_flattened_bool
 	   {
-	     \int_gincr:N \g__tag_para_main_end_int
+	     \__tag_gincr_para_main_end_int:
 	     \tag_struct_end:
 	   }
 	   \@endpefalse
@@ -3722,7 +3783,7 @@
   \@@_debug_typeout:n{block-end \on at line}
   \legacy_if:nT { @endpe }
     {
-      \int_gincr:N \g__tag_para_main_end_int
+      \__tag_gincr_para_main_end_int:
       \@@_debug_typeout:n{close~ /text-unit \on at line}
       \tagstructend
     }
@@ -3752,11 +3813,17 @@
 {
   \tagpdfsetup
       {
+        role/new-attribute = {itemize}{/O /List /ListNumbering/Unordered},
+        role/new-attribute = {enumerate}{/O /List /ListNumbering/Ordered},        
+        role/new-attribute = {description}{/O /List /ListNumbering/Description},
+%    \end{macrocode}
+%    Initially, we had \texttt{/None} for the basic \env{list}
+%    environment, but that is not allowed in PDF/UA-2 if the list
+%    contains any Lbl tags. So now we default to
+%    \texttt{Unordered}.
+%    \begin{macrocode}
         % default if unknown
-        newattribute = {list}{/O /List /ListNumbering/None},    
-        newattribute = {itemize}{/O /List /ListNumbering/Unordered},
-        newattribute = {enumerate}{/O /List /ListNumbering/Ordered},        
-        newattribute = {description}{/O /List /ListNumbering/Description},
+        role/new-attribute = {list}{/O /List /ListNumbering/Unordered},    
       }
 }
 %    \end{macrocode}
@@ -3792,7 +3859,7 @@
 \cs_set:Npn \__kernel_list_label_begin: {
 %
 % FMi: this needs a different logic to decide when to make the label
-%    an artifact (after cleaning up the the \item code  ), therefore
+%    an artifact (after cleaning up the \item code  ), therefore
 %    disabled for now
 %  \tl_if_empty:oTF \@itemlabel
 %     {
@@ -3835,7 +3902,7 @@
 \cs_set:Npn \@@_list_item_end: {
   \legacy_if:nT { @endpe }
     {
-      \int_gincr:N \g__tag_para_main_end_int
+      \__tag_gincr_para_main_end_int:
       \tagstructend                           % text-unit
 %      \@@_debug_typeout:n{Structure-end~ P~ at~ item-end \on at line }
     }
@@ -3854,7 +3921,7 @@
 \cs_set:Npn \@@_list_end: {
   \legacy_if:nT { @endpe }
     {
-      \int_gincr:N \g__tag_para_main_end_int
+      \__tag_gincr_para_main_end_int:
       \tagstructend                       % text-unit
       \@@_debug_typeout:n{Structure-end~ P~ at~ list-end \on at line }
     }

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-firstaid.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-firstaid.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-firstaid.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-%% File: latex-lab-firstaid.dtx (C) Copyright 2023 LaTeX Project
+%% File: latex-lab-firstaid.dtx (C) Copyright 2023-2024 LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -16,8 +16,8 @@
 %
 % for those people who are interested or want to report an issue.
 %
-\def\ltlabfirstaiddate{2023-07-20}
-\def\ltlabfirstaidversion{0.85a}
+\def\ltlabfirstaiddate{2024-05-25}
+\def\ltlabfirstaidversion{0.85d}
 %<*driver>
 \documentclass{l3doc}
 \EnableCrossrefs
@@ -55,6 +55,7 @@
 % patches once the packages have been updated.
 
 % \section{Implementation}
+%
 %    \begin{macrocode}
 %<*package>
 %<@@=tag>
@@ -64,8 +65,153 @@
    \ltlabfirstaiddate\space v\ltlabfirstaiddate\space
    Temporary patches to external packages needed for the tagging project]
 %    \end{macrocode}
+%  \begin{macro}{\FirstAidNeededT}
+%    This is a very simple help to ensure that we only apply first aid
+%    to an unmodified package or class. It only works in the case the
+%    file has already been loaded and the csname \cs{ver@\#1.\#2} got
+%    defined (holding the current date, version, and short description
+%    info). We then compare its content to a frozen string and make
+%    the modification \verb=#3= only if both agree. If they differ we
+%    assume that the package/class in question got updated by its
+%    maintainer.
+%    \begin{macrocode}
+\ExplSyntaxOn 
+\providecommand\FirstAidNeededT[3]{            
+  \exp_args:Ncx\str_if_eq:onF{ver@#1.#2}{#3}
+      { \typeout{==>~ First~ Aid~ for~ #1.#2~ no~ longer~ applied!^^J
+          \@spaces Expected:^^J
+          \@spaces\@spaces #3^^J
+          \@spaces but~ found:^^J
+          \@spaces\@spaces \use:c{ver@#1.#2}^^J
+          \@spaces so~ I'm~ assuming~ it~ got~ fixed.
+      } }
+  \exp_args:Ncx\str_if_eq:onT{ver@#1.#2}{#3}
+}
+\ExplSyntaxOff
+%    \end{macrocode}
+%  \end{macro}
 
+% \subsection{ams classes}
+% The amsart and amsbook classes do not use \cs{@author} to store the author list
+% but a command \cs{authors}. To be able to nevertheless use the authors in the
+% xmp-metadata we map \cs{@author} to this new command. 
+% 
+%    \begin{macrocode}
+\AddToHook{class/amsart/after}
+ {\def\@author{\authors}}
+\AddToHook{class/amsbook/after}
+ {\def\@author{\authors}}
+%    \end{macrocode}
+%
+%
+%
+% \subsection{verse}
+%
+%    The \pkg{verse} package has its own definition of the
+%    \env{verse} environment, which would tag correctly, except that
+%    it is overwritten by the block code in the hook
+%    \texttt{begindocument/before}. So the simplest way to make
+%    tagging work is to reinstall the package version afterwards,
+%    which is what we are doing here.
+%    \begin{macrocode}
+\AddToHook{package/verse/after}[latex-lab-firstaid]{%
+  \FirstAidNeededT{verse}{sty}{2014/05/10 v2.4b verse typesetting}%
+   {%
+     \AtBeginDocument{%
+       \renewenvironment{verse}[1][\linewidth]{%
+         \stepcounter{verse at envctr}%
+         \setcounter{poemline}{0}\refstepcounter{poemline}%
+         \setcounter{vslineno}{1}%
+         \let\\=\@vscentercr
+         \list{}{\itemsep \z@
+                 \itemindent  -\vindent
+                 \listparindent\itemindent
+                 \parsep       \stanzaskip
+                 \ifdim #1 < \linewidth
+                   \rightmargin        \z@
+                   \setlength{\leftmargin}{\linewidth}%
+                   \addtolength{\leftmargin}{-#1}%
+                   \addtolength{\leftmargin}{-0.5\leftmargin}%
+                 \else
+                   \rightmargin        \leftmargin
+                 \fi
+                 \addtolength{\leftmargin}{\vindent}}%
+         \item[]%
+       }%
+       {\endlist}%
+     }%
+   }%
+}
+%    \end{macrocode}
+%    Of course, this means that the
+%    optional argument of the environment then only accepts a length
+%    value and not any more a key value list for altering the
+%    environment settings.
+%    
+%    A more elabroate version could be something like this that allows
+%    key/val and legacy interface. Or one could extend the list
+%    template to support a \texttt{list-width} key.
+%\begin{verbatim}
+% \ExplSyntaxOn
+% \cs_new_protected:Npn \ExtractAndDropKey #1#2#3#4#5 {
+%   \tl_set_eq:NN #4 \c_novalue_tl      % or empty?
+%   \keys_define:nn { #1 } { #2 .code:n = \tl_set:Nn #4{##1} }
+%   \keys_set_known:nnN { #1 } { #3 } #5
+% }
+% \ExplSyntaxOff
+% 
+% % Change the env definition for verse matching verse.sty
+% % This keeps the verse.sty interface as it is and only adjusts the
+% % main environment to use the basic list env with the verse.sty
+% % specific settings.
+% \makeatletter
+% 
+% \AddToHook{package/verse/after}{%
+%   \AtBeginDocument{%
+%   \RenewDocumentEnvironment{verse}{={verse-width}!O{\linewidth}}%
+%     {% 
+%       \stepcounter{verse at envctr}%
+%       \setcounter{poemline}{0}\refstepcounter{poemline}%
+%       \setcounter{vslineno}{1}%
+%       \let\\=\@vscentercr
+%   %
+%       \ExtractAndDropKey{verse}{verse-width}{#1}\@vswidth\@vsremainingkvlist
+%   % If other keys have been specified but not verse-width we have no
+%   % default for \@vswidth and need to set it again
+%       \ExpandArgs{o}\IfNoValueT \@vswidth
+%                         {\def\@vswidth{\linewidth}}%
+%   %
+%   % This is a bit ugly but we can't stick \cs{@vsremainingkvlist} into
+%   % the instance argument as keys are expected to be visible on
+%   % top-level not hidden inside a macro.  The alternative is to push
+%   % in \verb=#1= but then the key/value \verb/verse-width=.../ is
+%   % passed into the instance which is not known there (not harmful as
+%   % it will get ignored but noticeably more and unnecessary
+%   % processing).
+%   %                      
+%       \def\next##1{%
+%         \UseInstance{blockenv}{list}% 
+%           {%
+%             item-indent =-\vindent,%
+%             parindent   =-\vindent,%
+%             par-skip    =\stanzaskip,%
+%             item-skip   =0pt,%
+%             leftmargin  = (\linewidth-\@vswidth)/2+\vindent,%
+%             rightmargin = \ifdim\@vswidth<\linewidth 0pt
+%                           \else (\linewidth-\@vswidth)/2\fi,%
+%             ##1%
+%            }}%
+%       \ExpandArgs{o}\next\@vsremainingkvlist
+%       \item\relax    
+%     }{\endblockenv}%
+%   }%
+% }  
+% \makeatother
+%\end{verbatim}
+%
+%
 % \subsection{blindtext}
+%
 % The blindtext package generates lists with nested \cs{loop} command.
 % The inner loop introduces a group around the list which error when lists are tagged
 % as \cs{@doendpe} is lost.
@@ -106,7 +252,10 @@
    }%
  }
 %    \end{macrocode}
+%
+%
 % \subsection{cleveref}
+%
 % The cleveref package redefines \cs{@makefntext} and this means that the patches in
 % the new footnote code fails. We use a hook instead
 %    \begin{macrocode}
@@ -130,9 +279,48 @@
     }%
  }   
 %    \end{macrocode}
+%
+% \subsection{booktabs}
+% In some cases booktabs inserts a 
+% \cs{multispan} into the table (through the commands \cs{@cmidruleb} 
+% and \cs{@cmidrulea} and this then errors 
+% with the tagging code. 
+% This affects both tabular and longtable 
+% (but longtable more as booktabs handles lines in longtable differently).
+% See also issue \url{https://github.com/latex3/tagging-project/issues/69}
+% 
+% 
+\ExplSyntaxOn
+\AddToHook{package/booktabs/after} 
+ {
+  \def\@cmidrulea{
+   \multispan\@cmidla
+   &\multispan\@cmidlb
+   \unskip\hskip\cmrkern at l
+  {
+   \tag_mc_begin:n{artifact}
+   \CT at arc@\leaders\hrule \@height\@thisrulewidth\hfill\kern\z@}
+   \hskip\cmrkern at r
+   \tag_mc_end: \int_gdecr:N \g__tbl_row_int 
+   \cr}
+
+  \def\@cmidruleb{%
+    \multispan\@cmidlb
+    \unskip\hskip \cmrkern at l%
+   {
+    \tag_mc_begin:n{artifact}
+    \CT at arc@\leaders\hrule \@height\@thisrulewidth\hfill\kern\z@}
+    \hskip\cmrkern at r
+    \tag_mc_end: \int_gdecr:N \g__tbl_row_int 
+    \cr} 
+  }
+\ExplSyntaxOff 
+%
 %    \begin{macrocode}
 %</package>
 %    \end{macrocode}
+%
+%
 %    \begin{macrocode}
 %<*latex-lab>
 \ProvidesFile{firstaid-latex-lab-testphase.ltx}

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-float.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-float.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-float.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -16,8 +16,8 @@
 %
 % for those people who are interested or want to report an issue.
 %
-\def\ltlabfloatdate{2023-07-20}
-\def\ltlabfloatversion{0.81a}
+\def\ltlabfloatdate{2024-03-23}
+\def\ltlabfloatversion{0.81e}
 %<*driver>
 \documentclass{l3doc}
 \EnableCrossrefs
@@ -86,8 +86,8 @@
 % In PDF~2.0 there is the suitable \texttt{Aside} tag which hopefully will 
 % be handled correctly regarding the reading order once processor actually support
 % PDF~2.0. But in PDF~1.7 we rolemap it to \texttt{Note} and this doesn't lead to 
-% a good reading order. The code therefore collect the float structures and moves
-% them to a \texttt{Sect} the end of the document or the chapter 
+% a good reading order. The code therefore collects the float structures and moves
+% them to a \texttt{Sect} at the end of the document or the chapter 
 % (H-floats once they are handled will not be moved).
 % 
 % To fulfill the requirement that a \texttt{Caption} should be at the begin or end, we always
@@ -106,6 +106,8 @@
 % 
 % The code add two keys for the \cs{tagtool} command
 % 
+% 
+% \begin{function}{flush-floats,split-float}
 % \begin{description}
 % \item[flush-floats]  This will flush out the collected floats sofar (currently
 % table and figure. The value is a sectioning level, e.g. \texttt{section} or \texttt{chapter},
@@ -117,9 +119,19 @@
 % \item[split-float] This can be used inside a float if there are two captions.
 % It will only work reasonably well if the content of the float parts are in a sensible order
 % and can be separated by this command. More complex setups with tabulars will need more
-% thoughts
+% thoughts.
+% \end{description} 
+% \end{function}
 % 
-%  \end{description} 
+% \section{Kernel commands}
+% \begin{function}{\@current at float@struct}
+% This variable holds the structure number of current float structure.
+% \end{function}
+% 
+% \begin{function}{\@makecaption}
+% \cs{@makecaption} is defined by the classes so we overwrite it for now
+% at begin document.
+% \end{function}
 %                                    
 %  
 %    \begin{macrocode}
@@ -182,7 +194,7 @@
         \seq_map_inline:Nn\g_@@_float_types_seq
           {
             \tag_struct_begin:n{tag=##1s,stash}
-            \prop_gput:Nnx\g_@@_float_sect_prop {##1-struct}{\int_use:N\c at g__tag_struct_abs_int} 
+            \prop_gput:Nne\g_@@_float_sect_prop {##1-struct}{\int_use:N\c at g__tag_struct_abs_int} 
             \tag_struct_end:
           }  
       }   
@@ -239,6 +251,7 @@
   {\par\__tag_sec_end:n{-10}\@@_float_stop_sect:}
 \DeclareHookRule{tagpdf/finish/before}{latex-lab/float}{before}{tagpdf}
 %    \end{macrocode}
+%
 % \subsection{Splitting floats}
 % \begin{macro}{split-float}
 % TODO: check if the target affect spacing!! 
@@ -249,7 +262,7 @@
     { 
       \@@_float_end:
       \@@_float_begin:
-      \MakeLinkTarget[tagstructure]{g__tag_struct_abs_int}
+      \MakeLinkTarget*{floatstructure.\int_use:N\c at g__tag_struct_abs_int}
     }  
  }
 %    \end{macrocode}
@@ -290,12 +303,12 @@
    {
      \exp_args:Ne
      \tag_struct_begin:n{tag=float,parent=0\prop_item:No\g_@@_float_sect_prop{\@captype-struct}}%
-     \prop_gput:Nxx \g_@@_float_sect_prop {\@captype-used}{true}
+     \prop_gput:Nee \g_@@_float_sect_prop {\@captype-used}{true}
    }
    {
      \tag_struct_begin:n{tag=float}
    }
-     \tl_set:Nx\@current at float@struct{\tag_get:n{struct_num}}%
+     \tl_set:Ne\@current at float@struct{\tag_get:n{struct_num}}%
      \typeout{Float structure: \@current at float@struct}   
  }
 
@@ -324,7 +337,7 @@
 %    \end{macrocode}
 % If the float is in hmode we have to interrupt the P 
 %    \begin{macrocode}
-     \@nameuse{@@_float_stoppar:} %<---end P     
+     \@nameuse{@@_float_stop_par:}% <---end P
      \@floatpenalty -\@Mii
    \else
      \@floatpenalty-\@Miii
@@ -381,7 +394,7 @@
 %    \end{macrocode}
 % We add a target for links. TODO: check that it doesn't affect spacing!!
 %    \begin{macrocode}
-        \MakeLinkTarget[tagstructure]{g__tag_struct_abs_int}%
+        \MakeLinkTarget*{floatstructure.\number\value{g__tag_struct_abs_int}}%
 }%
 %    \end{macrocode}
 %  The end code of the float ...
@@ -400,7 +413,7 @@
       \penalty\@floatpenalty
     \else
       \vadjust{\penalty -\@Miv \vbox{}\penalty\@floatpenalty}\@Esphack
-      \@nameuse{@@_float_start_par:} %restart P safe here??
+      \@nameuse{@@_float_start_par:}% restart P safe here??
     \fi
   \fi
 }
@@ -423,7 +436,7 @@
         \penalty\@floatpenalty
       \else
         \vadjust{\penalty -\@Miv \vbox{}\penalty\@floatpenalty}\@Esphack
-        \@nameuse{@@_float_start_par:} %restart P safe here??
+        \@nameuse{@@_float_start_par:}% restart P safe here??
       \fi
     \fi
   \else
@@ -446,10 +459,24 @@
 \let\@kernel at refstepcounter\refstepcounter %as long it is not in the kernel
 \def\caption{%
    \ifx\@captype\@undefined
-     \@latex at error{\noexpand\caption outside float}\@ehd
+     \@latex at error{\noexpand\caption\c_space_tl outside~float}\@ehd
      \expandafter\@gobble
-   \else
-     \@kernel at refstepcounter\@captype
+   \else 
+%    \end{macrocode}
+% if a caption is used outside a float no 
+% target has been set and \cs{@current at float@struct} is empty
+%    \begin{macrocode}
+     \tl_if_empty:NTF\@current at float@struct
+      { 
+        \refstepcounter\@captype 
+      }    
+      {
+        \@kernel at refstepcounter\@captype
+%    \end{macrocode}
+% we need to reset the target for \cs{addcontentsline}.
+%    \begin{macrocode}
+        \xdef\@currentHref{floatstructure.\@current at float@struct}%
+      }  
      \expandafter\@firstofone
    \fi
    {\@dblarg{\@caption\@captype}}%
@@ -471,7 +498,6 @@
   {
     \long\def\@makecaption#1#2{%
       \vskip\abovecaptionskip
-      \xdef\@currentHref{tagstructure.\@current at float@struct}%
 %    \end{macrocode}
 % we don't want tagging when storing the caption for the singleline check
 %    \begin{macrocode}
@@ -482,12 +508,21 @@
 % we stop paratagging. TODO: check 
 %    \begin{macrocode}
       \tagtool{para=false}
-      \tag_struct_begin:n{tag=Caption,parent=\@current at float@struct}
 %    \end{macrocode}
+% if caption is used outside a float there is perhaps no number, then we use
+% the parent structure and hope ...
+%    \begin{macrocode}
+      \tl_if_empty:NT \@current at float@struct 
+       { \tl_set:Ne \@current at float@struct {\tag_get:n{struct_num}} }     
+      \tag_struct_begin:n{tag=Caption,parent=\@current at float@struct}  
+%    \end{macrocode}
 % move the caption to the begin of the float structure:
 %    \begin{macrocode}
-     \seq_gpop_right:cN {g__tag_struct_kids_\@current at float@struct _seq}\l_@@_tmpa_tl
-     \seq_gput_left:cV  {g__tag_struct_kids_\@current at float@struct _seq}\l_@@_tmpa_tl  
+      \tag_if_active:T
+       {
+         \seq_gpop_right:cN {g__tag_struct_kids_\@current at float@struct _seq}\l_@@_tmpa_tl
+         \seq_gput_left:cV  {g__tag_struct_kids_\@current at float@struct _seq}\l_@@_tmpa_tl
+       }    
       \ifdim \wd\@tempboxa >\hsize
         \tag_struct_begin:n{tag=Lbl}
         \tag_mc_begin:n{}

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-footnotes.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-footnotes.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-footnotes.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
 %% File: latex-lab-footnotes.dtx
-% Copyright (C) 2022-2023 The LaTeX Project
+% Copyright (C) 2022-2024 The LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -17,8 +17,8 @@
 %
 % for those people who are interested or want to report an issue.
 %
-\def\ltlabfootnotedate{2023-09-04}
-\def\ltlabfootnoteversion{0.8c}
+\def\ltlabfootnotedate{2024-03-12}
+\def\ltlabfootnoteversion{0.8d}
 
 %<*driver>
 \documentclass{l3doc}
@@ -454,7 +454,15 @@
 %      option.
 %    \end{itemize}
 %
+% \subsection{Debugging sockets and hooks}
 %
+%    For some rudimentary debugging we currently have \cs{DebugFNotesOn}
+%    (and \cs{DebugFNotesOff}). At the moment \cs{DebugFNotesOn} only
+%    shows the current settings for hooks and sockets related to the
+%    footnote code and then
+%    automatically turns itself off again. 
+%
+%
 % \section{Tagging and hyperlinking support}
 %
 % \fmi{this section needs work (and probably csname changes)}
@@ -978,13 +986,22 @@
 % \end{hookdecl}
 %
 % \subsection{Debugging code}
-% the debugging code is just temporary
+%  The debugging code is just temporary
 %
-% For now we have debugging turned on by default
 %    \begin{macrocode}
 \bool_new:N        \g_fnote_debug_bool
-\bool_gset_true:N  \g_fnote_debug_bool
 %    \end{macrocode}
+
+%  \begin{macro}{\DebugFNotesOn,\DebugFNotesOff}
+%
+%    \begin{macrocode}
+\cs_new_protected:Npn \DebugFNotesOn  { \bool_gset_true:N  \g_fnote_debug_bool  }
+\cs_new_protected:Npn \DebugFNotesOff { \bool_gset_false:N  \g_fnote_debug_bool }
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%
 % We log the hooks in the footnote mark command, but only once
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_debug_footnotemark:
@@ -1485,10 +1502,18 @@
         \tl_if_in:NnTF \l_@@_patch_tl { \hb at xt@ }
           { \cs_set_eq:NN \@@_tmp:w \@@_patch_hb at xt@:w }
           {
-            \tl_if_in:NnTF \l_@@_patch_tl { \@makefnmark }
-              { \cs_set_eq:NN \@@_tmp:w \@@_patch_ at makefnmark:w }
-              { \ERROR
-                \cs_set_eq:NN \@@_tmp:w \exp_stop_f: }
+%    \end{macrocode}
+%    Some styles/classes use \verb=\makebox[...][...]= instead of \cs{hb at xt@}
+%    so try to patch those too.
+%    \begin{macrocode}
+            \tl_if_in:NnTF \l_@@_patch_tl { \makebox }
+              { \cs_set_eq:NN \@@_tmp:w \@@_patch_makebox:w }
+              {
+                \tl_if_in:NnTF \l_@@_patch_tl { \@makefnmark }
+                  { \cs_set_eq:NN \@@_tmp:w \@@_patch_ at makefnmark:w }
+                  { \ERROR
+                    \cs_set_eq:NN \@@_tmp:w \exp_stop_f: }
+              }
           }
       }
     \tl_set:Nf \l_@@_patch_tl
@@ -1512,6 +1537,17 @@
 %    \begin{macrocode}
 \cs_new:Npn \@@_patch_hb at xt@:w #1 \hb at xt@ #2 #
   { \exp_stop_f: #1 \@makefntext at processX { \hb at xt@ #2 } }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\cs_new:Npn \@@_patch_makebox:w #1 \makebox #2 #
+  { \exp_stop_f: #1 \@makefntext at processX { \makebox #2 } }
+%    \end{macrocode}
+%
+%    If the definition contains neither \cs{hbox}, \cs{hb at xt@} nor \cs{makebox},
+%    we see if it contains \cs{@makefnmark} and if so put the socket
+%    before that.
+%    \begin{macrocode}
 \cs_new:Npn \@@_patch_ at makefnmark:w #1 \@makefnmark
   { \exp_stop_f: #1 \@makefntext at processX { \use:n } { \@makefnmark } }
 %    \end{macrocode}
@@ -1539,7 +1575,12 @@
         \cs_set_eq:NN \@makefntext \fnote_makefntext:n
       }
       {
-        \@@_patch:
+%    \end{macrocode}
+%    If \cs{@makefntext} contains the definition from \pkg{footmisc}
+%    we do nothing, otherwise we try to patch.
+%    \begin{macrocode}
+        \cs_if_eq:NNF \@makefntext \footmisc at hang@makefntext
+                      { \@@_patch: }
       }
   }
 
@@ -2421,8 +2462,9 @@
 \else
 
   \ifFN at hangfoot
-    \long\def\@makefntext#1{%
+    \long\def\footmisc at hang@makefntext#1{%
       \bgroup
+        \SuspendTagging{footmisc}%
         \setbox\@tempboxa\hbox{%
           \ifdim\footnotemargin>\z@
             \hb at xt@\footnotemargin{\@makefnmark\hss}%
@@ -2437,8 +2479,22 @@
         \parshape \@ne \leftmargin \linewidth
         \footnotesize
         \@setpar{{\@@par}}%
+        \ResumeTagging{footmisc}%
         \leavevmode
-        \llap{\box\@tempboxa}%
+%    \end{macrocode}
+%    Typesetting the mark twice means that one can't have any material
+%    inside that gets unhappy in that case. Tha shouldn't be a
+%    problem, but perhaps we have to come up with a more elaborate
+%    solution in the end.
+%    \begin{macrocode}
+        \UseSocket{tagsupport/fntext/mark}%
+                  {\llap{%
+                    \ifdim\footnotemargin>\z@
+                      \hb at xt@\footnotemargin{\@makefnmark\hss}%
+                    \else
+                      \@makefnmark
+                    \fi
+                  }}%
         \parskip\hangfootparskip\relax
         \parindent\hangfootparindent\relax
         \footnotelayout#1%
@@ -2445,6 +2501,11 @@
         \par
       \egroup
     }
+%    \end{macrocode}
+%    Defined in a roundabout way so that we can test for it when
+%    patching classes that are not updated.
+%    \begin{macrocode}
+    \let \@makefntext \footmisc at hang@makefntext
 
  \else
 
@@ -2723,9 +2784,8 @@
   \@footnotemark
 }
 %    \end{macrocode}
-%    TEMP PATCHES FOR TESTING
+%
 %    \begin{macrocode}
-
 \endinput
 %</footmisc>
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-graphic.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-graphic.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-graphic.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-%% File: latex-lab-graphic.dtx (C) Copyright 2022-2023 LaTeX Project
+%% File: latex-lab-graphic.dtx (C) Copyright 2022-2024 LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -15,8 +15,8 @@
 %    https://github.com/latex3/latex2e/required/latex-lab
 %
 % for those people who are interested or want to report an issue.
-\def\ltlabgraphicdate{2023-10-13}
-\def\ltlabgraphicversion{0.80b}
+\def\ltlabgraphicdate{2024-03-13}
+\def\ltlabgraphicversion{0.80d}
 %
 %<*driver>
 \documentclass{l3doc}
@@ -184,7 +184,10 @@
 \RequirePackage{l3opacity}
 %    \end{macrocode}
 %
-%
+% Needed during switch to e-type:
+%    \begin{macrocode}
+\cs_generate_variant:Nn \@@_prop_gput:Nnn {cne}
+%    \end{macrocode}
 % \begin{macro}{\@@_graphic_savepos:n}
 % this is the command which stores the position. Similar to 
 % zref-savepos it uses two savepos commands 
@@ -323,7 +326,7 @@
 \msg_new:nnn {tag}{alt-text-missing}
   {
     Alternative~text~for~graphic~is~missing.\\
-    Using~'#1'~instead
+    Using~the~file~name~'#1'~instead.
   }
 \cs_new_protected:Npn\Gin at tag@struct at begin
  {
@@ -449,8 +452,9 @@
 %    \end{macrocode}
 % and here the tagging stops.
 %    \begin{macrocode}
+  \fi
   \Gin at tag@struct at end %new
-  \fi}
+  }
  }  
 %    \end{macrocode}
 %
@@ -894,7 +898,7 @@
 % The structure and the mc must be open earlier, before the \cs{setbox}  (at least
 % for luatex it has to). TODO: think about interface if more attributes are needed.
 %    \begin{macrocode}
-      \@@_prop_gput:cnx
+      \@@_prop_gput:cne
          { g_@@_struct_\int_eval:n {\c at g_@@_struct_abs_int}_prop }
          { A } 
          {
@@ -970,7 +974,7 @@
            {red}
            {\int_use:N\g_@@_graphic_int}
         }
-      \@@_prop_gput:cnx
+      \@@_prop_gput:cne
             { g_@@_struct_\int_eval:n {\c at g_@@_struct_abs_int}_prop }
             { A } 
             {

Added: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-marginpar.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-marginpar.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-marginpar.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -0,0 +1,259 @@
+% \iffalse meta-comment
+%
+%% File: latex-lab-marginpar.dtx 
+%% 
+% Copyright (C) 2024 LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version.  The latest version
+% of this license is in the file
+%
+%    https://www.latex-project.org/lppl.txt
+%
+%
+% The development version of the bundle can be found below
+%
+%    https://github.com/latex3/latex2e/required/latex-lab
+%
+% for those people who are interested or want to report an issue.
+%
+\def\ltlabmarginpardate{2024-02-12}
+\def\ltlabmarginparversion{0.85b}
+
+%<*driver>
+\documentclass[kernel]{l3doc}
+\EnableCrossrefs
+\CodelineIndex
+\begin{document}
+  \DocInput{latex-lab-marginpar.dtx}
+\end{document}
+%</driver>
+%
+% \fi
+%
+% \title{The \textsf{latex-lab-marginpar} package\\
+% Changes related to the tagging of margin notes}
+% \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}}
+% \date{v\ltlabmarginparversion\ \ltlabmarginpardate}
+%
+% \maketitle
+%
+% \newcommand{\xt}[1]{\textsl{\textsf{#1}}}
+% \newcommand{\TODO}[1]{\textbf{[TODO:} #1\textbf{]}}
+% \newcommand{\docclass}{document class \marginpar{\raggedright document class
+% customizations}}
+%
+% \providecommand\hook[1]{\texttt{#1\DescribeHook[noprint]{#1}}}
+% \providecommand\socket[1]{\texttt{#1\DescribeSocket[noprint]{#1}}}
+% \providecommand\plug[1]{\texttt{#1\DescribePlug[noprint]{#1}}}
+%
+% \NewDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl}
+% \NewDocElement[printtype=\textit{hook},idxtype=hook,idxgroup=Hooks]{Hook}{hookdecl}
+% \NewDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl}
+%
+% \begin{abstract}
+% \end{abstract}
+%
+% \section{Introduction}
+%
+% This module contains changes to improve the tagging (in the standard classes) of
+% margin notes created with the \cs{marginpar} command. 
+%
+% Such margin notes are rather small but nevertheless tagging is not trivial and poses
+% a number of interesting problems both regarding the structure and the implementation.
+% 
+% \subsection{Structure}
+% \cs{marginpar} creates small boxes in the margin of a page. 
+% While they are technically floats they also typically 
+% relate to the paragraph beside them, so their structure element should be placed near 
+% such a paragraph.
+%
+% They can be tagged either as artifacts (if they are merely distracting decoration),
+% as small headings before the paragraph, or as |Aside|. Unlike the PDF 1.7 fallback |Note|
+% the structure |Aside| is not allowed inside |P|,
+% so if |Aside| is used, it must be placed before or after the current |P| in the surounding |text-unit|, 
+% or it must split the |P|. Splitting is probably not so good as 
+% |\marginpar| is often used somewhere in the middle of sentence. 
+% The best default is probably to use |Aside|, find the parent |text-unit| and add it there. 
+%
+% \subsection{Implementation}
+%
+% |marginpar| has an optional argument which allows to define a different content 
+% on left/right margins for odd/even pages (depending on twoside and \cs{reversemarginpar}).
+%
+% The current implementation stores *both* arguments in boxes and 
+% decides in the output routine which
+% one to use. This is quite problematic for tagging, as the unused box produces 
+% structure objects, literals, labels, MCID numbers, 
+% and perhaps OBJR-objects from links
+% which must be later thrown away again (or are thrown away by the engine).
+% While it is theoretically not impossible to create
+% both boxes while taging is active but to keep everything on hold and insert
+% the real structure only when the box is used it is in practice quite difficult,
+% slow and error prone. 
+% 
+% There are a number of options to avoid this hassle.
+%
+% \begin{description}
+% \item[Minimal tagging] One option is to disable tagging when the boxes 
+% are built and when the box is used to surround them with a simple Aside.
+% 
+% \begin{description}
+% \item[Pro:] easy to implement
+% \item[Contra:] 
+% Content that perhaps needed tagging (|\LaTeX| logo with /ActualText, images, links) is not tagged.
+% \end{description}
+%
+% \item[Remaking the box]
+% Tagging is deactivated when the boxes are created. 
+% The arguments are stored and when the box should be used in the output routine
+% (and when it is known which one will be used) the box is (re)created, now with proper tagging.
+% 
+% Contra: The content can change e.g. if it uses counters or macros that are redefine later before the
+% output routine is called. As tagging is done later, it is not trivial to insert the 
+% |Aside| in the right place in the paragraph structure.
+%
+% \item[Two pass compilation]
+% A label is used to detect which argument/boxed is used and 
+% tagging is activated only for this one.
+% 
+% Contra: costs a |label| and requires a two pass compilation (which is needed anyway). 
+% This should be ok. |\marginnote| uses a label too, and the same
+% label could also be used to resolve problems if a margin note 
+% moves to a new page (and so replace the mparhack package). 
+% \end{description}
+% 
+% The last option seems the best and is therefore implemented. 
+%   
+% 
+% \section{Implementation}
+%    \begin{macrocode}
+%<*package>
+%<@@=tag>
+%    \end{macrocode}
+%    \begin{macrocode}
+\ProvidesExplPackage {latex-lab-testphase-marginpar} {\ltlabmarginpardate} {\ltlabmarginparversion}
+  {Changes related to the tagging of the margin notes}
+%    \end{macrocode}
+% \subsection{Variables}
+% We need a variable to make the label unique. 
+% Todo: Not sure about the name.
+% \begin{macro}{\g__kernel_marginpar_int}
+%    \begin{macrocode}
+\int_new:N \g__kernel_marginpar_int
+%    \end{macrocode}
+% \end{macro}
+% 
+% \subsection{Tagging sockets}
+% 
+% \begin{socketdecl}{tagsupport/marginpar/begin,tagsupport/marginpar/end}
+%    \begin{macrocode}
+\socket_new:nn {tagsupport/marginpar/begin}{0}
+\socket_new:nn {tagsupport/marginpar/end}{0}
+%    \end{macrocode}
+% \end{socketdecl}
+% \begin{plugdecl}{tagsupport/marginpar/begin,tagsupport/marginpar/end}
+%    \begin{macrocode}
+\socket_new_plug:nnn {tagsupport/marginpar/begin}{default}
+  {
+   \if_mode_horizontal:
+    \tag_mc_end: 
+    \tag_struct_begin:n{tag=Aside,parent=\g__tag_para_main_struct_tl}%
+   \else: 
+    \tag_struct_begin:n{tag=Aside}%
+   \fi:
+  }
+\socket_new_plug:nnn {tagsupport/marginpar/end}{default}
+  {
+    \tag_struct_end:   
+    \if_mode_horizontal: \tag_mc_begin:n{} \fi:
+  }
+\socket_assign_plug:nn {tagsupport/marginpar/begin}{default}  
+\socket_assign_plug:nn {tagsupport/marginpar/end}{default} 
+%    \end{macrocode}
+% \end{plugdecl}
+
+% \subsection{Kernel command changes}
+% \begin{macro}{\@savemarbox }
+% We add sockets that add a tagging structure Aside:
+%    \begin{macrocode}
+\long\def \@savemarbox #1#2{%
+  \UseTaggingSocket{marginpar/begin}
+  \global\setbox #1%
+    \color at vbox
+      \vtop{%
+        \hsize\marginparwidth
+        \@parboxrestore
+        \@marginparreset
+        #2\par
+        \@minipagefalse
+        \outer at nobreak
+        }%
+    \color at endbox
+   \UseTaggingSocket{marginpar/end}
+}
+%    \end{macrocode}
+% \end{macro}
+% 
+% \begin{macro}{\@ympar}
+% We must avoid that \cs{@xympar} creates tagging structure:
+%    \begin{macrocode}
+\long\def\@ympar#1{%
+  \@savemarbox\@marbox{#1}%
+  \global\setbox\@currbox\copy\@marbox
+  \tag_stop:
+  \@xympar
+  \tag_start:}
+%    \end{macrocode}
+% \end{macro}
+% 
+% \begin{macro}{\@xmpar}
+% \cs{@xmpar} is the command used if an optional argument is present.
+% In this case we must stop tagging for \cs{@xympar} as above
+% but also decide which of the two @savemarbox should have tagging active.
+% We add a label to \cs{@marbox}. If that exist tagging is activated for this
+% box else for the other one.
+%    \begin{macrocode}
+\long\def\@xmpar[#1]#2{%
+  \int_gincr:N\g__kernel_marginpar_int
+  \property_if_recorded:eTF { tag_marginpar-opt-\int_use:N\g__kernel_marginpar_int }
+    { 
+     \@savemarbox\@marbox {#1
+       \property_record:ee 
+         { tag_marginpar-opt-\int_use:N\g__kernel_marginpar_int }{page} 
+       }%
+     \tag_stop:
+     \@savemarbox\@currbox{#2}%
+     \tag_start:
+    }
+%    \end{macrocode}
+% order matters! the tagged box should be first so that it can pick up 
+% the correct text-unit number.
+%    \begin{macrocode}
+    {
+     \@savemarbox\@currbox{#2}%         
+     \tag_stop:
+     \@savemarbox\@marbox{#1
+       \property_record:ee 
+         { tag_marginpar-opt-\int_use:N\g__kernel_marginpar_int }{page}}
+     \tag_start: 
+    } 
+  \tag_stop:
+  \@xympar
+  \tag_start:
+  }
+%</package>
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+%<*latex-lab>
+\ProvidesFile{marginpar-latex-lab-testphase.ltx}
+        [\ltlabmarginpardate\space v\ltlabmarginparversion\space
+         Changes related to the tagging of the margin notes]
+
+\RequirePackage{latex-lab-testphase-marginpar}
+
+%</latex-lab>
+%    \end{macrocode}


Property changes on: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-marginpar.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-math.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-math.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-math.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -2,7 +2,7 @@
 %
 %% File: latex-lab-math.dtx
 %
-% Copyright (C) 2022-2023 The LaTeX Project
+% Copyright (C) 2022-2024 The LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -19,8 +19,8 @@
 % for those people who are interested or want to report an issue.
 %
 %
-\def\ltlabmathdate{2023-09-11}
-\def\ltlabmathversion{0.5c}
+\def\ltlabmathdate{2024-04-16}
+\def\ltlabmathversion{0.5j}
 %
 %<*driver>
 \documentclass{l3doc}
@@ -46,8 +46,15 @@
 % \newcommand\NEW[1]{\marginpar{\mbox{}\hfill\fbox{New: #1}}}
 % \providecommand\class[1]{\texttt{#1.cls}}
 % \providecommand\pkg[1]{\texttt{#1}}
-% \providecommand\hook[1]{\texttt{#1}}
 %
+% \providecommand\hook[1]{\texttt{#1\DescribeHook[noprint]{#1}}}
+% \providecommand\socket[1]{\texttt{#1\DescribeSocket[noprint]{#1}}}
+% \providecommand\plug[1]{\texttt{#1\DescribePlug[noprint]{#1}}}
+%
+% \NewDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl}
+% \NewDocElement[printtype=\textit{hook},idxtype=hook,idxgroup=Hooks]{Hook}{hookdecl}
+% \NewDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl}
+%
 % ^^A \car {...} for marginal comments
 % ^^A \car*{...} for longer inline comments
 %
@@ -59,8 +66,6 @@
 %   {\IfBooleanTF{#1}{\todo[inline,#2]{#3}}^^A
 %                    {\todo[#2]{#3}}}
 %
-%
-%
 % \begin{abstract}
 %    This is an experimental prototype. It captures math material
 %    (basically okay, but the interfaces for packages aren't yet
@@ -75,6 +80,18 @@
 % \car*{Todo: update all the documentation! Both here and 
 %   (what little there is!) in the implementation section.}
 %
+% Tagging math involves a variety of tasks that require that math is captured before the
+% typesetting
+% \begin{itemize} 
+% \item When typesetting the math MC-tags and structure commands must 
+% be inserted at the begin and the end, and perhaps also around lines 
+% or other subparts of the equation.   
+% \item The source and/or a mathml-representation of the source must be available
+% so that it can be (perhaps after some preprocessing) be used in an associated file
+% or in an alternate text
+% \item It must be possible to measure the math for e.g. a bbox setting. 
+% \end{itemize}
+% 
 % This file implements capture of all math mode material at the outer
 % level, i.e., a formula is captured in its entirety with inner text
 % blocks (possibly containing further math) absorbed as part of the
@@ -84,7 +101,24 @@
 %\end{verbatim}
 % would only result in a single capture of the tokens
 % ``\verb*/a \in A \text{ for all $a<5$}/''.
+% 
 %
+% \section{Math capture} \label{sec:mathcapture}
+% In the current setup 
+%  \begin{itemize}
+%   \item |$|, |\(...\)| and |$$| grab (through a command in \cs{everymath}/cs{everydisplay})
+%   if the boolean \cs{l_@@_collected_bool} is false.
+%   If the boolean is true they behave normally and can for example contain verbatim.
+%   
+%   \item All (registered) environments grab their body 
+%    regardless of the state of the boolean. For
+%    |equation|, |equation*| and |math| this is a change as they no longer can 
+%    contain verbatim.
+%   
+%   \item BUG: |\[...\]| grabs if \cs{l_@@_collected_bool} is false. If it is
+%   true it falls back to |equation*| and then errors because this can't find the end.   
+%  \end{itemize} 
+%  
 % \subsection{Code level interfaces}
 %
 % \begin{function}{\math_register_env:n, \math_register_env:nn}
@@ -109,7 +143,8 @@
 %   \end{syntax}
 %   Declares that the captured math content should be passed to the
 %   \meta{tokens}, which will receive the environment type as |#1| and
-%   the content as |#2|.
+%   the content as |#2|. The processing is done before the typesetting. It is not
+%   applied if \cs{ifmeasuring@} is true.
 % \end{function}
 %
 % \subsection{Document level interfaces}
@@ -129,6 +164,161 @@
 %   \end{itemize}
 % \end{function}
 % 
+% \section{Math tagging}
+% 
+% The tagging code has to handle 
+% \begin{itemize}
+% \item the embedding into the surrounding. This means 
+%   \begin{itemize} 
+%     \item closing and reopening MC-chunks 
+%     \item closing and reopening text/P-structures
+%     \item handling interferences of the tagging code with penalties and spacing.
+%   \end{itemize}
+% \item the actual tagging which means to do some or all of the following tasks:
+%   \begin{itemize}
+%     \item setup content for an associated source file
+%     \item setup content for an associated mathml file 
+%     \item setup content for the /Alt key
+%     \item setup content for the /ActualText key
+%     \item setup attributes
+%     \item add associated files     
+%     \item add a Formula structure
+%     \item surround subparts (e.g. lines) with Formula sub structures
+%          (perhaps with their own set of additional content)
+%     \item surround elements of the equation with mathml structure elements 
+%          (currently only luatex with luamml)
+%    \end{itemize}
+%  \end{itemize}
+%  
+%  \subsection{Inline math}
+%  
+%  The embedding code is added through
+%  the sockets 
+%   \begin{itemize}
+%    \item |tagsupport/math/inline/begin|                
+%    \item |tagsupport/math/inline/end|
+%   \end{itemize}  
+%  The sockets simply push and pop the MC currently. Without
+%  tagging they use the noop-plug. 
+%  
+%  The actual tagging is in done through the sockets
+%   \begin{itemize}
+%    \item |tagsupport/math/inline/formula/begin|
+%     This socket takes the math as argument and its code
+%     should output it for typesetting. Without tagging the 
+%     socket uses the identity plug.
+%     The |default| plug of the socket calls these three internal sockets
+%     for the tagging support:
+%      \begin{itemize}
+%      \item |tagsupport/math/content| This should set up the various
+%      content variables (empty variables are ignored by the structure code
+%       and so can be used to suppress a setting).
+%      \item |tagsupport/math/struct/begin| This calls \cs{tag_struct_begin:n}.
+%      It should also write the associated files if needed.
+%      \item |tagsupport/math/substruct/begin| this handles subparts.
+%      TODO: does it really make sense in inline math to have that?? 
+%      \end{itemize}
+%    \item |tagsupport/math/inline/formula/end|
+%      This socket ends the formula structure(s). The |default|
+%      plug calls these internal sockets:
+%       \begin{itemize}
+%        \item |tagsupport/math/substruct/end|
+%        \item |tagsupport/math/struct/end|      
+%       \end{itemize}
+%   \end{itemize} 
+%    
+%  \subsection{Display math}
+%    
+%  \textit{to be written}
+%    
+%  \subsection{Associated Files}
+%  
+%  The current code allows the attachment of two types of associated file to the
+%  Formula structure:
+%  the \LaTeX\ source and a MathML representation. 
+%  Technically both can be attached---AF is an array
+%  of file references---practically there can be problems with PDF consumers: 
+%  e.g. ngpdf used both and so showed the equation twice 
+%  (this has been corrected in the newest version) and 
+%  Foxit seems to see only the first AF in the array (so we attach the
+%  mathml as first file).
+%  
+%  The \LaTeX\ source can be (and is) attached automatically. 
+%  It can be suppressed by an option with
+%  \texttt{math/tex/AF=false}, see below. 
+%  
+%  The MathML is attached if a file |\jobname-mathml.html| is found and
+%  if it contains a suitable MathML snippet for the current formula. 
+%  The MathML processing can be suppressed globally by emptying the list of
+%  mathml files with |math/mathml/sources=|. Locally for a formula |math/mathml/AF=false|
+%  can be used. 
+%  
+%  For a MathML representation a file with such representations must be provided. 
+%  If the equation is numbered the numbering should be part of the MathML as 
+%  the |Lbl| substructure is ignored if an MathML is used (see https://github.com/foxitsoftware/PDF_UA-2).
+%    
+%  The MathML representation is given in a special format. 
+%  It is meant to be a valid html file
+%  that can be viewed  in a browser.
+%  For this it can start with |<!DOCTYPE html><html>| and end with |</html>|
+%  It should have the extension \texttt{.html}. The \meta{mathml} content 
+%  is read with special catcodes, so can contain ambersands, hashes, comment chars
+%  and unmatched braces such as |<mo>{</mo>|
+%  
+%  The file should contain a number of representations in this format:
+%  \begin{quote}
+%  |<div>| \\
+%  |  <h2>\mml| \meta{key}|</h2>|\\
+%  |  <p>|\meta{source}|</p>| \\
+%  |  <p>|\meta{hash}|</p>|   \\
+%  |  <math | \meta{attributes} |>|\\
+%  \meta{mathml}\\
+%  |  </math>|\\
+%  |</div>|
+%  \end{quote}
+%  The keywords |<div>|, |<h2>\mml|, |<p>|, |<math|, |</math>| |</div>| are required as
+%  they are used to delimit the arguments by the \LaTeX{} code.
+%  
+%  \meta{key} and \meta{source} are only used for debugging, they help to identify
+%  the equation referred by this representation. The source should be used correctly escaped
+%  |&| and |<| so that if gives valid html!
+%  
+%  \meta{attributes} is not required either, but can e.g. contain attributes
+%  to improve the display in a browser:
+%  \begin{verbatim}
+%  <math alttext="\mathbf{G}" class="ltx_Math" display="inline">
+%  \end{verbatim}
+%  It can also contain the name space declaration: |xmlns="http://www.w3.org/1998/Math/MathML"|%
+%  \footnote{But it is probably not needed and only blows up the PDF.}
+%  
+%  
+%  By default the code tries at the begin of the document 
+%  to read a file |\jobname-mathml.html| in the |html|-format. 
+%  The file name can be changed with |mathml/setfiles={filename1,filename2}| 
+%  (without extension, |html| is added automatically). 
+%  If there is a list, all files are loaded. 
+%  If a file doesn't exist it is ignored, only an info is written to the log.
+%  
+%  Currently every MathML-snippet from a file is embedded into the PDF, 
+%  it is not checked first if it is actually used (simply writing everything to the PDF 
+%  is a bit easier than keeping everything in memory and also means that 
+%  the snippets are one after the other in the PDF). 
+%  
+%  As mentioned above the MathML-AF can be suppressed for the equations in a group with 
+%  |math/mathml/AF=false|, or
+%  completly by setting |math/mathml/sources=| in the preamble. 
+%  
+%  Files embedded in a PDF can be listed in the attachments panel of a PDF viewer.
+%  This is probably not so useful for lots of small files (but one could create
+%  collections), but as long as PDF editors or viewers don't offer 
+%  proper support to access the AF it can help so have them there. The MathML are
+%  added by default, but the \LaTeX{} source not. This can be changed with
+%  |viewer/pane/mathsource=true| (anywhere in the document) and |viewer/pane/mathml=false| (in the
+%  preamble, before the external file is read).  
+%  
+%  \subsection{Options}
+%      
+%   
 % \section{Known current bugs, etc.}
 %     \car*{New Section, now with subsections.\\
 %      As indicated, these lists are probably incomplete.\\
@@ -135,25 +325,107 @@
 %      Some of these have been addressed in a more recent branch.} 
 %
 % \subsection{Capture/grabbing problems}
-% 
+%  
 % \begin{enumerate}
 %   \item Incorrect grabbing of |$|-math when there is also 
 %      explicit |$|-math within a \textit{text environment} 
 %      that is itself within the math that should all be grabbed.
+%      For example,
+%       \begin{verbatim}
+%        $a\begin{minipage}{1cm}$b$\end{minipage}$
+%       \end{verbatim}
+%      would only result in the capture of the tokens
+%      ``\verb*/a\begin {minipage}{1cm}/''. 
+%      This can be avoided by an additional brace group:
+%       \begin{verbatim}
+%        $a{\begin{minipage}{1cm}$b$\end{minipage}}$
+%       \end{verbatim} 
+%      
 %   \item Similar incorrect grabbing with |$$| also.
+%   
 %   \item The grabbing, for all the display environments (and |\) \]|), needs
 %       to deal with nesting: \pkg{amsmath} contains code for this. 
-%   \item 
+%        
+%   \item The math can't contain verbatim and verbatim-like commands. This is 
+%   nothing new for the \pkg{amsmath} environments but changes |$| and |\[\]|
+%   and |equation*| (see e.g. tagging-project issue \#30).    
+%   
+%   \item Begin and end of the math or math environment can not be hidden in commands.
+%   For example \verb+>{$}l<{$}+ in a tabular would lead to errors. 
+%   Defining |\[| to fall back to |equation*| doesn't work if |equation*| is 
+%   a grabbing environment.
+%   
+%   \item The behaviour of |\[...\]| is faulty. See above.
 % \end{enumerate} 
 %
+% \subsection{Fake math}
+% In a number of places in \LaTeX{} math commands (mainly |$|) is used 
+% only for technical reason, e.g. to access a math font, to setup a symbol
+% or to use \cs{vcenter}. 
+% 
+% The code identifies such fake math mostly by making use of the \cs{m at th} command
+% where two methods are used for the automatic detection:
+% 
+% \begin{itemize}
+%  \item After grabbing math content the code checks if the content contains the token 
+%  \cs{m at th} and if yes it doesn't call the processor before reinserting
+%  the content and perhaps adding tagging code.
+%  This method requires that the math can be grabbed (e.g. that the end dollar is visible)
+%  and that the \cs{m at th} is visible. It applies for example in \cs{@iiiparbox} where the
+%  code from |$\vcenter| to |\m at th$| is grabbed an put back. It does not work for
+%  example for |tabular| where the dollars and the \cs{m at th} token are spread around
+%  over three commands. |tabular| needs therefore manual intervention. 
+%  
+%  A look in the list of usages (in \texttt{usage-of-m at th.md}) justifies this approach.
+%  All usages are either not math at all, or related to small elements that probably
+%  shouldn't be grabbed and processed on their own. 
+%
+%  \item \cs{m at th} is redefined so that it sets the boolean \cs{l_@@_collected_bool}
+%  to true. If \cs{m at th} is used inside math that has been grabbed
+%  this doesn't change much as the boolean is set by the grabbing anyway. For usages
+%  outside math the benefit is not so clear: The setting avoids that in \cs{LaTeXe}
+%  the epsilon is processed as math, but it also prevents that the content of the amsmath
+%  command \cs{boxed} is processed as math. 
+%  It means that if one wants to reenable math processing inside some (fake) math
+%  one has to do it after \cs{m at th} calls.
+% \end{itemize}
+% 
+%  Open problems
+%  \begin{enumerate}
+%   \item The grabbing code doesn't pass the info that it detected a \cs{m at th} token.
+%   This means that the tagging code has to do the same check (and doesn't do this
+%   in all cases yet).
+%   
+%   \item Commands are missing to locally disable the grabbing and processing, e.g.
+%   to handle |tabular|.
+%   
+%   \item It must be checked if setting the boolean in \cs{m at th} really makes sense
+%   or if commands like \cs{LaTeXe} should be handled manually. 
+%           
+%  \end{enumerate}
+%  
+% \subsection{Processor}
+%  
+% The grabbed math is at first passed to the processor. The processor is not called
+% in a measuring phase (from the amsmath \cs{ifmeasuring@}) and if the \cs{m at th} 
+% token is detected. 
+% It is not quite clear what purpose the processor has. As it is a public interface
+% it can't be used for internal code. And typesetting happens later and the processor
+% can't really change this. Currently it is mostly used for debugging and messages.
+% If the \cs{m at th} is found the \cs{l_@@_fakemath_bool} is set, so if the code
+% is changed this must be preserved.
+%  
 % \subsection{Other problems}
 % 
 % \begin{enumerate} 
 %   \item 
-%      The presence of \cs{m at th} in association with \cs{ensuremath} 
+%      The presence of \cs{m at th} in association with \cs{ensuremath}
 %      does not necessarily indicate fakemath.  This is because  
 %      wanting mathsurround to be zero is very reasonable and common, 
 %      \emph{even when the math is genuine} (and hence needs to be collected).
+%      
+%      TODO: this claim needs some examples. 
+%      
 %   \item User-defined environments can create problems; but this area, of 
 %      new, copied and changed environments, has not yet been developed. 
 % 
@@ -160,7 +432,7 @@
 %  \car*{Joseph wrote, inter alia:\\
 %      My thinking [regarding] \cs{RegisterMathEnvironment}\\
 %    - (New) Math environments should not be created-then-patched, but only
-%    generated by a [(future)] dedicated command (\cs{DeclareMathEnviornment}, 
+%    generated by a [(future)] dedicated command (\cs{DeclareMathEnvironment}, 
 %    presumably)\\
 %    - Math environments created with \pkg{ltcmd} [commands] should not be copied, . . .\\
 %    - Package authors should be able to manually set up math environments with a public boolean.}
@@ -172,7 +444,10 @@
 % \begin{enumerate}
 %  \item Add (some of) the math display commands that were \enquote{lifted from 
 %    plain}, e.g., \cs{displaylines} \cs{eqalign}(??).
-%  \item 
+%  \item The breqn packages changes catcodes and that isn't yet covered
+%    by our mechanism.
+%  \item \cs{intertext} is not correctly taken into account by the
+%  code splitting multiline math into subformulas.   
 % \end{enumerate}
 %
 %
@@ -218,37 +493,824 @@
 % have conditional definitions and deals with how to define \cs{[}/\cs{]}
 % neatly.
 %    \begin{macrocode}
-\tl_gput_right:Nn \@kernel at before@begindocument
-  { \RequirePackage { amsmath } }
+\AddToHook{begindocument/before}{ \RequirePackage { amsmath } }
 %    \end{macrocode} 
 %
 %
 % \subsection{Data structures}
 %
-%
-%
-% \begin{variable}{\l_@@_collected_bool} 
+% \begin{variable}{\l_@@_collected_bool}
 %   Tracks whether math mode material has been collected, which happens inside
 %   \pkg{amsmath} environments as well as those handled directly here.
+%   If true following math will not grab and/or process. 
+%   See \ref{sec:mathcapture} for details.
+%    \begin{macrocode}
+\bool_new:N \l_@@_collected_bool
+%    \end{macrocode}
+% \end{variable}
 %
+% \begin{variable}{\l_@@_fakemath_bool}
+%   Tracks whether math mode material has been identified as fake math during
+%   the grabbing phase, which happens currently if the 
+%   grabbed contents contains the \cs{m at th} token.
 %
 %    \begin{macrocode}
-\bool_new:N \l_@@_collected_bool
+\bool_new:N \l_@@_fakemath_bool
 %    \end{macrocode}
 % \end{variable}
-% 
+%
+%
 %  \car{Change first tl name below: `env' $=>$ `info'?\\
 %        Or do we need an extra storage tl?}
 %
 % \begin{variable}{\g_@@_grabbed_env_tl, \g_@@_grabbed_math_tl}
-% \cs{g_@@_grabbed_env_tl} contains the name of the math environment (\texttt{math} in the case 
-% of inline math, \cs{g_@@_grabbed_math_tl} the math content.
+% \cs{g_@@_grabbed_env_tl} contains the name of the math environment
+% (\texttt{math} in the case of inline math,
+% \cs{g_@@_grabbed_math_tl} the math content.
 %    \begin{macrocode}
 \tl_new:N \g_@@_grabbed_env_tl
 \tl_new:N \g_@@_grabbed_math_tl
 %    \end{macrocode}
 % \end{variable}
+% 
+% \begin{variable}{\l_@@_tmpa_tl,\l_@@_tmpa_skip,\l_@@_tmpa_str}
+% Temporary variables
+%    \begin{macrocode}
+\tl_new:N \l_@@_tmpa_tl
+\skip_new:N \l_@@_tmpa_skip
+%    \end{macrocode}
+% \end{variable}
 %
+% \begin{variable}{\l_@@_content_alt_tl,
+%  \l_@@_content_actual_tl,
+%  \l_@@_content_AF_tl}
+% Temporary variables to hold math content that should 
+% be used in actual or alt text and stored as AF. 
+%    \begin{macrocode}
+\tl_new:N \l_@@_content_alt_tl
+\tl_new:N \l_@@_content_actual_tl
+\tl_new:N \l_@@_content_AF_source_tl
+\tl_new:N \l_@@_content_AF_source_tmpa_tl
+\tl_new:N \l_@@_content_AF_mathml_tl
+%    \end{macrocode}
+% \end{variable}
+% 
+% \subsection{Tagging tools}
+% The following commands implement small tagging code chunks. 
+% This should probably be collected and moved into tagpdf later.
+% \begin{macro}{\__tag_tool_close_P:}
+% This closes a P/text-chunk, both the MC and the structure and
+% increases the counter manually.
+%    \begin{macrocode}
+\cs_new_protected:Npn \__tag_tool_close_P: 
+  {
+    \tag_if_active:T
+     {
+       \tag_mc_end: %end P-chunk, should perhaps be \tag_mc_end_push: ...
+         \__tag_gincr_para_end_int:
+         \__tag_check_para_end_show:nn{red}{} %debug: show para
+         \tag_struct_end:
+     }
+  }
+%    \end{macrocode}
+% \end{macro}
+% 
+%  We add also an attribute. 
+%    \begin{macrocode} 
+\tl_new:N\l_@@_attribute_class_tl
+\tagpdfsetup
+      {role/new-attribute = {inline}    {/O /Layout /Placement/Inline},
+       role/new-attribute = {display}   {/O /Layout /Placement/Block},
+      } 
+%    \end{macrocode}
+%
+% \subsection{Code related to AF}
+% Booleans to handle the options.
+% \begin{variable}{
+%   \l__tag_math_texsource_AF_bool,
+%   \l__tag_math_texsource_pane_bool,
+%   \l__tag_math_mathml_AF_bool,
+%   \g__tag_math_mathml_AF_bool,
+%   \l__tag_math_mathml_pane_bool,
+%   \l__tag_math_alt_bool
+% }
+%    \begin{macrocode}
+\bool_new:N\l__tag_math_texsource_AF_bool
+\bool_new:N\l__tag_math_texsource_pane_bool
+\bool_new:N\l__tag_math_mathml_AF_bool
+\bool_new:N\g__tag_math_mathml_AF_bool
+\bool_new:N\l__tag_math_mathml_pane_bool
+\bool_new:N\l__tag_math_alt_bool
+%    \end{macrocode}
+% \end{variable}
+% 
+% \begin{variable}{
+%    \g_@@_mathml_total_int,
+%    \g_@@_mathml_int,
+%    \g_@@_math_total_int,
+%    \g_@@_mathml_AF_found_int,
+%    \g_@@_mathml_AF_attached_int,
+%    }
+% \cs{g_@@_mml_total_int} records the mathml fragments read in.
+% \cs{g_@@_mml_int} records the mathml fragments read in with a different hash.
+% \cs{g_@@_AF_total_int} records the number of math structures that try to 
+% attach a mathml AF. 
+% \cs{g_@@_AF_found_int} records the number of math structures for which a fitting
+% mathml is found. 
+% \cs{g_@@_AF_attached_int} records the number of math structures which got a mathml fragment
+% (if mathml-AF are not disabled locally this should be the equal to the previous number.
+% 
+%    \begin{macrocode}
+\int_new:N\g_@@_mathml_total_int
+\int_new:N\g_@@_mathml_int
+\int_new:N\g_@@_math_total_int
+\int_new:N\g_@@_mathml_AF_found_int
+\int_new:N\g_@@_mathml_AF_attached_int
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l__tag_math_mathml_files_clist}
+% A sequence to store the file list for the mathml.
+%    \begin{macrocode}
+\clist_new:N\l__tag_math_mathml_files_clist
+\clist_put_right:Ne\l__tag_math_mathml_files_clist {\c_sys_jobname_str-mathml}
+%    \end{macrocode}
+% \end{variable}
+
+% This is the internal variant of the \cs{mml} command. 
+% \begin{macro}{\@@_AF_mml:nnnn}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_AF_mml:nnnn #1 #2 #3 #4
+%#1 number, #2 tex source for debugging, #3 hash, #4 mathml
+  {
+    \int_gincr:N \g_@@_mathml_total_int
+%    \end{macrocode}
+% mathml with the same hash should be included only once:
+%    \begin{macrocode}
+    \tl_if_exist:cF { g_@@_mathml_#3_tl }
+     {
+       \int_gincr:N \g_@@_mathml_int
+%    \end{macrocode}
+%  a simple Desc key, take care that it is a valid string!
+%    \begin{macrocode}
+       \pdfdict_put:nne {l_pdffile/Filespec} {Desc}{(mathml-#1)} 
+       \pdffile_embed_stream:nnN {#4}{mathml-#1.xml}\l_@@_tmpa_tl
+%    \end{macrocode}
+%  not strictly necessary but makes the files visible in the file attachment 
+%  page 
+%    \begin{macrocode}
+       \bool_if:NT \l__tag_math_mathml_pane_bool
+        {\pdfmanagement_add:nne {Catalog/Names}{EmbeddedFiles}{\l_@@_tmpa_tl}}
+       \tl_new:c{g_@@_mathml_#3_tl}
+       \tl_gset_eq:cN{g_@@_mathml_#3_tl}\l_@@_tmpa_tl       
+     }
+  }   
+%    \end{macrocode}
+% \end{macro}
+%
+% The html reader. 
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_AF_html_reader:w#1</h2>#2<p>#3</p>#4<p>#5</p>#6<math{
+  \begingroup
+   \char_set_catcode_other:N\{
+   \char_set_catcode_other:N\}
+   \char_set_catcode_other:N\#
+   \char_set_catcode_other:N\%
+   \@@_AF_html_reader_verb:w{#1}{#3}{#5}<math
+}
+%    \end{macrocode}
+%    \begin{macrocode}
+\cs_new_protected:Npn\@@_AF_html_reader_verb:w#1#2#3#4~</div>{
+  \endgroup
+   \@@_AF_mml:nnnn{#1}{#2}{#3}{#4}
+   }
+%    \end{macrocode}
+
+%
+% \begin{socketdecl}{tagsupport/math/mathml/write}
+% This writes a html-dummy with the hash and the math content.
+% This should be optional, so it uses a socket that can be disabled
+% 
+%    \begin{macrocode}
+\socket_new:nn {tagsupport/math/mathml/write}{0}
+%    \end{macrocode}
+% \end{socketdecl}
+% 
+% \begin{plugdecl}{On}
+%    \begin{macrocode}
+\socket_new_plug:nnn{tagsupport/math/mathml/write}{On}
+ {
+    \str_set:NV\l_@@_tmpa_str\l_@@_content_AF_source_tl
+    \str_replace_all:Nnn\l_@@_tmpa_str{&}{&}
+    \str_replace_all:Nnn\l_@@_tmpa_str{<}{<}
+    \iow_now:Ne \g_@@_writedummy_iow 
+     {
+      \iow_newline:
+      <div>
+      \iow_newline:
+      <h2>\c_backslash_str mml\c_space_tl \int_use:N \g_@@_math_total_int </h2>
+      \iow_newline:
+      <p>\l_@@_tmpa_str</p>
+      \iow_newline:
+      <p>\l_@@_content_hash_tl </p>
+      \iow_newline:
+      <math></math>
+      \iow_newline:
+      </div>
+      \iow_newline:
+      }
+ }
+%    \end{macrocode}
+% \end{plugdecl}
+% And now a key to activate the socket.
+%    \begin{macrocode}
+
+\keys_define:nn { __tag / setup }
+   {
+     math/mathml/write-dummy .code:n = 
+       {
+         \bool_gset_true:N \g__tag_math_mathml_AF_bool
+         \tl_if_exist:NF\g_@@_writedummy_iow  
+          {
+            \iow_new:N  \g_@@_writedummy_iow
+            \iow_open:Nn \g_@@_writedummy_iow 
+             { 
+               \c_sys_jobname_str-mathml-dummy.html
+             }
+            \iow_now:Ne \g_@@_writedummy_iow
+             {
+               <!DOCTYPE~html>
+               \iow_newline:
+               <html>
+             }
+            \AssignSocketPlug {tagsupport/math/mathml/write}{On}
+            \AddToHook{enddocument/afterlastpage}
+             {
+               \iow_now:Nn \g_@@_writedummy_iow {</html>}
+               \iow_close:N \g_@@_writedummy_iow
+             }
+          }  
+       },
+     math/mathml/write-dummy .usage:n=preamble  
+   }          
+%    \end{macrocode}
+%
+% \begin{macro}{\@@_AF_process_mathml_files:}
+%    \begin{macrocode}
+\box_new:N\l_@@_tmpa_box
+\cs_new_protected:Npn \@@_AF_process_mathml_files:
+ {
+   \hbox_set:Nn \l_@@_tmpa_box
+    {
+      \pdfdict_put:nnn { l_pdffile/Filespec }{AFRelationship} { /Supplement }
+      \pdfdict_put:nne 
+       { l_pdffile }{Subtype} 
+       { \pdf_name_from_unicode_e:n{application/mathml+xml} } 
+      \char_set_catcode_other:N \#
+      \cs_set_eq:NN\mml \@@_AF_html_reader:w
+      \clist_map_inline:Nn \l__tag_math_mathml_files_clist
+        {
+          \file_if_exist:nTF {##1.html}
+            {
+              \typeout{Info:~reading~mathml~file~##1}
+              \file_input:n {##1.html}
+              \bool_gset_true:N\g__tag_math_mathml_AF_bool
+            }
+            {
+              \typeout{Info:~mathml~file~##1~does~not~exist}%info message
+            }
+        }  
+    }
+    \bool_if:NT\g__tag_math_mathml_AF_bool
+      {
+        \typeout{Info:~Activating~mathml~support}
+        \AssignSocketPlug{tagsupport/math/struct/begin}{test-mathml}
+        \AssignSocketPlug{tagsupport/math/struct/end}{test-mathml}    
+%    \end{macrocode}
+% mathml handling doesn't like subparts, so we disable them for now:
+%    \begin{macrocode}
+        \AssignSocketPlug{tagsupport/math/substruct/begin}{single}
+        \AssignSocketPlug{tagsupport/math/substruct/end}{single}
+        \AddToHook{enddocument/info}
+         {
+           \iow_term:n{MathML~statistic}
+           \iow_term:n{================}
+           \iow_term:e{==>~\int_use:N\g_@@_mathml_total_int\c_space_tl 
+           MathML~fragments~read}
+           \iow_term:e{==>~\int_use:N\g_@@_mathml_int\c_space_tl 
+           different~MathML~fragments}
+           \iow_term:e{==>~\int_use:N\g_@@_math_total_int\c_space_tl 
+           math~fragments~found}
+           \iow_term:e{==>~\int_use:N\g_@@_mathml_AF_found_int\c_space_tl 
+           fitting~MathML~AF~found}
+           \iow_term:e{==>~\int_use:N\g_@@_mathml_AF_attached_int\c_space_tl 
+           MathML~AF~attached}
+         }
+      }  
+ }
+\AddToHook{begindocument}{\@@_AF_process_mathml_files:} 
+%    \end{macrocode}
+% \end{macro}
+% 
+% \subsection{Mathstyle detection}
+% In some cases we need to detect the mathstyle used in a \cs{mathchoice}
+% command and to disable/enable tagging in the unused branches. 
+% This is currently only used in the amstext command \cs{text}
+% but is perhaps also needed in other cases, so we create a general command.
+% 
+%\begin{macro}{\l_@@_mathstyle_int,\g_@@_mathchoice_int,mathstyle}
+%    \begin{macrocode}
+\int_new:N \l_@@_mathstyle_int
+\int_new:N \g_@@_mathchoice_int
+\property_new:nnnn{mathstyle}{now}{-1}{\int_use:N \l_@@_mathstyle_int }
+%    \end{macrocode}
+%\end{macro}
+% For now internal, but perhaps will need a public version.
+% The command should be used in every branch of a \cs{mathchoice}
+% (with the correct mathstyle number) and with an unique label (which should
+% be the same in every branch). 
+% \cs{g_@@_mathchoice_int} can be e.g. increased before the mathchoice and 
+% then used.
+% \begin{macro}{\@@_tag_if_mathstyle:nn}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_tag_if_mathstyle:nn #1 #2 
+ %#1 refers to label
+ %#2 is a number for the mathstyle (typically 0,2,4,6)
+ {
+   \int_set:Nn \l_@@_mathstyle_int {#2}
+   \property_record:nn {#1} { mathstyle }
+   \int_compare:nNnTF { \property_ref:nn {#1}{ mathstyle} } = { #2 }
+    { \tag_start: }{ \tag_stop: }
+ }
+\cs_generate_variant:Nn \@@_tag_if_mathstyle:nn {en} 
+%    \end{macrocode}
+% \end{macro}
+% 
+% \subsection{Tagging options}
+%    \begin{macrocode}
+\keys_define:nn { __tag / setup }
+  {
+   math/mathml/sources .clist_set:N = \l__tag_math_mathml_files_clist,
+   math/alt/use       .bool_set:N = \l__tag_math_alt_bool,
+   viewer/pane/mathml      .bool_set:N = \l__tag_math_mathml_pane_bool,
+   viewer/pane/mathml      .initial:n = true,
+   viewer/pane/mathsource  .bool_set:N = \l__tag_math_texsource_pane_bool, 
+   math/mathml/AF .bool_set:N = \l__tag_math_mathml_AF_bool,
+   math/mathml/AF  .initial:n = true,
+   math/tex/AF    .bool_set:N = \l__tag_math_texsource_AF_bool,
+   math/tex/AF    .initial:n = true
+  } 
+%    \end{macrocode}
+%
+% \subsection{Sockets}
+% \subsubsection{Main inline math sockets}
+% 
+% \begin{socketdecl}
+%   {
+%     tagsupport/math/inline/begin,
+%     tagsupport/math/inline/end,
+%     tagsupport/math/inline/formula/begin,
+%     tagsupport/math/inline/formula/end,
+%   }
+%   The first two sockets are meant to embed inline
+%   math into the surrounding (so to close/reopen e.g. MC-chunks).
+%   The other two implement the actual formula structure.  
+%   The formula sockets are despite their naming not symmetric:
+%   the begin socket is issued after the math has started, while 
+%   the end socket is after the math!                               
+%    \begin{macrocode}
+\socket_new:nn {tagsupport/math/inline/begin}{0}
+\socket_new:nn {tagsupport/math/inline/end}{0}
+\socket_new:nn {tagsupport/math/inline/formula/begin}{1} %
+\socket_new:nn {tagsupport/math/inline/formula/end}{0}
+%    \end{macrocode}
+%\end{socketdecl}
+% 
+% 
+% \begin{plugdecl}{MC}
+%    \begin{macrocode}
+\socket_new_plug:nnn
+  {tagsupport/math/inline/begin}
+  {MC}
+  {\tag_mc_end_push:}
+\socket_new_plug:nnn
+  {tagsupport/math/inline/end}
+  {MC}
+  {\tag_mc_begin_pop:n{}}  
+%    \end{macrocode}
+% \end{plugdecl}
+% 
+% We probably will want to test different tagging receipes.
+% \begin{plugdecl}{default}
+%    \begin{macrocode}
+\socket_new_plug:nnn
+  {tagsupport/math/inline/formula/begin}
+  {default}
+  {  
+    \socket_use:n{tagsupport/math/content}
+    \socket_use:n{tagsupport/math/struct/begin}
+%    \end{macrocode}
+% TODO: does inline math need subformula handling?
+%    \begin{macrocode}
+    % inner formula if multiple parts (not really implemented yet)
+    \socket_use:n{tagsupport/math/substruct/begin}
+    #1
+    \socket_use:n{tagsupport/math/end}
+  }
+\socket_new_plug:nnn
+  {tagsupport/math/inline/formula/end}
+  {default}
+  {  
+    \socket_use:n{tagsupport/math/substruct/end}
+    \socket_use:n{tagsupport/math/struct/end}
+  }  
+%    \end{macrocode}
+% \end{plugdecl}
+% 
+% \subsubsection{Main display math sockets}
+% 
+% \begin{socketdecl}
+%   {
+%     tagsupport/math/display/begin,
+%     tagsupport/math/display/end,
+%     tagsupport/math/display/formula/begin,
+%     tagsupport/math/display/formula/end,
+%   }
+%   The first two sockets are meant to embed display
+%   math into the surrounding (so to close/reopen e.g. MC-chunks and
+%   P-structure).
+%   The other two implement the actual formula structure. 
+%   The formula sockets are despite their naming not symmetric:
+%   the begin socket is issued after the math has started, while 
+%   the end socket is after the math!                
+%    \begin{macrocode}
+\socket_new:nn {tagsupport/math/display/begin}{0}
+\socket_new:nn {tagsupport/math/display/end}{0}
+\socket_new:nn {tagsupport/math/display/formula/begin}{1} %
+\socket_new:nn {tagsupport/math/display/formula/end}{0}
+%    \end{macrocode}
+%\end{socketdecl}
+
+% \begin{plugdecl}{default}
+%    \begin{macrocode}
+\socket_new_plug:nnn
+  {tagsupport/math/display/begin}
+  {default}
+  { \__tag_tool_close_P:  }
+\socket_new_plug:nnn
+  {tagsupport/math/display/end}
+  {default}
+  {
+  }  
+%    \end{macrocode}
+% \end{plugdecl}
+
+
+% \begin{plugdecl}{default}
+%    \begin{macrocode}
+\socket_new_plug:nnn
+  {tagsupport/math/display/formula/begin}
+  {default}
+  { 
+    \socket_use:n{tagsupport/math/content}
+    \socket_use:n{tagsupport/math/struct/begin}
+    \socket_use:n{tagsupport/math/substruct/begin}
+    #1 
+    \socket_use:n{tagsupport/math/end}
+  }
+\socket_new_plug:nnn
+  {tagsupport/math/display/formula/end}
+  {default}
+  {  
+    \socket_use:n{tagsupport/math/substruct/end}
+    \socket_use:n{tagsupport/math/struct/end}
+  }  
+%    \end{macrocode}
+% \end{plugdecl}
+%
+% \subsubsection{Internal sockets}
+% 
+% \begin{variable}{\l_@@_content_template_tl}
+% The default text used as alt or actual text.
+%    \begin{macrocode}
+\tl_new:N\l_@@_content_template_tl
+\tl_set:Nn \l_@@_content_template_tl
+   {
+       LaTeX~ formula~ starts~
+       \exp_not:N\begin{\g_@@_grabbed_env_tl}
+       \c_space_tl
+       \exp_not:V\g_@@_grabbed_math_tl
+       \c_space_tl
+       \exp_not:N\end{\g_@@_grabbed_env_tl}
+       \c_space_tl LaTeX~ formula~ ends~
+   }    
+%    \end{macrocode}
+% \end{variable}
+
+% \begin{variable}{\l_@@_texsource_template_tl}
+% The default text used as texsource
+%    \begin{macrocode}
+\tl_new:N\l_@@_texsource_template_tl
+\tl_const:Nn\c_@@_inline_env_tl {math}
+\tl_set:Nn \l_@@_texsource_template_tl
+   {    
+     \tl_if_eq:NNTF\g_@@_grabbed_env_tl\c_@@_inline_env_tl
+      {
+       $
+         \exp_not:V\g_@@_grabbed_math_tl
+       $
+      }
+      {
+       \exp_not:N\begin{\g_@@_grabbed_env_tl}
+       \exp_not:V\g_@@_grabbed_math_tl
+       \exp_not:N\end{\g_@@_grabbed_env_tl}
+      } 
+   } 
+%    \end{macrocode}
+% \end{variable}
+
+% 
+% \begin{socketdecl}{tagsupport/math/content}
+% The math content is stored in associated files and used for 
+% actual and alternative text. As the exact text is still
+% unclear we use a socket to be able to test variants.
+% The socket should set all four tl vars above, if needed
+% to identical values. It can use the two variables 
+% \cs{g_@@_grabbed_env_tl} and \cs{g_@@_grabbed_math_tl}
+%    \begin{macrocode}
+\socket_new:nn {tagsupport/math/content}{0}
+%    \end{macrocode}
+% \end{socketdecl}
+% 
+% Some default sockets to set the contents.
+% TODO: think about naming convention. 
+% TODO: think how this should organized so that one
+% has options to change from the outside and so that
+% there are less repetitions. 
+% \begin{plugdecl}{actual+source}
+%    \begin{macrocode}
+\socket_new_plug:nnn
+  {tagsupport/math/content}
+  {actual+source}
+  {
+   \tl_set:Ne\l_@@_content_actual_tl
+    {
+       \l_@@_content_template_tl
+    }   
+   \tl_set:Ne \l_@@_content_AF_source_tl 
+    {
+      \l_@@_texsource_template_tl
+    }  
+   \tl_set:Nn    \l_@@_content_AF_mathml_tl {}
+   \tl_set:Nn    \l_@@_content_alt_tl    {}
+  }
+%    \end{macrocode}
+% \end{plugdecl}  
+% 
+% \begin{plugdecl}{alt+source}
+%    \begin{macrocode}
+\socket_new_plug:nnn
+  {tagsupport/math/content}
+  {alt+source}
+  {
+   \tl_set:Ne\l_@@_content_alt_tl
+    {
+       \l_@@_content_template_tl
+    }   
+   \tl_set:Ne \l_@@_content_AF_source_tl 
+    {
+       \l_@@_texsource_template_tl
+    }  
+   \tl_set:Nn    \l_@@_content_AF_mathml_tl {}
+   \tl_set:Nn    \l_@@_content_actual_tl    {}
+  }
+%    \end{macrocode}
+% \end{plugdecl}
+%    \begin{macrocode}
+\socket_assign_plug:nn {tagsupport/math/content}{alt+source}  
+%    \end{macrocode}
+%
+% \begin{socketdecl}{tagsupport/math/struct/begin,
+%  tagsupport/math/struct/end}
+% For the main structure we use a socket too. 
+% This allow e.g. to create a special one for luamml
+% which setups additional objects. 
+% The begin socket can use the two variables 
+% \cs{g_@@_grabbed_env_tl} and \cs{g_@@_grabbed_math_tl}
+%    \begin{macrocode}
+\socket_new:nn {tagsupport/math/struct/begin}{0}
+\socket_new:nn {tagsupport/math/struct/end}{0}
+%    \end{macrocode}
+% \end{socketdecl}
+%
+% \begin{plugdecl}{default}
+% TODO: think about some naming convention ...
+%    \begin{macrocode}
+\socket_new_plug:nnn
+  {tagsupport/math/struct/begin}
+  {default}
+  {
+    \bool_if:NTF\l__tag_math_texsource_AF_bool  
+     { \tl_set_eq:NN \l_@@_content_AF_source_tmpa_tl \l_@@_content_AF_source_tl }
+     { \tl_clear:N \l_@@_content_AF_source_tmpa_tl }
+    \tag_struct_begin:n
+     {
+       tag=Formula,
+       texsource   = \l_@@_content_AF_source_tmpa_tl,
+       title-o     = \g_@@_grabbed_env_tl,
+       actualtext  = \l_@@_content_actual_tl,
+       alt         = \l_@@_content_alt_tl
+     }
+  }
+\socket_new_plug:nnn
+  {tagsupport/math/struct/end}
+  {default}
+  { \tag_struct_end: }
+  
+\socket_assign_plug:nn {tagsupport/math/struct/begin}{default}  
+\socket_assign_plug:nn {tagsupport/math/struct/end}{default}   
+%    \end{macrocode}  
+% \end{plugdecl}   
+% 
+% \begin{plugdecl}{test-mathml}
+% This (test-)socket tries to add a mathml-AF to formula. 
+% It is activated if a mathml.html has been found and loaded. 
+% Additionally it also sets an attribute 
+% (this can perhaps be done by default anyway.)
+% As it disturbs the reading of the AF it currently deactivates the /Alt key,
+% unless it has been reenabled with |math/alt/use=true| 
+%    \begin{macrocode}
+\cs_generate_variant:Nn \str_mdfive_hash:n {o}
+\tl_new:N\l_@@_content_hash_tl
+%    \end{macrocode}
+% we need to save the grabbed math:
+%    \begin{macrocode}
+\tl_new:N\l_@@_grabbed_math_tl
+%    \end{macrocode}
+% the socket definition
+%    \begin{macrocode}
+\socket_new_plug:nnn
+  {tagsupport/math/struct/begin}
+  {test-mathml}
+  { 
+   \int_gincr:N\g_@@_math_total_int  
+   \tl_set:Ne\l_@@_content_hash_tl 
+    {\str_mdfive_hash:o { \l_@@_content_AF_source_tl }} 
+   \tl_set_eq:NN\l_@@_grabbed_math_tl\g_@@_grabbed_math_tl   
+   \tl_if_eq:NnTF\g_@@_grabbed_env_tl {math}
+     {
+       \tl_set:Nn\l_@@_attribute_class_tl{inline}       
+     }
+     {
+       \tl_set:Nn\l_@@_attribute_class_tl{display}
+     }
+   \bool_if:NF\l__tag_math_alt_bool
+     { \tl_set:Nn \l_@@_content_alt_tl{} }  
+%    \end{macrocode}
+% debugging option. TODO: hide in debug key.
+%    \begin{macrocode}
+   \tl_if_exist:cTF { g_@@_mathml_ \l_@@_content_hash_tl _tl }
+    {  
+      \int_gincr:N\g_@@_mathml_AF_found_int 
+      \bool_if:NTF \l__tag_math_mathml_AF_bool
+       { 
+         \int_gincr:N\g_@@_mathml_AF_attached_int                                        
+         \typeout {Inserting~mathml~with~Hash~\l_@@_content_hash_tl}
+       }      
+       {
+         \typeout {Ignoring~mathml~with~Hash~\l_@@_content_hash_tl}
+       }
+    }
+    {
+      \typeout{WARNING:~mathml~missing~for~hash~\l_@@_content_hash_tl}
+    }    
+   \socket_use:n {tagsupport/math/mathml/write} % write hash if request  
+    \bool_if:NTF\l__tag_math_texsource_AF_bool  
+     { \tl_set_eq:NN \l_@@_content_AF_source_tmpa_tl \l_@@_content_AF_source_tl }
+     { \tl_clear:N \l_@@_content_AF_source_tmpa_tl }   
+   \tag_struct_begin:n
+     {
+       tag=Formula,
+       attribute-class=\l_@@_attribute_class_tl, %
+       AFref       = 
+        \bool_if:NT\l__tag_math_mathml_AF_bool
+         {
+           \cs_if_exist_use:c {g_@@_mathml_ \l_@@_content_hash_tl _tl}
+         },
+       texsource   = \l_@@_content_AF_source_tmpa_tl, % should be after mathml AF!
+       title-o     = \g_@@_grabbed_env_tl,    %
+       alt         = \l_@@_content_alt_tl
+     }
+   }
+%    \end{macrocode}
+% not really needed but looks more symmetric:
+%    \begin{macrocode}
+\socket_new_plug:nnn
+  {tagsupport/math/struct/end}
+  {test-mathml}
+  {
+    \tag_struct_end:
+  }     
+%    \end{macrocode}
+% \end{plugdecl}
+%  
+% \begin{socketdecl}{tagsupport/math/substruct/begin,
+%  tagsupport/math/substruct/end}
+%  This holds the code to handle subparts of the formula.
+%    \begin{macrocode}
+\socket_new:nn {tagsupport/math/substruct/begin}{0}
+\socket_new:nn {tagsupport/math/substruct/end}{0}
+%    \end{macrocode}
+% \end{socketdecl}
+% 
+% \begin{plugdecl}{default}
+%    \begin{macrocode}
+\socket_new_plug:nnn
+  {tagsupport/math/substruct/begin}
+  {default}
+  { \grabaformulapartandstart }
+\socket_new_plug:nnn
+  {tagsupport/math/substruct/end}
+  {default}
+  { 
+    \tagmcend
+    \if at subformulas
+      \tagstructend
+    \fi
+ } 
+\socket_assign_plug:nn {tagsupport/math/substruct/begin}{default}  
+\socket_assign_plug:nn {tagsupport/math/substruct/end}{default}   
+%    \end{macrocode}  
+% \end{plugdecl}  
+
+% \begin{plugdecl}{single}
+% We need an option to disable subparts as it is unclear
+% if consumers can handle them:
+%    \begin{macrocode}
+\socket_new_plug:nnn
+  {tagsupport/math/substruct/begin}
+  {single}
+  {
+    \typeout{====>subpart~splitting~deactivated}
+    \typeout{====>grabbed~math=\meaning\g_@@_grabbed_math_tl}
+    \tag_mc_begin:n{} 
+  }
+\socket_new_plug:nnn
+  {tagsupport/math/substruct/end}
+  {single}
+  { \tag_mc_end:}
+%    \end{macrocode}
+% \end{plugdecl}
+% 
+% \begin{socketdecl}{tagsupport/math/end}
+%  A socket used at the end of the math (before the closing dollar(s))
+%  which can e.g. set a flag for luamml.
+%    \begin{macrocode}
+\socket_new:nn {tagsupport/math/end}{0}
+%    \end{macrocode}
+% \end{socketdecl}
+ 
+% 
+%  \begin{macro}{\__tag_math_disable:}
+%  Similar to the table code we collect the plugs that should be
+%  assigned to do nothing if we don't want tagging
+%    \begin{macrocode}
+\cs_new_protected:Npn \__tag_math_disable: 
+  {
+    \socket_assign_plug:nn {tagsupport/math/inline/begin}{noop}
+    \socket_assign_plug:nn {tagsupport/math/inline/end}{noop}
+    \socket_assign_plug:nn {tagsupport/math/inline/formula/begin}{identity}
+    \socket_assign_plug:nn {tagsupport/math/inline/formula/end}{noop}
+    \socket_assign_plug:nn {tagsupport/math/display/begin}{noop}
+    \socket_assign_plug:nn {tagsupport/math/display/end}{noop}
+    \socket_assign_plug:nn {tagsupport/math/display/formula/begin}{identity}
+    \socket_assign_plug:nn {tagsupport/math/display/formula/end}{noop}   
+  } 
+%    \end{macrocode}
+% \end{macro}
+% 
+%  \begin{macro}{\__tag_math_enable:}
+%  Similar to the table code we collect the default plugs that should be
+%  assigned if we want tagging
+%    \begin{macrocode}
+\cs_new_protected:Npn \__tag_math_enable: 
+  {
+    \socket_assign_plug:nn {tagsupport/math/inline/begin}{MC}
+    \socket_assign_plug:nn {tagsupport/math/inline/end}{MC}
+    \socket_assign_plug:nn {tagsupport/math/inline/formula/begin}{default}
+    \socket_assign_plug:nn {tagsupport/math/inline/formula/end}{default}
+    \socket_assign_plug:nn {tagsupport/math/display/begin}{default}
+    \socket_assign_plug:nn {tagsupport/math/display/end}{default}
+    \socket_assign_plug:nn {tagsupport/math/display/formula/begin}{default}
+    \socket_assign_plug:nn {tagsupport/math/display/formula/end}{default}
+  } 
+%    \end{macrocode}
+% \end{macro}
+% At begin document we can activate:
+%    \begin{macrocode}
+\AtBeginDocument{\tag_if_active:T{\__tag_math_enable: }}
+%    \end{macrocode}
+%
 % \subsection{Interface commands}
 %
 % \begin{macro}
@@ -260,7 +1322,8 @@
   {
     \legacy_if:nF { measuring@ }
       {
-        \tl_if_in:nnF {#2} { \m at th }
+        \tl_if_in:nnTF {#2} { \m at th }
+          { \bool_set_true:N\l_@@_fakemath_bool }
           { \tl_trim_spaces_apply:nN {#2} \@@_process_auxi:nn {#1} }
       }
   }
@@ -287,16 +1350,16 @@
 %
 % \begin{macro}{\@@_grab_dollar:w}
 %   Grab up to a single |$|, for inline math mode, suppressing
-%   any processing if the first token is \tn{m at th}.
+%   any processing if the token is \tn{m at th} found in the content.
 %
-%    \fmi{what's that test doing?} 
+%    \fmi{what's that test doing?}
 %
-%    \car{It is some kind of fix, to avoid the remote 
-%      possibility that the math is empty, making the code 
-%      produce an unwanted \texttt{\$\$}.} 
-% 
-%\car{cf.~the code for this in \cs{@ensuredmath}} 
+%    \car{It is some kind of fix, to avoid the remote
+%      possibility that the math is empty, making the code
+%      produce an unwanted \texttt{\$\$}.}
 %
+%\car{cf.~the code for this in \cs{@ensuredmath}}
+%
 %\car{It is harmless but unnecessary in the dollardollar grabbing below.}
 %
 %    \begin{macrocode}
@@ -309,91 +1372,62 @@
     \tl_if_blank:nF {#1}
       {
         \@@_process:nn { math } {#1} % $
-% fairly simple this one
 %    \end{macrocode}
-% We do not want math tagging in fakemath or when measuring, 
-% so we imitate the test inside \cs{@@_process:nn} for now, 
-% see https://github.com/latex3/tagging-project/issues/5
-% TODO: use socket to get more control about typesetting variants (tagged, drop etc)?
+%  We do not want math tagging in fakemath or when measuring,
+%  We also do not want math tagging if tagging has been suspended.
 %    \begin{macrocode}
-        \legacy_if:nTF { measuring@ }
-          { #1 $ }
-          {
-            \tl_if_in:nnTF {#1} { \m at th }
-              { #1 $ }
-              { 
-                \tagmcend %end P-chunk, in code: \tag_mc_end_push:
-                \@kernel at math@begin
-                #1 $
-                \@kernel at math@end
-                \tagmcbegin{}  % restart P-chunk (whatsits in pdftex)
-              }
-          }        
+      \bool_lazy_or:nnTF 
+        {\legacy_if_p:n { measuring@ }}
+        { \l_@@_fakemath_bool }
+        { #1 $ }
+        {
+            \tag_socket_use:n  {math/inline/begin} %end P-MC  
+            \tag_socket_use:nn {math/inline/formula/begin}{#1}
+             $
+            \tag_socket_use:n  {math/inline/formula/end}
+            \tag_socket_use:n  {math/inline/end} % restart P-MC
+        }         
       }
   }
 %    \end{macrocode}
 % \end{macro}
+% 
 % \begin{macro}{\@@_grab_dollardollar:w}
 %   And for the classical \TeX{} display structure.
 %    \begin{macrocode}
-
-\skip_new:N \l_@@_tmpa_skip
-  
 \cs_new_protected:Npn \@@_grab_dollardollar:w % $$
   #1 $$
   {
     \tl_if_blank:nF {#1}
       {
-        \@@_tag_dollardollar_display:nn { equation* }{#1}
-        #1
+        \@@_process:nn { equation* } {#1}
+        \socket_use:n {tagsupport/math/display/begin}
+        \socket_use:nn{tagsupport/math/display/formula/begin}{#1}
         $$
       }
   }
 %    \end{macrocode}
-% To allow to use the code without tagging we guard. But probably tagpdf should
-% provide some tools for such manual para-ends.
+% 
+% The end code is added through a \cs{aftergroup} so we
+% store it inside a command.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@kernel at close@P {
-   \tag_if_active:T
-    {
-     \tagmcend %end P-chunk, should perhaps be \tag_mc_end_push: ...
-        \int_gincr:N \g__tag_para_end_int
-        \bool_if:NT \l__tag_para_show_bool
-          { \tag_mc_begin:n{artifact}
-            \rlap{\color_select:n{red}\tiny\ \int_use:N\g__tag_para_end_int}
-            \tag_mc_end:
-          }
-        \tag_struct_end:
-    }    
-}
-  
-
-
-\cs_new_protected:Npn \@@_tag_dollardollar_display:nn #1#2 {
-  \@@_process:nn {#1} {#2}
-  \@kernel at close@P
-  \@kernel at math@begin
-%        \skip_set:Nn \belowdisplayskip      {-\belowdisplayskip}
-%        \skip_set:Nn \belowdisplayshortskip {-\belowdisplayshortskip}
-%        \int_set:Nn \postdisplaypenalty {10000}
-%%
-%        \group_insert_after:N \@@_tag_dollardollar_display_end:
-}
-
-\cs_new_protected:Npn \@@_tag_dollardollar_display_end: {
-%  \typeout{== tag dollarldollar display end}
-%  \ShowTagging{struct-stack}
-  \tagpdfparaOff
-  \para_raw_end:
-  \tagpdfparaOn
-  \l_@@_tmpa_skip \lastskip  
-  \@kernel at math@end
-  \penalty \postdisplaypenalty
+\cs_new_protected:Npn \@@_tag_dollardollar_display_end: 
+  {
+    %  \typeout{== tag dollarldollar display end}
+    %  \ShowTagging{struct-stack}
+    \para_raw_end:
 %    \end{macrocode}
+% TODO why is that needed? where is para-tagging disabled?
+%    \begin{macrocode}
+    \tagpdfparaOn
+    \l_@@_tmpa_skip \lastskip
+    \socket_use:n{tagsupport/math/display/formula/end}    
+    \penalty \postdisplaypenalty
+%    \end{macrocode}
 % This reinserts the below display skips. It must be doubled to
 % get the right amount:
 %    \begin{macrocode}
-  \skip_vertical:n { -\l_@@_tmpa_skip * 2 }  
+  \skip_vertical:n { -\l_@@_tmpa_skip * 2 }
 %
   \@doendpe             % this has no \end{...} to take care of it
 }
@@ -410,7 +1444,6 @@
   {
     \tl_if_blank:nF {#1}
       {
-        \@@_process:nn { math } {#1}
         $ #1 $
       }
     \bool_set_false:N \l_@@_collected_bool
@@ -417,6 +1450,7 @@
   }
 %    \end{macrocode}
 % \end{macro}
+%
 % \begin{macro}{\@@_grab_eqn:w}
 %   For the most common use of \cs{[}/\cs{]}: turn into an environment.
 %    \begin{macrocode}
@@ -463,7 +1497,7 @@
 % \begin{macro}{\math_register_env:n}
 % \begin{macro}{\RegisterMathEnvironment}
 %   Set up to capture environment content and make available.
-% 
+%
 %    \begin{macrocode}
 \cs_new_protected:Npn \math_register_env:nn #1#2
   {
@@ -472,15 +1506,8 @@
     \cs_gset_eq:cc { @@_env_ #1 _begin: } {#1}
     \cs_gset_eq:cc { @@_env_ #1 _end: } { end #1 }
 %
-    \ExpandArgs { nnx } \RenewDocumentEnvironment {#1} { b }
+    \ExpandArgs { nne } \RenewDocumentEnvironment {#1} { b }
       {
-%        \bool_set_true:N \exp_not:N \l_@@_collected_bool
-%        \cs_if_exist:cTF { @@_env #1 _aux: }
-%          {
-%            \exp_not:c { @@_env #1 _aux: }
-%              ####1 \exp_not:N \@@_env_end: {#1}
-%          }
-%          { \exp_not:N \@@_process:nn {#1} {####1} }
         \exp_not:N \bool_if:NTF \exp_not:N \l_@@_collected_bool
           {
 %            \typeout{===>B1}
@@ -490,34 +1517,22 @@
             \cs_if_exist:cTF { @@_env #1 _aux: }
               {
                 \exp_not:c { @@_env #1 _aux: }
-                  ####1 \exp_not:N \@@_env_end: {#1}
+                  ##1 \exp_not:N \@@_env_end: {#1}
               }
-              { \exp_not:N \@@_process:nn {#1} {####1} }
+              { \exp_not:N \@@_process:nn {#1} {##1} }
             \exp_not:n { \@kernel at math@registered at begin }
             \bool_set_true:N \exp_not:N \l_@@_collected_bool
           }
-%        \exp_not:N \tracingall  
+%        \exp_not:N \tracingall
         \exp_not:c { @@_env_ #1 _begin: }
-        ####1
+        ##1
         \exp_not:c { @@_env_ #1 _end: }
-%        \exp_not:c { @@_env_ #1 _end: }
 %        \exp_not:N \tracingnone
-%        \exp_not:n { \@kernel at math@registered at end }
      }
-      {
-      }
+     {
+     }
   }
 
-\cs_set_protected:Npn \__cs_tmp:w #1
-  {
-    \group_begin:
-      \exp_args:No \__cs_generate_internal_variant:n
-        { \tl_to_str:n {#1} }
-    \group_end:
-  }
-\__cs_tmp:w { nnxx }
-  
-  
 \cs_new_protected:Npn \math_register_halign_env:nn #1#2
   {
     \tl_set:Nn \l_@@_env_name_tl {#1}
@@ -525,15 +1540,8 @@
     \cs_gset_eq:cc { @@_env_ #1 _begin: } {#1}
     \cs_gset_eq:cc { @@_env_ #1 _end: } { end #1 }
 %
-    \ExpandArgs { nnxx } \RenewDocumentEnvironment {#1} { b }
+    \ExpandArgs { nnee } \RenewDocumentEnvironment {#1} { b }
       {
-%        \bool_set_true:N \exp_not:N \l_@@_collected_bool
-%        \cs_if_exist:cTF { @@_env #1 _aux: }
-%          {
-%            \exp_not:c { @@_env #1 _aux: }
-%              ####1 \exp_not:N \@@_env_end: {#1}
-%          }
-%          { \exp_not:N \@@_process:nn {#1} {####1} }
         \exp_not:N \bool_if:NTF \exp_not:N \l_@@_collected_bool
           {
 %            \typeout{===>B1}
@@ -543,23 +1551,24 @@
             \cs_if_exist:cTF { @@_env #1 _aux: }
               {
                 \exp_not:c { @@_env #1 _aux: }
-                  ####1 \exp_not:N \@@_env_end: {#1}
+                  ##1 \exp_not:N \@@_env_end: {#1}
               }
-              { \exp_not:N \@@_process:nn {#1} {####1} }
+              { \exp_not:N \@@_process:nn {#1} {##1} }
             \exp_not:n { \@kernel at math@registered at begin }
             \bool_set_true:N \exp_not:N \l_@@_collected_bool
           }
-%        \exp_not:N \tracingall  
+%        \exp_not:N \tracingall
         \exp_not:c { @@_env_ #1 _begin: }
-        ####1
-%        \exp_not:c { @@_env_ #1 _end: }
+        ##1
 %        \exp_not:N \tracingnone
      }
-      {
-        \exp_not:c { @@_env_ #1 _end: }
-      }
+     {
+       \exp_not:c { @@_env_ #1 _end: }
+     }
   }
-
+%    \end{macrocode}
+% TODO: the following command is neither documented nor used. Is is needed?
+%    \begin{macrocode}
 \cs_new_protected:Npn \math_register_odd_env:nn #1#2
   {
     \tl_set:Nn \l_@@_env_name_tl {#1}
@@ -567,7 +1576,7 @@
     \cs_gset_eq:cc { @@_env_ #1 _begin: } {#1}
     \cs_gset_eq:cc { @@_env_ #1 _end: } { end #1 }
 %
-    \ExpandArgs { nnxx } \RenewDocumentEnvironment {#1} { b }
+    \ExpandArgs { nnee } \RenewDocumentEnvironment {#1} { b }
       {
         \exp_not:N \bool_if:NTF \exp_not:N \l_@@_collected_bool
           {
@@ -578,19 +1587,19 @@
             \cs_if_exist:cTF { @@_env #1 _aux: }
               {
                 \exp_not:c { @@_env #1 _aux: }
-                  ####1 \exp_not:N \@@_env_end: {#1}
+                  ##1 \exp_not:N \@@_env_end: {#1}
               }
-              { \exp_not:N \@@_process:nn {#1} {####1} }
+              { \exp_not:N \@@_process:nn {#1} {##1} }
             \exp_not:n { \@kernel at math@registered at begin }
             \bool_set_true:N \exp_not:N \l_@@_collected_bool
           }
-%        \exp_not:N \tracingall  
+%        \exp_not:N \tracingall
         \exp_not:c { @@_env_ #1 _begin: }
-        ####1
+        ##1
      }
       {
         \exp_not:c { @@_env_ #1 _end: }
-% needed if we don't have $$...$$        
+% needed if we don't have $$...$$
 %        \exp_not:n { \typeout{---> @kernel at math@registered at end }}
         \exp_not:n { \@kernel at math@registered at end }
       }
@@ -614,7 +1623,7 @@
 
 
 \cs_new:Npn \@kernel at math@registered at begin {
-%  \ShowTagging{struct-stack} 
+%  \ShowTagging{struct-stack}
 %\typeout{==>A1}\ShowTagging{struct-stack,mc-current}
   \mode_if_vertical:TF
        {
@@ -623,19 +1632,21 @@
 %           { \__block_list_beginpar_vmode: }
 %
 %         \typeout{==>~ at:~ \g__tag_struct_tag_tl}
-%         
-         \exp_args:Noo\str_if_eq:nnF \g__tag_struct_tag_tl { \l__tag_para_main_tag_tl }    % needs correction!
+%
+        \tag_if_active:T
+          {
+            \exp_args:Noo\str_if_eq:nnF \g__tag_struct_tag_tl { \l__tag_para_main_tag_tl }    % needs correction!
              {
 %               \typeout{==>A2}
                \__block_beginpar_vmode:
              }              % needs correction!
+          }
        }
        {
 %         \typeout{==>A3}
-         \@kernel at close@P
-%         \tagmcend                      % needs correction!
+         \__tag_tool_close_P: 
        }
-  \@kernel at math@begin
+  \socket_use:nn{tagsupport/math/display/formula/begin}{}
   \tagpdfparaOff
 %  \typeout{==>MC1}\ShowTagging{mc-current}
 }
@@ -644,13 +1655,14 @@
 %  \typeout{==>MC2}\ShowTagging{mc-current}
   \para_raw_end:
   \tagpdfparaOn
-  \@kernel at math@end
+  \socket_use:n{tagsupport/math/display/formula/end}
 %  \typeout{==>MC3}\ShowTagging{mc-current}
   \@endpetrue
 }
-  
+
 \cs_new_protected:Npn \math_register_env:n #1
   { \math_register_env:nn {#1} { } }
+  
 \NewDocumentCommand \RegisterMathEnvironment { O{} m }
   { \math_register_env:nn {#2} {#1} }
 %    \end{macrocode}
@@ -660,13 +1672,13 @@
 %
 % \begin{macro}{\@@_env_forward:w}
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_env_forward:w #1 \@@_env_end: #2 
+\cs_new_protected:Npn \@@_env_forward:w #1 \@@_env_end: #2
   { \@@_process:nn {#2} {#1} }
 %    \end{macrocode}
 % \end{macro}
-% 
-% \subsection{Document commands} 
 %
+% \subsection{Document commands}
+%
 % \car*{Add one more here: \texttt{displaymath}, which
 %        is equivalent to \cs{[} , \cs{]}\\
 %        and hence to the basic \texttt{equation*}.\\
@@ -692,9 +1704,9 @@
 % at the moment register_env can only do display math
 %    \math_register_env:n { math }
     \RenewDocumentEnvironment{math} {b}{$#1$}{}
-% and this one doesn't work either    
+% and this one doesn't work either
 %    \math_register_env:n { displaymath }
-    \RenewDocumentEnvironment{displaymath} {b}{\[#1\]}{}    
+    \RenewDocumentEnvironment{displaymath} {b}{\[#1\]}{}
   }
 %    \end{macrocode}
 % \end{macro}
@@ -737,29 +1749,31 @@
   {
     \cs_gset_protected:Npn \[ % \]
        {
-        \bool_if:NTF \l_@@_collected_bool
-          { \begin { equation* } }
-          { \@@_grab_eqn:w }
+         \@@_grab_eqn:w 
+ %       \bool_if:NTF \l_@@_collected_bool
+%          { \begin { equation* } }
+%          { \@@_grab_eqn:w }
       } % \[
     \cs_gset_protected:Npn \]
       {
-        \bool_if:NTF \l_@@_collected_bool
-          { \end{ equation* } }
-          { \@badmath }
+        \@badmath
+%        \bool_if:NTF \l_@@_collected_bool
+%          { \end{ equation* } }
+%          { \@badmath }
       }
   }
 %    \end{macrocode}
 % \end{macro}
-% 
 %
+%
 % \begin{macro}{\ensuremath}
 %   A bit of nesting fun to make sure we collect only if required.
 %   \fmi{why does ensuremath need handling at all?}
-% 
-%   \car{Indeed!  Currently, this is setup to process the math that 
-%     it has anyways already captured as its argument; thus it is more 
+%
+%   \car{Indeed!  Currently, this is setup to process the math that
+%     it has anyways already captured as its argument; thus it is more
 %     efficient than leaving the capture to be repeated by the \cs{everymath}}
-% 
+%
 %    \begin{macrocode}
 %\cs_gset_protected:Npn \ensuremath #1
 %  {
@@ -786,47 +1800,6 @@
 % have macro control.
 %    \begin{macrocode}
 
-\tl_new:N\tmpmathcontent
-
-  
-\def\@kernel at math@begin {
-%  \typeout{==>~math~begin}
-% needs different handling if we support nesting
-  \tl_gset:Nx\tmpmathcontent
-     {
-       LaTeX~ formula~ starts~
-       \exp_not:N\begin{\g_@@_grabbed_env_tl}
-       \space
-       \exp_not:V\g_@@_grabbed_math_tl
-       \space
-       \exp_not:N\end{\g_@@_grabbed_env_tl} 
-       \space LaTeX~ formula~ ends~
-    }
-  \tagstructbegin{tag=Formula,
-    AFinline-o=\tmpmathcontent,
-    title-o=\g_@@_grabbed_env_tl,
-    actualtext=\tmpmathcontent
-%    alt=\tmpmathcontent
-  }
-% inner formula if multiple parts (not really implemented yet)
-  \grabaformulapartandstart
-% the above does:  
-%    \tagstructbegin{tag=Formula}\tagmcbegin{}
-%  or just
-% \tagmcbegin{}
-}
-\def\@kernel at math@end {
-%  \typeout{==>~math~end}
-%  \ShowTagging{struct-stack}
-  \tagmcend
-  \if at subformulas
-    \tagstructend
-  \else
-  \fi
-  \tagstructend
-%  \ShowTagging{struct-stack} 
-}
-  
 \exp_args:No \tex_everymath:D
   {
     \tex_the:D \tex_everymath:D
@@ -841,24 +1814,21 @@
   {
     \tex_the:D \tex_everydisplay:D
     \iftrue  % this may have to be a settable flag!
-%      {
 %        \typeout{==>~ in~ everydisplay}
 %    \end{macrocode}
-% flipping the \cs{belowdisplay} values is done so that we get (assumption) 
-% a negative skip and not make the page bigger then we take that out, 
-% then we add the tagging code (in \cs{@@_tag_dollardollar_display_end} ) and 
-% then we put a real \cs{postdisplaypenalty} in and 
-% the right skip (of which we don't know if it is short or a 
-% normal \cs{belowdisplayskip}). This might need some refinement if that skip 
-% is actually negative from the start 
+% flipping the \cs{belowdisplay} values is done so that we get (assumption)
+% a negative skip and not make the page bigger then we take that out,
+% then we add the tagging code (in \cs{@@_tag_dollardollar_display_end} ) and
+% then we put a real \cs{postdisplaypenalty} in and
+% the right skip (of which we don't know if it is short or a
+% normal \cs{belowdisplayskip}). This might need some refinement if that skip
+% is actually negative from the start
 % (not sure it ever is and is worth bothering about)
 %    \begin{macrocode}
         \skip_set:Nn \belowdisplayskip      {-\belowdisplayskip}
         \skip_set:Nn \belowdisplayshortskip {-\belowdisplayshortskip}
         \int_set:Nn \postdisplaypenalty {10000}
-%
         \group_insert_after:N \@@_tag_dollardollar_display_end:
-%      }
     \fi
     \bool_if:NF \l_@@_collected_bool
       {
@@ -876,14 +1846,23 @@
 \math_register_env:n { eqnarray* }
 %    \end{macrocode}
 %
-% Places where math mode is (ab)used.
+% Tabulars currently contain a \$ that shouldn't trigger math
+% tagging.  
 %    \begin{macrocode}
-\clist_map_inline:nn
-  { tabular }
-  {
-    \AddToHook{ env / #1 / begin }
-      { \bool_set_true:N \l_@@_collected_bool }
-  }
+\RequirePackage{array}
+\tl_if_in:NnT\@tabular{$}
+ {
+   \def\@tabular{%
+   \leavevmode
+   \UseTaggingSocket{tbl/hmode/begin}%
+   \hbox \bgroup
+   \bool_set_true:N \l_@@_collected_bool 
+   $
+   \bool_set_false:N \l_@@_collected_bool
+   \col at sep\tabcolsep \let\d at llarbegin\begingroup
+                                    \let\d at llarend\endgroup
+   \@tabarray}
+ }
 %    \end{macrocode}
 %
 % \begin{macro}{\@@_m at th:, \m at th}
@@ -898,6 +1877,20 @@
   }
 %    \end{macrocode}
 % \end{macro}
+% 
+% \subsection{Disable math grabbing in the begindocument hook}
+% For example amsart uses math to measure text there.
+% 
+%    \begin{macrocode}
+\tl_gput_right:Nn\@kernel at before@begindocument
+  {
+    \bool_set_true:N\l_@@_collected_bool
+  }
+\tl_gput_right:Nn\@kernel at after@begindocument
+ {
+   \bool_set_false:N\l_@@_collected_bool
+ }
+%    \end{macrocode}
 %
 % \subsection{Modifying \pkg{amsmath}}
 %
@@ -934,7 +1927,7 @@
   $$\ignorespacesafterend
 }
 %    \end{macrocode}
-%    
+%
 %    \begin{macrocode}
 \def\common at align@ending {
   \math at cr \black@\totwidth@
@@ -1007,9 +2000,11 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-%    
+%
   \math_register_halign_env:nn {align}{}
   \math_register_halign_env:nn {align*}{}
+  \math_register_halign_env:nn {alignat}{}
+  \math_register_halign_env:nn {alignat*}{}  
   \math_register_halign_env:nn {flalign}{}
   \math_register_halign_env:nn {flalign*}{}
   \math_register_halign_env:nn {gather}{}
@@ -1032,45 +2027,9 @@
     \fi
   }
 %    \end{macrocode}
-%    
+%
+%
 %    \begin{macrocode}
-    \def\intertext@{%
-      \def\intertext##1{%
-        \ifvmode\else\\\@empty\fi
-        \noalign{%
-% we have to flip the sign on the skip because we flipped it on the outside
-          \penalty\postdisplaypenalty\vskip-\belowdisplayskip
-          \vbox{
-%    \end{macrocode}
-% Stop tagging when measuring:
-%    \begin{macrocode}
-           \ifmeasuring@\tag_stop:\fi
-           \normalbaselines
-            \ifdim\linewidth=\columnwidth
-            \else \parshape\@ne \@totalleftmargin \linewidth
-            \fi
-%    \end{macrocode}
-% End the previous mc:\fmi{if we use 2 levels of formulas this would
-%    need changing}
-%    \begin{macrocode}
-            \tag_mc_end_push:
-%    \end{macrocode}
-% We are already in a par so we change now to Span:\fmi{not true any longer}
-%    \begin{macrocode}
-            \tagpdfsetup{paratag=P}%
-            \tagpdfparaOn
-            \noindent\ignorespaces##1\par
-%    \end{macrocode}
-% Restart the MC
-%    \begin{macrocode}
-            \tag_mc_begin_pop:n{}}%
-          \penalty\predisplaypenalty\vskip\abovedisplayskip%
-        }%
-      }
-    }
-%    \end{macrocode}
-%    
-%    \begin{macrocode}
 \@namedef{math at cr @ @ @ gather}{%
     \ifst at rred\nonumber\fi
    &\relax
@@ -1083,7 +2042,7 @@
     \cr
 }
 %    \end{macrocode}
-%    
+%
 %    \begin{macrocode}
 \@namedef{math at cr @ @ @ align}{%
   \ifst at rred\nonumber\fi
@@ -1104,7 +2063,7 @@
   \cr
 }
 %    \end{macrocode}
-%    
+%
 %    \begin{macrocode}
 \def\restore at math@cr{\@namedef{math at cr @ @ @}{
 %
@@ -1113,7 +2072,7 @@
     \cr}}
 \restore at math@cr
 %    \end{macrocode}
-%    
+%
 %    \begin{macrocode}
 }
 %    \end{macrocode}
@@ -1125,9 +2084,18 @@
 %
 %
 
-%  \begin{macro}{}
+%  \begin{macro}{\@@_split_at_nl:NN}
+%  This splits grabbed math at newlines. 
 %    
 %    \begin{macrocode}
+\cs_new:Npn \@@_split_at_nl:NN #1#2 {
+  \tl_set:Nf \l_@@_tmpa_tl {
+      \exp_after:wN \@@_split_at_nl_first:w #1 \\ \q_nil \\ \s_stop }
+  \exp_after:wN \@@_split_at_nl_aux:nnNN \l_@@_tmpa_tl #1 #2
+}
+%    \end{macrocode}
+% and the auxiliary commands
+%    \begin{macrocode}
 \cs_new:Npn \@@_split_at_nl_first:w #1 \\ #2 \\ #3 \s_stop
   {
     \quark_if_nil:nTF {#2}
@@ -1137,9 +2105,16 @@
           #2 \\ #3 \s_stop
       }
   }
-\cs_new:Npn \@@_split_chk_if_begin:ww #1 \begin #2 #3 \s_mark
-    #4 \\ \q_nil \\ \s_stop
+  
+\cs_new_protected:Npn \@@_split_at_nl_aux:nnNN #1 #2 #3 #4
   {
+    \tl_gset:Nn #4 {#1}
+    \tl_gset:Nn #3 {#2}
+  }
+
+\cs_new:Npn \@@_split_chk_if_begin:ww 
+   #1 \begin #2 #3 \s_mark #4 \\ \q_nil \\ \s_stop
+  {
     \quark_if_nil:nTF {#2}
       { {#1} {#4} }
       {
@@ -1148,7 +2123,9 @@
             { } { 1 }
       }
   }
+
 \cs_new:Npn \@@_split_cleanup_begin_q_nil:w #1 \begin \q_nil {#1}
+
 \cs_new:Npn \@@_split_collect_one_end:w #1 \end #2 #3 \s_stop #4 #5
   {
     \exp_args:Nf \@@_split_check_count_begins:nnnn
@@ -1157,14 +2134,16 @@
   }
 \cs_new:Npn \@@_split_count_begins:n #1
   { \int_eval:n { 0 \@@_split_count_begins:w #1 \begin \q_nil } }
+
 \cs_new:Npn \@@_split_count_begins:w #1 \begin #2
   { \quark_if_nil:nF {#2} { +1 \@@_split_count_begins:w } }
+
 \cs_new:Npn \@@_split_check_count_begins:nnnn #1 #2 #3 #4
   {
     \int_compare:nNnTF {#1} = {#2}
       {
         \exp_last_unbraced:Nf \@@_split_final_cleanup:nn
-          { \split:n { \@@_split_guard:n {#3} #4 } }
+          { \@@_split:n { \@@_split_guard:n {#3} #4 } }
       }
       {
         \exp_args:No \use_ii_i:nn
@@ -1184,29 +2163,17 @@
       { \exp_end: { #4 #1 } }
       { \@@_split_final_cleanup:w #3 \s_mark { #4 #1 #2 } }
   }
-\NewDocumentCommand \splitnl { mm +m }
-  {
-    \tl_set:Nf \l_tmpa_tl { \split:n {#3} }
-    \show \l_tmpa_tl
-    \exp_after:wN \__splitnl_aux:nnNN \l_tmpa_tl #1 #2
-  }
-
-
-\cs_new:Npn \split:n #1 {
+  
+\cs_new:Npn \@@_split:n #1 {
     \@@_split_at_nl_first:w #1 \\ \q_nil \\ \s_stop }
-
-\cs_new:Npn \@@_split_at_nl:NN #1#2 {
-  \tl_set:Nf \l_tmpa_tl {
-      \exp_after:wN \@@_split_at_nl_first:w #1 \\ \q_nil \\ \s_stop }
-  \exp_after:wN \@@_split_at_nl_aux:nnNN \l_tmpa_tl #1 #2
-}
-
-\cs_new_protected:Npn \@@_split_at_nl_aux:nnNN #1 #2 #3 #4
-  {
-    \tl_gset:Nn #4 {#1}
-    \tl_gset:Nn #3 {#2}
-}
-
+  
+% this looks unused.  
+%\NewDocumentCommand \splitnl { mm +m }
+%  {
+%    \tl_set:Nf \l_@@_tmpa_tl { \split:n {#3} }
+%    \show \l_@@_tmpa_tl
+%    \exp_after:wN \__splitnl_aux:nnNN \l_@@_tmpa_tl #1 #2
+%  }
 %    \end{macrocode}
 %  \end{macro}
 %
@@ -1233,9 +2200,11 @@
        \edef\resulttitle{\g_@@_grabbed_env_tl\space (part)}
        \tagstructbegin{tag=Formula,
 %    \end{macrocode}
-%    For now we don't put anything in /alt or /ActualText on subformulas
+%    For now we don't put real content in /alt or /ActualText on subformulas
+%    but we add a short text to satisfy the pdf/ua-2 validator
 %    \begin{macrocode}
 %         alt=\result,
+         alt = subformula,         
          title-o=\resulttitle
        }
     }
@@ -1301,10 +2270,6 @@
 %    \end{macrocode}
 %    
 %    \begin{macrocode}
-%
-%    \end{macrocode}
-%
-%    \begin{macrocode}
 %</kernel>
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathpkg.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathpkg.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathpkg.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -2,7 +2,7 @@
 %
 %% File: latex-lab-mathpkg.dtx
 %
-% Copyright (C) 2022,2023 The LaTeX Project
+% Copyright (C) 2022-2024 The LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -68,16 +68,9 @@
 \ProvidesFile{latex-lab-mathpkg.ltx}
         [2023-01-05 v0.1a mathpkg adaptions]
 %    \end{macrocode}
-% \subsection{Tagpdf support}
-% To make the code independent from tagging being loaded and active
-% we load the \pkg{tagpdf-base} package:
 %
+% \subsection{breqn}
 %    \begin{macrocode}
-\RequirePackage{tagpdf-base}
-%    \end{macrocode}
-% 
-%
-%    \begin{macrocode}
 \AddToHook{package/breqn/after}{
    \RegisterMathEnvironment{dmath}
    \RegisterMathEnvironment{dgroup*}
@@ -86,6 +79,7 @@
 }
 %    \end{macrocode}
 %
+% \subsection{cases}
 % Force loading of \pkg{amsmath} before \pkg{cases}.
 %    \begin{macrocode}
 \AddToHook {package/cases/before}{\RequirePackage{amsmath}}
@@ -94,7 +88,30 @@
 }  
 %    \end{macrocode}
 %    
+% \subsection{bm}
+% Similar to the amsbsy code in latex-lab-amsmath for \cs{pmb} we need to mark up 
+% copies as artifact:
+% 
 %    \begin{macrocode}
+\ExplSyntaxOn
+\AddToHook{package/bm/after}
+ {
+   \def\bm at pmb@@@@#1#2#3{{%
+     \hbox_set:Nn\l_@@_tmpa_box{$\m at th#1#3$}%
+     \dimen@#2\wd\tw@
+     \rlap{\box_use:N\l_@@_tmpa_box}%
+     \tag_mc_end:\tag_mc_begin:n{artifact}
+     \tag_mc_reset_box:N\l_@@_tmpa_box
+     \kern\dimen@
+     \raise1.5\dimen@\rlap{\box_use:N\l_@@_tmpa_box}%
+     \kern\dimen@
+     \box_use_drop:N\l_@@_tmpa_box
+     \tag_mc_end:\tag_mc_begin:n{}%
+     }}
+ }
+\ExplSyntaxOff 
+%    \end{macrocode}
+%    \begin{macrocode}
 %</kernel>
 %    \end{macrocode}
 % \subsection{Wrapper files for testphase key}

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathtools.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathtools.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-mathtools.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -2,7 +2,7 @@
 %
 %% File: latex-lab-mathtools.dtx
 %
-% Copyright (C) 2022,2023 The LaTeX Project
+% Copyright (C) 2022-2024 The LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -109,7 +109,7 @@
      \def\intertext##1{%
        \ifvmode\else\\\@empty\fi
        \noalign{%
-         \penalty\postdisplaypenalty\vskip\belowdisplayskip
+         \penalty\postdisplaypenalty\vskip-\belowdisplayskip
          \vskip-\lineskiplimit      % CCS
          \vskip\normallineskiplimit % CCS
          \vskip\l_MT_above_intertext_sep
@@ -135,7 +135,7 @@
 %    \end{macrocode}
 % We are already in a par so we change now to Span:
 %    \begin{macrocode}
-            \tagpdfsetup{paratag=Span}
+            \tagpdfsetup{para/tag=Span}
             \noindent\ignorespaces##1\par
 %    \end{macrocode}
 % Restart the MC
@@ -169,7 +169,8 @@
             \parshape\@ne \@totalleftmargin \linewidth
           \MH_fi:
           \tag_mc_end_push:
-          \tagpdfsetup{paratag=Span}
+          \tagpdfsetup{para/tag=Span}
+          \tagpdfparaOn
           \noindent\ignorespaces#1\par
           \tag_mc_begin_pop:n{}}
         \penalty\predisplaypenalty\vskip\abovedisplayshortskip%
@@ -197,7 +198,11 @@
            \parshape\@ne \@totalleftmargin \linewidth
          \MH_fi:
          \tag_mc_end_push:
-         \tagpdfsetup{paratag=Span}
+         \tagpdfsetup{para/tag=P}
+%    \end{macrocode}
+% Why is it needed to enable paratagging??
+%    \begin{macrocode}
+         \tagpdfparaOn
          \noindent\ignorespaces#1\par
          \tag_mc_begin_pop:n{}}%
        \penalty\predisplaypenalty\vskip\abovedisplayshortskip%

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-minipage.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-minipage.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-minipage.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,8 @@
 % \iffalse meta-comment
 %
-%% File: latex-lab-minipage.dtx (C) Copyright 2023 LaTeX Project
+%% File: latex-lab-minipage.dtx 
+%% 
+% Copyright (C) 2023-2024 LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-namespace.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-namespace.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-namespace.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,8 @@
 % \iffalse meta-comment
 %
-%% File: latex-lab-namespace.dtx (C) Copyright 2023 LaTeX Project
+%% File: latex-lab-namespace.dtx 
+%% 
+% Copyright (C) 2023-2024 LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -24,7 +26,7 @@
 % \fi
 % \title{Prototype reimplementation of \LaTeXe{}'s role mapping}
 % \author{\LaTeX{} Project, initial implementation Ulrike Fischer}
-% \date{v0.8 2023-09-04}
+% \date{v0.8b 2024-03-24}
 %
 % \maketitle
 %
@@ -60,11 +62,26 @@
 %    \begin{macrocode}
 title,        Title,    pdf2,
 part,         Title,    pdf2,
+%    \end{macrocode}
+%    Headings differ in article and book class. This here is for article:
+%    \begin{macrocode}
 section,      H1,       pdf2, 
 subsection,   H2,       pdf2,
 subsubsection,H3,       pdf2,
 paragraph,    H4,       pdf2, 
 subparagraph, H5,       pdf2,
+%    \end{macrocode}
+%    And this here is used in book:
+%    \begin{macrocode}
+%chapter,       H1,      pdf2,
+%section,       H2,      pdf2,
+%subsection,    H3,      pdf2,
+%subsubsection, H4,      pdf2,
+%paragraph,     H5,      pdf2,
+%subparagraph,  H6,      pdf2,
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 list,         L,        pdf2,
 itemize,      L,        pdf2,
 enumerate,    L,        pdf2,
@@ -71,7 +88,7 @@
 description,  L,        pdf2,
 quote,        BlockQuote,pdf,
 quotation,    BlockQuote,pdf,
-verbatim,     Div,      pdf2, 
+verbatim,     Div,      pdf2,  % overwritten by block
 item,         LI,       pdf2,
 itemlabel,    Lbl,      pdf2,
 itembody,     LBody,    pdf2,

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-1.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-1.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-1.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-%% File: latex-lab-new-or-1.dtx (C) Copyright 2020-2023 Frank Mittelbach
+%% File: latex-lab-new-or-1.dtx (C) Copyright 2020-2024 Frank Mittelbach
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-2.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-2.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-new-or-2.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
 %% File: latex-lab-new-or-2.dtx
-% Copyright (C) 2022-2023 The LaTeX Project
+% Copyright (C) 2022-2024 The LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-sec.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-sec.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-sec.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-%% File: latex-lab-sec.dtx (C) Copyright 2022-2023 LaTeX Project
+%% File: latex-lab-sec.dtx (C) Copyright 2022-2024 LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -16,10 +16,10 @@
 %
 % for those people who are interested or want to report an issue.
 %
-\def\ltlabsecdate{2023-10-16}
-\def\ltlabsecversion{0.84b}
+\def\ltlabsecdate{2024-02-12}
+\def\ltlabsecversion{0.84c}
 %<*driver>
-\documentclass{l3doc}
+\documentclass[kernel]{l3doc}
 \EnableCrossrefs
 \CodelineIndex
 \begin{document}
@@ -214,11 +214,11 @@
   \fi
   \IfBooleanTF {#1}
    {
-     \tl_gset:Nx \@currentHref {#3}
+     \tl_gset:Ne \@currentHref {#3}
    }
    {
      \int_gincr:N\g__kernel_target_int
-     \tl_gset:Nx \@currentHref {target*.\int_use:N\g__kernel_target_int}
+     \tl_gset:Ne \@currentHref {target*.\int_use:N\g__kernel_target_int}
    }  
  }
 \ExplSyntaxOff 
@@ -260,7 +260,7 @@
          tag= {\int_compare:nNnTF {#1}={-1}{Part}{Sect}}
         ,#2
       } 
-    \seq_gpush:Nx \g__tag_sec_stack_seq {{\g__tag_struct_tag_tl}{\int_eval:n{#1}}}    
+    \seq_gpush:Ne \g__tag_sec_stack_seq {{\g__tag_struct_tag_tl}{\int_eval:n{#1}}}    
   }
 %    \end{macrocode}
 % \end{macro}
@@ -289,7 +289,7 @@
               \__tag_sec_end:n {#1}        
             }
             { 
-              \msg_warning:nnxx {tag}{wrong-sect-nesting}
+              \msg_warning:nnee {tag}{wrong-sect-nesting}
                { \exp_last_unbraced:NV\use_i:nn \l__tag_tmpa_tl }
                { \exp_last_unbraced:NV\use_i:nn \l__tag_tmpb_tl } 
             }
@@ -670,6 +670,7 @@
 \cs_new_protected:Npn \@kernel at tag@hangfrom #1
   {
      \tagstructbegin{tag=\l__tag_para_tag_tl}
+     \cs_if_exist_use:N \__tag_gincr_para_begin_int:
      \tagstructbegin{tag=Lbl}
      \setbox\@tempboxa
        \hbox

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-table.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-table.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-table.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-%% File: latex-lab-table.dtx (C) Copyright 2023 LaTeX Project
+%% File: latex-lab-table.dtx (C) Copyright 2023-2024 LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -16,8 +16,8 @@
 %
 % for those people who are interested or want to report an issue.
 %
-\def\ltlabtbldate{2023-10-30}
-\def\ltlabtblversion{0.85d}
+\def\ltlabtbldate{2024-05-25}
+\def\ltlabtblversion{0.85i}
 %<*driver>
 \documentclass{l3doc}
 \EnableCrossrefs
@@ -115,9 +115,20 @@
 % Such tables can be nested. 
 %
 % If a table should not be tagged as table, for example because it is merely used
-% to produce a layout or because it is a not yet (fully) supported table structure, 
+% as a layout to ensure that the content is properly aligned
+% or because it is a not yet (fully) supported table structure, 
 % the tagging can be disabled with
-%  \verb|\tagpdfsetup{table-tagging=false}|.
+% \verb|\tagpdfsetup{table/tagging=false}| or with \verb|\tagpdfsetup{table/tagging=presentation}|%
+% \footnote{The key has been renamed. The old name `table-tagging` still works but is 
+% deprecated. The value \texttt{presentation} refers to the ARIA role \enquote{presentation}.}
+% The first option disables the table tagging code and the content of the tabular
+% is then treated more or less like running text. This works ok for simple tables using
+% only hmode-cells (l/c/r) with normal text content, but fails if the table uses vmode-cells
+% (p/m/b). In such cases the second option works better: it keeps the tagging code active
+% but changes the tag names to \texttt{Div} and the grouping structure \texttt{NonStruct}. It also
+% (re)sets the \texttt{table/header-rows} key to empty. 
+% The key should currently only be used in a group as there is no key (yet) to reset to the default 
+% tag names.
 %
 % Inside cells the automatic tagging of paragraphs is disabled with the exception of
 % p/m/b-type cells. 
@@ -126,9 +137,10 @@
 % added with an empty TD-structure.
 %
 % There is some basic support\footnote{This is not meant to be the
-% final interface, though.} for headers. With
+% final interface, though.} for headers. With\footnote{The old key name \texttt{table-header-rows} still
+% works but is deprecated.}
 % \begin{quote}
-%   \verb|\tagpdfsetup{table-header-rows={|\meta{list of row numbers}\verb|}|
+%   \verb|\tagpdfsetup{table/header-rows={|\meta{list of row numbers}\verb|}|
 % \end{quote}
 % you can
 % declare which (absolute) row numbers should be tagged as header rows.
@@ -139,7 +151,7 @@
 % for header columns yet. In a \env{longtable} the code will currently use the \cs{endhead} or
 % \cs{endfirsthead} rows as header if one of these commands has been
 % used and in that case the code
-% ignores a \texttt{table-header-rows} setting.
+% ignores a \texttt{table/header-rows} setting.
 %
 % You should not insert meaningful text with \verb+!{...}+ or \verb+@{...}+ or \cs{noalign}
 % between the rows or columns of the table.
@@ -193,7 +205,8 @@
 %
 % \item Not every table should be tagged as a Table structure, often they are
 % only used as layout help, e.g. to align authors in a title pages. In such uses
-% the tagging of the table must be deactivated with \verb|\tagpdfsetup{table-tagging=false}|.
+% the tagging of the table must be deactivated with \verb|\tagpdfsetup{table/tagging=false}|
+% or \verb|\tagpdfsetup{table/tagging=presentation}|.
 %
 % \item Only simple header rows are currently supported. Columns and complex headers with
 % subheaders will be handled later as that needs some syntax changes. Tables
@@ -210,6 +223,8 @@
 % 
 % \item The \env{longtable} environment supports footnotes in p-type columns, but it hasn't been
 % tested yet if this works also with the tagging code. 
+% 
+% \item Vertical boxes (\cs{parbox}, \texttt{minipage}, \ldots) inside cells can be problematic. 
 %
 % \item The code is quite noisy and fills the log with lots of
 %   messages.\footnote{Helpful for us at this stage.}
@@ -271,10 +286,11 @@
 % \begin{macro}
 %  {
 %    \l_@@_celltag_tl
+%    \l_@@_pcelltag_tl
 %   ,\l_@@_rowtag_tl
+%   ,\l_@@_table_tl
 %   ,\l_@@_cellattribute_tl
 %   ,\l_@@_rowattribute_tl
-%   ,\g_@@_missingcells_int
 %   ,\l_@@_tmpa_clist
 %   ,\l_@@_tmpa_seq
 %   ,\l_@@_tmpa_tl
@@ -283,6 +299,8 @@
 %    \begin{macrocode}
 \tl_new:N  \l_@@_celltag_tl
 \tl_set:Nn \l_@@_celltag_tl {TD}
+\tl_new:N  \l_@@_pcelltag_tl
+\tl_set:Nn \l_@@_pcelltag_tl {TD}
 %    \end{macrocode}
 %    For the rowtag, probably always TR:
 %    \begin{macrocode}
@@ -289,6 +307,11 @@
 \tl_new:N  \l_@@_rowtag_tl
 \tl_set:Nn \l_@@_rowtag_tl {TR}
 %    \end{macrocode}
+%    For the tabletag, probably always Table:
+%    \begin{macrocode}
+\tl_new:N  \l_@@_tabletag_tl
+\tl_set:Nn \l_@@_tabletag_tl {Table}
+%    \end{macrocode}
 %    And here cell and row attributes:
 %    \begin{macrocode}
 \tl_new:N  \l_@@_cellattribute_tl
@@ -296,94 +319,27 @@
 \tl_new:N  \l_@@_rowattribute_tl
 \tl_set:Nn \l_@@_rowattribute_tl {}
 %    \end{macrocode}
-% This will contain the number of missing cells used:
-%    \begin{macrocode}
-\int_new:N \g_@@_missing_cells_int
-%    \end{macrocode}
 % Temp variables
 %    \begin{macrocode}
 \clist_new:N \l_@@_tmpa_clist
-\seq_new:N \l_@@_tmpa_seq
 \tl_new:N \l_@@_tmpa_tl
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{Sockets}
+% \subsection{Tagging support sockets}
 %
-% The code uses a number of sockets to inject the tagging
-% commands. These can be easily set to a noop-plug in case the
-% automated tagging is not wanted At first sockets for the begin and
-% end of cells and rows
 %
-% \begin{socketdecl}{tagsupport/tblcell/begin,
-%                    tagsupport/tblcell/end,
-%                    tagsupport/tblrow/begin,
-%                    tagsupport/tblrow/end,
-%                   }
-%    \begin{macrocode}
-\NewSocket{tagsupport/tblcell/begin}{0}
-\NewSocket{tagsupport/tblcell/end}{0}
-\NewSocket{tagsupport/tblrow/begin}{0}
-\NewSocket{tagsupport/tblrow/end}{0}
-%    \end{macrocode}
-% \end{socketdecl}
-%
-% \begin{socketdecl}{tagsupport/tbl/init}
-%    This socket should be at the begin of the table, inside a group.
-%    It is meant for settings like disabling paratagging.  This socket
-%    can perhaps be merged later into the begin-sockets when they are
-%    no longer added as hooks but in the environment definitions.
-%    \begin{macrocode}
-\NewSocket{tagsupport/tbl/init}{0}
-%    \end{macrocode}
-% \end{socketdecl}
-%
-%
-% \begin{socketdecl}{tagsupport/tbl/finalize}
-%    To fine tune the structure (change cells to header cells, remove
-%    unwanted structures, move a foot to the end, etc.) we also need a
-%    socket that is executed at the end of the table but \emph{before}
-%    all the variables are restored to the outer or default values.
-%    The code in the socket can make assignments, but probably
-%    shouldn't do typesetting and not write whatsits.
-%    \begin{macrocode}
-\NewSocket{tagsupport/tbl/finalize}{0}
-%    \end{macrocode}
-% \end{socketdecl}
-%
-% \begin{socketdecl}{tagsupport/tbl/finalize/longtable}
-%    \env{longtable} needs its own socket to fine tune the structure.
-%    Simply switching the plug in the previous socket interferes with
-%    enabling/disabling the tagging.
-%    \begin{macrocode}
-\NewSocket{tagsupport/tbl/finalize/longtable}{0}
-%    \end{macrocode}
-% \end{socketdecl}
-%
-% \begin{socketdecl}{tagsupport/tblhmode/begin,
-%                    tagsupport/tblhmode/end,
-%                    tagsupport/tblvmode/begin,
-%                    tagsupport/tblvmode/end
-%                   }
-%
-%    These sockets are used in the begin and end code of environments,
-%    to allow a fast enabling and disabling of the tagging. We
-%    distinguish between tables that can be used inside paragraphs and
-%    standalone tables like longtable.
-%    \begin{macrocode}
-\NewSocket{tagsupport/tblhmode/begin}{0}
-\NewSocket{tagsupport/tblhmode/end}{0}
-\NewSocket{tagsupport/tblvmode/begin}{0}
-\NewSocket{tagsupport/tblvmode/end}{0}
-%    \end{macrocode}
-% \end{socketdecl}
-%
 % This are the standard plugs for tagging of cells and rows.
 %
 % \begin{plugdecl}{TD}
 %    \begin{macrocode}
-\NewSocketPlug{tagsupport/tblcell/begin}{TD}
+\NewSocketPlug{tagsupport/tbl/cell/begin}{TD}
   {
+%    \end{macrocode}
+%    Next line was previously outside of the plug, so if we want to execute it
+%    always even if the noop plug is in force this needs a different solution.
+%    \begin{macrocode}
+    \@@_show_curr_cell_data:
     \tag_struct_begin:n
       {
         tag             =\l_@@_celltag_tl,
@@ -405,7 +361,7 @@
 %
 % \begin{plugdecl}{TD}
 %    \begin{macrocode}
-\NewSocketPlug{tagsupport/tblcell/end}{TD}
+\NewSocketPlug{tagsupport/tbl/cell/end}{TD}
   {
     \tag_mc_end:
     \tag_struct_end:
@@ -415,14 +371,14 @@
 % 
 %    In p-columns we need a slightly different plug which reactivates the
 %    paragraph tagging.
-% tagging
-% \begin{plugdecl}{TD}
+% \begin{plugdecl}{TDpbox}
 %    \begin{macrocode}
-\NewSocketPlug{tagsupport/tblcell/begin}{TDpbox}
+\NewSocketPlug{tagsupport/tbl/pcell/begin}{TDpbox}
   {
+    \@@_show_curr_cell_data:
     \tag_struct_begin:n
       {
-        tag             =\l__tbl_celltag_tl,
+        tag             =\l__tbl_pcelltag_tl,
         attribute-class =\l__tbl_cellattribute_tl
       }
     \seq_gput_right:Ne \g__tbl_struct_cur_seq { \tag_get:n {struct_num} }
@@ -436,9 +392,9 @@
 %    \end{macrocode}
 % \end{plugdecl}
 % 
-% \begin{plugdecl}{TD}
+% \begin{plugdecl}{TDpbox}
 %    \begin{macrocode}
-\NewSocketPlug{tagsupport/tblcell/end}{TDpbox}
+\NewSocketPlug{tagsupport/tbl/pcell/end}{TDpbox}
   {
     \tag_struct_end:
   }  
@@ -447,7 +403,7 @@
 %
 % \begin{plugdecl}{TR}
 %    \begin{macrocode}
-\NewSocketPlug{tagsupport/tblrow/begin}{TR}
+\NewSocketPlug{tagsupport/tbl/row/begin}{TR}
   {
     \seq_gclear:N \g_@@_struct_cur_seq
     \tag_struct_begin:n
@@ -462,24 +418,28 @@
 %
 % \begin{plugdecl}{TR}
 %    \begin{macrocode}
-\NewSocketPlug{tagsupport/tblrow/end}{TR}
+\NewSocketPlug{tagsupport/tbl/row/end}{TR}
   {
-    \__tag_tbl_add_missing_cells:n { \g_@@_missing_cells_int }
+    \tag_if_active:T
+      {
+    \@@_add_missing_cells:
     \seq_gput_right:Ne \g_@@_struct_cells_seq
       {
         \seq_use:Nn \g_@@_struct_cur_seq {,}
       }
-    \int_compare:nNnTF { \g_@@_row_int } = { \seq_count:N\g_@@_struct_cells_seq }
+    \int_compare:nNnTF { \g_@@_row_int } =
+                       { \seq_count:N \g_@@_struct_cells_seq }
       {
-        \typeout
+        \@@_trace:n
           {==>~
             stucture~stored~for~row~\int_use:N\g_@@_row_int :~
             \seq_use:Nn \g_@@_struct_cur_seq {,}
           }
       }
-      { \ERROR } % should not happen ...
+      { \ERRORtbl/row } % should not happen ...
     \tag_struct_end:
   }
+  }
 %    \end{macrocode}
 % \end{plugdecl}
 %
@@ -497,6 +457,10 @@
     \tag_if_active:T
       {
         \bool_set_false:N \l__tag_para_bool
+%    \end{macrocode}
+%    We also initialize the structure data variables a this point.
+%    \begin{macrocode}
+        \@@_init_struct_data:
       }
   }
 %    \end{macrocode}
@@ -509,14 +473,41 @@
 \NewSocketPlug{tagsupport/tbl/finalize}{Table}
   {
     \@@_set_header_rows:
+%    \end{macrocode}
+%    Similarly, we restore the outer values of the structure data when
+%    we leave the table.
+%    \begin{macrocode}
+    \@@_restore_struct_data:
   }
 %    \end{macrocode}
 % \end{plugdecl}
 %
+%
+%
+%
 % \begin{plugdecl}{Table}
-%  This plug will fine tune the structure of longtable.
+%  This plug will initialize the structure in longtable.
 %    \begin{macrocode}
-\NewSocketPlug{tagsupport/tbl/finalize/longtable}{Table}
+\NewSocketPlug{tagsupport/tbl/longtable/init}{Table}
+ {
+   \seq_gclear:N\g_@@_struct_rows_seq
+   \seq_gclear:N\g_@@_struct_cells_seq
+   \seq_gclear:N\g_@@_struct_cur_seq
+   \seq_gclear:N\g_@@_LT at firsthead_rows_seq
+   \seq_gclear:N\g_@@_LT at head_rows_seq
+   \seq_gclear:N\g_@@_LT at lastfoot_rows_seq
+   \seq_gclear:N\g_@@_LT at foot_rows_seq
+ }
+%    \end{macrocode}
+% \end{plugdecl}
+%
+%
+
+
+% \begin{plugdecl}{Table}
+%  This plug will fine tune the structure in longtable.
+%    \begin{macrocode}
+\NewSocketPlug{tagsupport/tbl/longtable/finalize}{Table}
   {
 %    \end{macrocode}
 %    If neither \cs{endhead} nor \cs{endfirsthead} has been used
@@ -582,7 +573,7 @@
                     \prop_if_exist:cT
                       { g__tag_struct_ \l_@@_tmpa_tl _prop }
                       {
-                        \@@_struct_prop_gput:Vnn \l_@@_tmpa_tl {S}{/Artifact}
+                        \exp_args:No \__tag_struct_prop_gput:nnn {\l_@@_tmpa_tl} {S}{/Artifact}
                       }
                    }
                }
@@ -673,7 +664,7 @@
                     \prop_if_exist:cT
                       { g__tag_struct_ \l_@@_tmpa_tl _prop }
                       {
-                        \@@_struct_prop_gput:Vnn \l_@@_tmpa_tl {S}{/Artifact}
+                        \exp_args:No\__tag_struct_prop_gput:nnn {\l_@@_tmpa_tl} {S}{/Artifact}
                       }
                    }
                }
@@ -683,11 +674,40 @@
 %    \end{macrocode}
 % \end{plugdecl}
 %
+%
+%
 % \begin{plugdecl}{Table}
+%  
+%    We must avoid that the reuse of the header foot box leads to duplicated
+%    content, thus reset attribute of the box:
 %    \begin{macrocode}
-\NewSocketPlug{tagsupport/tblhmode/begin}{Table}
+\NewSocketPlug{tagsupport/tbl/longtable/head}{Table}
+ {
+  \tagmcbegin{artifact}
+   \tag_mc_reset_box:N\LT at head
+  \tagmcend
+ }
+%    \end{macrocode}
+% \end{plugdecl}
+%
+% \begin{plugdecl}{Table}
+%    \begin{macrocode}
+\NewSocketPlug{tagsupport/tbl/longtable/foot}{Table}
+ {
+   \tagmcbegin{artifact}
+   \tag_mc_reset_box:N \LT at foot
+   \tagmcend
+ }
+%    \end{macrocode}
+% \end{plugdecl}
+%
+%
+%
+%
+% \begin{plugdecl}{Table}
+%    \begin{macrocode}
+\NewSocketPlug{tagsupport/tbl/hmode/begin}{Table}
   {
-    \mode_leave_vertical:
     \tag_mc_end_push:
 %    \end{macrocode}
 %    Close the P-chunk. This assumes that para-tagging is active.
@@ -696,7 +716,7 @@
      \bool_lazy_and:nnT
       { \bool_if_exist_p:N \l__tag_para_bool } { \l__tag_para_bool }
       { \tag_struct_end:n { text } }
-    \tag_struct_begin:n {tag=Table}
+    \tag_struct_begin:n {tag=\l_@@_tabletag_tl}
     \tl_gset:Ne \g_@@_struct_table_tl { \tag_get:n {struct_num} }
   }
 %    \end{macrocode}
@@ -704,7 +724,7 @@
 %
 % \begin{plugdecl}{Table}
 %    \begin{macrocode}
-\NewSocketPlug{tagsupport/tblhmode/end}{Table}
+\NewSocketPlug{tagsupport/tbl/hmode/end}{Table}
   {
     \tag_struct_end:
 %    \end{macrocode}
@@ -721,9 +741,9 @@
 %
 % \begin{plugdecl}{Table}
 %    \begin{macrocode}
-\NewSocketPlug{tagsupport/tblvmode/begin}{Table}
+\NewSocketPlug{tagsupport/tbl/vmode/begin}{Table}
   {
-    \tag_struct_begin:n {tag=Table}
+    \tag_struct_begin:n {tag=\l_@@_tabletag_tl}
     \tl_gset:Ne \g_@@_struct_table_tl { \tag_get:n {struct_num} }
   }
 %    \end{macrocode}
@@ -731,7 +751,7 @@
 %
 % \begin{plugdecl}{Table}
 %    \begin{macrocode}
-\NewSocketPlug{tagsupport/tblvmode/end}{Table}
+\NewSocketPlug{tagsupport/tbl/vmode/end}{Table}
   {
     \tag_struct_end:
     \par
@@ -740,30 +760,50 @@
 % \end{plugdecl}
 %
 %
+% \begin{plugdecl}{code}
+%    This socket takes a number, checks if is larger than one,
+%    checks if the colspan attribute already exists (we can't predefine an
+%    arbitrary number), and updates \cs{l_@@_cellattribute_tl}.
+%    \begin{macrocode}
+\NewSocketPlug{tagsupport/tbl/colspan}{code}
+  {
+    \int_compare:nNnT {#1}>{1}
+     {
+       \prop_get:NeNF \g__tag_attr_entries_prop
+          {colspan-\int_eval:n{#1}}
+          \l_@@_tmpa_tl
+          {
+            \__tag_attr_new_entry:ee
+              {colspan-\int_eval:n{#1}}
+              {/O /Table /ColSpan~\int_eval:n{#1}}
+          }
+       \tl_set:Ne \l_@@_cellattribute_tl
+          {colspan-\int_eval:n{#1}}
+     }
+  }
+%    \end{macrocode}
+%    TODO: move to tagpdf
+%    \begin{macrocode}
+\tag_if_active:T
+  { \cs_generate_variant:Nn \__tag_attr_new_entry:nn {ee} }
+
+%    \end{macrocode}
+% \end{plugdecl}
 %
 %
 %
 %\subsection{Environments}
 %
-% Currently only tabular, tabular*, tabularx and longtable.
-% We must use the \texttt{before} and \texttt{after} hooks as the \texttt{end}
-% hook is executed before the end of the last row and then MC are messed up.
-% This means that this sockets should only contain code that doesn't needs to be
-% grouped!
-%    \begin{macrocode}
-\AddToHook{env/tabular/before}  {\UseSocket{tagsupport/tblhmode/begin}}
-\AddToHook{env/tabular/after}   {\UseSocket{tagsupport/tblhmode/end}}
-\AddToHook{env/tabular*/before} {\UseSocket{tagsupport/tblhmode/begin}}
-\AddToHook{env/tabular*/after}  {\UseSocket{tagsupport/tblhmode/end}}
-\AddToHook{env/tabularx/before} {\UseSocket{tagsupport/tblhmode/begin}}
-\AddToHook{env/tabularx/after}  {\UseSocket{tagsupport/tblhmode/end}}
-\AddToHook{env/longtable/before}{\UseSocket{tagsupport/tblvmode/begin}}
-\AddToHook{env/longtable/after} {\UseSocket{tagsupport/tblvmode/end}}
-%    \end{macrocode}
+% Currently we support only tabular, tabular*, tabularx and longtable
+% (and possibly environments build directly on top of them). 
 %
 % The \env{array} environment is math. So we disable table tagging for now.
+% We use the command hook to catch also cases where \cs{array} is used directly
+% in other environments like matrix environments.
+% Perhaps table tagging should be disable for math generally, but then
+% we have to handle text insertions. 
 %    \begin{macrocode}
-\AddToHook{env/array/begin} {\__tag_tbl_disable:}
+\AddToHook{cmd/array/before}{\__tag_tbl_disable:}
 %    \end{macrocode}
 %
 %
@@ -771,34 +811,6 @@
 %
 % \subsubsection{Tagging helper commands}
 %
-% \begin{macro}{\@@_set_colspan:n}
-%    This commands takes a number, checks if is larger than one,
-%    checks if the colspan attribute exists (we can't predefine an
-%    arbitrary number), and updates \cs{l_@@_cellattribute_tl}.
-%    \begin{macrocode}
-\tag_if_active:T
-  { \cs_generate_variant:Nn \__tag_attr_new_entry:nn {ee} }
-\cs_new_protected:Npn \@@_set_colspan:n #1
-  {
-    \tag_if_active:T
-      {
-        \int_compare:nNnT {#1}>{1}
-         {
-           \prop_get:NeNF \g__tag_attr_entries_prop
-              {colspan-\int_eval:n{#1}}
-              \l_@@_tmpa_tl
-              {
-                \__tag_attr_new_entry:ee
-                  {colspan-\int_eval:n{#1}}
-                  {/O /Table /ColSpan~\int_eval:n{#1}}
-              }
-           \tl_set:Ne \l_@@_cellattribute_tl
-              {colspan-\int_eval:n{#1}}
-         }
-      }
-  }
-%    \end{macrocode}
-% \end{macro}
 %
 % \subsubsection{Disabling/enabling}
 %
@@ -810,17 +822,23 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \__tag_tbl_disable:
  {
-   \AssignSocketPlug{tagsupport/tblcell/begin}{noop}
-   \AssignSocketPlug{tagsupport/tblcell/end}{noop}
-   \AssignSocketPlug{tagsupport/tblrow/begin}{noop}
-   \AssignSocketPlug{tagsupport/tblrow/end}{noop}
+   \AssignSocketPlug{tagsupport/tbl/cell/begin}{noop}
+   \AssignSocketPlug{tagsupport/tbl/cell/end}{noop}
+   \AssignSocketPlug{tagsupport/tbl/pcell/begin}{noop}
+   \AssignSocketPlug{tagsupport/tbl/pcell/end}{noop}
+   \AssignSocketPlug{tagsupport/tbl/row/begin}{noop}
+   \AssignSocketPlug{tagsupport/tbl/row/end}{noop}
    \AssignSocketPlug{tagsupport/tbl/init}{noop}
    \AssignSocketPlug{tagsupport/tbl/finalize}{noop}
-   \AssignSocketPlug{tagsupport/tbl/finalize/longtable}{noop}
-   \AssignSocketPlug{tagsupport/tblhmode/begin}{noop}
-   \AssignSocketPlug{tagsupport/tblhmode/end}{noop}
-   \AssignSocketPlug{tagsupport/tblvmode/begin}{noop}
-   \AssignSocketPlug{tagsupport/tblvmode/end}{noop}
+   \AssignSocketPlug{tagsupport/tbl/longtable/init}{noop}
+   \AssignSocketPlug{tagsupport/tbl/longtable/head}{noop}
+   \AssignSocketPlug{tagsupport/tbl/longtable/foot}{noop}
+   \AssignSocketPlug{tagsupport/tbl/longtable/finalize}{noop}
+   \AssignSocketPlug{tagsupport/tbl/hmode/begin}{noop}
+   \AssignSocketPlug{tagsupport/tbl/hmode/end}{noop}
+   \AssignSocketPlug{tagsupport/tbl/vmode/begin}{noop}
+   \AssignSocketPlug{tagsupport/tbl/vmode/end}{noop}
+   \AssignSocketPlug{tagsupport/tbl/colspan}{noop}
  }
 %    \end{macrocode}
 %  \end{macro}
@@ -831,46 +849,59 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \__tag_tbl_enable:
  {
-   \AssignSocketPlug{tagsupport/tblcell/begin}{TD}
-   \AssignSocketPlug{tagsupport/tblcell/end}{TD}
-   \AssignSocketPlug{tagsupport/tblrow/begin}{TR}
-   \AssignSocketPlug{tagsupport/tblrow/end}{TR}
+   \AssignSocketPlug{tagsupport/tbl/cell/begin}{TD}
+   \AssignSocketPlug{tagsupport/tbl/cell/end}{TD}
+   \AssignSocketPlug{tagsupport/tbl/pcell/begin}{TDpbox}
+   \AssignSocketPlug{tagsupport/tbl/pcell/end}{TDpbox}
+   \AssignSocketPlug{tagsupport/tbl/row/begin}{TR}
+   \AssignSocketPlug{tagsupport/tbl/row/end}{TR}
    \AssignSocketPlug{tagsupport/tbl/init}{Table}
    \AssignSocketPlug{tagsupport/tbl/finalize}{Table}
-   \AssignSocketPlug{tagsupport/tbl/finalize/longtable}{Table}
-   \AssignSocketPlug{tagsupport/tblhmode/begin}{Table}
-   \AssignSocketPlug{tagsupport/tblhmode/end}{Table}
-   \AssignSocketPlug{tagsupport/tblvmode/begin}{Table}
-   \AssignSocketPlug{tagsupport/tblvmode/end}{Table}
+   \AssignSocketPlug{tagsupport/tbl/longtable/head}{Table}
+   \AssignSocketPlug{tagsupport/tbl/longtable/foot}{Table}
+   \AssignSocketPlug{tagsupport/tbl/longtable/init}{Table}
+   \AssignSocketPlug{tagsupport/tbl/longtable/finalize}{Table}
+   \AssignSocketPlug{tagsupport/tbl/hmode/begin}{Table}
+   \AssignSocketPlug{tagsupport/tbl/hmode/end}{Table}
+   \AssignSocketPlug{tagsupport/tbl/vmode/begin}{Table}
+   \AssignSocketPlug{tagsupport/tbl/vmode/end}{Table}
+   \AssignSocketPlug{tagsupport/tbl/colspan}{code}
  }
 %    \end{macrocode}
 %  \end{macro}
 
 %    \begin{macrocode}
-% TODO decide about key name
+% See tagpdfsetup-keys.md in tagpdf/doc for the naming scheme.
 \keys_define:nn { __tag / setup }
   {
-    table-tagging .choices:nn = { true, on }
+    table/tagging .choices:nn = { true, on }
       { \__tag_tbl_enable: },
-    table-tagging .choices:nn = { false, off }
+    table/tagging .choices:nn = { false, off }
       { \__tag_tbl_disable: },
-    table-tagging .default:n = true,
-    table-tagging .initial:n = true
+    table/tagging .choice:,
+    table/tagging / presentation .code:n = 
+     {
+       \__tag_tbl_enable:
+       \tl_set:Nn\l_@@_rowtag_tl   {NonStruct}
+       \tl_set:Nn\l_@@_pcelltag_tl {NonStruct}
+       \tl_set:Nn\l_@@_celltag_tl  {text}
+       \tl_set:Nn\l_@@_tabletag_tl {Div} 
+       \clist_clear:N \l_@@_header_rows_clist 
+     },  
+    table/tagging .default:n = true,
+    table/tagging .initial:n = true
   }
 %    \end{macrocode}
-%
-% Table tagging should be disabled in the head and foot.
+% This are the old key names kept for now for 
+% compability. They will got at some time.
 %    \begin{macrocode}
-\AddToHook{begindocument}
- {
-  \cs_if_exist:NT \@kernel at before@head
-   {
-     \tl_put_right:Nn \@kernel at before@head {\__tag_tbl_disable:}
-     \tl_put_right:Nn \@kernel at before@foot {\__tag_tbl_disable:}
-   }
- }
+\keys_define:nn { __tag / setup }
+  {
+    table-tagging .meta:n = {table/tagging={#1}}
+  }
 %    \end{macrocode}
 %
+%
 % \subsubsection{Header support}
 %
 % Accessible table must have header cells declaring the meaning of the
@@ -900,17 +931,17 @@
      {
        \tagpdfsetup
          {
-           newattribute =
+           role/new-attribute =
             {TH-col}{/O /Table /Scope /Column},
-           newattribute =
+           role/new-attribute =
              {TH-row}{/O /Table /Scope /Row},
-           newattribute =
+           role/new-attribute =
              {TH-both}{/O /Table /Scope /Both},
          }
 %    \end{macrocode}
 %
 % And we put all three into the class map (perhaps the next tagpdf
-% should do that directly with newattribute):
+% should do that directly with role/new-attribute):
 %
 %    \begin{macrocode}
          \seq_gput_left:Ne\g__tag_attr_class_used_seq
@@ -926,7 +957,7 @@
 %
 % \begin{variable}{\l_@@_header_rows_clist}
 %    This holds the numbers of the header rows. Negative numbers are
-%    possible and count from the back.
+%    possible and count from the last column backwards. 
 %    \begin{macrocode}
 \clist_new:N  \l_@@_header_rows_clist
 %    \end{macrocode}
@@ -933,22 +964,7 @@
 % \end{variable}
 %
 % \begin{macro}{\@@_set_header_rows:}
-%    TEMP: Next tagpdf will have the right command which also updates
-%    the debug info.
-%    For now a temporary command:
 %    \begin{macrocode}
-\cs_if_free:NTF \__tag_struct_prop_gput:nnn
-   {
-     \cs_new_protected:Npn \@@_struct_prop_gput:nnn #1#2#3
-       { \prop_gput:cnn { g__tag_struct_#1_prop }{#2}{#3} }
-   }
-   { \cs_new_protected:Npn  \@@_struct_prop_gput:nnn #1#2#3
-       { \__tag_struct_prop_gput:nnn {#1}{#2}{#3} }
-   }
-\cs_generate_variant:Nn \@@_struct_prop_gput:nnn {nne,Vnn}
-%    \end{macrocode}
-%
-%    \begin{macrocode}
 \cs_new_protected:Npn \@@_set_header_rows:
   {
     \clist_map_inline:Nn \l_@@_header_rows_clist
@@ -964,7 +980,7 @@
 %    \begin{macrocode}
             \prop_if_exist:cT { g__tag_struct_####1_prop }
               {
-                \@@_struct_prop_gput:nnn{ ####1 }{S}{/TH}
+                \__tag_struct_prop_gput:nnn{ ####1 }{S}{/TH}
 %    \end{macrocode}
 %    This need refinement once row headers (and perhaps other attributes)
 %    are used too, but for now it should be ok.
@@ -973,8 +989,8 @@
                   { g__tag_struct_####1_prop }
                   { C }
                   \l_@@_tmpa_tl
-                  {\@@_struct_prop_gput:nne{ ####1 }{C}{[/TH-col~\l_@@_tmpa_tl]} }
-                  {\@@_struct_prop_gput:nnn{ ####1 }{C}{/TH-col}}
+                  {\__tag_struct_prop_gput:nne{ ####1 }{C}{[/TH-col~\l_@@_tmpa_tl]} }
+                  {\__tag_struct_prop_gput:nnn{ ####1 }{C}{/TH-col}}
              }
           }
       }
@@ -983,17 +999,21 @@
 % \end{macro}
 %  
 % And some key support:
+% (See tagpdfsetup-keys.md for the naming scheme.) 
 %    \begin{macrocode}
-% TODO decide about key name
 \keys_define:nn { __tag / setup }
   {
-    table-header-rows .clist_set:N = \l_@@_header_rows_clist
+    table/header-rows .clist_set:N = \l_@@_header_rows_clist,
+%    \end{macrocode}
+% obsolete older name:
+%    \begin{macrocode}
+    table-header-rows .meta:n = {table/header-rows={#1}}
   }
 %    \end{macrocode}
 %
-% \subsection{Changes to \pkg{array} commands}
 %
 %
+% \subsection{Misc stuff}
 %
 %  \begin{macro}{\@@_show_curr_cell_data:}
 %    Show the row/column index and span count for current table cell
@@ -1000,11 +1020,11 @@
 %    for debugging.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_show_curr_cell_data: {
-   \typeout { ==>~ current~cell~data:~
-              \int_use:N \g_@@_row_int ,
-              \int_use:N \g_@@_col_int ,
-              \g_@@_span_tl
-            }
+   \@@_trace:n { ==>~ current~cell~data:~
+                 \int_use:N \g_@@_row_int ,
+                 \int_use:N \g_@@_col_int ,
+                 \g_@@_span_tl
+               }
 }
 %    \end{macrocode}
 %  \end{macro}
@@ -1011,234 +1031,37 @@
 %
 %
 %
-%
-% \begin{macro}{\insert at column}
-%    \cs{insert at column} is defined in \pkg{array}, here only the two
-%    sockets are inserted.
+%  \begin{macro}{\@@_add_missing_cells:}
+%    The storing and use of the number of missing cells must happen at
+%    different places as the testing happens at the end of the last
+%    cell of a row, but still inside that cell, so we use two
+%    commands. The one adding is used in the row/end socket.
 %    \begin{macrocode}
-\def\insert at column{%
-  \@@_show_curr_cell_data:
-  \UseSocket{tagsupport/tblcell/begin}%
-  \the at toks \the \@tempcnta
-  \ignorespaces \@sharp \unskip
-  \the at toks \the \count@ \relax
-  \UseSocket{tagsupport/tblcell/end}%
-}
+\NewSocket{tbl/celldata/missingcount}{1}
+\NewSocketPlug{tbl/celldata/missingcount}{code}{\tbl_count_missing_cells:n{#1}}
+\AssignSocketPlug{tbl/celldata/missingcount}{code}
+
 %    \end{macrocode}
-% \end{macro}
 %
-%
-% \begin{macro}{\@classz}
 %    \begin{macrocode}
-\def\@classz{\@classx
-   \@tempcnta \count@
-   \prepnext at tok
-   \@addtopreamble{\ifcase \@chnum
-      \hfil
-      \hskip1sp%
-      \d at llarbegin
-      \insert at column
-      \d at llarend \do at row@strut \hfil \or
-      \hskip1sp\d at llarbegin \insert at column \d at llarend \do at row@strut \hfil \or
-      \hfil\hskip1sp\d at llarbegin \insert at column \d at llarend \do at row@strut \or
-    \setbox\ar at mcellbox\vbox
-    \@startpbox{\@nextchar}
-    \AssignSocketPlug{tagsupport/tblcell/begin}{TDpbox}
-    \AssignSocketPlug{tagsupport/tblcell/end}{TDpbox}
-    \insert at column \@endpbox
-    \ar at align@mcell
-    \do at row@strut \or
-   \vtop \@startpbox{\@nextchar}
-    \AssignSocketPlug{tagsupport/tblcell/begin}{TDpbox}
-    \AssignSocketPlug{tagsupport/tblcell/end}{TDpbox}
-    \insert at column \@endpbox\do at row@strut \or
-   \vbox \@startpbox{\@nextchar}
-    \AssignSocketPlug{tagsupport/tblcell/begin}{TDpbox}
-    \AssignSocketPlug{tagsupport/tblcell/end}{TDpbox}
-    \insert at column \@endpbox\do at row@strut
-  \fi}\prepnext at tok}
-%    \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@array,\@@@@array}
-%    We modificate the \cs{@array} from \pkg{array}.
-%    \begin{macrocode}
-\def\@array[#1]#2{%
-  \@tempdima \ht \strutbox
-  \advance \@tempdima by\extrarowheight
-  \setbox \@arstrutbox \hbox{\vrule
-             \@height \arraystretch \@tempdima
-             \@depth \arraystretch \dp \strutbox
-             \@width \z@}%
-%    \end{macrocode}
-%    The total number of table columns of the current table is
-%    determined in \cs{@@_determine_table_cols:} but this is called in
-%    a group, so local settings do not survive. Thus, to save away the
-%    outer value of \cs{g_@@_table_cols_tl} we do it before the group.
-%    \begin{macrocode}
-  \tl_set_eq:NN \l_@@_saved_table_cols_tl  \g_@@_table_cols_tl
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-  \begingroup
-  \@mkpream{#2}
-%    \end{macrocode}
-%    Next call has to happen immediately after \cs{@mkpream} because
-%    it uses implementation details from that.
-%    \begin{macrocode}
-  \@@_determine_table_cols:
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-  \xdef\@preamble{%
-    \noexpand
-%    \end{macrocode}
-%    \cs{ialign} in the original definition is replaced by
-%    \cs{ar at ialign} defined below.
-%    \begin{macrocode}
-     \ar at ialign
-     \@halignto
-     \bgroup \@arstrut
-%    \end{macrocode}
-%    A socket is inserted
-%    \begin{macrocode}
-      \UseSocket{tagsupport/tblrow/begin}%
-%    \end{macrocode}
-%    At the start of the preamble for the first column we set
-%    \cs{g_@@_col_int} to \texttt{1} as we are no longer "at" but "in"
-%    the first column. This is done in \cs{@@_init_cell_data:}. In
-%    later columns this data is updated via \cs{@@_update_cell_data:}.
-%    \begin{macrocode}
-      \@@_init_cell_data:
-      \@preamble
-      \tabskip \z@ \cr}%
-  \endgroup
-  \@arrayleft
-%    \end{macrocode}
-%    Another socket for tagging. TODO: what about \cs{arrayleft}?
-%    \begin{macrocode}
-  \UseSocket{tagsupport/tbl/init}
-  \if #1t\vtop \else \if#1b\vbox \else \vcenter \fi \fi
-  \bgroup
-  \let \@sharp ##\let \protect \relax
-  \lineskip \z@
-  \baselineskip \z@
-  \m at th
-  \let\\\@arraycr \let\tabularnewline\\\let\par\@empty
-%\show\@preamble
-  \@preamble}
-%    \end{macrocode}
-%    Finally, also set \cs{@@@@array} to the new definition:
-%    \begin{macrocode}
-\let\@@@@array\@array
-%    \end{macrocode}
-% \end{macro}
-%
-%
-%  \begin{macro}{\@@_init_cell_data:}
-%
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_init_cell_data: {
-        \int_gset:Nn \g_@@_col_int {1}
-        \tl_gset:Nn  \g_@@_span_tl {1}
-}
-%    \end{macrocode}
-%  \end{macro}
-%
-%  \begin{macro}{\@@_update_cell_data:}
-%    Updating cell data in columns after the first means we have to
-%    increment the \cs{g_@@_col_int} by the span count of the previous
-%    cell (in case it was a \cs{multicolumn} and then reset the
-%    \cs{g_@@_span_tl} to one (as the default).
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_update_cell_data: {
-        \int_gadd:Nn \g_@@_col_int { \g_@@_span_tl }
-        \tl_gset:Nn  \g_@@_span_tl {1}
-}
-%    \end{macrocode}
-%  \end{macro}
-%
-%
-%
-%  \begin{macro}{\@@_determine_table_cols:}
-%    Current implementation of \cs{@mkpream} uses the scratch counter
-%    \cs{count@} to keep track of the number of toks registers it needs
-%    (2 per column), but this can't be used as it counts also
-%    insertings made with \verb+!{}+ and \verb+@{}+.
-%    So similar as does longtable for \cs{LT at cols} we count the
-%    numbers of ambersands instead.
-%    \begin{macrocode}
-\cs_new:Npn \@@_determine_table_cols:  {
-  \seq_set_split:NnV\l_@@_tmpa_seq {&}\@preamble
-  \tl_gset:Ne \g_@@_table_cols_tl { \seq_count:N \l_@@_tmpa_seq }
-  \typeout{ ==>~ Table~ has~ \g_@@_table_cols_tl \space columns }
-}
-%    \end{macrocode}
-%  \end{macro}
-%
-%
-%  \begin{macro}{\@arraycr}
-%    Add code that figures out if the current table row is incomplete
-%    (not enough \verb=&=s). It can then do extra actions, such as
-%    inserting missing cell tags.
-%    \begin{macrocode}
-\protected\def\@arraycr{
-  \relax
-  \@@_store_missing_cells:n{@arraycr}
-  %
-  \iffalse{\fi\ifnum 0=`}\fi
-  \@ifstar \@xarraycr \@xarraycr}
-%    \end{macrocode}
-%  \end{macro}
-%
-%
-%
-%  \begin{macro}{\@@_store_missing_cells:n,
-%                \__tag_tbl_add_missing_cells:n}
-%    The storing and use of the number of missing cells
-%    must happen at different places  as the testing happens at
-%    the end of the last cell of a row, but
-%    still inside that cell, so we use two commands. The second is used in
-%    the endrow socket.
-%    \begin{macrocode}
-\cs_new:Npn \@@_store_missing_cells:n #1 {
-  \int_compare:nNnT \g_@@_col_int > 0
-      {
-        \int_gset:Nn \g_@@_missing_cells_int
-            {
-              \g_@@_table_cols_tl
-            - \g_@@_col_int
-            - \g_@@_span_tl
-            + 1
-            }
-        \int_compare:nNnT \g_@@_missing_cells_int < 0 \ERROR % should not happen
-        \typeout{==>~
-          (#1)~
-          This~ row~ needs~
-          \int_use:N \g_@@_missing_cells_int \space
-          additional~ cell(s)
-        }
-      }
-}
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-\cs_new:Npn \__tag_tbl_add_missing_cells:n #1
+\cs_new:Npn \@@_add_missing_cells:
   {
 %    \end{macrocode}
-% The TD-socket messages are issued after the message about the end-row socket,
-% but the structure is ok, so better issue a message for now to avoid confusion:
+%    The TD-socket messages are issued after the message about the
+%    end-row socket, but the structure is ok, so better issue a
+%    message for now to avoid confusion:
 %    \begin{macrocode}
-    \int_compare:nNnT {#1}>{0}
+    \int_compare:nNnT \g_@@_missing_cells_int > 0
       {
-       \typeout{==>~
-          ~Inserting~\int_eval:n{#1}~additional~cell(s)~into~previous~row:}
+       \@@_trace:n {==>~
+         ~Inserting~\int_use:N \g_@@_missing_cells_int \space
+          additional~cell(s)~into~previous~row:}
+       \int_step_inline:nn { \g_@@_missing_cells_int }
+           {
+             \UseTaggingSocket{tbl/cell/begin}
+             \UseTaggingSocket{tbl/cell/end}
+           }
       }
-    \int_step_inline:nn { #1 }
-      {
-        \UseSocket{tagsupport/tblcell/begin}
-        \UseSocket{tagsupport/tblcell/end}
-      }
   }
 %    \end{macrocode}
 %  \end{macro}
@@ -1245,120 +1068,9 @@
 %
 %
 %
-% \begin{macro}{\endarray}
-%    If tables are nested into another then  it is necessary to
-%    restore information about the cell the inner table started
-%    in. Otherwise, \cs{g_@@_row_int}, \cs{g_@@_col_int}, and
-%    \cs{g_@@_span_tl} reflect the status in the outer table as they
-%    are globally manipulated. We restore in all cases even if we are
-%    not in a nesting situation as that makes the code simpler (and
-%    probably faster).
 %
-%    \cs{endtabular} and \cs{endtabular*} inherit from \cs{endarray}
-%    so we only need to change that. \texttt{tabularx} is handled
-%    below.
-%    \begin{macrocode}
-\def\endarray{
-  \@@_store_missing_cells:n{endarray}
-  \crcr \egroup
-  \UseSocket{tagsupport/tbl/finalize}
-  \int_gset:Nn \g_@@_col_int { \l_@@_saved_col_tl }
-  \int_gset:Nn \g_@@_row_int { \l_@@_saved_row_tl }
-  \tl_gset_eq:NN \g_@@_span_tl \l_@@_saved_span_tl
-  \tl_gset_eq:NN \g_@@_table_cols_tl   \l_@@_saved_table_cols_tl
-  \tl_gset_eq:NN \g_@@_struct_table_tl  \l_@@_saved_struct_table_tl
-  \seq_gset_eq:NN \g_@@_struct_rows_seq \l_@@_saved_struct_rows_seq
-  \seq_gset_eq:NN \g_@@_struct_cells_seq\l_@@_saved_struct_cells_seq
-  \seq_gset_eq:NN \g_@@_struct_cur_seq  \l_@@_saved_struct_cur_seq
-  \typeout{==>~ restored~cell~data:~
-                \int_use:N \g_@@_row_int,
-                \int_use:N \g_@@_col_int,
-                \l_@@_saved_span_tl \space
-                (
-                \int_compare:nNnTF \g_@@_table_cols_tl = 0
-                    { outer~ level }
-                    { max:~ \g_@@_table_cols_tl }
-                )
-          }
-  \egroup
-  \@arrayright \gdef\@preamble{}%
-}
-%    \end{macrocode}
-% \end{macro}
 %
 %
-%  \begin{macro}{\@addamp}
-%    If we are after the first column we have to insert a \verb=&= and
-%    also update the cell data.
-%    \begin{macrocode}
-\def\@addamp {
-  \if at firstamp
-    \@firstampfalse
-  \else
-    \edef\@preamble{\@preamble &
-        \@@_update_cell_data:
-    }
-  \fi
-}
-%    \end{macrocode}
-%  \end{macro}
-%
-%
-%
-%  \begin{macro}{
-%     \g_@@_col_int,
-%     \g_@@_row_int,
-%     \g_@@_span_tl,
-%     \g_@@_table_cols_tl}
-%    \cs{g_@@_row_int} holds the current row number in the table. The value
-%    \texttt{0} means we haven't yet processed the table preamble. It
-%    is incremented by every \cs{cr} including the one ending the
-%    table preamble.
-%
-%    \cs{g_@@_col_int} holds the current column number. The value
-%    \texttt{0} means we have not yet started the table or just finished a table row
-%    (with \verb=\\= typically); any other positive value means we
-%    are currently typesetting a cell in that column in some row
-%    (denoted by the \cs{g_@@_row_int}.
-%
-%    In a \cs{multicolumn} it holds the column number of the first
-%    spanned column and \cs{g_@@_span_tl} the info how many cells are
-%    spanned.
-%
-%    \cs{g_@@_span_tl} is normally \texttt{1} except in a
-%    \cs{multicolumn} cell.
-%    \begin{macrocode}
-\int_new:N \g_@@_col_int
-\int_new:N \g_@@_row_int
-\tl_new:N  \g_@@_span_tl
-\tl_new:N  \g_@@_table_cols_tl
-
-\tl_gset:Nn \g_@@_span_tl {1}
-\tl_gset:Nn \g_@@_table_cols_tl {0}  % indicates outer level
-%    \end{macrocode}
-%  \end{macro}
-%
-%
-%  \begin{macro}{\l_@@_saved_col_tl,\l_@@_saved_row_tl,
-%                \l_@@_saved_span_tl,\l_@@_saved_table_cols_tl}
-%
-%    Saving the outer values if we are nesting tables is necessary (as
-%    the above variables are globally altered. For this we use always
-%    token lists because they don't change and we do not need to blow
-%    additional integer registers.
-%    \begin{macrocode}
-\tl_new:N \l_@@_saved_col_tl
-\tl_new:N \l_@@_saved_row_tl
-\tl_new:N \l_@@_saved_span_tl
-\tl_new:N \l_@@_saved_table_cols_tl
-
-\tl_set:Nn \l_@@_saved_col_tl{0}
-\tl_set:Nn \l_@@_saved_row_tl{0}
-\tl_set:Nn \l_@@_saved_span_tl{1}
-\tl_set:Nn \l_@@_saved_table_cols_tl{0}  % indicates outer level
-%    \end{macrocode}
-%  \end{macro}
-%
 % \begin{macro}
 %   {
 %     \g_@@_struct_table_tl, \l_@@_saved_struct_table_tl,
@@ -1390,475 +1102,54 @@
 \seq_new:N \l_@@_saved_struct_cur_seq
 %    \end{macrocode}
 % \end{macro}
+
+
+
+%  \begin{macro}{\@@_init_struct_data:}
+%    Save the global structure data variables locally so the we can
+%    restore them when the table ends (important in case of nested
+%    tables).
 %
-% \begin{macro}{\ar at ialign}
-%    A new command that replaces \cs{ialign} above.  \cs{everycr} is
-%    also applied to the \cs{cr} ending the preamble so we have to
-%    program around that.
+%    This is also the right point to initialize
+%    them. \cs{g_@@_struct_table_tl} is set elsewhere.
 %    \begin{macrocode}
-\def\ar at ialign{%
-%    \end{macrocode}
-%    Before starting a table we locally stored the information related
-%    to the current cell (if any) so that we can restore it once the
-%    table is finished.
-%    \begin{macrocode}
-  \tl_set:No \l_@@_saved_col_tl {\int_use:N \g_@@_col_int }
-  \tl_set:No \l_@@_saved_row_tl {\int_use:N \g_@@_row_int }
-  \tl_set_eq:NN \l_@@_saved_span_tl  \g_@@_span_tl
+\cs_new_protected:Npn \@@_init_struct_data: {
   \tl_set_eq:NN  \l_@@_saved_struct_table_tl \g_@@_struct_table_tl
   \seq_set_eq:NN \l_@@_saved_struct_rows_seq \g_@@_struct_rows_seq
   \seq_set_eq:NN \l_@@_saved_struct_cells_seq \g_@@_struct_cells_seq
   \seq_set_eq:NN \l_@@_saved_struct_cur_seq \g_@@_struct_cur_seq
 %
-  \typeout{==>~ saved~cell~data:~
-                \l_@@_saved_row_tl,
-                \l_@@_saved_col_tl,
-                \l_@@_saved_span_tl \space
-                (
-                \int_compare:nNnTF \l_@@_saved_table_cols_tl = 0
-                    { outer~ level }
-                    { max:~ \l_@@_saved_table_cols_tl }
-                )
-          }
-%    \end{macrocode}
-%    These are the initial values when starting a table:
-%    \begin{macrocode}
-  \int_gzero:N \g_@@_row_int
-  \int_gzero:N \g_@@_col_int
-  \tl_gset:Nn  \g_@@_span_tl {1}
   \seq_gclear:N\g_@@_struct_rows_seq
   \seq_gclear:N\g_@@_struct_cells_seq
   \seq_gclear:N\g_@@_struct_cur_seq
+}
 %    \end{macrocode}
-%
+%  \end{macro}
+
+
+
+
+%  \begin{macro}{\@@_restore_struct_data:}
+%    
 %    \begin{macrocode}
-  \everycr{%
-    \noalign{%
+\cs_new_protected:Npn \@@_restore_struct_data: {
+  \tl_gset_eq:NN  \g_@@_struct_table_tl \l_@@_saved_struct_table_tl
+  \seq_gset_eq:NN \g_@@_struct_rows_seq \l_@@_saved_struct_rows_seq
+  \seq_gset_eq:NN \g_@@_struct_cells_seq\l_@@_saved_struct_cells_seq
+  \seq_gset_eq:NN \g_@@_struct_cur_seq  \l_@@_saved_struct_cur_seq
+}
 %    \end{macrocode}
-%    We use \cs{g_@@_col_int} equal zero to indicate that we are just
-%    after a TR (or at the very beginning of the table). Using the row
-%    count is not so good as longtable may split the table in chunks.
-%    \begin{macrocode}
-      \int_compare:nNnT \g_@@_col_int > 0
-         { \UseSocket{tagsupport/tblrow/end} }
-      \int_gincr:N \g_@@_row_int          % this row about to start
-      \int_gzero:N \g_@@_col_int          % we are before first col
-    }%
-  }%
-  \tabskip\z at skip\halign}
-%    \end{macrocode}
-% \end{macro}
+%  \end{macro}
+
+
 %
 %
-% \begin{macro}{\multicolumn}
-%
-%    \cs{multicolumn} is also defined in \pkg{array}. The redefinition
-%    has to solve two problems: it must handle the row begin if it is
-%    used there, and it must save the numbers of cells it spans so
-%    that we can add a suitable ColSpan attribute.\footnote{FMi: This can
-%    now perhaps cleaned up somewhat}
-%    \begin{macrocode}
-\long\def\multicolumn#1#2#3{%
-  % alternative: determine first col with vmode test ...
-  %  \ifvmode
-  %    \multispan{#1}\typeout{A==> vmode}%
-  %  \else
-  %    \multispan{#1}\typeout{A==> not vmode}
-  %  \fi
-  % but this makes the \crcr handling really complicated which would
-  % then need to become something like
-  %    \ifvmode \expandafter \@gobble
-  %    \else \expandafter \@iden \fi {\cr\noalign{do something}}%
-  % so not used.
-  % Instead:
-   \multispan{#1}\begingroup
-%    \end{macrocode}
-%    Insert rowbegin socket only if this multicolumn
-%    replaces the preamble of the first column. In that case we have
-%    to set \cs{g_@@_col_int} to 1 since this is no longer done in the
-%    preamble for the cell.
-%    \begin{macrocode}
-   \int_compare:nNnTF \g_@@_col_int = 0
-       {
-         \UseSocket{tagsupport/tblrow/begin}
-         \int_gset:Nn \g_@@_col_int {1}
-       }
-%    \end{macrocode}
-%    If we are in a later column we use \cs{g_@@_span_tl} from the
-%    previous column to update.
-%    \begin{macrocode}
-       {
-         \int_gadd:Nn \g_@@_col_int { \g_@@_span_tl }
-       }
-%    \end{macrocode}
-%    Then we set the span value so that it can be use in the next column.
-%    \begin{macrocode}
-   \tl_gset:Nn \g_@@_span_tl {#1}
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-  \def\@addamp{\if at firstamp\@firstampfalse \else
-                \@preamerr 5\fi}%
-   \@mkpream{#2}\@addtopreamble\@empty
-   \endgroup
-%    \end{macrocode}
-%    Now we update the colspan attribute.  This needs setting after
-%    the group as it is hidden inside the plug in \cs{insert at column}.
-%    \begin{macrocode}
-   \@@_set_colspan:n {#1}
-%    \end{macrocode}
-%    \begin{macrocode}
-   \def\@sharp{#3}%
-   \@arstrut \@preamble
-   \null
-   \ignorespaces}
-%    \end{macrocode}
-% \end{macro}
-%
 % \subsection{longtable}
 %
-% Longtable is complicated. When at the begin the \cs{endhead},
-% \cs{endfirsthead}, \cs{endfoot} and \cs{endlastfoot} are used to
-% setup head and foot they create each a structure subtree with one or
-% more rows. From this structures we want to keep at most two (head
-% and foot) and move the foot to the end of the table. When the head
-% and foot boxes are (re)inserted on following pages we want to mark
-% them up as artifact with the exception of the head at the begin and
-% the foot box at the end.
 %
-% TODO: When a line is killed the structure subtree is there already
-% too and must be removed.
-% 
-% Hyperref patches longtable. This must be disabled and replace with
-% genuine code
-%    \begin{macrocode}
-\let\@kernel at refstepcounter\refstepcounter
-\def\hyper at nopatch@longtable{}
-%    \end{macrocode}
-%    \begin{macrocode}
-\def\@@_patch_LT at array[#1]#2{%
-%    \end{macrocode}
-% \cs{LT at array} is executed in a group, so we can disable para-tagging here.
-%    \begin{macrocode}
-  \UseSocket{tagsupport/tbl/init}%
-  \@kernel at refstepcounter{table}\stepcounter{LT at tables}%
-%    \end{macrocode}
-% The target is created rather late and a \cs{label} can come earlier, 
-% so we have to define \cs{@currentHref} explicitly. We can't currently
-% assume that \cs{theHtable} is defined always.   
-%    \begin{macrocode}
-  \tl_gset:Ne \@currentHref {table.\cs_if_exist_use:N\theHtable}
-  \int_gzero:N \g_@@_row_int
-  \seq_gclear:N\g_@@_struct_rows_seq
-  \seq_gclear:N\g_@@_struct_cells_seq
-  \seq_gclear:N\g_@@_struct_cur_seq
-  \seq_gclear:N\g_@@_LT at firsthead_rows_seq
-  \seq_gclear:N\g_@@_LT at head_rows_seq
-  \seq_gclear:N\g_@@_LT at lastfoot_rows_seq
-  \seq_gclear:N\g_@@_LT at foot_rows_seq
-  \if l#1%
-    \LTleft\z@ \LTright\fill
-  \else\if r#1%
-    \LTleft\fill \LTright\z@
-  \else\if c#1%
-    \LTleft\fill \LTright\fill
-  \fi\fi\fi
-  \let\LT at mcol\multicolumn
-  \let\LT@@@@tabarray\@tabarray
-  \let\LT@@@@hl\hline
-  \def\@tabarray{%
-    \let\hline\LT@@@@hl
-    \LT@@@@tabarray}%
-  \let\\\LT at tabularcr
-  \let\tabularnewline\\%
-  \def\newpage{\noalign{\break}}%
-  \def\pagebreak{\noalign{\ifnum`}=0\fi\@testopt{\LT at no@pgbk-}4}%
-  \def\nopagebreak{\noalign{\ifnum`}=0\fi\@testopt\LT at no@pgbk4}%
-  \let\hline\LT at hline \let\kill\LT at kill\let\caption\LT at caption
-  \@tempdima\ht\strutbox
-  \let\@endpbox\LT at endpbox
-  \ifx\extrarowheight\@undefined
-    \let\@acol\@tabacol
-    \let\@classz\@tabclassz \let\@classiv\@tabclassiv
-    \def\@startpbox{\vtop\LT at startpbox}%
-    \let\@@@@startpbox\@startpbox
-    \let\@@@@endpbox\@endpbox
-    \let\LT at LL@FM at cr\@tabularcr
-  \else
-    \advance\@tempdima\extrarowheight
-    \col at sep\tabcolsep
-    \let\@startpbox\LT at startpbox\let\LT at LL@FM at cr\@arraycr
-  \fi
-  \setbox\@arstrutbox\hbox{\vrule
-    \@height \arraystretch \@tempdima
-    \@depth \arraystretch \dp \strutbox
-    \@width \z@}%
-  \let\@sharp##\let\protect\relax
-   \begingroup
-    \@mkpream{#2}%
-    \@@_determine_table_cols:
-    \xdef\LT at bchunk{%
-%    \end{macrocode}
-%    At the start of a chunk we set \cs{g_@@_col_int} to zero to make
-%    sure that we aren't generating /TR with the \cs{cr} ending the
-%    chunk preamble.
-%    \begin{macrocode}
-       \int_gzero:N \g_@@_col_int
-       \global\advance\c at LT@chunks\@ne
-       \global\LT at rows\z@\setbox\z@\vbox\bgroup
-       \LT at setprevdepth
-       \tabskip\LTleft \noexpand\halign to\hsize\bgroup
-       \tabskip\z@ \@arstrut
-%    \end{macrocode}
-% Insert the socket and the setting of the conditional
-%    \begin{macrocode}
-       \UseSocket{tagsupport/tblrow/begin}%
-       \@@_init_cell_data:
-%    \end{macrocode}
-%    \begin{macrocode}
-       \@preamble \tabskip\LTright \cr}%
-  \endgroup
-  \expandafter\LT at nofcols\LT at bchunk&\LT at nofcols
-  \LT at make@row
-  \m at th\let\par\@empty
-%    \end{macrocode}
-% Socket and conditional
-%    \begin{macrocode}
-  \everycr{%
-    \noalign{%
-%    \end{macrocode}
-%    In \pkg{longtable} we have a bunch of extra \cs{cr}s that are
-%    executed whenever a chunk ends. In that case they should not
-%    increment the main row counter, sigh.
-%    \begin{macrocode}
-      \typeout{--longtable-->~chunk~row:~ \the\LT at rows \space
-               row:~ \the\g_@@_row_int   \space
-               column:~ \the\g_@@_col_int
-      }
-      \int_compare:nNnT \g_@@_col_int > 0
-          {
-            \UseSocket{tagsupport/tblrow/end}
-          }
-%    \end{macrocode}
-%    This prevents any of the additional \cs{cr}s at the end of the
-%    chunk to add another /TR. Then once we really start a new chunk
-%    it gets incremented so\ldots
-%    \begin{macrocode}
-      \int_gzero:N \g_@@_col_int           % before first col
-%    \end{macrocode}
-%    And for the same reason such \cs{cr}s should not increment the
-%    main row counter (but it has to be incremented after the preamble
-%    of a chunk), so here we test against \cs{LT at rows} which is
-%    \cs{LTchunksize} at the end of a chunk.
-%    \begin{macrocode}
-      \int_compare:nNnT \LT at rows < \LTchunksize
-         { \int_gincr:N \g_@@_row_int  }   % this row about to start
-    }%
-  }%
-%    \end{macrocode}
-%    \begin{macrocode}
-  \lineskip\z@\baselineskip\z@
-  \LT at bchunk}
-%    \end{macrocode}
-% The end code most stop to insert the endrow too.
-%    \begin{macrocode}
-\def\@@_patch_endlongtable{%
-  \@@_store_missing_cells:n{endlongtable}
-  \crcr
-  \noalign{%
-    \UseSocket{tagsupport/tbl/finalize/longtable}
-    \int_gzero:N \g_@@_row_int      % this prevents considering the next
-                                    % \crcr as another row end.
-    \let\LT at entry\LT at entry@chop
-    \xdef\LT at save@row{\LT at save@row}}%
-  \LT at echunk
-  \LT at start
-  \unvbox\z@
-  \LT at get@widths
-  \if at filesw
-    {\let\LT at entry\LT at entry@write\immediate\write\@auxout{%
-      \gdef\expandafter\noexpand
-        \csname LT@\romannumeral\c at LT@tables\endcsname
-          {\LT at save@row}}}%
-  \fi
-  \ifx\LT at save@row\LT@@@@save at row
-  \else
-    \LT at warn{Column~\@width s~have~changed\MessageBreak
-             in~table~\thetable}%
-    \LT at final@warn
-  \fi
-  \endgraf\penalty -\LT at end@pen
-  \ifvoid\LT at foot\else
-    \global\advance\vsize\ht\LT at foot
-    \global\advance\@colroom\ht\LT at foot
-    \dimen@\pagegoal\advance\dimen@\ht\LT at foot\pagegoal\dimen@
-  \fi
-  \endgroup
-  \global\@mparbottom\z@
-  \endgraf\penalty\z@\addvspace\LTpost
-  \ifvoid\footins\else\insert\footins{}\fi}
-%    \end{macrocode}
 %
 %
 %
-%  \begin{macro}{\@@_patch_LT at t@bularcr}
-%
-%    \begin{macrocode}
-\def\@@_patch_LT at t@bularcr{%
-  \global\advance\LT at rows\@ne
-  \ifnum\LT at rows=\LTchunksize
-%    \end{macrocode}
-%    At the end of the chunk \verb=\\= is doing something special and
-%    so we loose \cs{@@_store_missing_cells:n}. Below is about the
-%    right place to add it do this code branch.
-%    \begin{macrocode}
-    \@@_store_missing_cells:n{echunk}
-    \gdef\LT at setprevdepth{%
-      \prevdepth\z@
-      \global\let\LT at setprevdepth\relax}%
-    \expandafter\LT at xtabularcr
-  \else
-    \ifnum0=`{}\fi
-    \expandafter\LT at LL@FM at cr
-  \fi}
-
-%    \end{macrocode}
-%  \end{macro}
-%
-%
-%
-%  \begin{macro}{\@@_patch_LT at end@hd at ft}
-%    This command is used to store the head and foot boxes.
-%    We need to retrieve and store the row so that we can clean
-%    up the structure in the finalize code.
-%    \begin{macrocode}
-\def\@@_patch_LT at end@hd at ft#1{%
-%    \end{macrocode}
-%    To handle missing columns in the header we need this:
-%    \begin{macrocode}
-  \__tbl_store_missing_cells:n{head/foot}
-  \int_step_inline:nn
-   { \LT at rows + 1 }
-   {
-     \seq_gput_left:ce
-       {g_@@_\cs_to_str:N #1 _rows_seq }
-       { \int_eval:n {\g_@@_row_int + 1 - ##1 } }
-   }
-%    \end{macrocode}
-%    We also have to set the chunk rows to its max value before
-%    calling \cs{LTechunk} so that we don't get extra increments of
-%    the main row counter due to \cs{everycr}.
-%    \begin{macrocode}
-  \int_gset:Nn \LT at rows { \LTchunksize }
-  \LT at echunk
-  \ifx\LT at start\endgraf
-    \LT at err
-     {Longtable head or foot not at start of table}%
-     {Increase LTchunksize}%
-  \fi
-  \setbox#1\box\z@
-  \LT at get@widths
-  \LT at bchunk}
-%    \end{macrocode}
-%  \end{macro}
-
-% \begin{macro}{\@@_patch_LT at start}
-%    \begin{macrocode}
-\def\@@_patch_LT at start{%
-  \let\LT at start\endgraf
-  \endgraf\penalty\z@\vskip\LTpre\endgraf
-   \ifdim \pagetotal<\pagegoal \else
-      \dimen@=\pageshrink
-      \advance \dimen@ 1sp %
-      \kern\dimen@\penalty 9999\endgraf \kern-\dimen@
-   \fi
-  \dimen@\pagetotal
-  \advance\dimen@ \ht\ifvoid\LT at firsthead\LT at head\else\LT at firsthead\fi
-  \advance\dimen@ \dp\ifvoid\LT at firsthead\LT at head\else\LT at firsthead\fi
-  \advance\dimen@ \ht\LT at foot
-  \edef\LT at reset@vfuzz{\vfuzz\the\vfuzz\vbadness\the\vbadness\relax}%
-  \vfuzz\maxdimen
-  \vbadness\@M
-  \setbox\tw@\copy\z@
-  \setbox\tw@\vsplit\tw@ to \ht\@arstrutbox
-  \setbox\tw@\vbox{\unvbox\tw@}%
-  \LT at reset@vfuzz
-  \advance\dimen@ \ht
-        \ifdim\ht\@arstrutbox>\ht\tw@\@arstrutbox\else\tw@\fi
-  \advance\dimen@\dp
-        \ifdim\dp\@arstrutbox>\dp\tw@\@arstrutbox\else\tw@\fi
-  \advance\dimen@ -\pagegoal
-  \ifdim \dimen@>\z@
-    \vfil\break
-  \else
-    \ifdim\pageshrink>\z@\pageshrink\z@\fi
-  \fi
-      \global\@colroom\@colht
-  \ifvoid\LT at foot\else
-    \global\advance\vsize-\ht\LT at foot
-    \global\advance\@colroom-\ht\LT at foot
-    \dimen@\pagegoal\advance\dimen at -\ht\LT at foot\pagegoal\dimen@
-    \maxdepth\z@
-  \fi
-  \MakeLinkTarget{table}
-  \ifvoid\LT at firsthead\copy\LT at head\else\box\LT at firsthead\fi\nobreak
-%    \end{macrocode}
-% Avoid that following uses of the box add content:
-%    \begin{macrocode}
-  \tagmcbegin{artifact}
-   \tag_mc_reset_box:N\LT at head
-  \tagmcend
-  \output{\LT at output}}
-%    \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{\@@_patch_LT at output}
-%    We must also avoid that the reuse of the foot box leads to
-%    duplicated content:
-%    \begin{macrocode}
-\def\@@_patch_LT at output{%
-  \ifnum\outputpenalty <-\@Mi
-    \ifnum\outputpenalty > -\LT at end@pen
-      \LT at err{floats and marginpars not allowed in a longtable}\@ehc
-    \else
-      \setbox\z@\vbox{\unvbox\@cclv}%
-      \ifdim \ht\LT at lastfoot>\ht\LT at foot
-        \dimen@\pagegoal
-        \advance\dimen@\ht\LT at foot
-        \advance\dimen at -\ht\LT at lastfoot
-        \ifdim\dimen@<\ht\z@
-          \setbox\@cclv\vbox{\unvbox\z@\copy\LT at foot\vss}%
-          \@makecol
-          \@outputpage
-          \global\vsize\@colroom
-          \setbox\z@\vbox{\box\LT at head}%
-        \fi
-      \fi
-        \unvbox\z@\box\ifvoid\LT at lastfoot\LT at foot\else\LT at lastfoot\fi
-%    \end{macrocode}
-%    Reset attribute of foot box:
-%    \begin{macrocode}
-        \tagmcbegin{artifact}
-        \tag_mc_reset_box:N \LT at foot
-        \tagmcend
-    \fi
-  \else
-    \setbox\@cclv\vbox{\unvbox\@cclv\copy\LT at foot\vss}%
-%    \end{macrocode}
-%    Reset attribute of foot box:
-%    \begin{macrocode}
-    \tagmcbegin{artifact}
-    \tag_mc_reset_box:N \LT at foot
-    \tagmcend
-    \@makecol
-    \@outputpage
-      \global\vsize\@colroom
-    \copy\LT at head\nobreak
-  \fi}
-%    \end{macrocode}
-% \end{macro}
-%
 % \begin{macro}{\@@_patch_\LT at makecaption}
 %     This patch is quite similar to the one for LaTeX's \cs{@makecaption}
 %     we also have to change the parbox sockets.
@@ -1893,75 +1184,12 @@
 %    \begin{macrocode}
 \AddToHook{package/longtable/after}
   {
-   \seq_new:N \g_@@_LT at firsthead_rows_seq
-   \seq_new:N \g_@@_LT at head_rows_seq
-   \seq_new:N \g_@@_LT at lastfoot_rows_seq
-   \seq_new:N \g_@@_LT at foot_rows_seq
-   \cs_set_eq:NN \LT at array\@@_patch_LT at array
-   \cs_set_eq:NN \endlongtable\@@_patch_endlongtable
-   \cs_set_eq:NN \LT at start\@@_patch_LT at start
-   \cs_set_eq:NN \LT at output\@@_patch_LT at output
-   \cs_set_eq:NN \LT at t@bularcr\@@_patch_LT at t@bularcr
-   \cs_set_eq:NN \LT at end@hd at ft\@@_patch_LT at end@hd at ft
    \cs_set_eq:NN \LT at makecaption\@@_patch_LT at makecaption
   }
 %    \end{macrocode}
 
 
-
-
-
-% \subsection{tabularx}
-%
-% In tabularx we mainly need to ensure that no tagging is done during
-% the trial.
-%
 %    \begin{macrocode}
-\def\@@_patch_TX at endtabularx{%
-   \expandafter\expandafter\expandafter
-     \TX at find@endtabularxa\csname end\TX@\endcsname
-     \endtabularx\TX@\endtabularx\TX at find@endtabularxa
-  \expandafter\TX at newcol\expandafter{\tabularxcolumn{\TX at col@width}}%
-  \let\verb\TX at verb
-  \def\@elt##1{\global\value{##1}\the\value{##1}\relax}%
-  \edef\TX at ckpt{\cl@@@@ckpt}%
-  \let\@elt\relax
-  \TX at old@table\maxdimen
-  \TX at col@width\TX at target
-  \global\TX at cols\@ne
-  \TX at typeout@
-    {\@spaces Table Width\@spaces Column Width\@spaces X Columns}%
-%    \end{macrocode}
-%    Here we stop tagging:
-%    \begin{macrocode}
-  \tag_stop:n{tabularx}
-  \TX at trial{\def\NC at rewrite@X{%
-          \global\advance\TX at cols\@ne\NC at find p{\TX at col@width}}}%
-  \loop
-    \TX at arith
-    \ifTX@
-    \TX at trial{}%
-  \repeat
-%    \end{macrocode}
-%    And now we restart it again.
-%    \begin{macrocode}
-  \tag_start:n{tabularx}
-  {\let\@footnotetext\TX at ftntext\let\@xfootnotenext\TX at xftntext
-    \csname tabular*\expandafter\endcsname\expandafter\TX at target
-      \the\toks@
-    \csname endtabular*\endcsname}%
-  \global\TX at ftn\expandafter{\expandafter}\the\TX at ftn
-  \ifnum0=`{\fi}%
-   \expandafter\expandafter\expandafter
-   \TX at find@endtabularxbb
-    \expandafter\end\expandafter{\TX@}%
-    \endtabularx\TX@\endtabularx\TX at find@endtabularxb
-}
-
-\AddToHook{package/tabularx/after}
-  {\cs_set_eq:NN \TX at endtabularx\@@_patch_TX at endtabularx }
-%    \end{macrocode}
-%    \begin{macrocode}
 %</package>
 %    \end{macrocode}
 %
@@ -1973,3 +1201,11 @@
 \RequirePackage{latex-lab-testphase-table}
 %</latex-lab>
 %    \end{macrocode}
+
+%    \begin{macrocode}
+%<*latex-lab-alias>
+\ProvidesFile{tabular-latex-lab-testphase.ltx}
+        [\ltlabtbldate\space v\ltlabtblversion\space latex-lab wrapper tabular]
+\RequirePackage{latex-lab-testphase-table}
+%</latex-lab-alias>
+%    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-testphase.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-testphase.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-testphase.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
 %% File: latex-lab-testphase.dtx
-% Copyright (C) 2021-2023 The LaTeX Project
+% Copyright (C) 2021-2024 The LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -79,7 +79,7 @@
 %    \begin{macrocode}
 %<*phase-III> 
 \ProvidesFile{phase-III-latex-lab-testphase.ltx}
-              [2023-07-20 v0.1b  latex-lab wrapper phase-III]
+              [2024-02-12 v0.1c  latex-lab wrapper phase-III]
 \input{phase-II-latex-lab-testphase.ltx}
 \IfFormatAtLeastTF{2023-06-01}
  {
@@ -91,6 +91,7 @@
   \RequirePackage{latex-lab-testphase-float}
   \RequirePackage{latex-lab-testphase-bib}
   \RequirePackage{latex-lab-testphase-text}
+  \RequirePackage{latex-lab-testphase-marginpar}
  }
  {\PackageWarning{latex-lab}{Testphase III needs newer format}{}} 
 %</phase-III>
@@ -122,9 +123,9 @@
 \RequirePackage{tagpdf}
 \AddToDocumentProperties [document]{testphase/tagpdf}{loaded}
 %</tagpdf|phase-I|phase-II>
-%<tagpdf|phase-II>\tagpdfsetup{activate,paratagging,interwordspace}
+%<tagpdf|phase-II>\tagpdfsetup{activate,para/tagging,activate/spaces}
 %<tagpdf|phase-II>\AddToDocumentProperties [document]{tagging/para}{active}
-%<phase-I>\tagpdfsetup{activate,interwordspace}
+%<phase-I>\tagpdfsetup{activate,activate/spaces}
 %<*tagpdf|phase-I|phase-II>
 \AddToDocumentProperties [document]{tagging}{active}
 \AddToDocumentProperties [document]{tagging/interwordspace}{active}

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-text.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-text.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-text.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-%% File: latex-lab-text.dtx (C) Copyright 2023 LaTeX Project
+%% File: latex-lab-text.dtx (C) Copyright 2023-2024 LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this

Added: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-title.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-title.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-title.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -0,0 +1,518 @@
+% \iffalse meta-comment
+%
+%% File: latex-lab-title.dtx (C) Copyright 2023-2024 LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version.  The latest version
+% of this license is in the file
+%
+%    https://www.latex-project.org/lppl.txt
+%
+%
+% The development version of the bundle can be found below
+%
+%    https://github.com/latex3/latex2e/required/latex-lab
+%
+% for those people who are interested or want to report an issue.
+%
+\def\ltlabtitledate{2024-02-09}
+\def\ltlabtitleversion{0.85c}
+
+%<*driver>
+\documentclass{l3doc}
+\EnableCrossrefs
+\CodelineIndex
+\begin{document}
+  \DocInput{latex-lab-title.dtx}
+\end{document}
+%</driver>
+%
+% \fi
+%
+% \title{The \textsf{latex-lab-title} package\\
+% Changes related to the tagging of the title}
+% \author{\LaTeX{} Project\thanks{Initial implementation done by Ulrike Fischer}}
+% \date{v\ltlabtitleversion\ \ltlabtitledate}
+%
+% \maketitle
+%
+% \newcommand{\xt}[1]{\textsl{\textsf{#1}}}
+% \newcommand{\TODO}[1]{\textbf{[TODO:} #1\textbf{]}}
+% \newcommand{\docclass}{document class \marginpar{\raggedright document class
+% customizations}}
+%
+% \providecommand\hook[1]{\texttt{#1}}
+%
+% \begin{abstract}
+% \end{abstract}
+%
+% \section{Introduction}
+%
+% This module contains changes to improve the tagging (in the standard classes) of
+% the title created with the \cs{maketitle} command. It also improves the
+% setting of the metadata related to the title and the author.
+% 
+% For basic tagging of the printed title there are basically three things to do:
+% 
+% \begin{itemize}
+% \item The actual title should be tagged with the \texttt{Title} tag.
+% \item The tabular used to format the author list should \emph{not} be tagged as a tabular.
+% \item \cs{maketitle} redefines footnote internals. These must be made tagging aware.
+% \end{itemize} 
+% 
+% A second task related to title is to store the authors and the title text 
+% (or a shorter version) inside the  XMP-metadata and (in PDF 1.7 or lower) in
+% the Info dictionary. Currently this can only be set if hyperref
+% is loaded and requires the use of the \texttt{pdftitle} and \texttt{pdfauthor} keys. 
+% The new code therefore extends the \cs{title} and \cs{author} commands: They
+% stores their argument and use them at the end of the document 
+% for the PDF metadata if the data hasn't been given in another way. 
+% The code also gives \cs{title} and \cs{author} 
+% an optional argument where the PDF title or author can be given with
+% in a key-value syntax. As with hyperref it is possible to store titles 
+% in more than one language:
+%  
+% \begin{verbatim}
+% \title
+%   [pdftitle = 
+%      {[en]English Title,[de] Deutscher Titel,[fr]{titre français, avec comma}}]
+%   {Document title} 
+% \end{verbatim}
+% 
+% It is also possible to set a subtitle which is then stored in the XMP-metadata:
+% 
+% \begin{verbatim}
+% \title
+%   [pdfsubtitle = 
+%      {[en]English Subtitle,[de] Deutscher Subtitel,[fr]{subtitre français, avec comma}}]
+%   {Document title} 
+% \end{verbatim}
+ 
+% 
+% If using the \texttt{pdfauthor} key authors should be separated
+% by commas, and to hide commas in a name inside braces if needed:
+%
+%  \begin{verbatim}
+%  \author[pdfauthor = {Bär, Peter Anteater, {Riley, the sloth}}]{\ldots}
+%  \end{verbatim}
+% 
+% If hyperref is loaded there is no difference to the \texttt{pdftitle} and
+% \texttt{pdfauthor} key used in \cs{hypersetup}. Both can be used (and the last
+% key used will win). 
+% 
+% \subsection{Open questions and TODOs}
+% 
+% \begin{itemize}
+% \item Writing into the Info dictionary needs to convert the input into a PDF string.
+% This is here done with a simple version of hyperref's \cs{pdfstringdef}, similar code
+% exist also in in the generic hyperref driver. This should be moved into a better place
+% module. 
+% 
+% \item Is it sensible to enhance \cs{author} and \cs{title} with an optional argument as done here?
+% An advantage is that it is rather light-weight and
+% doesn't require to decide how this values should be set in \cs{DocumentMetadata} (and would also work
+% without \cs{DocumentMetadata}. But a problem could be that various classes and packages already
+% extend this commands with other optional arguments.
+% 
+% \item Some of the definitions related to metadata should perhaps be moved into l3pdfmeta.
+% 
+% \item Are the names \texttt{pdftitle} and \texttt{pdfauthor} ok? 
+% 
+% \item The patch for \cs{thanks} to get a rlap-footnotemarker looks wrong. This 
+% probably means that some configuration option is missing in the footnote code.
+% \end{itemize}
+% 
+%   
+% 
+% \section{Implementation}
+%    \begin{macrocode}
+%<*package>
+%<@@=tag>
+%    \end{macrocode}
+%    \begin{macrocode}
+\ProvidesExplPackage {latex-lab-testphase-title} {\ltlabtitledate} {\ltlabtitleversion}
+  {Changes related to the tagging of the title}
+%    \end{macrocode}
+%
+% \subsection{\cs{maketitle} in article class}
+% 
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_patch_thanks:n #1
+  {
+    \rlap{\footnotemark}
+    \protected at xdef\@thanks{\@thanks
+      \protect\footnotetext[\the\c at footnote]{#1}}
+  }
+%    \end{macrocode}
+% The no-titlepage version of article, report and book
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_patch_maketitle:
+  {
+    \par
+    \begingroup
+%    \end{macrocode}
+% Disable table tagging
+%    \begin{macrocode}
+      \cs_if_exist_use:N\__tag_tbl_disable:
+      \renewcommand\thefootnote{\@fnsymbol\c at footnote}%
+%    \end{macrocode}
+% the original definition redefines \cs{@makefnmark} and
+% \cs{@makefntext} to get an rlap-mark in the text without 
+% affecting the mark in the note (which gives by the way
+% a wrong link area with hyperref). There seem to be currently
+% no good way in the footnote to configure this, so we redefine 
+% \cs{thanks} instead 
+%    \begin{macrocode}
+      \cs_set_eq:NN \thanks \@@_patch_thanks:n
+      \if at twocolumn
+        \ifnum \col at number=\@ne
+          \@maketitle
+        \else
+          \twocolumn[\@maketitle]%
+        \fi
+      \else
+      \newpage
+        \global\@topnum\z@   % Prevents figures from going at top of page.
+        \@maketitle
+      \fi
+      \thispagestyle{plain}\@thanks
+    \endgroup
+    \setcounter{footnote}{0}%
+    \global\let\thanks\relax
+    \global\let\maketitle\relax
+    \global\let\@maketitle\relax
+    \global\let\@thanks\@empty
+    \global\let\@author\@empty
+    \global\let\@date\@empty
+    \global\let\@title\@empty
+    \global\let\title\relax
+    \global\let\author\relax
+    \global\let\date\relax
+    \global\let\and\relax
+  }
+%    \end{macrocode}
+% We must also change \cs{@maketitle} to insert a Title tag
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_patch_ at maketitle:
+ {
+  \newpage
+  \null
+  \vskip 2em%
+  \begin{center}%
+  \let \footnote \thanks
+%    \end{macrocode}
+% use Title around the title. As in PDF 1.7 this is 
+% rolemapped to P we change the text-unit tag there.
+%    \begin{macrocode}  
+  \pdf_version_compare:NnTF > {1.7}
+    {{\LARGE \tag_struct_begin:n{tag=Title}\@title \par\tag_struct_end:}}
+    {{\LARGE \tagtool{paratag=Title}\@title \par}}%
+   \vskip 1.5em%
+    {\large
+      \lineskip .5em%
+      \begin{tabular}[t]{c}%
+        \@author
+      \end{tabular}\par}%
+    \vskip 1em%
+    {\large \@date}%
+  \end{center}%
+  \par
+  \vskip 1.5em
+  }
+ 
+%    \end{macrocode}
+% The titlepage variant
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_patch_maketitle_page:
+  {\begin{titlepage}%
+%    \end{macrocode}
+% disable table tagging
+%    \begin{macrocode}
+  \cs_if_exist_use:N\__tag_tbl_disable:
+  \let\footnotesize\small
+  \let\footnoterule\relax
+  \let \footnote \thanks
+  \null\vfil
+  \vskip 60\p@
+%    \end{macrocode}
+% use Title around the title. As in PDF 1.7 this is 
+% rolemapped to P we change the text-unit tag there.
+%    \begin{macrocode}
+  \begin{center}%
+   \pdf_version_compare:NnTF > {1.7}
+     {{\LARGE \tag_struct_begin:n{tag=Title}\@title \par\tag_struct_end:}}
+     {{\LARGE \tagtool{paratag=Title}\@title \par}}%
+   \vskip 3em%
+    {\large
+     \lineskip .75em%
+      \begin{tabular}[t]{c}%
+        \@author
+      \end{tabular}\par}%
+      \vskip 1.5em%
+    {\large \@date \par}%       % Set date in \large size.
+  \end{center}\par
+  \@thanks
+  \vfil\null
+  \end{titlepage}%
+  \setcounter{footnote}{0}%
+  \global\let\thanks\relax
+  \global\let\maketitle\relax
+  \global\let\@thanks\@empty
+  \global\let\@author\@empty
+  \global\let\@date\@empty
+  \global\let\@title\@empty
+  \global\let\title\relax
+  \global\let\author\relax
+  \global\let\date\relax
+  \global\let\and\relax
+  }
+
+%    \end{macrocode}
+% Map the new commands onto \cs{maketitle}:
+%    \begin{macrocode}
+\AddToHook{class/article/after}
+  {
+    \if at titlepage
+     \cs_set_eq:NN \maketitle \@@_patch_maketitle_page:
+    \else
+     \cs_set_eq:NN \maketitle \@@_patch_maketitle:
+     \cs_set_eq:NN \@maketitle \@@_patch_ at maketitle:
+    \fi
+  } 
+\AddToHook{class/report/after}
+  {
+    \if at titlepage
+     \cs_set_eq:NN \maketitle \@@_patch_maketitle_page:
+    \else
+    \cs_set_eq:NN \maketitle \@@_patch_maketitle:
+    \cs_set_eq:NN \@maketitle \@@_patch_ at maketitle:
+    \fi
+  } 
+\AddToHook{class/book/after}
+  {
+    \if at titlepage
+     \cs_set_eq:NN \maketitle \@@_patch_maketitle_page:
+    \else
+    \cs_set_eq:NN \maketitle \@@_patch_maketitle:
+    \cs_set_eq:NN \@maketitle \@@_patch_ at maketitle:   
+    \fi
+  } 
+%    \end{macrocode}
+%
+% \subsection{Helper commands to set metadata}
+% 
+% Some temp variables
+%    \begin{macrocode}
+\str_new:N \g_@@_title_tmpa_str
+\str_new:N \l_@@_title_tmpa_str
+\tl_new:N  \l_@@_title_tmpa_tl
+\seq_new:N \l_@@_title_tmpa_seq
+%    \end{macrocode}
+% Support for \cs{texorpdfstring}
+%    \begin{macrocode}
+\providecommand\texorpdfstring[2]{#1}%
+%    \end{macrocode}
+%
+% A helper command to convert the title into a pdfstring similar to 
+% \cs{pdfstringdef}.
+% As we use \cs{text_purify} we must ensure that the default definitions
+% of \cs{@title} and \cs{@author} are robust:
+%    \begin{macrocode}
+\protected\def\@title{\@latex at error{No \noexpand\title given}\@ehc}
+\protected\def\@author{\@latex at warning@no at line{No \noexpand\author given}}
+%    \end{macrocode}
+% TODO: This should be improved and moved into the pdf module so that 
+% it is generally available.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_title_pdfstring:nnN #1 #2 #3 % #1 text, #2 e.g. utf16/hex
+  {
+    \group_begin:
+%    \end{macrocode}
+% TODO: we need probably a common boolean to handle 
+% \cs{texorpdfstring} also without hyperref.
+%    \begin{macrocode}
+    \cs_set_eq:NN\texorpdfstring\use_ii:nn
+    \str_set:Ne \l_@@_title_tmpa_str {\text_purify:n { #1 } }     
+    \pdf_string_from_unicode:nVN { #2 } \l_@@_title_tmpa_str \l_@@_title_tmpa_str
+    \str_gset_eq:NN \g_@@_title_tmpa_str\l_@@_title_tmpa_str
+    \group_end:
+    \str_set_eq:NN #3 \g_@@_title_tmpa_str
+  }
+\cs_generate_variant:Nn\@@_title_pdfstring:nnN {e} 
+%    \end{macrocode}
+
+% \subsection{Extend title to set metadata}
+% At first a variable to store the title, as \cs{@title} is emptied by \LaTeX. 
+%    \begin{macrocode}
+\tl_new:N \g_@@_title_title_tl 
+%    \end{macrocode}
+% Now we redefine \cs{title} so that it stores the title, and processes
+% keys in the optional argument. We use \texttt{hyp} as module
+% name for the key as this means that if hyperref is loaded its definition
+% of \texttt{pdftitle} will be used -- at some time probably this
+% should be moved out of hyperref so that we have only one definition.
+% 
+%    \begin{macrocode}
+\RenewDocumentCommand\title{O{}m}
+ {
+    \gdef\@title{#2}
+    \tl_gset_eq:NN\g_@@_title_title_tl\@title
+    \keys_set:nn {hyp}{#1}
+ } 
+%    \end{macrocode}
+% Now we define the \texttt{pdftitle} key. This is more or less
+% the same definition as in the generic hyperref driver. 
+%    \begin{macrocode}
+\regex_new:N\l_@@_title_optlang_regex
+\regex_set:Nn\l_@@_title_optlang_regex {\A\[([A-Za-z\-]+)\](.*)}
+\cs_generate_variant:Nn \regex_extract_once:NnN{NVN}
+\cs_generate_variant:Nn \clist_item:nn {on}
+%    \end{macrocode}
+% and now the keys.
+%    \begin{macrocode}
+\keys_define:nn { hyp }
+   {
+     pdftitle  .code:n =
+       {
+         \tl_if_blank:nTF {#1}
+           {
+             \pdfmanagement_remove:nn {Info}{Title}
+           }
+           {
+             \tl_set:Ne\l_@@_title_tmpa_tl {\clist_item:on{#1}{1}}           
+             \regex_extract_once:NVN 
+                \l_@@_title_optlang_regex 
+                \l_@@_title_tmpa_tl
+                \l_@@_title_tmpa_seq
+             \seq_if_empty:NTF\l_@@_title_tmpa_seq
+              {
+                \@@_title_pdfstring:nnN {#1}{utf16/hex}\l_@@_title_tmpa_str
+              }
+              {         
+                \@@_title_pdfstring:enN 
+                   {\seq_item:Nn \l_@@_title_tmpa_seq{3}}{utf16/hex}\l_@@_title_tmpa_str
+              }
+             \str_if_eq:VnF\l_@@_title_tmpa_str{<FEFF>}
+               {
+                 \pdfmanagement_add:nne {Info}{Title}{\l_@@_title_tmpa_str}
+               }
+           }
+          \AddToDocumentProperties[hyperref]{pdftitle}{#1}
+       }
+   ,pdfsubtitle .code:n = { \AddToDocumentProperties[hyperref]{pdfsubtitle}{#1} }    
+   }
+%    \end{macrocode}
+%
+% \subsection{Extend \cs{author} to set metadata}
+% 
+% At first a variable to store the authors, as \cs{@author} is emptied by \LaTeX. 
+%    \begin{macrocode}
+\tl_new:N \g_@@_title_author_tl 
+%    \end{macrocode}
+% Now we redefine \cs{author} so that it stores the authors, and processes
+% keys in the optional argument. We use \texttt{hyp} as module
+% name for the key as this means that if hyperref is loaded its definition
+% of \texttt{pdfauthor} will be used -- at some time probably this
+% should be moved out of hyperref so that we have only one definition.
+% 
+%    \begin{macrocode}
+\RenewDocumentCommand\author{O{}m}
+ {
+    \gdef\@author{#2}
+    \tl_gset_eq:NN\g_@@_title_author_tl\@author
+    \keys_set:nn {hyp}{#1}
+ } 
+%    \end{macrocode}
+%
+% Now we define the \texttt{pdfauthor} key. This is more or less
+% the same definition as in the generic hyperref driver. 
+
+%    \begin{macrocode}
+\keys_define:nn { hyp }
+   {
+     pdfauthor  .code:n =
+       {
+         \tl_if_blank:nTF {#1}
+           {
+             \pdfmanagement_remove:nn {Info}{Author}
+           }
+           {
+             \tl_set:Ne\l_@@_title_tmpa_tl {\clist_item:on{#1}{1}}           
+             \regex_extract_once:NVN 
+                \l_@@_title_optlang_regex 
+                \l_@@_title_tmpa_tl
+                \l_@@_title_tmpa_seq
+             \seq_if_empty:NTF\l_@@_title_tmpa_seq
+              {
+                \@@_title_pdfstring:nnN {#1}{utf16/hex}\l_@@_title_tmpa_str
+              }
+              {         
+                \@@_title_pdfstring:enN 
+                   {\seq_item:Nn \l_@@_title_tmpa_seq{3}}{utf16/hex}\l_@@_title_tmpa_str
+              }
+             \str_if_eq:VnF\l_@@_title_tmpa_str{<FEFF>}
+               {
+                 \pdfmanagement_add:nne {Info}{Author}{\l_@@_title_tmpa_str}
+               }
+           }
+          \AddToDocumentProperties[hyperref]{pdfauthor}{#1}
+       }
+   }
+%    \end{macrocode}
+% \subsection{Fallback for classes and packages that redefine \cs{title} or \cs{author}}
+% If a class redefines \cs{author} and \cs{title} again, we try to retrieve at
+% least the values. 
+%    \begin{macrocode}
+\AddToHook{cmd/maketitle/before}
+  {
+   \tl_gset_eq:NN \g_@@_title_author_tl\@author
+   \tl_gset_eq:NN \g_@@_title_title_tl\@title
+  }  
+%    \end{macrocode}
+%
+% \subsection{Finalize document}
+% At last we set the title and the author at the end of document 
+% if that hasn't happened yet:
+%    \begin{macrocode}
+\AddToHook{shipout/lastpage}
+ {
+   \tl_if_empty:eT{\GetDocumentProperties{hyperref/pdftitle}}
+      { 
+        \group_begin:
+        \cs_set_eq:NN\thanks \use_none:n
+        \str_set:Ne \l_@@_title_tmpa_str {\text_purify:n { \g_@@_title_title_tl } }
+        \keys_set:ne{hyp}{pdftitle={\exp_not:V\l_@@_title_tmpa_str}}
+        \group_end:
+      }
+   \tl_if_empty:eT{\GetDocumentProperties{hyperref/pdfauthor}}
+      { 
+        \group_begin:
+        \cs_set_eq:NN\thanks \use_none:n
+        \cs_set:Npn \and {,}
+        \str_set:Ne \l_@@_title_tmpa_str {\text_purify:n { \g_@@_title_author_tl } }
+        \keys_set:ne{hyp}{pdfauthor={\exp_not:V\l_@@_title_tmpa_str}}
+        \group_end:
+      }
+%    \end{macrocode}
+% force display title, if an UA-standard is detected.
+%    \begin{macrocode}
+   \tl_if_empty:eF{\GetDocumentProperties{document/pdfstandard-UA}}
+     {
+       \pdfmanagement_add:nnn {Catalog / ViewerPreferences } { DisplayDocTitle } { true }
+     }            
+ }
+\DeclareHookRule{shipout/lastpage}{latex-lab-testphase-title}{before}{pdfmanagement-testphase}
+%</package>  
+%    \end{macrocode}
+
+%    \begin{macrocode}
+%<*latex-lab>
+\ProvidesFile{title-latex-lab-testphase.ltx}
+        [\ltlabtitledate\space v\ltlabtitleversion\space
+         Changes related to the tagging of the title]
+
+\RequirePackage{latex-lab-testphase-title}
+
+%</latex-lab>
+%    \end{macrocode}


Property changes on: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-title.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-hyperref-changes.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-hyperref-changes.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-hyperref-changes.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-%% File: latex-lab-toc-hyperref-changes.dtx (C) Copyright 2022-2023 LaTeX Project
+%% File: latex-lab-toc-hyperref-changes.dtx (C) Copyright 2022-2024 LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-kernel-changes.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-kernel-changes.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc-kernel-changes.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-%% File: latex-lab-toc-kernel-changes.dtx (C) Copyright 2022-2023 LaTeX Project
+%% File: latex-lab-toc-kernel-changes.dtx (C) Copyright 2022-2024 LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -17,8 +17,8 @@
 % for those people who are interested or want to report an issue.
 %
 % dates for latex-lab-kernel-changes.sty (pulled from various sources, see ins)
-\def\ltlabkerneldate{2023-10-16}
-\def\ltlabkernelversion{0.85b}
+\def\ltlabkerneldate{2024-02-12}
+\def\ltlabkernelversion{0.85c}
 %<*driver>
 \documentclass{l3doc}
 \EnableCrossrefs
@@ -235,7 +235,7 @@
     \makeatletter
     \@starttoc at cfgpoint@before{#1}%
     \@input{\jobname.#1}%
-    \@starttoc at cfgpoint@after{#1}
+    \@starttoc at cfgpoint@after{#1}%
     \if at filesw
       \expandafter\newwrite\csname tf@#1\endcsname
       \immediate\openout \csname tf@#1\endcsname \jobname.#1\relax

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab-toc.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-%% File: latex-lab-toc.dtx (C) Copyright 2022-2023 LaTeX Project
+%% File: latex-lab-toc.dtx (C) Copyright 2022-2024 LaTeX Project
 %
 % It may be distributed and/or modified under the conditions of the
 % LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -271,7 +271,7 @@
             { \int_compare_p:nNn { \g_@@_toc_level_int } > {-100} }
             { \int_compare_p:nNn { \use:c{toclevel@#1} }   > { \g_@@_toc_level_int } }
             {
-              \seq_gpush:Nx \g_@@_toc_stack_seq {{TOC}\use:c{toclevel@#1}}
+              \seq_gpush:Ne \g_@@_toc_stack_seq {{TOC}\use:c{toclevel@#1}}
               \tag_struct_begin:n{tag=TOC}
             }
 %    \end{macrocode}
@@ -298,7 +298,7 @@
 %    \begin{macrocode}
           \group_begin:
            \text_declare_expand_equivalent:Nn \numberline \use_none:n
-           \exp_args:Nx \tag_struct_begin:n{tag=TOCI,title={\text_purify:n {#2}}}
+           \exp_args:Ne \tag_struct_begin:n{tag=TOCI,title={\text_purify:n {#2}}}
 %    \end{macrocode}
 % The TOCI structure should get a /Ref, so we put a request with its destination
 % name into the prop.
@@ -307,9 +307,9 @@
 % need to store fake names.
 % \end{NOTE}
 %    \begin{macrocode}
-           \prop_gput:Nxx \g_@@_struct_ref_by_dest_prop
+           \prop_gput:Nee \g_@@_struct_ref_by_dest_prop
              { \tag_get:n {struct_num} }{#3}
-           \seq_gpush:Nx \g_@@_toc_stack_seq {{TOCI}\use:c{toclevel@#1}}
+           \seq_gpush:Ne \g_@@_toc_stack_seq {{TOCI}\use:c{toclevel@#1}}
           \group_end:
        }
     }

Modified: trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab.ins	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/latex-lab/latex-lab.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -154,9 +154,17 @@
 
 %table
 \generate{\file{table-latex-lab-testphase.ltx}{\from{latex-lab-table.dtx}{latex-lab}}}
+\generate{\file{tabular-latex-lab-testphase.ltx}{\from{latex-lab-table.dtx}{latex-lab-alias}}}
 \generate{\file{latex-lab-testphase-table.sty}{\from{latex-lab-table.dtx}{package}}}
 
+%title
+\generate{\file{title-latex-lab-testphase.ltx}{\from{latex-lab-title.dtx}{latex-lab}}}
+\generate{\file{latex-lab-testphase-title.sty}{\from{latex-lab-title.dtx}{package}}}
 
+%marginpar
+\generate{\file{marginpar-latex-lab-testphase.ltx}{\from{latex-lab-marginpar.dtx}{latex-lab}}}
+\generate{\file{latex-lab-testphase-marginpar.sty}{\from{latex-lab-marginpar.dtx}{package}}}
+
 % stop docstrip adding \endinput
 \preamble
 \endpreamble

Modified: trunk/Master/texmf-dist/source/latex/tools/afterpage.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/afterpage.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/afterpage.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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.

Modified: trunk/Master/texmf-dist/source/latex/tools/afterpage.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/afterpage.ins	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/afterpage.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -3,7 +3,7 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
@@ -45,7 +45,7 @@
 reports for it can be opened at https://latex-project.org/bugs/
 (but please observe conditions on bug reports sent to that address!)
 
-Copyright (C) 1993-2023
+Copyright (C) 1993-2024
 The LaTeX Project and any individual authors listed elsewhere
 in this file.
 

Modified: trunk/Master/texmf-dist/source/latex/tools/array.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/array.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/array.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2023
+% Copyright (C) 1993-2024
 %
 % The LaTeX Project and any individual authors listed elsewhere
 % in this file.
@@ -25,15 +25,21 @@
 %% Package `array' to use with LaTeX 2e
 %% Copyright (C) 1989-1998 Frank Mittelbach, all rights reserved.
 %<+package>\NeedsTeXFormat{LaTeX2e}[1995/06/01]
-%<+package>\providecommand\DeclareRelease[3]{}
-%<+package>\providecommand\DeclareCurrentRelease[2]{}
 %<+package>
+% For anything before 2016-10-06 we load the 2016 version and hope for the best:
+%<+package>\DeclareRelease{}{1994-06-01}{array-2016-10-06.sty}
+%
 %<+package>\DeclareRelease{}{2016-10-06}{array-2016-10-06.sty}
 %<+package>\DeclareRelease{v2.4}{2020-02-10}{array-2020-02-10.sty}
-%<+package>\DeclareCurrentRelease{}{2020-10-01}
+%<+package>\DeclareRelease{v2.5}{2023-11-01}{array-2023-11-01.sty}
+%<+package>\DeclareCurrentRelease{}{2024-06-01}
 %<+package>
+%    \end{macrocode}
+%    Current version needs a new kernel.
+%    \begin{macrocode}
+%<+package>\NeedsTeXFormat{LaTeX2e}[2024/06/01]
 %<+package>\ProvidesPackage{array}
-%<+package>         [2023/10/16 v2.5g Tabular extension package (FMi)]
+%<+package>         [2024/05/23 v2.6c Tabular extension package (FMi)]
 %
 % \fi
 %
@@ -177,6 +183,18 @@
 % \DoNotIndex{\xdef}
 % \DoNotIndex{\z@}
 %
+%
+% \providecommand\env[1]{\texttt{#1}}
+%
+% \providecommand\hook[1]{\texttt{#1\DescribeHook[noprint]{#1}}}
+% \providecommand\socket[1]{\texttt{#1\DescribeSocket[noprint]{#1}}}
+% \providecommand\plug[1]{\texttt{#1\DescribePlug[noprint]{#1}}}
+%
+% \NewDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl}
+% \NewDocElement[printtype=\textit{hook},idxtype=hook,idxgroup=Hooks]{Hook}{hookdecl}
+% \NewDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl}
+%
+%
 % \GetFileInfo{array.sty}
 %
 % \title{A new implementation of \LaTeX's \textsf{tabular}
@@ -195,6 +213,8 @@
 % \MaintainedByLaTeXTeam{tools}
 % \maketitle
 %
+%
+%
 % \MakeShortVerb{\=}
 %
 % \begin{abstract}
@@ -750,12 +770,29 @@
 % \end{itemize}
 %
 %
+% \section{Support for tagged PDF}
 %
+% With version 2.6a the package is made tagging aware, which means that
+% it will automatically produce tagged tables (necessary, for example, for
+% accessibility) if tagging is requested via \cs{DocumentMetadata}.
+%
+% More granular control, e.g., explicitly deciding which cells are
+% header cells, etc., is currently under development, but syntax for
+% this will not appear in this package. Instead it will become
+% available across all tabular-generating packages and then
+% automatically apply here as well.
+%
+% Enabling \LaTeX{} to automatically produce tagged PDF is a long-term
+% project and this is a tiny step in this puzzle. For more information
+% on the project and already available functionality, see
+% \url{https://latex-project.org/publications/indexbytopic/pdf} and
+% \url{https://github.com/latex3/tagging-project}.
+%
+%
+%
 % \changes{v2.2b}{1994/02/04}{Removed interactive prompt}
 %
 % \MaybeStop{
-%
-%
 % \begin{thebibliography}{1}
 %    \bibitem{bk:GMS94} \textsc{M.~Goossens}, \textsc{F.~Mittelbach}
 %       and \textsc{A.~Samarin}.
@@ -772,7 +809,6 @@
 %       \newblock
 %       Addison-Wesley, Reading, Massachusetts, 1986.
 % \end{thebibliography}
-%
 % }   ^^A  end of \MaybeStop
 %
 %
@@ -786,9 +822,50 @@
 % \texttt{docstrip} program.
 %    \begin{macrocode}
 %<*driver>
-\NeedsTeXFormat{LaTeX2e}[1995/12/01]
-\documentclass{ltxdoc}
+\NeedsTeXFormat{LaTeX2e}[2024/06/01]
+%    \end{macrocode}
+%
+%    We switched from \cls{ltxdoc} to \cls{l3doc} to get support for
+%    code written in the L3 programming layer. The first is that we
+%    are currently missing \cs{MaintainedByLaTeXTeam}, so we have to
+%    provide that for now. 
+%    \begin{macrocode}
+\documentclass{l3doc}
 
+% currently missing in l3doc
+\makeatletter
+\def\MaintainedBy#1{\gdef\@maintainedby{#1}}
+\let\@maintainedby\@empty
+\def\MaintainedByLaTeXTeam#1{%
+{\gdef\@maintainedby{%
+This file is maintained by the \LaTeX{} Project team.\\%
+Bug reports can be opened (category \texttt{#1}) at\\%
+\url{https://latex-project.org/bugs.html}.}}}
+\def\@maketitle{%
+  \newpage
+  \null
+  \vskip 2em%
+  \begin{center}%
+  \let \footnote \thanks
+    {\LARGE \@title \par}%
+    \vskip 1.5em%
+    {\large
+      \lineskip .5em%
+      \begin{tabular}[t]{c}%
+        \@author
+      \end{tabular}\par}%
+    \vskip 1em%
+    {\large \@date}%
+    \ifx\@maintainedby\@empty
+    \else
+    \vskip 1em%
+    \fbox{\fbox{\begin{tabular}{@{}l@{}}\@maintainedby\end{tabular}}}%
+    \fi
+  \end{center}%
+  \par
+  \vskip 1.5em}
+\makeatother
+
 % undo the default is not used:
 
 \IfFormatAtLeastTF {2020/10/01}
@@ -817,6 +894,29 @@
 %    \end{macrocode}
 %
 %
+% \section{A note on the updates done December 2023}
+%
+% We introduced support for tagged PDf and at the same time we added
+% code to determine row and column numbers for each cell in
+% preparation for supporting  formatting or type specifications for individual
+% cells (or group of cells) from the outside, e.g., \enquote{rows 1,
+% 2, and 10 are header rows} (syntax to be decided).
+%
+% This new code is already written with L3 programming layer conventions
+% while most of the legay code is still as it was before. This make the code
+% currently somewhat clattered, unfortunately. Eventually this will all move to L3
+% programming layer but this will take time.
+%
+%
+%    \begin{macrocode}
+%<@@=tbl>
+\ExplSyntaxOn
+%    \end{macrocode}
+%
+%
+%
+%
+%
 % \section{The construction of the preamble}
 %
 % \DeleteShortVerb{\"}
@@ -972,6 +1072,7 @@
 %    =\@chclass= and =\@chnum=.
 % \changes{v2.0f}{1992/02/29}{Argument removed since implicitly known}
 %    \begin{macrocode}
+\ExplSyntaxOff
 \def\@testpach{\@chclass
 %    \end{macrocode}
 %    First we deal with the cases in which the \textsf{token}
@@ -981,7 +1082,7 @@
  \ifnum \@lastchclass=6 \@ne \@chnum \@ne \else
   \ifnum \@lastchclass=7 5 \else
    \ifnum \@lastchclass=8 \tw@ \else
-    \ifnum \@lastchclass=9 \thr@@
+    \ifnum \@lastchclass=9 \thr@@@@
 %    \end{macrocode}
 %    Otherwise we will assume that the \textsf{token} belongs to the
 %    class $0$
@@ -1032,7 +1133,7 @@
 %    \begin{macrocode}
   10
   \@chnum
-  \if \@nextchar m\thr@@\else
+  \if \@nextchar m\thr@@@@ \else
    \if \@nextchar p4 \else
     \if \@nextchar b5 \else
 %    \end{macrocode}
@@ -1042,6 +1143,7 @@
 %    \begin{macrocode}
    \z@ \@chclass \z@ \@preamerr \z@ \fi \fi \fi \fi
    \fi \fi  \fi  \fi  \fi  \fi  \fi \fi \fi \fi \fi \fi}
+\ExplSyntaxOn
 %    \end{macrocode}
 % \end{macro}
 %
@@ -1062,10 +1164,10 @@
 %    they are in explicit braces, as in =@{*}=.
 %
 %    This macro is called via
-%    =\@xexpast=\meta{preamble}=*0x\@@=.
+%    =\@xexpast=\meta{preamble}=*0x\@@@@=.
 %    The $*$--expression =*0x= is being used to terminate the
 %    recursion,
-%    as we shall see later, and =\@@= serves as an argument
+%    as we shall see later, and =\@@@@= serves as an argument
 %    delimiter. =\@xexpast= has four arguments. The first
 %    one is the part of the
 %    user preamble before the first $*$--expression while the second
@@ -1074,7 +1176,7 @@
 %    above).
 %    The fourth argument is the rest of the preamble.
 %    \begin{macrocode}
-\def\@xexpast#1*#2#3#4\@@{%
+\def\@xexpast#1*#2#3#4\@@@@{%
 %    \end{macrocode}
 %    The number of copies of \textit{String} (=#2=) that are to be
 %    produced will be saved in a \textsf{count} register.
@@ -1111,7 +1213,7 @@
 %    \end{macrocode}
 %    If \textit{N\/} was greater than zero we prepare for another call
 %    of =\@xexpast=. Otherwise we assume we have reached the end of
-%    the user preamble, because we had appended =*0x\@@= when we first
+%    the user preamble, because we had appended =*0x\@@@@= when we first
 %    called =\@xexpast=.  In other words: if the user inserts
 %    =*{0}{..}= in his preamble, \LaTeX\ ignores the rest of it.
 %    \begin{macrocode}
@@ -1133,7 +1235,7 @@
 %    $*$--expression is handled, or to the macro =\@xexnoop=,
 %    which only ends the recursion by deleting its argument.
 %    \begin{macrocode}
-   \expandafter \@tempb \@tempa #4\@@}
+   \expandafter \@tempb \@tempa #4\@@@@}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -1142,10 +1244,10 @@
 % \begin{macro}{\@xexnoop}
 %    So the first big problem is solved. Now it is easy to
 %    specify =\@xexnoop=.
-%    Its argument is delimited by =\@@= and it simply expands to
+%    Its argument is delimited by =\@@@@= and it simply expands to
 %    nothing.
 %    \begin{macrocode}
-%  \def\@xexnoop#1\@@{}
+%  \def\@xexnoop#1\@@@@{}
 %    \end{macrocode}
 % \end{macro}
 %
@@ -1270,11 +1372,19 @@
 %
 % \begin{macro}{\insert at column}
 % \begin{macro}{\@sharp}
+% \begin{macro}{\textonly at unskip}
 %    We now define the macro =\insert at column= which will do
 %    this work for us.
 %    \begin{macrocode}
 \def\insert at column{%
 %    \end{macrocode}
+%
+%    For tagging we insert as special socket, that adds the necessary
+%    PDF tag at the beginning of the cell if tagging is enabled.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+%    \begin{macrocode}
+  \UseTaggingSocket{tbl/cell/begin}%
+%    \end{macrocode}
 %    Here, we assume that the \textsf{count} register
 %    =\@tempcnta= has saved the value $=\count@= - 1$.
 %    \begin{macrocode}
@@ -1291,8 +1401,9 @@
 % \changes{v2.0e}{1991/02/07}{Added \{\} around \cs{@sharp} for new ftsel}
 % \changes{v2.0h}{1992/06/22}{Removed \{\} again in favour of
 %                             \cs{d at llarbegin}}
+% \changes{v2.6b}{2024/04/08}{Do not \cs{unskip} if in math mode (gh/1323)}
 %    \begin{macrocode}
-   \ignorespaces \@sharp \unskip
+   \ignorespaces \@sharp \textonly at unskip
 %    \end{macrocode}
 %    Then the second \textsf{token} register follows whose number should
 %    be saved in =\count@=.
@@ -1302,12 +1413,42 @@
 % \changes{v2.0c}{1990/08/14}{\cs{relax} added to avoid problem
 %                           \cs{the}\cs{toks0}\cs{the}\cs{toks1}.}
 %    \begin{macrocode}
-   \the at toks \the \count@ \relax}
+   \the at toks \the \count@ \relax
 %    \end{macrocode}
+%
+%    And another socket for tagging that adds the necessary closing tag
+%    if enabled.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+%    \begin{macrocode}
+   \UseTaggingSocket{tbl/cell/end}%
+}
+%    \end{macrocode}
+%    Do the unskip only if we are in hmode:
+% \changes{v2.6b}{2024/04/08}{Do not \cs{unskip} if in math mode (gh/1323)}
+%    \begin{macrocode}
+\protected\def\textonly at unskip{\ifhmode\unskip\fi}
+%    \end{macrocode}
 % \end{macro}
 % \end{macro}
+% \end{macro}
 %
 %
+%  \begin{macro}{\insert at pcolumn}
+%    Handling pcolumn-cells needs slightly different handling when
+%    doing tagging.  Rather than changing the plugs in
+%    \cs{insert at column} back and forth, we simply use a different
+%    version of \cs{insert at column} that has its own sockets.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+%    \begin{macrocode}
+\def\insert at pcolumn{%
+   \UseTaggingSocket{tbl/pcell/begin}%
+   \the at toks \the \@tempcnta
+   \ignorespaces \@sharp \unskip
+   \the at toks \the \count@ \relax
+   \UseTaggingSocket{tbl/pcell/end}%
+}
+%    \end{macrocode}
+%  \end{macro}
 %
 %
 % \subsection{The separation of columns}
@@ -1321,11 +1462,24 @@
 %    =\@addamp=, the macro that inserts the =&=.
 %    \begin{macrocode}
 %    \newif \@iffirstamp
-%    \def\@addamp{\if at firstamp \@firstampfalse
-%                 \else \@addtopreamble &\fi}
+\def\@addamp {
+  \if at firstamp
+    \@firstampfalse
+  \else
 %    \end{macrocode}
+%    If we are after the first column we have to insert a \verb=&= and
+%    also update the cell data.
+% \changes{v2.6a}{2023/12/11}{Managing cell indexes}
+%    \begin{macrocode}
+    \edef\@preamble{\@preamble &
+      \noexpand\tbl_update_cell_data: }
+  \fi
+}
+%    \end{macrocode}
 % \end{macro}
 %
+%
+%
 % \begin{macro}{\@acol}
 % \begin{macro}{\@acolampacol}
 % \begin{macro}{\col at sep}
@@ -1393,7 +1547,7 @@
 %    command =\@xexpast=.  As we already know, this command saves
 %    its result in the macro =\@tempa=.
 %    \begin{macrocode}
-%   \@xexpast #1*0x\@@
+%   \@xexpast #1*0x\@@@@
 %    \end{macrocode}
 %    Afterwards we initialize all registers and macros, that we need
 %    for the build-up of the preamble.
@@ -1477,7 +1631,7 @@
 %    \texttt{r}, \texttt{p},\texttt{m} or \texttt{b}. We report an
 %    error and ignore the declaration given by ={..}=.
 %    \begin{macrocode}
-%   \@preamerr \thr@@ \or
+%   \@preamerr \thr@@@@ \or
 %    \end{macrocode}
 %    If =\@lastchclass= is $4$ the user preamble has been empty.
 %    To continue, we insert a =#= in the preamble.
@@ -1671,18 +1825,17 @@
     \setbox\ar at mcellbox\vbox
 %    \end{macrocode}
 %    The part of the templates which is the same in all three cases
-%    (\texttt{p}, \texttt{m} and \texttt{b})
-%    is built by the macros =\@startpbox= and
-%    =\@endpbox=. =\@startpbox= has an argument:
-%    the width of the column which is stored in the current
-%    \textsf{token} (i.e.\ =\@nextchar=).
-%    Between these two macros we find the well known
-%    =\insert at column=.
-%    The strut is places after the box
+%    (\texttt{p}, \texttt{m} and \texttt{b}) is built by the macros
+%    =\@startpbox= and =\@endpbox=. =\@startpbox= has an argument: the
+%    width of the column which is stored in the current \textsf{token}
+%    (i.e.\ =\@nextchar=).  Between these two macros we find the well
+%    known =\insert at column= or rather the variant for tagging:
+%    \cs{insert at pcolumn}.  The strut is placed after the box.
 % \changes{v2.4e}{2016/10/07}{Fixing SX68732}
 % \changes{v2.4f}{2017/11/04}{Managing m-cells without \cs{vcenter}}
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
 %    \begin{macrocode}
-    \@startpbox{\@nextchar}\insert at column \@endpbox
+    \@startpbox{\@nextchar}\insert at pcolumn \@endpbox
     \ar at align@mcell
     \do at row@strut \or
 %    \end{macrocode}
@@ -1690,9 +1843,10 @@
 %    same way though we do not need the =$= characters because we use
 %    =\vtop= or =\vbox=.
 % \changes{v2.4e}{2016/10/07}{Fixing SX68732}
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
 %    \begin{macrocode}
-   \vtop \@startpbox{\@nextchar}\insert at column \@endpbox\do at row@strut \or
-   \vbox \@startpbox{\@nextchar}\insert at column \@endpbox\do at row@strut
+   \vtop \@startpbox{\@nextchar}\insert at pcolumn \@endpbox\do at row@strut \or
+   \vbox \@startpbox{\@nextchar}\insert at pcolumn \@endpbox\do at row@strut
 %    \end{macrocode}
 %    Other values for =\@chnum= are impossible. Therefore we
 %    end the arguments to =\@addtopreamble= and =\ifcase=.
@@ -1783,8 +1937,8 @@
 %    So the declarations defined by the first  =>{...}=
 %    are ignored.
 %    \begin{macrocode}
-%\def\@classix{\ifnum \@lastchclass = \thr@@
-%       \@preamerr \thr@@ \fi
+%\def\@classix{\ifnum \@lastchclass = \thr@@@@
+%       \@preamerr \thr@@@@ \fi
 %    \end{macrocode}
 %    Furthermore, we call up =\@class10= because afterwards always a
 %    new column is started by \texttt{c}, \texttt{l}, \texttt{r},
@@ -1836,7 +1990,7 @@
 %    We only check if the last \textsf{token} was of class $3$ which is
 %    forbidden.
 %    \begin{macrocode}
-\def\@classvii{\ifnum \@lastchclass = \thr@@
+\def\@classvii{\ifnum \@lastchclass = \thr@@@@
 %    \end{macrocode}
 %    If this is true we output an error message and
 %    ignore the declarations stored
@@ -1843,7 +1997,7 @@
 %    by the last  =>{...}=, because these are overwritten
 %    by the argument of \texttt{@}.
 %    \begin{macrocode}
-   \@preamerr \thr@@ \fi}
+   \@preamerr \thr@@@@ \fi}
 %    \end{macrocode}
 % \end{macro}
 %
@@ -2032,7 +2186,7 @@
 %    second one describes the wanted preamble,
 %    e.g.\ it has the form =|c|c|c|=.
 %    \begin{macrocode}
-\def\@array[#1]#2{%
+\def\@array[#1]#2{
 %    \end{macrocode}
 %    First we define a \textsf{strut} whose size basically corresponds
 %     to a normal \textsf{strut} multiplied by the factor
@@ -2051,6 +2205,14 @@
              \@depth \arraystretch \dp \strutbox
              \@width \z@}%
 %    \end{macrocode}
+%    The total number of table columns of the current table is
+%    determined in \cs{tbl_count_table_cols:} but this is called in
+%    a group, so local settings do not survive. Thus, to save away the
+%    outer value of \cs{g_@@_table_cols_tl} we do it before the group.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+%    \begin{macrocode}
+  \tbl_save_outer_table_cols:
+%    \end{macrocode}
 %    Then we open a group, in which the user preamble is evaluated by
 %    the macro =\@mkpream=. As we know this must happen locally.
 %    This macro creates a preamble for a =\halign= and saves
@@ -2059,6 +2221,11 @@
   \begingroup
   \@mkpream{#2}%
 %    \end{macrocode}
+%    Figure out how many columns this table has:
+% \changes{v2.6a}{2023/12/11}{Managing cell indexes}
+%    \begin{macrocode}
+  \tbl_count_table_cols:
+%    \end{macrocode}
 %    We again redefine =\@preamble= so that a call up of =\@preamble=
 %    now starts the =\halign=. Thus also the arguments of \texttt{>},
 %    \texttt{<}, \texttt{@} and \texttt{!}, saved in the
@@ -2085,13 +2252,38 @@
 %    unsupported redefinition of a \TeX{} primitive for the moment (as people rely
 %    on that experimental code).
 %    \begin{macrocode}
-  \xdef\@preamble{\noexpand \ialign \@halignto
-                  \bgroup \@arstrut \@preamble
-                          \tabskip \z@ \cr}%
+  \xdef\@preamble{
 %    \end{macrocode}
+%    \cs{ialign} in the original definition is replaced by
+%    \cs{ar at ialign} defined below. This does what \cs{ialign} does but
+%    additionally handles the tagging structure for the whole table if necessary.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+%    \begin{macrocode}
+    \noexpand \ar at ialign
+    \@halignto
+       \bgroup \@arstrut
+%    \end{macrocode}
 %    What we have not explained yet is the macro =\@halignto=
 %    that was just used. Depending on its replacement text the
 %    =\halign= becomes a =\halign= \texttt{to} \meta{dimen}.
+%
+%    Next, a tagging support socket is inserted adding the start row tag.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+%    \begin{macrocode}
+      \UseTaggingSocket{tbl/row/begin}
+%    \end{macrocode}
+%    At the start of the preamble for the first column we call
+%    \cs{tbl_init_cell_data_for_row:} to initialize the cell index data. In
+%    later columns this data is updated via \cs{tbl_update_cell_data:}.
+% \changes{v2.6a}{2023/12/11}{Managing cell indexes}
+%    \begin{macrocode}
+      \tbl_init_cell_data_for_row:
+%    \end{macrocode}
+%    
+%    \begin{macrocode}
+      \@preamble
+      \tabskip \z@ \cr}
+%    \end{macrocode}
 %    Now we close the group again. Thus
 %    =\@startpbox= and =\@endpbox= as well as all
 %    \textsf{token} registers get their former meaning back.
@@ -2128,13 +2320,17 @@
 %    around every column in the \textsf{array}--environment
 %     the parameter =\mathsurround= should
 %    also be set to \textsf{0pt}. This prevents additional space between
-%    the rows. The
-%    \PlainTeX--macro =\m at th= does this.
+%    the rows.
 %    \begin{macrocode}
   \lineskip \z@
   \baselineskip \z@
-  \m at th
 %    \end{macrocode}
+%    Don't use \cs{m at th} here as that signals to the math taggingg
+%    code that this is fake math that should not be tagged.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+%    \begin{macrocode}
+  \mathsurround \z@
+%    \end{macrocode}
 %    Beside, we have to assign a special meaning (which we still have
 %    to specify) to the line separator =\\=. We also have to
 %    redefine the command =\par= in such a way that empty lines in
@@ -2144,10 +2340,61 @@
 %    start the wanted =\halign=.
 %    \changes{1994/12/08}{v2.3b}{add \cs{tabularnewline}}
 %    \begin{macrocode}
-  \let\\\@arraycr \let\tabularnewline\\\let\par\@empty \@preamble}
+  \let\\\@arraycr \let\tabularnewline\\\let\par\@empty
 %    \end{macrocode}
+%    Another socket for tagging. TODO: what about \cs{arrayleft} above?
+%    \begin{macrocode}
+  \UseTaggingSocket{tbl/init}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+  \@preamble
+}
+%    \end{macrocode}
 % \end{macro}
 %
+%
+%
+% \begin{macro}{\ar at ialign}
+%    A new command that replaces \cs{ialign} used previously.  \cs{everycr} is
+%    also applied to the \cs{cr} ending the preamble so we have to
+%    program around that.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+%    \begin{macrocode}
+\def\ar at ialign{%
+%    \end{macrocode}
+%    Before starting a table we have to initialize the variables
+%    holding row and column information for cells. We also have
+%    locally store the information related to the current cell (if we
+%    are already inside a table) so that we can restore it once the
+%    inner table is finished.
+% \changes{v2.6a}{2023/12/11}{Managing cell indexes}
+%    \begin{macrocode}
+  \tbl_init_cell_data_for_table:
+%    \end{macrocode}
+%    
+%    \begin{macrocode}
+  \everycr{%
+    \noalign{%
+%    \end{macrocode}
+%    If this \cs{cr} was at the end of a real row (e.g., not at the
+%    end of the table preamble) we have add a row end tag. 
+%    \begin{macrocode}
+      \tbl_if_row_was_started:T  { \UseTaggingSocket{tbl/row/end} }
+%    \end{macrocode}
+%    The we prepare for the next row.
+%    \begin{macrocode}
+      \tbl_update_cell_data_for_next_row:
+    }%
+  }%
+  \tabskip\z at skip\halign}
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
 % \begin{macro}{\arraybackslash}
 % \changes{v2.4a}{2003/12/17}{(DPC) Macro added (from tabularx)}
 % Restore =\\= for use in array and tabular environment (after
@@ -2182,7 +2429,27 @@
 % \begin{macro}{\@arraycr}
 %    In the macro =\@array= the line separator =\\= is
 %    =\let= to the command =\@arraycr=.
-%    Its definition starts with a special brace which I have directly
+% \changes{v2.3c}{1995/04/23}{Avoid adding an ord atom in math}
+% \changes{v2.5e}{2021/04/20}{Use \cs{protected} for \cs{\bslash} variant (gh/548)}
+%    \begin{macrocode}
+\protected\def\@arraycr {
+%    \end{macrocode}
+%    Add code that figures out if the current table row is incomplete
+%    (not enough \verb=&=s). It can then do extra actions, such as
+%    inserting missing cell tags.
+% \changes{v2.6a}{2023/12/11}{Managing cell indexes}
+%    \begin{macrocode}
+  \tbl_count_missing_cells:n {@arraycr}
+%    \end{macrocode}
+%    TODO: maybe this is also the right place to add a socket that
+%    could be used to actually enter missing cells instead of just
+%    adding tagging structures for them later. This would be optional
+%    but in many cases it would be the right thing to do (for example
+%    if tables contain vertical lines or similar visual structures
+%    that require fully specified rows.
+%  
+%    
+%    We then start a special brace which I have directly
 %    copied from the original definition. It is
 %    necessary, because the =\futurlet= in =\@ifnextchar=
 %    might
@@ -2198,10 +2465,8 @@
 %    =\halign= while we are looking for a =*= or =[=.
 %    For further information see
 %    \cite[Appendix D]{bk:knuth}.
-% \changes{v2.3c}{1995/04/23}{Avoid adding an ord atom in math}
-% \changes{v2.5e}{2021/04/20}{Use \cs{protected} for \cs{\bslash} variant (gh/548)}
 %    \begin{macrocode}
-\protected\def\@arraycr{\relax\iffalse{\fi\ifnum 0=`}\fi
+  \iffalse{\fi\ifnum 0=`}\fi
 %    \end{macrocode}
 %    Then we test whether the user is using the star form and ignore
 %    a possible star (I also disagree with this procedure, because a
@@ -2210,6 +2475,11 @@
   \@ifstar \@xarraycr \@xarraycr}
 %    \end{macrocode}
 % \end{macro}
+
+
+
+
+
 %
 % \begin{macro}{\@xarraycr}
 %    In the command =\@xarraycr= we test if an optional argument
@@ -2301,6 +2571,7 @@
 %    the result column and the actual column entry.
 % \changes{v2.3j}{1998/01/29}{Command made \cs{long} to match
 %      kernel change for pr/2180}
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
 %    \begin{macrocode}
 \long\def\multicolumn#1#2#3{%
 %    \end{macrocode}
@@ -2310,6 +2581,16 @@
 %    \begin{macrocode}
    \multispan{#1}\begingroup
 %    \end{macrocode}
+%    For tagging support we have to solve two problems:
+%    \cs{multicolumn} must handle the row begin if it is used there,
+%    and it must save the numbers of cells it spans so that we can add
+%    a suitable ColSpan attribute. We do this in the next macro
+%    (which in turn calls the \texttt{tbl/row/begin} socket, if
+%    necessary).
+% \changes{v2.6a}{2023/12/11}{Managing cell indexes}
+%    \begin{macrocode}
+   \tbl_update_multicolumn_cell_data:n {#1}    
+%    \end{macrocode}
 %    Since a =\multicolumn= should only describe the format of a
 %    result column, we redefine =\@addamp= in such a way that one gets
 %    an error message if one uses more than one \texttt{c},
@@ -2336,6 +2617,12 @@
 %    \begin{macrocode}
    \endgroup
 %    \end{macrocode}
+%    Now we update the colspan attribute.  This needs setting after
+%    the group as it is hidden inside the plug in \cs{insert at column}.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+%    \begin{macrocode}
+   \UseTaggingSocket{tbl/colspan}{#1}%
+%    \end{macrocode}
 %    In the special situation of  =\multicolumn= =\@preamble=
 %    is not needed as preamble for a =\halign= but it is directly
 %    inserted into our table. Thus instead of =\sharp=
@@ -2458,6 +2745,12 @@
 %    \begin{macrocode}
   \leavevmode
 %    \end{macrocode}
+%    Now that we know we are in hmode we can add the start tag for the
+%    whole table.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+%    \begin{macrocode}
+  \UseTaggingSocket{tbl/hmode/begin}%
+%    \end{macrocode}
 %    It should be taken into consideration that the macro =\@array=
 %    must be called in math mode. Therefore we open a \textsf{box},
 %    insert a =$= and then assign the correct values to =\col at sep= and
@@ -2486,11 +2779,41 @@
 %    =\@array=. To save \textsf{token} space we then redefine
 %    =\@preamble=
 %    because its replacement text isn't longer needed.
+%
+%    To handle cell indexes, we do not use \cs{crcr} but a variant
+%    that also handles missing cells as necessary.
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
 %    \begin{macrocode}
-%\def\endarray{\crcr \egroup \egroup \gdef\@preamble{}}
+\def\endarray {
+  \tbl_crcr:n{endarray} \egroup
+  \UseTaggingSocket{tbl/finalize}
 %    \end{macrocode}
+%    
+%    If tables are nested into another then  it is necessary to
+%    restore information about the cell the inner table started
+%    in. Otherwise, the cell index data structures reflect the
+%    status in the outer table as they
+%    are globally manipulated. We restore in all cases even if we are
+%    not in a nesting situation as that makes the code simpler (and
+%    probably faster).
+%
+%    \cs{endtabular} and \cs{endtabular*} inherit from \cs{endarray}
+%    so we only need to change that. \texttt{tabularx} uses a similar method.
+% \changes{v2.6a}{2023/12/11}{Managing cell indexes}
+%    \begin{macrocode}
+  \tbl_restore_outer_cell_data:
+%    \end{macrocode}
+%    
+%    \begin{macrocode}
+  \egroup
+  \@arrayright \gdef\@preamble{}%
+}
+%    \end{macrocode}
 % \end{macro}
 %
+%
+%
+%
 % \begin{macro}{\endtabular}
 % \begin{macro}{\endtabular*}
 %    To end a \textsf{tabular} or \textsf{tabular$*$} environment we
@@ -2499,7 +2822,13 @@
 %    any =\mathsurround= so we cancel that with =\m at th=.
 % \changes{v2.5f}{2021/07/12}{Cancel any outside \cs{mathsurround} (gh/614)}
 %    \begin{macrocode}
-\def\endtabular{\endarray\m at th $\egroup}
+\def\endtabular{\endarray\m at th $\egroup
+%    \end{macrocode}
+%    
+% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
+%    \begin{macrocode}
+  \UseTaggingSocket{tbl/hmode/end}%
+}
 \expandafter\let\csname endtabular*\endcsname=\endtabular
 %    \end{macrocode}
 % \end{macro}
@@ -2518,7 +2847,7 @@
 \let\@arrayclassiv=\relax   \let\@arrayclassz=\relax
 \let\@tabclassiv=\relax     \let\@tabclassz=\relax
 \let\@arrayacol=\relax      \let\@tabacol=\relax
-\let\@tabularcr=\relax      \let\@@endpbox=\relax
+\let\@tabularcr=\relax      \let\@@@@endpbox=\relax
 \let\@argtabularcr=\relax   \let\@xtabularcr=\relax
 %    \end{macrocode}
 %
@@ -2576,6 +2905,7 @@
 % to define letters, to be used in the same way as the primitive
 % column specifiers, `c' `p' etc.
 %    \begin{macrocode}
+\ExplSyntaxOff  % this is really oldstyle using \@tfor :=
 \def\newcolumntype#1{%
 %    \end{macrocode}
 % "\NC at char" was added in V2.01 so that active characters, like "@" in
@@ -2615,6 +2945,7 @@
 % If an optional argument was not given, give a default argument of 0.
 %    \begin{macrocode}
   \@ifnextchar[{\newcol@{\NC at char}}{\newcol@{\NC at char}[0]}}
+\ExplSyntaxOn
 %    \end{macrocode}
 % \end{macro}
 % \begin{macro}{\newcol@}
@@ -2710,16 +3041,18 @@
 % produced and then "\typeout" the required string.
 %    \begin{macrocode}
 \def\NC at show#1{%
-  \typeout{Column #1\expandafter\expandafter\expandafter\NC at strip
-  \expandafter\meaning\csname NC at rewrite@#1\endcsname\@@}}
+  \typeout{Column~ #1\expandafter\expandafter\expandafter\NC at strip
+  \expandafter\meaning\csname NC at rewrite@#1\endcsname\@@@@}}
 %    \end{macrocode}
 % \end{macro}
 % \begin{macro}{\NC at strip}
 % Delimit the arguments to "\NC at strip" with `\texttt{:}', `\texttt{->}',
-% a space, and "\@@" to pull out the required parts of the output from
+% a space, and "\@@@@" to pull out the required parts of the output from
 % "\meaning".
 %    \begin{macrocode}
-\def\NC at strip#1:#2->#3 #4\@@{#2 -> #4}
+\ExplSyntaxOff
+\def\NC at strip#1:#2->#3 #4\@@@@{#2 -> #4}
+\ExplSyntaxOn
 %    \end{macrocode}
 % \end{macro}
 % \begin{macro}{\NC at list}
@@ -2807,6 +3140,7 @@
 % \changes{v2.4e}{2016/10/07}{Fixing SX68732}
 % \changes{v2.4f}{2017/11/04}{Managing m-cells without \cs{vcenter}}
 %    \begin{macrocode}
+\ExplSyntaxOff % really oldstyle using \@tfor :=
 \def\@mkpream#1{\gdef\@preamble{}\@lastchclass 4 \@firstamptrue
    \let\@sharp\relax
 %    \end{macrocode}
@@ -2869,11 +3203,12 @@
    \@acol \or
    \or
    \@acol \or
-   \@preamerr \thr@@ \or
+   \@preamerr \thr@@@@ \or
    \@preamerr \tw@ \@addtopreamble\@sharp \or
    \or
    \else  \@preamerr \@ne \fi
    \def\the at toks{\the\toks}}
+\ExplSyntaxOn
 %    \end{macrocode}
 % \end{macro}
 %
@@ -2908,7 +3243,7 @@
 % \texttt{array.sty} 2.0h.
 %    \begin{macrocode}
 \def\@classv{\save at decl
-   \expandafter\NC at ecs\@nextchar\extracolsep{}\extracolsep\@@@
+   \expandafter\NC at ecs\@nextchar\extracolsep{}\extracolsep\@@@@@@
    \@addtopreamble{\d at llarbegin\the at toks\the\count@\relax\d at llarend}%
    \prepnext at tok}
 %    \end{macrocode}
@@ -2920,7 +3255,7 @@
 % second "\extracolsep", there is no point in the user entering two of
 % these commands anyway, so this is not really a restriction.
 %    \begin{macrocode}
-\def\NC at ecs#1\extracolsep#2#3\extracolsep#4\@@@{\def\@tempa{#2}%
+\def\NC at ecs#1\extracolsep#2#3\extracolsep#4\@@@@@@{\def\@tempa{#2}%
   \ifx\@tempa\@empty\else\toks\count@={#1\tabskip#2\relax#3}\fi}
 %</ncols>
 %    \end{macrocode}
@@ -2936,28 +3271,27 @@
 %
 % \begin{macro}{\@tabarray}
 %    This macro tests for an optional bracket and then calls up
-%    "\@@array" or "\@@array[c]" (as default).
+%    "\@@@@array" or "\@@@@array[c]" (as default).
 %    \begin{macrocode}
 %<*package>
-\def\@tabarray{\@ifnextchar[{\@@array}{\@@array[c]}}
+\def\@tabarray{\@ifnextchar[{\@@@@array}{\@@@@array[c]}}
 %    \end{macrocode}
 % \end{macro}
-% \begin{macro}{\@@array}
+% \begin{macro}{\@@@@array}
 %    This macro tests could then test an optional delimiter before the
 %    left brace of the main preamble argument. Here in the main package
 %    it simply is let to be "\@array".
 %    \begin{macrocode}
-\let\@@array\@array
+\let\@@@@array\@array
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\endarray}
+% \begin{macro}{\@arrrayleft}
 % \begin{macro}{\@arrayright}
 %    We have to declare the hook we put into "\@array" above.
-%    A similar hook `"\@arrayright"' will be inserted into the
+%    A similar hook \cs{@arrayright} will be inserted into the
 %    "\endarray" to gain control. Both defaults to empty.
 %    \begin{macrocode}
-\def\endarray{\crcr \egroup \egroup \@arrayright \gdef\@preamble{}}
 \let\@arrayleft\@empty
 \let\@arrayright\@empty
 %    \end{macrocode}
@@ -3182,6 +3516,14 @@
 %  \end{macro}
 %
 %
+%
+%
+%
+%    \begin{macrocode}
+\ExplSyntaxOff
+%    \end{macrocode}
+%
+%
 % \PrintIndex
 % \PrintChanges
 %

Modified: trunk/Master/texmf-dist/source/latex/tools/bm.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/bm.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/bm.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2023
+% Copyright (C) 1993-2024
 %
 % The LaTeX Project and any individual authors listed elsewhere
 % in this file.
@@ -22,7 +22,7 @@
 % \fi
 %
 % \iffalse
-%% Copyright 1996 1997 1998 1999 2002 2003 2004 2016 2017 2019 2021 2022
+%% Copyright 1996 1997 1998 1999 2002 2003 2004 2016 2017 2019 2021 2022 2023
 %% David Carlisle Frank Mittelbach
 %%
 %% Development of this package was commissioned by Y&Y Inc.
@@ -36,7 +36,7 @@
 %<driver>\ProvidesFile{bm.drv}
 % \fi
 %         \ProvidesFile{bm.dtx}
-          [2023/07/08 v1.2f Bold Symbol Support (DPC/FMi)]
+          [2023/12/19 v1.2f Bold Symbol Support (DPC/FMi)]
 %
 % \iffalse
 %<*driver>
@@ -178,7 +178,7 @@
 % spacing). So the third example produces identical output to the first
 % (but \TeX\ takes more time producing it).
 %
-% In the fourth example the |\mathrm{\bm{g}}| is essentially
+% In the fourth example the |\mathrm{\bm{{g}}}| is essentially
 % equivalent to |\mathrm{\mbox{\boldmath$g$}}|. Currently math alphabet
 % settings are not passed down to `nested' math lists, and so in this
 % example, the |\mathrm| has no effect, and a bold math italic $\bm g$
@@ -185,7 +185,7 @@
 % is obtained.
 %
 % Similarly the last example is equivalent to
-% |$\mbox{\boldmath$\mathrm{g}$}}| and so in this case, one obtains a
+% |$\mbox{\boldmath$\mathrm{g}$}$| and so in this case, one obtains a
 % bold roman \textbf{g}.
 %
 % \subsection{Delimiters}

Modified: trunk/Master/texmf-dist/source/latex/tools/bm.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/bm.ins	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/bm.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -3,7 +3,7 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
@@ -45,7 +45,7 @@
 reports for it can be opened at https://latex-project.org/bugs/
 (but please observe conditions on bug reports sent to that address!)
 
-Copyright (C) 1993-2023
+Copyright (C) 1993-2024
 The LaTeX Project and any individual authors listed elsewhere
 in this file.
 

Modified: trunk/Master/texmf-dist/source/latex/tools/calc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/calc.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/calc.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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.

Modified: trunk/Master/texmf-dist/source/latex/tools/dcolumn.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/dcolumn.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/dcolumn.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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.

Modified: trunk/Master/texmf-dist/source/latex/tools/delarray.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/delarray.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/delarray.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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.

Modified: trunk/Master/texmf-dist/source/latex/tools/enumerate.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/enumerate.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/enumerate.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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.

Modified: trunk/Master/texmf-dist/source/latex/tools/fileerr.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/fileerr.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/fileerr.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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.

Modified: trunk/Master/texmf-dist/source/latex/tools/fontsmpl.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/fontsmpl.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/fontsmpl.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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.

Modified: trunk/Master/texmf-dist/source/latex/tools/ftnright.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/ftnright.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/ftnright.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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.

Modified: trunk/Master/texmf-dist/source/latex/tools/hhline.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/hhline.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/hhline.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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.

Modified: trunk/Master/texmf-dist/source/latex/tools/indentfirst.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/indentfirst.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/indentfirst.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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.

Added: trunk/Master/texmf-dist/source/latex/tools/l3sys-query.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/l3sys-query.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/tools/l3sys-query.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -0,0 +1,545 @@
+% \iffalse
+%% Source File: l3sys-query.dtx
+%% Copyright (C) 2024
+%%
+%% The LaTeX Project and any individual authors listed elsewhere
+%% in this file.
+%%
+%% This file may be distributed under the terms of the LPPL.
+%% See README for details.
+%
+%<*dtx>
+          \ProvidesFile{l3sys-query.dtx}
+%</dtx>
+%<package>\ProvidesPackage{l3sys-query}
+%<driver> \ProvidesFile{l3sys-query.drv}
+% \fi
+%         \ProvidesFile{l3sys-query.dtx}
+       [2024-03-28 v1.0a LaTeX2e interface for l3sys file queries]
+%
+% \iffalse
+%<*driver>
+\documentclass{l3doc}%{ltxdoc}
+\begin{document}
+\DocInput{l3sys-query.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \GetFileInfo{l3sys-query.dtx}
+%
+% \title{\LaTeX\ document interface to the \pkg{l3sys-query} script:
+% System queries for LaTeX using Lua\thanks{This file
+%        has version number \fileversion, last
+%        revised \filedate.}}
+% \author{\LaTeX\ project}
+% \date{\filedate}
+%
+%
+% \maketitle
+%
+% \tableofcontents
+%
+% \section{Introduction}
+% 
+% \TeX{} engines provide only very limited access to information about the system
+% they are used on: using primitives, one can for example get the size of a single
+% file, but not a list of files in a given location. For most documents, this is
+% not an issue as they are self-contained. However, for cases where
+% \enquote{dynamic} construction of parts of a document is needed based on file
+% lists or other system-dependent data, methods to obtain this from (restricted)
+% shell escape are desirable.
+% 
+% Security considerations mean that directly querying the system shell is
+% problematic for general use. Instead, \emph{restricted} shell escape may be used
+% to get many details, provided a suitable tool is available to provide the
+% information in a platform-neutral and security-conscious way. The Java program
+% \texttt{texosquery}, written by Nicola Talbot, has been available for a number
+% of years to provide this facility. As well as file system insight,
+% \texttt{texosquery} also provides for example locale data and other system
+% information. However, the requirement for Java means that the script is not
+% automatically usable when a \TeX{} system is installed.
+% 
+% The \LaTeX{} team have therefore provided a Lua-based script,
+% \texttt{l3sys-query}, which conforms to the security requirements of \TeX{} Live
+% using Lua to obtain the system information. This means that it can be used
+% \enquote{out of the box} across platforms. The facilities provided by
+% \texttt{l3sys-query} are more limited than \texttt{texosquery}, partly as some
+% information is available in modern \TeX{} systems using primitives, and partly
+% as the aim of \texttt{l3sys-query} is to provide information where there are
+% defined use cases. Requests for additional data interfaces are welcome.
+%
+% This package provides a document level \textit{Key-Value} interface
+% to The \texttt{l3sys-query} functionality, although as a convenience
+% it also summarizes the documentation for the L3 programming
+% interface layer (prvided by the \pkg{l3sys} module of
+% \pkg{l3kernel}, and of the command line Lua script
+% \texttt{l3sys-query} which is distributed separately and provides
+% the underlying functionality.
+%
+% 
+% 
+% \section{The document level key-value  interface\label{sec:kv}}
+%
+% This provides an interface to \texttt{l3sys-query} based on
+% \pkg{l3keys} that allows the options to be specified and checked
+% individually. Internally the supplied key values are used to build
+% up the arguments to the commands described above in the L3
+% programming layer commands described in section~\ref{sec:expl3}
+%
+% Results containing path separators \emph{always}
+% use~|/|, irrespective of the platform in use.
+% 
+%
+% \begin{function}
+%   {\QueryWorkingDirectory}
+%   \begin{syntax}
+%     \cs{QueryWorkingDirectory} \Arg{result cmd}
+%   \end{syntax}
+%   Defines supplied command \meta{result cmd} to hold
+%   the absolute path to the current working directory of the
+%   \TeX\ system.
+%   This is the directory (folder) from which \TeX\ was started, so usually
+%   the location of the main document file.
+% \end{function}
+% 
+% \begin{function}
+%   {\QueryFiles, \QueryFilesTF}
+%   \begin{syntax}
+%     \cs{QueryFiles} \oarg{options} \Arg{spec} \Arg{function}
+%     \cs{QueryFilesTF} \oarg{options} \Arg{spec} \Arg{function} \Arg{pre code} \Arg{empty list code}
+%   \end{syntax}
+%   This generates a file list  based on the \meta{spec} and \meta{options}.
+%   The command then applies \meta{function}  to each item in the sequence of filenames.
+%   The \meta{function} should be a macro body which will be passed the file path as |#1|.
+% 
+%  The TF version executes the T (\meta{pre code}) argument before iterating over the list
+%  and the F (\meta{empty list code}) argument if the list is empty.
+% \end{function}
+% 
+%  Note that this interface in mapping directly over the sequence of
+%  filenames does not allow some uses which are provided by the
+%  programming interface described in the following section, which allows
+%  the sequence to be manipulated before being used.
+% 
+%  The defined keys map very closely to the options of the
+%  \texttt{l3sys-query} command which is described in
+%  section~\ref{sec:lua}.
+% 
+%  \begin{itemize}
+%  \item 
+%  The keys \texttt{recursive}, \texttt{ignore-case}, \texttt{reverse}, \texttt{pattern}
+%  take no values and map directly to the command line options of the same name.
+% 
+%  \item
+%  The key \texttt{sort} accepts the values \texttt{date} and \texttt{name}.
+% 
+%  \item
+%  The key \texttt{type} accepts \texttt{d} or \texttt{f}.
+% 
+%  \item
+%  The key \texttt{exclude} accepts a glob (or Lua pattern) matching
+%  files to be excluded.  The package arranges that the quoting of the
+%  argument is automatically added if unrestricted shell escape is
+%  enabled.
+% 
+% \end{itemize}
+% 
+%  Within the main \meta{spec} argument, and the value of the \texttt{exclude} key,
+%  the following characters may need special handling.
+%  |~| may be used (which \texttt{kpathsea} uses to denote the users home directory).
+%  |\%|, or at the top level |%|, may be used to produce a literal |%|
+%  which may be especially useful if the \texttt{pattern} key is used
+%  as \% is the escape character in Lua patterns.
+%  
+%  \subsection{Examples\label{sec:examples2e}}
+%
+%  \begin{itemize}
+%  \item 
+%  Include every |png| file in the current directory.
+% \begin{verbatim}
+% \QueryFiles{*.png}{\includegraphics{#1}\par}
+% \end{verbatim}
+%
+% \item
+%  Input every \TeX\ file with a filename matching \texttt{chapter[0-9].tex}.
+% \begin{verbatim}
+% \QueryFiles[pattern]{chapter%d.*%.tex}{\input{#1}}
+% \end{verbatim}
+%  \end{itemize}
+%
+% \section{The L3 programming layer interface\label{sec:expl3}}
+% 
+% \begin{function}
+%   {\sys_get_query:nN, \sys_get_query:nnN, \sys_get_query:nnnN}
+%   \begin{syntax}
+%     \cs{sys_get_query:nN} \Arg{cmd} \Arg{tl var}
+%     \cs{sys_get_query:nnN} \Arg{cmd} \Arg{spec} \Arg{tl var}
+%     \cs{sys_get_query:nnnN} \Arg{cmd} \Arg{options} \Arg{spec} \Arg{tl var}
+%   \end{syntax}
+%   Sets the \meta{tl var} to the information returned by the
+%   \texttt{l3sys-query} \meta{cmd}, potentially supplying the \meta{options}
+%   and \meta{spec} to the query call. The valid \meta{cmd} names are at present
+%   \begin{itemize}
+%     \item \texttt{pwd} Returns the absolute path to the current working directory
+%     \item \texttt{ls} Returns a directory listing, using the \meta{spec} to
+%       select files and applying the \meta{options} if given
+%   \end{itemize}
+%   The \meta{spec} should be a file glob and will automatically be passed to
+%   the script without shell expansion.
+% \end{function}
+% 
+% \begin{function}
+%   {\sys_split_query:nN, \sys_split_query:nnN, \sys_split_query:nnnN}
+%   \begin{syntax}
+%     \cs{sys_split_query:nN} \Arg{cmd} \Arg{seq}
+%     \cs{sys_split_query:nnN} \Arg{cmd} \Arg{spec} \Arg{seq}
+%     \cs{sys_split_query:nnnN} \Arg{cmd} \Arg{options} \Arg{spec} \Arg{seq}
+%   \end{syntax}
+%   Works as described for \cs{sys_get_query:nnnN}, but sets the \meta{seq}
+%   to contain one entry for each line returned by \texttt{l3sys-query}.
+% \end{function}
+% 
+% \section{The \texttt{l3sys-query} Lua script\label{sec:lua}}
+% \subsection{The command line interface}
+% 
+% The command line interface to 
+% \begin{center}
+%   \ttfamily
+%   l3sys-query \meta{cmd} [\meta{option(s)}] [\meta{args}]
+% \end{center}
+% where \texttt{\meta{cmd}} can be one of the following:
+% \begin{itemize}[noitemsep]\ttfamily
+%   \item ls
+%   \item ls \meta{args}
+%   \item pwd
+% \end{itemize}
+% The \meta{cmd} are described below. The result of the \meta{cmd} will be printed
+% to the terminal in an interactive run; in normal usage, this will be piped to
+% the calling \TeX{} process. Results containing path separators \emph{always}
+% use~|/|, irrespective of the platform in use.
+% 
+% As well as these targets, the script recognizes the options
+% \begin{itemize}
+%   \item |--exclude| Specification for directory entries to exclude
+%   \item |--ignore-case| Ignores case when sorting directory listings
+%   \item |--pattern| (|-p|) Treat the \meta{args} as Lua patterns rather
+%     than converting from wildcards
+%   \item |--recursive| (|-r|) Enables recursive searching during directory
+%     listings
+%   \item |--reverse| Causes sorting to go from highest to lowest rather
+%     than lowest to highest
+%   \item |--sort| Sets the method used to sort entries returned by |ls|
+%   \item |--type| Selects the type of entry returned by |ls|
+% \end{itemize}
+% The action of these options on the appropriate \meta{cmd(s)} is detailed below.
+% 
+% \subsubsection{\texttt{ls [\meta{args}]}}
+% 
+% Lists the contents of one or more directories, in a manner somewhat reminiscent
+% of the Unix command |ls| or the Windows command |dir|. The exact nature of the
+% output will depend on the \meta{args}, if given, along with the prevailing
+% options. Note that the options names are inspired by ideas from the Unix
+% commands |ls| and |find| as well as the Windows command |dir|: they therefore do
+% not map directly to those of any one of the command line tools that they
+% somewhat mirror.
+% 
+% When no \meta{args} are given, all entries in the current directory will be
+% listed, one per line in the output. This will include both files and
+% subdirectories. Each entry will include a path relative to the current
+% directory: for files \emph{in} the current directory, this will be |./|. The
+% order of results will be determined by the underlying operating system process:
+% unless requested \emph{via} an option, no sorting takes place.
+% 
+% As standard, the \meta{args} are treated as a file/path name potentially
+% including |?| and |*| as wildcards, for example |*.png| or |file?.txt|.
+% \begin{verbatim}
+%   l3sys-query ls '*.png'
+% \end{verbatim}
+% Some care is needed in preventing expansion of such wildcards by the shell or
+% \texttt{texlua} process: these are detailed in Section~\ref{sec:wildcard}. In
+% this section, |'| is used to indicate a character being used to suppress
+% expansion: this is for example normal on macOS and Linux.
+% 
+% Removal of entries from the listing can be achieved using the |--exclude|
+% option, which should be given with a \meta{xarg}, for example
+% \begin{verbatim}
+%   l3sys-query ls --exclude '*.bak' 'graphics/*'
+% \end{verbatim}
+% Directory entries starting |.| are traditionally hidden on Linux and macOS
+% systems: these \enquote{dot} entries are excluded from the output of
+% \texttt{l3sys-query}. The entries |.| and |..| for the current and parent
+% directory are also excluded from the results returned by \texttt{l3sys-query} as
+% they can always be assumed.
+% 
+% For more complex matching, the \meta{args} can be treated as a Lua pattern using
+% the |--pattern| (|-p|) option; this also applies to the \meta{xarg} argument to
+% the |--exclude| option. For example, the equivalent to wildcard |*.png| could be
+% obtained using
+% \begin{verbatim}
+%   l3sys-query ls --pattern '^.*%.png$'
+% \end{verbatim}
+% 
+% The results returned by |ls| can be sorted using the |--sort| option. This can
+% be set to |none| (use the order from the file system: the default), |name| (sort
+% by file name) or |date| (sort by date last modified). The sorting order can be
+% reversed using |--reverse|. Sorting normally takes account of case: this can be
+% suppressed with the |--ignore-case| option.
+% 
+% The listing can be filtered based on the type of entry using the |--type|
+% option. This takes a string argument, one of |d| (directory) or |f| (file).
+% 
+% As standard, only the path specified as part of the \meta{args} is queried.
+% However, if the |--recursive| (|-r|) option is set, the query is applied within
+% all subdirectories. Subdirectories starting with~|.| (macOS and Linux hidden)
+% are excluded from recursion.
+% 
+% For security reasons, only paths within the current working directory can be
+% queried, thus for example |graphics/*.png| will list all |png| files in the
+% |graphics| subdirectory, but |../graphics/*.png| will yield no output.
+% 
+% \subsubsection{\texttt{pwd}}
+% 
+% Returns the current working directory from which \texttt{l3sys-query} is run.
+% From within a \TeX{} run, this will (usually) be the directory containing the
+% main file, assuming a command such as
+% \begin{verbatim}
+%   pdflatex main.tex
+% \end{verbatim}
+% The \texttt{pwd} command is unaffected by any options.
+% 
+% \subsection{Spaces in arguments}
+% 
+% Since \texttt{l3sys-query} is intended primarily for use with restricted shell
+% escape calls from \TeX{} processes, handling of spaces is unusual. It is not
+% possible to quote spaces in such a call, so for example whilst
+% \begin{verbatim}
+%   l3sys-query ls "foo *"
+% \end{verbatim}
+% does work from the command prompt to find all files with names starting
+% \verb*|foo |, it would not work \emph{via} restricted shell escape. To
+% circumvent this, \texttt{l3sys-query} will collect all command line arguments
+% after any \meta{options}, and combine these as a space-separated \meta{args},
+% for example allowing
+% \begin{verbatim}
+%   l3sys-query ls foo '*'
+% \end{verbatim}
+% to achieve the same result as the first example. The result is that the
+% \meta{args} will only every be interpreted by \texttt{l3sys-query} as a single
+% argument. It also means that spaces cannot be used at the start or end of the
+% argument, nor can multiple spaces appear between non-space arguments.
+% 
+% \subsection{Wildcard expansion handling\label{sec:wildcard}}
+% 
+% The handling of wildcards needs some further comment for those using
+% \texttt{l3sys-query} from the command line: the \pkg{expl3} interface described
+% in Section~\ref{sec:expl3} handles this aspect automatically for the user.
+% 
+% On macOS and Linux, the shell normally expands globs, which include the
+% wildcards |*| and |?|, before passing arguments to the appropriate command.
+% This can be suppressed by surrounding the argument with |'| characters, hence
+% the formulation
+% \begin{verbatim}
+%   l3sys-query ls '*.png'
+% \end{verbatim}
+% earlier.
+% 
+% On Windows, the shell does no expansion, and thus arguments are passed as-is to
+% the relevant command. As such, |'| has no special meaning here. However, to
+% allow quoting of wildcards from the shell in a platform-neutral manner,
+% \texttt{l3sys-query} will strip exactly one set of |'| characters around each
+% argument before further processing.
+% 
+% It is not possible to use |"| quotes at all in the argument passed to
+% \texttt{l3sys-query} from \TeX{}, as the \TeX{} system removes all |"| in
+% |\input| while handling space quoting.
+% 
+% Restricted shell escape prevents shell expansion of wildcards entirely. On
+% non-Windows systems, it does this by ensuring that each argument is |'| quoted
+% to ensure further expansion. Thus a \TeX{} call such as
+% \begin{verbatim}
+%   \input|"l3sys-query ls '*.png'"
+% \end{verbatim}
+% will work if |--shell-escape| is used as the argument is passed directly to the
+% shell, but in restricted shell escape will give an error such as:
+% \begin{verbatim}
+% ! I can't find file `"|l3sys-query ls '*.png'"'.
+% \end{verbatim}
+% The \LaTeX{} interfaces described above adjust the quoting used depending on the
+% |shell-escape| status.
+% 
+% 
+% \MaybeStop{}
+%
+% \section{The \LaTeXe\ package implementation}
+%
+%    \begin{macrocode}
+%<*package>
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\ExplSyntaxOn
+%<@@=queryfiles>
+%    \end{macrocode}
+%
+% The package should eventually work in restricted shell escape but will do
+% nothing useful if the process was started with |--no-shell-escape|.
+%    \begin{macrocode}
+\sys_if_shell:F{
+  \PackageWarningNoLine{l3sys-query}
+  {Shell ~Escape ~is ~disabled.\MessageBreak All ~queries ~will ~return ~empty ~results}
+  }
+%    \end{macrocode}
+%
+% \subsection{\cs{QueryWorkingDirectory}}
+% |\QueryWorkingDirectory| is a direct call to the |pwd| command provided by \texttt{l3sys-query}.
+%    \begin{macrocode}
+\NewDocumentCommand\QueryWorkingDirectory {m} {
+  \sys_get_query:nN {pwd} #1
+}
+%    \end{macrocode}
+%
+% \subsection{\cs{QueryFiles} and \cs{QueryFilesTF}}
+%
+% The declarations of these commands are done in two steps to allow catcode chanes
+% before the arguments are read. This allows the use of |%| and |^^| in patterns
+% at least if the command is not nested in another command argument. (|\%| may be used
+% to generate |%| in all cases).
+%
+% Variables for saving the current definition of |\%| and |~|.
+%    \begin{macrocode}
+\tl_new:N\l_query_percent_tl
+\tl_new:N\l_query_tilde_tl
+%    \end{macrocode}
+%
+% Allow |%| and |^^| at the top level.
+%    \begin{macrocode}
+\NewDocumentCommand\QueryFiles {} {
+  \group_begin:
+    \char_set_catcode_other:N \%
+    \char_set_catcode_other:N \^
+    \QueryFiles_inner
+  }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\char_set_catcode_active:N \~
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\NewDocumentCommand\QueryFiles_inner {O{}m}{
+  \group_end:
+  \tl_set:Nn\l_tmpa_tl{}
+  \cs_set_eq:NN  \l_query_percent_tl \%
+  \cs_set_eq:NN  \% \c_percent_str
+  \cs_set_eq:NN  \l_query_tilde_tl ~
+  \cs_set_eq:NN  ~ \c_tilde_str
+  \keys_set:nn{QueryFiles}{#1}
+  \exp_args:NnV\sys_split_query:nnnN {ls} \l_tmpa_tl {#2} \l_tmpa_seq
+  \cs_set_eq:NN  \% \l_query_percent_tl
+  \cs_set_eq:NN  ~ \l_query_tilde_tl
+  \seq_map_inline:Nn\l_tmpa_seq
+}
+%    \end{macrocode}
+%
+% This duplicates rather than shares code so as to read the function
+% and TF arguments with normal catcode regime.
+% (This could probably be optimised.)
+%    \begin{macrocode}
+\NewDocumentCommand\QueryFilesTF {} {
+  \group_begin:
+    \char_set_catcode_other:N \%
+    \QueryFilesTF_inner
+ }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\NewDocumentCommand\QueryFilesTF_inner {O{}m}{
+  \group_end:
+  \tl_set:Nn\l_tmpa_tl{}
+  \cs_set_eq:NN  \l_query_percent_tl \%
+  \cs_set_eq:NN  \% \c_percent_str
+  \cs_set_eq:NN  \l_query_tilde_tl ~
+  \cs_set_eq:NN  ~ \c_tilde_str
+  \keys_set:nn{QueryFiles}{#1}
+  \exp_args:NnV\sys_split_query:nnnN {ls} \l_tmpa_tl {#2} \l_tmpa_seq
+  \cs_set_eq:NN  \% \l_query_percent_tl
+  \cs_set_eq:NN  ~ \l_query_tilde_tl
+  \seq_if_empty:NTF \l_tmpa_seq \use_iii:nnn \__queryfiles_aux:nnn
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\char_set_catcode_space:N \~
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\cs_new:Npn  \__queryfiles_aux:nnn #1#2#3 {
+    #2
+    \seq_map_inline:Nn\l_tmpa_seq {#1}
+ }
+%    \end{macrocode}
+%
+% Defining the keys. Most take no value and simply add a \texttt{l3sys-query} \texttt{-{}-}
+% option to the command linebeing constructed.
+%    \begin{macrocode}
+\keys_define:nn {QueryFiles} {
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+recursive .code:n  =\tl_put_right:Nn \l_tmpa_tl {--recursive ~ } ,
+recursive .value_forbidden:n = true ,
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+ignore-case .code:n  =\tl_put_right:Nn \l_tmpa_tl {--ignore-case ~ } ,
+ignore-case .value_forbidden:n = true ,
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+reverse .code:n  =\tl_put_right:Nn \l_tmpa_tl {--reverse ~ } ,
+reverse .value_forbidden:n = true ,
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+exclude .code:n  =\tl_put_right:Ne \l_tmpa_tl {
+  --exclude ~
+  \sys_if_shell_restricted:F'
+  \exp_not:n{#1}
+  \sys_if_shell_restricted:F'
+  ~ } ,
+exclude .value_required:n = true ,
+%    \end{macrocode}
+%
+% The |type| key checks the supplied value is valid |d| for directories
+% or |f| for files The default behaviour lists both.
+%    \begin{macrocode}
+type .choices:nn = {d,f}
+                   {\tl_put_right:Nn \l_tmpa_tl {--type ~ #1 ~ }} ,
+%    \end{macrocode}
+%
+% The |sort| key checks the supplied value is valid |date| or |name|.
+%    \begin{macrocode}
+sort .choices:nn = {date,name}
+{\tl_put_right:Nn \l_tmpa_tl {--sort ~ #1 ~ }} ,
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+pattern .code:n  =\tl_put_right:Nn \l_tmpa_tl {--pattern ~ } ,
+pattern .value_forbidden:n = true ,
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\ExplSyntaxOff
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%</package>
+%    \end{macrocode}
+%
+% \Finale
+%


Property changes on: trunk/Master/texmf-dist/source/latex/tools/l3sys-query.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/tools/l3sys-query.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/l3sys-query.ins	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/tools/l3sys-query.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -0,0 +1,76 @@
+%%
+%% This file will generate fast loadable files and documentation
+%% driver files from the doc files in this package when run through
+%% LaTeX or TeX.
+%%
+%% Copyright (C) 1993-2024
+%% The LaTeX Project and any individual authors listed elsewhere
+%% in this file.
+%%
+%% This file is part of the Standard LaTeX `Tools Bundle'.
+%% -------------------------------------------------------
+%%
+%% It may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%%    https://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%% As this file contains legal notices, it is NOT PERMITTED to modify
+%% this file in any way that the legal information placed into
+%% generated files is changed (i.e., the files generated when the
+%% original file is executed). This restriction does not apply if
+%% (parts of) the content is reused in a different WORK producing its
+%% own generated files.
+%%
+%% The list of all files belonging to the `Tools Bundle' is
+%% given in the file `manifest.txt'.
+%%
+%%
+%% --------------- start of docstrip commands ------------------
+%%
+\input docstrip
+
+\keepsilent
+
+\usedir{tex/latex/tools}
+
+\preamble
+
+This is a generated file.
+
+The source is maintained by the LaTeX Project team and bug
+reports for it can be opened at https://latex-project.org/bugs/
+(but please observe conditions on bug reports sent to that address!)
+
+Copyright (C) 1993-2024
+The LaTeX Project and any individual authors listed elsewhere
+in this file.
+
+This file was generated from file(s) of the Standard LaTeX `Tools Bundle'.
+--------------------------------------------------------------------------
+
+It may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either version 1.3c
+of this license or (at your option) any later version.
+The latest version of this license is in
+   https://www.latex-project.org/lppl.txt
+and version 1.3c or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+This file may only be distributed together with a copy of the LaTeX
+`Tools Bundle'. You may however distribute the LaTeX `Tools Bundle'
+without such generated files.
+
+The list of all files belonging to the LaTeX `Tools Bundle' is
+given in the file `manifest.txt'.
+
+\endpreamble
+
+\keepsilent
+
+\generate{\file{l3sys-query.sty}{\from{l3sys-query.dtx}{package}}}
+
+\endbatchfile

Modified: trunk/Master/texmf-dist/source/latex/tools/layout.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/layout.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/layout.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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.

Modified: trunk/Master/texmf-dist/source/latex/tools/longtable.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/longtable.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/longtable.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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,9 +27,10 @@
           \ProvidesFile{longtable.dtx}
 %</dtx>
 %<package>\NeedsTeXFormat{LaTeX2e}[1995/06/01]
-%<package>\providecommand\DeclareRelease[3]{}
-%<package>\providecommand\DeclareCurrentRelease[2]{}
 %<package>
+% Try the 2020 version for any rollback before that date:          
+%<package>\DeclareRelease{}{1994-06-01}{longtable-2020-01-07.sty}
+%<package>
 %<package>\DeclareRelease{v4.13}{2020-01-02}{longtable-2020-01-07.sty}
 %<package>\DeclareCurrentRelease{}{2020-02-07}
 %<package>
@@ -37,7 +38,7 @@
 %<driver> \ProvidesFile{longtable.drv}
 % \fi
 %         \ProvidesFile{longtable.dtx}
-          [2023-11-01 v4.19 Multi-page Table package (DPC)]
+          [2024-04-26 v4.20 Multi-page Table package (DPC)]
 %
 % \iffalse
 %<*driver>
@@ -1048,6 +1049,14 @@
   \if at twocolumn
     \LT at err{longtable not in 1-column mode}\@ehc
   \fi
+%    \end{macrocode}
+%    
+% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
+%    \begin{macrocode}
+  \UseTaggingSocket{tbl/vmode/begin}%
+%    \end{macrocode}
+%    
+%    \begin{macrocode}
   \begingroup
 %    \end{macrocode}
 % Check for an optional argument.
@@ -1056,7 +1065,14 @@
 %    \end{macrocode}
 % \end{macro}
 %
+%
+%
 % \begin{macro}{\LT at array}
+%    \begin{macrocode}
+%<@@=tbl>
+\ExplSyntaxOn
+%    \end{macrocode}
+%
 % Start setting the alignment.
 % Based on "\@array" from the \LaTeX\ kernel
 % and the \package{array} package.
@@ -1066,8 +1082,44 @@
 % so that "\caption" works correctly.
 %    \begin{macrocode}
 \def\LT at array[#1]#2{%
-  \refstepcounter{table}\stepcounter{LT at tables}%
 %    \end{macrocode}
+%
+%    With respect to tagging we have a complicated situation with
+%    longtable. When at the begin the \cs{endhead},
+%    \cs{endfirsthead}, \cs{endfoot} and \cs{endlastfoot} are used to
+%    setup head and foot they create each a structure subtree with one or
+%    more rows. From these structures we want to keep at most two (head
+%    and foot) and move the foot to the end of the table. When the head
+%    and foot boxes are (re)inserted on following pages we want to mark
+%    them up as artifact with the exception of the head at the begin and
+%    the foot box at the end.
+%
+%    TODO: When a line is killed the structure subtree is there already
+%    too and must be removed. If hard to do, then maybe at first warn if the
+%    construction is used.
+%  
+%    \cs{LT at array} is executed in a group, so we can disable para-tagging here.
+% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
+%    \begin{macrocode}
+  \UseTaggingSocket{tbl/init}
+  \@kernel at refstepcounter{table}\stepcounter{LT at tables}
+%    \end{macrocode}
+% The target is created rather late and a \cs{label} can come earlier, 
+% so we have to define \cs{@currentHref} explicitly. We can't currently
+% assume that \cs{theHtable} is defined always.
+%    \begin{macrocode}
+  \tl_gset:Ne \@currentHref {table.\cs_if_exist_use:N\theHtable}
+%    \end{macrocode}
+%    
+% \changes{v4.19}{2023/12/16}{Managing cell indexes}
+%    \begin{macrocode}
+  \tbl_gzero_row_count:
+%    \end{macrocode}
+%    
+% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
+%    \begin{macrocode}
+  \UseTaggingSocket{tbl/longtable/init}
+%    \end{macrocode}
 % Set up the glue around the table if an optional argument given.
 %    \begin{macrocode}
   \if l#1%
@@ -1101,17 +1153,18 @@
 % here so that you can load the \package{array} package before or after
 % \package{longtable}.
 %    \begin{macrocode}
-  \let\LT@@tabarray\@tabarray
-  \let\LT@@hl\hline
+  \let\LT@@@@tabarray\@tabarray
+  \let\LT@@@@hl\hline
   \def\@tabarray{%
-    \let\hline\LT@@hl
+    \let\hline\LT@@@@hl
 %    \end{macrocode}
 %\begin{verbatim}
 %    \let\multicolumn\LT at mcol
 %\end{verbatim}
 %    \begin{macrocode}
-    \LT@@tabarray}%
-  \let\\\LT at tabularcr\let\tabularnewline\\%
+    \LT@@@@tabarray}%
+  \let\\\LT at tabularcr
+  \let\tabularnewline\\%
   \def\newpage{\noalign{\break}}%
 %    \end{macrocode}
 % \changes{v4.05}{1996/11/12}
@@ -1128,8 +1181,8 @@
 %    \end{macrocode}
 %
 % \changes{v4.08}{1998/01/20}
-%      {Move \cs{@endpbox} definition earlier and define \cs{@@endpbox}
-%      and \cs{@@startpbox} for non-array case. tools/2736}
+%      {Move \cs{@endpbox} definition earlier and define \cs{@@@@endpbox}
+%      and \cs{@@@@startpbox} for non-array case. tools/2736}
 %    \begin{macrocode}
   \let\@endpbox\LT at endpbox
 %    \end{macrocode}
@@ -1142,8 +1195,8 @@
     \let\@acol\@tabacol
     \let\@classz\@tabclassz \let\@classiv\@tabclassiv
     \def\@startpbox{\vtop\LT at startpbox}%
-    \let\@@startpbox\@startpbox
-    \let\@@endpbox\@endpbox
+    \let\@@@@startpbox\@startpbox
+    \let\@@@@endpbox\@endpbox
     \let\LT at LL@FM at cr\@tabularcr
   \else
 %    \end{macrocode}
@@ -1172,6 +1225,11 @@
    \begingroup
     \@mkpream{#2}%
 %    \end{macrocode}
+%    
+% \changes{v4.19}{2023/12/16}{Managing cell indexes}
+%    \begin{macrocode}
+    \tbl_count_table_cols:
+%    \end{macrocode}
 % We need to rename "\@preamble" here as F.M.'s scheme uses
 % "\global", and we may need to nest "\@mkpream", eg for
 % "\multicolumn"
@@ -1180,6 +1238,11 @@
 %    \begin{macrocode}
     \xdef\LT at bchunk{%
 %    \end{macrocode}
+%    We aren't inside any row when a chunk starts.
+% \changes{v4.19}{2023/12/16}{Managing cell indexes}
+%    \begin{macrocode}
+      \tbl_inbetween_rows:
+%    \end{macrocode}
 % \changes{v4.00}{1996/04/08}
 %      {(DK) Increment Chunk counter}
 %    \begin{macrocode}
@@ -1205,7 +1268,21 @@
 %    \begin{macrocode}
        \tabskip\LTleft \noexpand\halign to\hsize\bgroup
 %       \tabskip\LTleft\halign to\hsize\bgroup
-      \tabskip\z@ \@arstrut \@preamble \tabskip\LTright \cr}%
+       \tabskip\z@ \@arstrut
+%    \end{macrocode}
+%    Insert the tagging socket to start the row and initialize the cell
+%    data for the row.  
+% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
+%    \begin{macrocode}
+       \UseTaggingSocket{tbl/row/begin}%
+%    \end{macrocode}
+%    
+% \changes{v4.19}{2023/12/16}{Managing cell indexes}
+%    \begin{macrocode}
+       \tbl_init_cell_data_for_row:
+%    \end{macrocode}
+%    \begin{macrocode}
+       \@preamble \tabskip\LTright \cr}%
   \endgroup
 %    \end{macrocode}
 % Find out how many columns we have (store in "\LT at cols").
@@ -1220,11 +1297,57 @@
 % A few more internal commands for \env{longtable}.
 %    \begin{macrocode}
   \m at th\let\par\@empty
-  \everycr{}\lineskip\z@\baselineskip\z@
 %    \end{macrocode}
+% Tagging socket and conditional
+%    \begin{macrocode}
+  \everycr{%
+    \noalign{%
+%    \end{macrocode}
+%    In \pkg{longtable} we have a bunch of extra \cs{cr}s that are
+%    executed whenever a chunk ends. In that case they should not
+%    increment the main row counter, sigh.
+%
+%    TODO: At the moment this tracing still exposes the internal row counter!
+%    \begin{macrocode}
+      \@@_trace:n {--longtable-->~chunk~row:~ \the\LT at rows \space
+                   row:~ \the\g_@@_row_int   \space
+                   column:~ \the\g_@@_col_int
+      }
+%    \end{macrocode}
+%    
+% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
+%    \begin{macrocode}
+      \tbl_if_row_was_started:T
+          {
+            \UseTaggingSocket{tbl/row/end}
+%    \end{macrocode}
+%    The next setting prevents any of the additional \cs{cr}s at the end of the
+%    chunk to add another /TR. Then once we really start a new chunk
+%    it gets incremented so\ldots
+% \changes{v4.19}{2023/12/16}{Managing cell indexes}
+%    \begin{macrocode}
+            \tbl_inbetween_rows:
+          }
+%    \end{macrocode}
+%    And for the same reason such \cs{cr}s should not increment the
+%    main row counter (but it has to be incremented after the preamble
+%    of a chunk), so here we test against \cs{LT at rows} which is
+%    \cs{LTchunksize} at the end of a chunk.
+% \changes{v4.19}{2023/12/16}{Managing cell indexes}
+%    \begin{macrocode}
+      \int_compare:nNnT \LT at rows < \LTchunksize
+         { \tbl_gincr_row_count: }   % next is row about to start
+    }%
+  }%
+%    \end{macrocode}
+%    \begin{macrocode}
+  \lineskip\z@\baselineskip\z@
+%    \end{macrocode}
 % Start the first chunk.
 %    \begin{macrocode}
   \LT at bchunk}
+\ExplSyntaxOff
+%<@@=>
 %    \end{macrocode}
 % \end{macro}
 %
@@ -1251,6 +1374,11 @@
 % force the page-breaker to wake up. The second "\endgraf" is there so
 % that "\pagetotal" is updated and so takes "\LTpre" into account.
 %    \begin{macrocode}
+%<@@=tbl>
+\ExplSyntaxOn
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \def\LT at start{%
   \let\LT at start\endgraf
   \endgraf\penalty\z@\vskip\LTpre\endgraf
@@ -1334,7 +1462,7 @@
 % \changes{v3.14}{1995/05/02}
 %      {Set \cs{@colroom}, for tools/1584}
 %    \begin{macrocode}
-      \global\@colroom\@colht
+ \global\@colroom\@colht
 %    \end{macrocode}
 % If the foot is non empty, reduce the "\vsize" and "\@colroom"
 % accordingly.
@@ -1342,7 +1470,6 @@
 %      {Rearrange vertical space tests for tools/3512 (floats on same page)}
 %    \begin{macrocode}
   \ifvoid\LT at foot\else
-%    \advance\vsize-\ht\LT at foot
     \global\advance\vsize-\ht\LT at foot
     \global\advance\@colroom-\ht\LT at foot
     \dimen@\pagegoal\advance\dimen at -\ht\LT at foot\pagegoal\dimen@
@@ -1349,6 +1476,10 @@
     \maxdepth\z@
   \fi
 %    \end{macrocode}
+%    
+%    \begin{macrocode}
+  \MakeLinkTarget{table}
+%    \end{macrocode}
 % Put the table head on the page, and then switch to the new output
 % routine.
 % \changes{v4.11}{2004/02/01}
@@ -1355,11 +1486,30 @@
 %      {\cs{nobreak}, for tools/3484}
 %    \begin{macrocode}
   \ifvoid\LT at firsthead\copy\LT at head\else\box\LT at firsthead\fi\nobreak
+%    \end{macrocode}
+%    
+% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
+%    \begin{macrocode}
+  \UseTaggingSocket{tbl/longtable/head}
+%    \end{macrocode}
+%    
+%    \begin{macrocode}
   \output{\LT at output}}
+\ExplSyntaxOff
+%<@@=>
 %    \end{macrocode}
 % \end{macro}
 %
+%
+%
+%
 % \begin{macro}{\endlongtable}
+%
+%    \begin{macrocode}
+%<@@=tbl>
+\ExplSyntaxOn
+%    \end{macrocode}
+%
 % Called by "\end{longtable}".
 %    \begin{macrocode}
 \def\endlongtable{%
@@ -1370,11 +1520,23 @@
 % been shortened, or the table numbering has gone awry). In that case
 % we at least start collecting valid new information with the last
 % chunk of this table, by removing the width constraint.
+% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
+%    \begin{macrocode}
+  \tbl_crcr:n {endlongtable}
+%    \end{macrocode}
+%    
 % \changes{v4.01}{1996/04/11}
 %      {(DPC) use \cs{noalign} to sneak in \cs{LT at entry@chop}}
 %    \begin{macrocode}
-  \crcr
   \noalign{%
+%    \end{macrocode}
+%    
+% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
+%    \begin{macrocode}
+    \UseTaggingSocket{tbl/longtable/finalize}
+%    \end{macrocode}
+%    
+%    \begin{macrocode}
     \let\LT at entry\LT at entry@chop
     \xdef\LT at save@row{\LT at save@row}}%
   \LT at echunk
@@ -1414,10 +1576,10 @@
 % \changes{v4.04}{1996/05/24}
 %      {Use \cs{LT at final@warn}}
 %    \begin{macrocode}
-  \ifx\LT at save@row\LT@@save at row
+  \ifx\LT at save@row\LT@@@@save at row
   \else
-    \LT at warn{Column \@width s have changed\MessageBreak
-             in table \thetable}%
+    \LT at warn{Column~ widths~ have~ changed\MessageBreak
+             in~ table~ \thetable}%
     \LT at final@warn
   \fi
 %    \end{macrocode}
@@ -1449,8 +1611,16 @@
 %    \end{macrocode}
 % Footnotes. As done in  the \package{multicol} package.
 %    \begin{macrocode}
-  \ifvoid\footins\else\insert\footins{}\fi}
+  \ifvoid\footins\else\insert\footins{}\fi
 %    \end{macrocode}
+%    
+% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
+%    \begin{macrocode}
+  \UseTaggingSocket{tbl/vmode/end}%
+}
+\ExplSyntaxOff
+%<@@=>
+%    \end{macrocode}
 % \end{macro}
 %
 % \subsection{Counting Columns}
@@ -1518,6 +1688,10 @@
 \protected\def\LT at tabularcr{%
   \relax\iffalse{\fi\ifnum0=`}\fi
   \@ifstar
+%    \end{macrocode}
+%    TODO: as we replace crcr later in one case, we probably have to
+%    implement some further logic there!
+%    \begin{macrocode}
     {\def\crcr{\LT at crcr\noalign{\nobreak}}\let\cr\crcr
      \LT at t@bularcr}%
     {\LT at t@bularcr}}
@@ -1544,8 +1718,13 @@
 %    \end{macrocode}
 % \end{macro}
 %
+%
+%
+%
 % \begin{macro}{\LT at t@bularcr}
 %    \begin{macrocode}
+%<@@=tbl>
+\ExplSyntaxOn
 \def\LT at t@bularcr{%
 %    \end{macrocode}
 % Increment the counter, and do  \env{tabular}'s "\\" or finish the
@@ -1555,6 +1734,13 @@
 %    \begin{macrocode}
   \global\advance\LT at rows\@ne
   \ifnum\LT at rows=\LTchunksize
+%    \end{macrocode}
+%    At the end of the chunk \verb=\\= is doing something special and
+%    so we lose \verb=\tbl_count_missing_cells:n=. Below is about the
+%    right place to add it do this code branch.
+% \changes{v4.19}{2023/12/16}{Managing cell indexes}
+%    \begin{macrocode}
+    \tbl_count_missing_cells:n {echunk}
     \gdef\LT at setprevdepth{%
       \prevdepth\z@
       \global\let\LT at setprevdepth\relax}%
@@ -1563,6 +1749,8 @@
     \ifnum0=`{}\fi
     \expandafter\LT at LL@FM at cr
   \fi}
+\ExplSyntaxOff
+%<@@=>
 %    \end{macrocode}
 % \end{macro}
 %
@@ -1943,7 +2131,9 @@
 % This code is based on "\cline". Two copies of the line are produced,
 % as described above.
 %    \begin{macrocode}
-\def\LT@@hline{%
+%<@@=tbl>
+\ExplSyntaxOn
+\def\LT@@@@hline{%
   \ifx\@let at token\hline
     \global\let\@gtempa\@gobble
     \gdef\LT at sep{\penalty-\@medpenalty\vskip\doublerulesep}%
@@ -1954,11 +2144,25 @@
   \ifnum0=`{\fi}%
   \multispan\LT at cols
      \unskip\leaders\hrule\@height\arrayrulewidth\hfill\cr
-  \noalign{\LT at sep}%
+%    \end{macrocode}
+%    Don't update the row counter, or rather undo the update done in \cs{everycr}:
+% \changes{v4.19}{2023/12/16}{Managing cell indexes}
+%    \begin{macrocode}
+  \noalign{
+    \tbl_gdecr_row_count:
+    \LT at sep}
   \multispan\LT at cols
      \unskip\leaders\hrule\@height\arrayrulewidth\hfill\cr
-  \noalign{\penalty\@M}%
+%    \end{macrocode}
+%    Same here.
+% \changes{v4.19}{2023/12/16}{Managing cell indexes}
+%    \begin{macrocode}
+  \noalign{
+    \tbl_gdecr_row_count:
+    \penalty\@M}
   \@gtempa}
+\ExplSyntaxOff
+%<@@=>
 %    \end{macrocode}
 % \end{macro}
 %
@@ -2049,6 +2253,8 @@
 % \begin{macro}{\LT at output}
 %     Actually this is not so bad, with FM leading the way.
 %    \begin{macrocode}
+%<@@=tbl>
+\ExplSyntaxOn
 \def\LT at output{%
   \ifnum\outputpenalty <-\@Mi
     \ifnum\outputpenalty > -\LT at end@pen
@@ -2055,7 +2261,7 @@
 %    \end{macrocode}
 %     If this was a float or a marginpar we complain.
 %    \begin{macrocode}
-      \LT at err{floats and marginpars not allowed in a longtable}\@ehc
+      \LT at err{floats~ and~ marginpars~ not~ allowed~ in~ a~ longtable}\@ehc
     \else
 %    \end{macrocode}
 % We have reached the end of the table, on the scroll at least,
@@ -2103,6 +2309,13 @@
 %    \begin{macrocode}
         \unvbox\z@\box\ifvoid\LT at lastfoot\LT at foot\else\LT at lastfoot\fi
 %    \end{macrocode}
+%    Handle foot box when tagging:
+%
+% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
+%    \begin{macrocode}
+        \UseTaggingSocket{tbl/longtable/foot}
+%    \end{macrocode}
+%
 % End of "\ifnum\outputpenalty > -\LT at end@pen".
 %    \begin{macrocode}
     \fi
@@ -2114,6 +2327,15 @@
 % If we have not reached the end of the table,
 %    \begin{macrocode}
     \setbox\@cclv\vbox{\unvbox\@cclv\copy\LT at foot\vss}%
+%    \end{macrocode}
+%
+%    Handle foot box when tagging:
+% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
+%    \begin{macrocode}
+    \UseTaggingSocket{tbl/longtable/foot}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
     \@makecol
     \@outputpage
 %    \end{macrocode}
@@ -2133,8 +2355,15 @@
 %    \begin{macrocode}
   \fi}
 %    \end{macrocode}
+%
+%    \begin{macrocode}
+\ExplSyntaxOff
+%<@@=>
+%    \end{macrocode}
 % \end{macro}
 %
+%
+%
 % \subsection{Commands for the table head and foot}
 %
 % \begin{macro}{\LT at end@hd at ft}
@@ -2142,7 +2371,67 @@
 % box specified by "#1". Issue an error if the table has already
 % started. Then start a new chunk.
 %    \begin{macrocode}
+%<@@=tbl>
+\ExplSyntaxOn
 \def\LT at end@hd at ft#1{%
+%    \end{macrocode}
+%    
+%    This command is used to store the head and foot boxes.
+%    We need to retrieve and store the row so that we can clean
+%    up the structure in the finalize code.
+%
+%    To handle missing columns in the header we need this:
+% \changes{v4.19}{2023/12/16}{Managing cell indexes}
+%    \begin{macrocode}
+  \tbl_if_row_was_started:TF
+     {
+%    \end{macrocode}
+%    TODO: This is exposing internal counters, so it should be encapsulated
+%    in some interface command (but I'm not sure what that should be
+%    called, so not done yet. 
+% \changes{v4.19}{2023/12/16}{Managing cell indexes}
+%    \begin{macrocode}
+       \tbl_count_missing_cells:n {head/foot}
+       \int_step_inline:nn
+         { \LT at rows + 1 }
+         {
+           \seq_gput_left:ce
+             {g_@@_\cs_to_str:N #1 _rows_seq }
+             { \int_eval:n {\g_@@_row_int + 1 - ##1 } }
+         }
+%    \end{macrocode}
+%    We also have to set the chunk rows to its max value before
+%    calling \cs{LTechunk} so that we don't get extra increments of
+%    the main row counter due to \cs{everycr}.
+%    \begin{macrocode}
+       \int_gset:Nn \LT at rows { \LTchunksize }
+     }
+%    \end{macrocode}
+
+%    If  we are still in column zero then we had an empty \cs{endhead}
+%    and so making any assignment, etc., would start a row --- something we don't want.
+%    To get out of this trap we  run \cs{crcr} (which would normally
+%    come inside \cs{LT at echunk}. That will then trigger \cs{everycr}
+%    and update row counter unnecessarily, but now we have a defined state, so
+%    we can use \cs{noalign} to undo that. 
+%    We also change \cs{LT at rows} so that further \cs{cr}s do not do
+%    any harm (as explained above.
+%
+%    The \cs{crcr} inside \cs{LT at echunk} will be bypassed in that case
+%    as we have just executed a \cs{crcr} and are still in scanning modus for
+%    \cs{omit} or \cs{noalign}.     
+%    \begin{macrocode}
+     {
+       \crcr
+       \noalign{
+%    \end{macrocode}
+%    
+% \changes{v4.19}{2023/12/16}{Managing cell indexes}
+%    \begin{macrocode}
+         \tbl_gdecr_row_count:         % undo the increment
+         \int_gset:Nn \LT at rows { \LTchunksize }
+       }
+     }
   \LT at echunk
 %    \end{macrocode}
 % Changed from "\relax" to "\endgraf" at V3.04, see "\LT at start".
@@ -2149,13 +2438,19 @@
 %    \begin{macrocode}
   \ifx\LT at start\endgraf
     \LT at err
-     {Longtable head or foot not at start of table}%
-     {Increase LTchunksize}%
+     {Longtable~ head~ or~ foot~ not~ at~ start~ of~ table}%
+     {Increase~ LTchunksize}%
   \fi
   \setbox#1\box\z@
+  \@@_trace:n {-->>~ Saving~\noexpand#1}  
   \LT at get@widths
   \LT at bchunk}
 %    \end{macrocode}
+%
+%    \begin{macrocode}
+\ExplSyntaxOff
+%<@@=>
+%    \end{macrocode}
 % \end{macro}
 %
 % \begin{macro}{\endfirsthead}
@@ -2255,7 +2550,25 @@
 %    \end{macrocode}
 % \end{macro}
 %
+%
+%
+%
+%
+%    Some variables need for the tagging support.
 %    \begin{macrocode}
+%<@@=tbl>
+\ExplSyntaxOn
+   \seq_new:N \g_@@_LT at firsthead_rows_seq
+   \seq_new:N \g_@@_LT at head_rows_seq
+   \seq_new:N \g_@@_LT at lastfoot_rows_seq
+   \seq_new:N \g_@@_LT at foot_rows_seq
+\ExplSyntaxOff
+%<@@=>
+%    \end{macrocode}
+%
+%
+%
+%    \begin{macrocode}
 %</package>
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/tools/longtable.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/longtable.ins	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/longtable.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -3,7 +3,7 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
@@ -45,7 +45,7 @@
 reports for it can be opened at https://latex-project.org/bugs/
 (but please observe conditions on bug reports sent to that address!)
 
-Copyright (C) 1993-2023
+Copyright (C) 1993-2024
 The LaTeX Project and any individual authors listed elsewhere
 in this file.
 

Modified: trunk/Master/texmf-dist/source/latex/tools/multicol.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/multicol.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/multicol.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -86,11 +86,10 @@
 %<*dtx>
           \ProvidesFile{multicol.dtx}
 %</dtx>
-%<package>\NeedsTeXFormat{LaTeX2e}[2018-04-01]
 %<package>
-%<package>\providecommand\DeclareRelease[3]{}
-%<package>\providecommand\DeclareCurrentRelease[2]{}
-%<package>
+% For any rollback before 2017 load the 2017 version and hope for the best:          
+%<package>\DeclareRelease{}{1994-06-01}{multicol-2017-04-11.sty}
+%
 %<package>\DeclareRelease{}{2017-04-11}{multicol-2017-04-11.sty}
 %<package>\DeclareRelease{v1.8}{2019-10-01}{multicol-2019-10-01.sty}
 %<package>\DeclareCurrentRelease{}{2021-11-15}
@@ -99,11 +98,11 @@
 %<driver> \ProvidesFile{multicol.drv}
 % \fi
 %         \ProvidesFile{multicol.dtx}
-          [2023/03/30 v1.9f  multicolumn formatting (FMi)]
+          [2024/05/23 v1.9h  multicolumn formatting (FMi)]
 %
 %
-%%
 %
+%
 % \changes{v1.9c}{2021/11/30}{Added rollback to v1.8}
 % \changes{v1.5n}{1997/06/05}{Applied improvement of documentation,
 %          kindly done by Robin Fairbairns.}
@@ -919,9 +918,22 @@
 %    And we don't show macro names in the margin.
 %    \begin{macrocode}
 \setcounter{IndexColumns}{4}
-\let\DescribeMacro\SpecialUsageIndex
-\let\DescribeEnv\SpecialEnvIndex
-\renewcommand\PrintMacroName[1]{}
+%    \end{macrocode}
+%
+%    The following redefinitions have to be moved until after the
+%    preamble because version 3 of \pkg{doc} resets them after the
+%    premable (this is tmp, because \pkg{hypdoc} is not yet
+%    integrated, but as we all know, tmp solutions have a tendency to
+%    survive for a long time\ldots).
+%    \begin{macrocode}
+\AddToHook{begindocument}{%
+  \let\DescribeMacro\SpecialUsageIndex
+  \let\DescribeEnv\SpecialEnvIndex
+  \renewcommand\PrintMacroName[1]{}%
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \CodelineIndex
 %\DisableCrossrefs           % Partial index
 \RecordChanges               % Change log
@@ -1082,7 +1094,7 @@
 %    better test for this situation. Otherwise, we will get a \TeX{}
 %    stack overflow as this would generate a self-referencing definition.
 % \changes{v1.6e}{2004/02/14}{Avoid self-referencing definition of
-%    \cs{@footnotetext} (pr/3618)}.
+%    \cs{@footnotetext} (pr/3618)}
 %    \begin{macrocode}
      \ifx\@footnotetext\mult at footnotetext
      \else
@@ -2376,7 +2388,7 @@
 %    If |\raggedcolumns| is in force we add a |vfill| at the bottom by
 %    unboxing the split box.
 %    But we need to unbox anyway to ensure that at the end of the box
-%    we do not have unwanted space. This can sneak in in certain
+%    we do not have unwanted space. This can sneak in, in certain
 %    situations, for example, if two lists follow each other and we
 %    break between them. While such space is usually zero it still has
 %    an effect because it hides depth of the last line in the column
@@ -2925,7 +2937,11 @@
 %    We start by setting the kept marks by updating them with any
 %    marks from this box. This has to be done \emph{before} we add a
 %    penalty of $-10000$ to the top of the box, otherwise only an
-%    empty box will be considered.
+%    empty box will be considered. But even that is not enough: the box
+%    may contain \cs{columnbreak}s in which case doing some artifical
+%    splitting to get the marks out still fails to see all marks
+%    unless we take some special precaution in \cs{get at keptmarks}
+%    (which is now done).
 % \changes{v1.5h}{1994/08/26}{Get kept marks first}
 %    \begin{macrocode}
    \get at keptmarks\mult at box
@@ -3751,8 +3767,15 @@
 %    everything is split off. As a result |\splitfirstmark| and
 %    |\splitbotmark| will contain the first and last mark in the box
 %    respectively.
+%
+%    Unfortunately, a simple \cs{vsplit} is not enough if the material
+%    contains forced breaks in that case we first have to get rid of
+%    those which is why we do this work in a separate macro that can
+%    call itself recursively.
+% \changes{v1.9g}{2023/11/10}{Get rid of forced breaks for mark
+%      extraction (gh/1130)}
 %    \begin{macrocode}
-   \setbox#1\vsplit#1to\maxdimen
+   \mc at get@all at box@marks #1%
 %    \end{macrocode}
 %    Therefore we can now set the kept marks which is a global
 %    operation and afterwards close the group. This will restore the
@@ -3773,6 +3796,29 @@
 %  \end{macro}
 %
 %
+%  \begin{macro}{\mc at get@all at box@marks}
+%    This macro splits a box to \cs{maxdimen} in order to get at the
+%    marks inside. If it turns out that we have a remainder after the
+%    split (e.g., if there was a \cs{columnbreak} in the material) we
+%    stitch the two parts together again (which omits the forced
+%    break) and recurse. Eventually, everything is split off and the
+%    split marks will then have the appropriate values.
+% \changes{v1.9g}{2023/11/10}{Get rid of forced breaks for mark
+%      extraction (gh/1130)}
+%    \begin{macrocode}
+\def\mc at get@all at box@marks #1{%
+  \setbox\@tempboxa\vsplit#1to\maxdimen
+  \ifvoid#1\else
+    \setbox#1\vbox{\unvbox\@tempboxa \unvbox#1}%
+    \mc at get@all at box@marks #1%
+  \fi
+}
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%
+%
 %  \begin{macro}{\set at keptmarks}
 %    The macro |\set at keptmarks| is responsible for setting
 %    |\kept at firstmark| and |\kept at botmark|, by checking the current

Modified: trunk/Master/texmf-dist/source/latex/tools/multicol.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/multicol.ins	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/multicol.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -3,7 +3,7 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
@@ -45,7 +45,7 @@
 reports for it can be opened at https://latex-project.org/bugs/
 (but please observe conditions on bug reports sent to that address!)
 
-Copyright (C) 1993-2023
+Copyright (C) 1993-2024
 The LaTeX Project and any individual authors listed elsewhere
 in this file.
 

Modified: trunk/Master/texmf-dist/source/latex/tools/rawfonts.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/rawfonts.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/rawfonts.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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.

Modified: trunk/Master/texmf-dist/source/latex/tools/shellesc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/shellesc.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/shellesc.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse
 %% Source File: shellesc.dtx
-%% Copyright (C) 2015-2023
+%% Copyright (C) 2015-2024
 %%
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.

Modified: trunk/Master/texmf-dist/source/latex/tools/showkeys.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/showkeys.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/showkeys.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2023
+% Copyright (C) 1993-2024
 %
 % The LaTeX Project and any individual authors listed elsewhere
 % in this file.
@@ -22,7 +22,7 @@
 % \fi
 % \iffalse
 %% File: showkeys.dtx Copyright (C) 1992-1997 David Carlisle
-%% File: showkeys.dtx Copyright (C) 2006-2019 David Carlisle, LaTeX Project
+%% File: showkeys.dtx Copyright (C) 2006-2024 David Carlisle, LaTeX Project
 %
 %<*dtx>
           \ProvidesFile{showkeys.dtx}
@@ -29,9 +29,8 @@
 %</dtx>
 %<package>\NeedsTeXFormat{LaTeX2e}
 %<package>
-%<package>\providecommand\DeclareRelease[3]{}
-%<package>\providecommand\DeclareCurrentRelease[2]{}
-%<package>
+% For every rollback request before 2022 use the 2014 version:
+%<package>\DeclareRelease{}{1994-06-01}{showkeys-2014-10-28.sty}
 %<package>\DeclareRelease{}{2014-10-28}{showkeys-2014-10-28.sty}
 %<package>\DeclareCurrentRelease{}{2022-06-01}
 %<package>
@@ -39,7 +38,7 @@
 %<driver> \ProvidesFile{showkeys.drv}
 % \fi
 %         \ProvidesFile{showkeys.dtx}
-          [2023/07/08 v3.19 Show cite and label keys (DPC, MH)]
+          [2024/05/23 v3.21 Show cite and label keys (DPC, MH)]
 %
 % \iffalse
 %<*driver>
@@ -417,6 +416,8 @@
 %    \end{macrocode}
 % \changes{v3.02}{1995/03/17}
 %         {New code for `in label' case.}
+% \changes{v3.20}{2023/12/16}
+%         {Avoid adding an extra box layer github/1123}
 % If the |\label| is straight after |\item| (|\bibitem| is handled by
 % this case as well) then the item label has not been added to the page
 % yet. It is hanging around in the box |\@labels| waiting for the
@@ -425,7 +426,7 @@
       \global\setbox\@labels\hbox{%
         \llap{\SK at lab\SK at lab@relax
               \kern\@totalleftmargin\kern\marginparsep}%
-        \box\@labels}%
+        \unhbox\@labels}%
 %    \end{macrocode}
 %
 %    \begin{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/tools/somedefs.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/somedefs.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/somedefs.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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.

Modified: trunk/Master/texmf-dist/source/latex/tools/tabularx.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/tabularx.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/tabularx.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2023
+% Copyright (C) 1993-2024
 %
 % The LaTeX Project and any individual authors listed elsewhere
 % in this file.
@@ -31,7 +31,7 @@
 %<driver> \ProvidesFile{tabularx.drv}
 % \fi
 %         \ProvidesFile{tabularx.dtx}
-          [2023/07/08 v2.11c `tabularx' package (DPC)]
+          [2023/12/11 v2.12a `tabularx' package (DPC)]
 % \iffalse
 %<*driver>
 \documentclass{ltxdoc}
@@ -261,6 +261,25 @@
 % This behaviour of the package can be customised slightly
 % as noted in the documentation of the code section.
 %
+% \section{Support for tagged PDF}
+%
+% With version 2.12a the package is made tagging aware, which means that
+% it will automatically produce tagged tables (necessary, for example, for
+% accessibility) if tagging is requested via \cs{DocumentMetadata}.
+%
+% More granular control, e.g., explicitly deciding which cells are
+% header cells, etc., is currently under development, but syntax for
+% this will not appear in this package. Instead it will become
+% available across all tabular-generating packages and then
+% automatically apply here as well.
+%
+% Enabling \LaTeX{} to automatically produce tagged PDF is a long-term
+% project and this is a tiny step in this puzzle. For more information
+% on the project and already available functionality, see
+% \url{https://latex-project.org/publications/indexbytopic/pdf} and
+% \url{https://github.com/latex3/tagging-project}.
+%
+%
 % \MaybeStop{}
 %
 % \section{The Macros}
@@ -269,6 +288,14 @@
 %<*package>
 %    \end{macrocode}
 %
+%    We only need two changes for tagging support, but they require
+%    that a recent \LaTeX{} kernel is used (which should be no problem
+%    if \texttt{tools} is distributed in parallel with the kernel.
+% \changes{v2.12a}{2023/12/11}{Require newer LaTeX kernel}
+%    \begin{macrocode}
+\NeedsTeXFormat{LaTeX2e}[2024/06/01]
+%    \end{macrocode}
+%
 % \changes{v2.00}{1994/02/07}
 %    {New Option Handling}
 %    \begin{macrocode}
@@ -506,7 +533,15 @@
 %    \begin{macrocode}
   \TX at typeout@
     {\@spaces Table Width\@spaces Column Width\@spaces X Columns}%
-%    \end{macrocode}%
+%    \end{macrocode}
+%
+%    While we do trial typesetting we suspend any tagging if that is
+%    active:
+% \changes{v2.12a}{2023/12/11}
+%    {Suspend any tagging while doing trial typesetting}
+%    \begin{macrocode}
+   \SuspendTagging {tabularx}%
+%    \end{macrocode}
 % First attempt. Modify the {\ttfamily X} definition to count {\ttfamily
 % X} columns.
 %    \begin{macrocode}
@@ -523,6 +558,12 @@
     \TX at trial{}%
   \repeat
 %    \end{macrocode}
+%
+%    And here we restart it again:
+%    \begin{macrocode}
+  \ResumeTagging {tabularx}%
+%    \end{macrocode}
+%
 % One last time, with warnings back on (see appendix D)
 % use {\ttfamily tabular*} to put it in a box of the right size, in case
 % the algorithm failed to find the correct size.
@@ -737,8 +778,9 @@
 % Make the table, and finish the hbox.
 % Since v1.06, "\toks@" contains the preamble specification,
 % and possible optional argument, as well as the table body.
+%    
 %    \begin{macrocode}
-    \expandafter\tabular\the\toks@
+   \expandafter\tabular\the\toks@
     \endtabular}%
 %    \end{macrocode}
 % Since v1.05 reset all \LaTeX\ counters, by executing "\TX at ckpt".
@@ -961,6 +1003,7 @@
 %    \end{macrocode}
 % \end{macro}
 %
+%
 %    \begin{macrocode}
 %</package>
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/tools/tabularx.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/tabularx.ins	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/tabularx.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -3,7 +3,7 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
@@ -45,7 +45,7 @@
 reports for it can be opened at https://latex-project.org/bugs/
 (but please observe conditions on bug reports sent to that address!)
 
-Copyright (C) 1993-2023
+Copyright (C) 1993-2024
 The LaTeX Project and any individual authors listed elsewhere
 in this file.
 

Modified: trunk/Master/texmf-dist/source/latex/tools/theorem.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/theorem.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/theorem.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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.

Modified: trunk/Master/texmf-dist/source/latex/tools/tools.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/tools.ins	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/tools.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -3,7 +3,7 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
@@ -49,7 +49,7 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2023
+Copyright (C) 1993-2024
 The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
@@ -178,6 +178,13 @@
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \SimplePackage{shellesc}
 
+
+% Shell Filee System Queries
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\batchinput{l3sys-query.ins}
+
+
+
 % File-Error files
 %%%%%%%%%%%%%%%%%%
 \generate{%

Modified: trunk/Master/texmf-dist/source/latex/tools/trace.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/trace.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/trace.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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.

Modified: trunk/Master/texmf-dist/source/latex/tools/varioref.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/varioref.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/varioref.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2023
+% Copyright (C) 1993-2024
 %
 % The LaTeX Project and any individual authors listed elsewhere
 % in this file.
@@ -33,14 +33,15 @@
 %%
 %
 %<package>\NeedsTeXFormat{LaTeX2e}[1995/05/16]
-%<package>\providecommand\DeclareRelease[3]{}
-%<package>\providecommand\DeclareCurrentRelease[2]{}
 %<package>
+%
+% For any rollback before 2019 load the 2016 version and hope for the best:
+%<package>\DeclareRelease{}{1994-06-01}{varioref-2016-02-16.sty}
 %<package>\DeclareRelease{}{2016-02-16}{varioref-2016-02-16.sty}
 %<package>\DeclareCurrentRelease{}{2019-10-01}
 %<package>
 %<package>\ProvidesPackage{varioref}
-%<package>    [2022/01/09 v1.6f package for extended references (FMi)]
+%<package>    [2024/05/23 v1.6g package for extended references (FMi)]
 % \fi
 %
 %%
@@ -144,8 +145,8 @@
 %\DescribeMacro\vref The implementation of |\vref| below produces only
 % a |\ref| when reference and |\label| are on the same page. It will
 % additionally produce one of the strings `on the facing page', `on
-% the preceding page', or `on the following page', if label and
-% reference differ by one and it will produce both |\ref| and
+% the preceding page', or `on the following page' if label and
+% reference differ by one; and it will produce both |\ref| and
 % |\pageref| when the difference is larger.  The word `facing' is used
 % when label and reference both fall onto a double spread.  However,
 % if a special page numbering scheme is used instead of the usual
@@ -169,7 +170,7 @@
 % comes out as ``\ldots~see the example which shows~\ldots'', which
 % could be misleading.
 %
-% A space in front of |\vpageref| it will be ignored if
+% A space in front of |\vpageref| will be ignored if
 % the command doesn't produce any text at all.
 %
 % But in fact |\vpageref| allows even more control. It has two
@@ -210,7 +211,7 @@
 % \DescribeMacro\vrefrange
 % This command is similar to |\vref| but it
 % takes two mandatory arguments denoting a range to refer to (e.g., a
-% sequences of figures or a sequence of equations, etc.). So if
+% sequence of figures or a sequence of equations, etc.). So if
 % |fig:a| is your first figure in the sequence and |fig:c| your last
 % you can write
 %\begin{verbatim}
@@ -273,8 +274,8 @@
 % \DescribeMacro\vpagerefcompare
 % \NewIn{2019}
 % For this kind of application the package also provides
-% |\vpagerefcompare| as a command that takes four argument: two labels for
-% comparison and a \meta{true} and \meta{false} argument. One of them
+% |\vpagerefcompare| as a command that takes four arguments: two labels
+% for comparison and a \meta{true} and \meta{false} argument. One of them
 % is executed depending on whether the two labels are on the same page
 % or on different pages. With its help the above definition could be
 % shortened to
@@ -293,8 +294,9 @@
 % Another command for conditional processing is |\vpagerefnearby|. It
 % takes three arguments: a label and a \meta{true} and \meta{false}
 % argument. It compares the page reference to the label with the
-% current page number and if both are Arabic number and only differ by
-% $\pm1$ the \meta{true} argument is executed otherwise the
+% current page number; if each of these is a positive integer
+% (expressed in Arabic numerals) and they differ by at most
+% $\pm1$, the \meta{true} argument is executed, otherwise the
 % \meta{false} argument. In other words it tells you if a |\vpageref|
 % to the label would result in a textual reference to the previous,
 % current or next page.\footnote{There is also a
@@ -320,11 +322,11 @@
 % versions of the macros which do not add any space before the
 % generated text (they do nevertheless remove space at the left).
 %
-% However, that too has problems (one is that \pkg{hyperref}
+% However, that too has problems: one is that \pkg{hyperref}
 % \ChangedIn{2019}
-% introduced the star forms as a means to generating references
-% without hyperlinks (which is clearly the more important
-% application).
+% introduced the star forms as a means of generating references
+% without hyperlinks, which is clearly the more important
+% application.
 % So these days I recommend to always call the package with the option
 % \option{nospace} which prevents \pkg{varioref} from messing with the
 % space in front. Of course you are then responsible to always add it
@@ -381,7 +383,7 @@
 % label and reference fall onto the same page, but prefer reference to
 % page numbers otherwise then |\thevpagerefnum| can be used. This macro
 % hold the current page ``number'' when |\vpageref| and friends are
-% executed. Thus, by defining, for example
+% executed. Thus, by defining, for example,
 %\begin{verbatim}
 %\renewcommand\reftextfaceafter {on page~\thevpagerefnum}
 %\renewcommand\reftextfacebefore{on page~\thevpagerefnum}
@@ -436,7 +438,7 @@
 %\DescribeMacro\reftextafter
 %\DescribeMacro\reftextfaceafter Backward references use
 % |\reftextbefore| if the label is on the preceding page but invisible
-% and |\reftextfacebefore| if it is one the facing page (i.e., if the
+% and |\reftextfacebefore| if it is on the facing page (i.e., if the
 % current page number is odd).  Similarly |\reftextafter| is used
 % when the label comes on the next page but one has to turn the page
 % and |\reftextfaceafter| if it is on the following but facing page.
@@ -447,7 +449,7 @@
 %\DescribeMacro\reftextfaraway Finally we have |\reftextfaraway| which
 % is used whenever label and reference differ by more than one or when
 % they aren't numeric. This macro is a bit different because it takes
-% one argument, the symbolic reference string so that one cane make
+% one argument, the symbolic reference string, so that one can make
 % use of |\pageref| in its replacement text.
 %
 %
@@ -521,7 +523,7 @@
 % and \option{nospace}. While the former is the default to allow
 % \NewIn{2019}
 % documents written in the last twenty years to continue to work
-% correctly, I nowadays, suggest that you always use the package with
+% correctly, I nowadays suggest that you always use the package with
 % the option \option{nospace}. This will stop \pkg{varioref} from
 % meddling with the spaces preceding commands and thus make the star
 % forms |\vref*| and |\vpageref*| unnecessary.
@@ -536,7 +538,7 @@
 % Defining commands like the ones described above poses some
 % interesting problems. Suppose, for example, that a generated text
 % like `on the next page' gets broken across pages. If this happens it
-% is very difficult to find an acceptable solution and in fact can
+% is very difficult to find an acceptable solution and it can, in fact,
 % even result in a document that will always change from one state to
 % another (i.e., inserting one string, finding that this is wrong,
 % inserting another string on the next run which makes the first
@@ -699,7 +701,7 @@
 %  \begin{macro}{\reftextbefore}
 %  \begin{macro}{\reftextcurrent}
 % \label{reftextbefore} The options do set the macros that
-%    generate the textual strings. Note, that they do not start with a
+%    generate the textual strings. Note that they do not start with a
 %    space, the space is already added in the main macro below.
 % \changes{v1.2a}{1998/08/22}{Added American defaults for
 %      \cs{reftextpagerange} and \cs{reftextlabelrange}}
@@ -838,7 +840,7 @@
 %    the noun (clause); bertentangan is ``opposite'' in the sense of
 %    ``facing''; berikutnya is ``next'' (in this context - actually
 %    next-to-this, literally); berikutnya also translates as ``following
-%    this'' sebelumnya is ``preceding''; also ``previous'' ``ini'' translates,
+%    this''; sebelumnya is ``preceding'', also ``previous''; ``ini'' translates,
 %    literally, as ``this'' but is also used in the sense of current page.
 % \changes{v1.4o}{2005/12/02}{Bahasa Malaysia defaults added.}
 %    \begin{macrocode}
@@ -1036,7 +1038,7 @@
     \let\vrefrangeformat\vrefrangedefaultformat
   }}
 %    \end{macrocode}
-%    Default string for dutch have been contributed by Frank Poppe
+%    Default strings for Dutch have been contributed by Frank Poppe
 %    (\verb=POPPE at SWOV.NL=).
 %    This option currently supports one additional string macro
 %    |\refpagename| so that you can easily change to |bladzijde|
@@ -1124,9 +1126,9 @@
     \let\vrefrangeformat\vrefrangedefaultformat
   }}
 %    \end{macrocode}
-%    The finnish strings were suggested by Matti Rintala
+%    The Finnish strings were suggested by Matti Rintala
 %    (\verb=bitti at cs.tut.fi=) and Hillevi Gavel
-%    \verb=Hillevi.Gavel at mdh.se=.
+%    (\verb=Hillevi.Gavel at mdh.se=).
 % \changes{v1.0m}{1994/09/23}{Added finnish strings}
 % \changes{v1.4o}{2005/11/07}{Added a few more finnish strings}
 %    \begin{macrocode}
@@ -1200,10 +1202,10 @@
   }}
 %    \end{macrocode}
 %    There are no good variants for German (I think and still think but
-%    this is a matter of taste :-).
+%    this is a matter of taste :-)).
 % \changes{v1.0b}{1994/01/31}{Replace in incorrect `def by `let}
 %    The following definitions were recently suggested to me but since
-%    the original are in for a long time i don't want to change them
+%    the originals have been there for a long time I don't want to change them
 %    now since that could make a lot of documents change their formatting.
 %    If you fancy them, add a redefinition of the corresponding macro(s)
 %    to the preamble of your document.
@@ -1935,7 +1937,7 @@
 %    \end{macrocode}
 %    But if \texttt{nospace} is in force we simply use the same space
 %    value that was used in the source document (unless that was zero
-%    or non-existent.
+%    or non-existent).
 %    \begin{macrocode}
     \ifdim\@tempskipa=\z@ \else
       \hskip\@tempskipa
@@ -1978,7 +1980,7 @@
 %    \begin{macrocode}
   \vrefpagenum\thevpagerefnum{#3}%
 %    \end{macrocode}
-%    Now after the internal label has served its purpose if would be
+%    Now after the internal label has served its purpose it would be
 %    nice to free the memory it occupies by using something like
 %    \begin{verbatim}
 % \global\expandafter\let
@@ -2008,7 +2010,7 @@
     \fi
   \else
 %    \end{macrocode}
-%    If |#2| is empty we do nothing otherwise we insert it followed by
+%    If |#2| is empty we do nothing, otherwise we insert it followed by
 %    a space.
 %    \begin{macrocode}
     \def\@tempc{#2}%
@@ -2017,7 +2019,7 @@
     \fi
 %    \end{macrocode}
 %    Now we check if the page number of the referenced object (stored
-%    in |\thevpagerefnum| is a single positive number.
+%    in |\thevpagerefnum|) is a single positive number.
 %    \begin{macrocode}
     \is at pos@number\thevpagerefnum
        {%
@@ -2032,7 +2034,7 @@
          }%
 %    \end{macrocode}
 %    If it is not a positive number we assign the largest possible
-%    number to |\@tempcnta| and thereby pretending that label and
+%    number to |\@tempcnta|, thereby pretending that label and
 %    reference are miles away from each other.
 %    \begin{macrocode}
          {\@tempcnta\maxdimen}%
@@ -2049,7 +2051,7 @@
 %    Thus if the object falls onto an odd page then the reference is
 %    on the facing even page (and so we insert |\reftextfaceafter|),
 %    otherwise the object can not be seen from the reference (and we
-%    in insert |\reftextafter|).  Don't be surprised if we are not
+%    insert |\reftextafter|).  Don't be surprised if we are not
 %    using |\thevpagerefnum| in the check. Since |\@tempcnta| has the same
 %    value it is faster to use the register instead of parsing the
 %    macro contents anew.
@@ -2061,7 +2063,7 @@
 %    used.
 %    Since the value of |\if at twoside| is evaluated before reading in
 %    packages we could do better (saving some tokens) by defining
-%    the current macro in dependence of this boolean.
+%    the current macro depending on this boolean.
 %    \begin{macrocode}
            \if at twoside
              \reftextfaceafter
@@ -2075,11 +2077,11 @@
 %    If the object is not on the page following the reference we check
 %    if it is on the page before the reference. In \LaTeX{} this
 %    situation is not too common, for example with floats it normally
-%    does not occur, but of course it isn't impossible if you more
+%    does not occur, but of course it isn't impossible if you have more
 %    than one reference to the same object, or if you have back
 %    references to sections, theorems, etc.  To test this we now
 %    subtract two from the current value of |\@tempcnta| (which was
-%    set to one higher as the reference page number). Note, that
+%    set to one higher as the reference page number). Note that
 %    subtraction is also possible if the value was |\maxdimen| --- we
 %    still get something that is much larger than any sensible page
 %    number.
@@ -2131,7 +2133,7 @@
          \reftextfaraway{#3}}%
   \fi
 %    \end{macrocode}
-%    Finally we generate the internal label so that it can be check on
+%    Finally, we generate the internal label so that it can be checked on
 %    the next run. This means that we compare the position after the
 %    string with the position of the referenced object. There is one
 %    thing to note: to conserve space we locally make |\@currentlabel|
@@ -2252,8 +2254,8 @@
 %    The star form is easy (and just a convenient shortcut), just call
 %    |\ref| followed by |\vpageref| and pass the optional argument to
 %    the latter. We don't support the second optional argument of
-%    |\vpageref|, it that is needed one has to call both commands
-%    explicitly
+%    |\vpageref|, if that is needed one has to call both commands
+%    explicitly.
 % \changes{v1.6a}{2019/08/25}{Command added to support hyperref better}
 % \changes{v1.6e}{2020/07/25}{Changed for Japanese (gh/352)}
 %    \begin{macrocode}
@@ -2264,7 +2266,7 @@
 %
 %  \begin{macro}{\vrefformat,\vrefdefaultformat}
 %    Japanese needs a different word order in \cs{vref at star} so this
-%    is separated out o that it can be changed on language level.
+%    is separated out so that it can be changed at the language level.
 % \changes{v1.6e}{2020/07/25}{Macro added (gh/352)}
 %    \begin{macrocode}
 \def\vrefdefaultformat#1#2{% 
@@ -2293,7 +2295,7 @@
     \unskip \nobreakspace
   \fi
 %    \end{macrocode}
-%    The use of|\nobreakspace| or |~| after the |\unskip| means that
+%    The use of |\nobreakspace| or |~| after the |\unskip| means that
 %    this command will always produce a normal space while
 %    something like |\nobreak\space| will
 %    react to settings of |\nonfrenchspacing|.
@@ -2341,10 +2343,10 @@
 %    Now we have to check whether or not the whole string was parsed
 %    into that register or some remainder was left over. Since we have
 %    added a |\@nil| token at the very end we can use that to delimit
-%    the argument of |\is at pos@num@|. Note, that the added space in
+%    the argument of |\is at pos@num@|. Note that the added space in
 %    |\is at pos@number| \vpageref[above]{isposnumber} gets parsed away
 %    by the counter assignment. If it would be missing, and the full
-%    string would consist of a number, \TeX{}would try to replace
+%    string would consist of a number, \TeX{} would try to replace
 %    |\@nil| by its definition to see if it would contain additional
 %    digits and thus we would be in trouble at this point.
 %    \begin{macrocode}
@@ -2389,7 +2391,7 @@
 %
 %  \begin{macro}{\fullrefformat,\fullrefdefaultformat}
 %    Japanese needs a different word order in \cs{fullref}  so this
-%    is separated out o that it can be changed on language level.
+%    is separated out so that it can be changed at the language level.
 % \changes{v1.6e}{2020/07/25}{Macro added (gh/352)}
 %    \begin{macrocode}
 \def\fullrefdefaultformat#1{% 
@@ -2523,7 +2525,7 @@
 %
 %  \begin{macro}{\vrefrangeformat,\vrefrangedefaultformat}
 %    Japanese needs a different word order in \cs{vrefrange}  so this
-%    is separated out o that it can be changed on language level.
+%    is separated out so that it can be changed at the language level.
 % \changes{v1.6d}{2020/07/20}{Macro added (gh/352)}
 %    \begin{macrocode}
 \def\vrefrangedefaultformat#1#2#3{% 
@@ -2558,7 +2560,7 @@
 %
 %  \begin{macro}{\Vrefformat,\Vrefdefaultformat}
 %    Japanese needs a different word order in \cs{Vref}  so this
-%    is separated out o that it can be changed on language level.
+%    is separated out so that it can be changed at the language level.
 % \changes{v1.6e}{2020/07/25}{Macro added (gh/352)}
 %    \begin{macrocode}
 \def\Vrefdefaultformat#1#2{% 

Modified: trunk/Master/texmf-dist/source/latex/tools/varioref.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/varioref.ins	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/varioref.ins	2024-06-02 20:26:39 UTC (rev 71408)
@@ -3,7 +3,7 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2023
+%% Copyright (C) 1993-2024
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
@@ -45,7 +45,7 @@
 reports for it can be opened at https://latex-project.org/bugs/
 (but please observe conditions on bug reports sent to that address!)
 
-Copyright (C) 1993-2023
+Copyright (C) 1993-2024
 The LaTeX Project and any individual authors listed elsewhere
 in this file.
 

Modified: trunk/Master/texmf-dist/source/latex/tools/verbatim.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/verbatim.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/verbatim.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2023
+% Copyright (C) 1993-2024
 %
 % The LaTeX Project and any individual authors listed elsewhere
 % in this file.
@@ -69,6 +69,8 @@
 %\fi
 %
 %
+% 
+% \changes{v1.5x}{2024/01/22}{Added TAB marking support to \cs{verbatiminput*}}
 % \changes{v1.5u}{2020-07-07}{Typo repair and added a missing comment
 %    character}
 % \changes{v1.5q}{2003/08/22}{Reintroduced \cs{@noligs}, by popular
@@ -508,7 +510,7 @@
 %<*package>
 \NeedsTeXFormat{LaTeX2e}
 \ProvidesPackage{verbatim}
-     [2023-11-06 v1.5v LaTeX2e package for verbatim enhancements]
+     [2024-01-22 v1.5x LaTeX2e package for verbatim enhancements]
 \@ifundefined{verbatim@@@}{}{\endinput}
 %    \end{macrocode}
 %
@@ -1570,7 +1572,14 @@
 %    arguments, depending on whether an asterisk follows.
 %    \begin{macrocode}
 \def\verbatiminput{\begingroup
-  \@ifstar{\verbatim at input\relax}%
+%    \end{macrocode}
+% 
+%   \changes{v1.5x}{2024/01/22}{Added TAB marking support into the
+%   starred version (gh/1245)}
+%   If starred, we mark spaces and TABs, the two
+%   added pieces are the same as for verbatim*.
+%    \begin{macrocode}
+  \@ifstar{\verbatim at input{\@setupverbvisiblespace\@vobeyspaces}}%
           {\verbatim at input{\frenchspacing\@vobeyspaces}}}
 %    \end{macrocode}
 % \end{macro}

Modified: trunk/Master/texmf-dist/source/latex/tools/xr.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/xr.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/xr.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,6 +1,6 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2023
+% Copyright (C) 1993-2024
 %
 % The LaTeX Project and any individual authors listed elsewhere
 % in this file.
@@ -21,14 +21,49 @@
 %
 % \fi
 % \iffalse
-%% File: xr.dtx Copyright (C) 1993-2019 David Carlisle
+%% File: xr.dtx Copyright (C) 1993-2024 David Carlisle
 %
 %<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\DeclareRelease{v5}{2023-07-04}{xr-2023-07-04.sty}
+%<package>\DeclareCurrentRelease{}{2024-04-10}
 %<package>\ProvidesPackage{xr}
-%<package>         [2023-07-04 v5.06 eXternal References (DPC)]
+%<package>         [2024-04-10 v6.00 eXternal References (DPC)]
 %
 %<*driver>
-\documentclass{ltxdoc}
+\documentclass{l3doc}
+% currently missing in l3doc, copied from array.dtx
+\makeatletter
+\def\MaintainedBy#1{\gdef\@maintainedby{#1}}
+\let\@maintainedby\@empty
+\def\MaintainedByLaTeXTeam#1{%
+{\gdef\@maintainedby{%
+This file is maintained by the \LaTeX{} Project team.\\%
+Bug reports can be opened (category \texttt{#1}) at\\%
+\url{https://latex-project.org/bugs.html}.}}}
+\def\@maketitle{%
+  \newpage
+  \null
+  \vskip 2em%
+  \begin{center}%
+  \let \footnote \thanks
+    {\LARGE \@title \par}%
+    \vskip 1.5em%
+    {\large
+      \lineskip .5em%
+      \begin{tabular}[t]{c}%
+        \@author
+      \end{tabular}\par}%
+    \vskip 1em%
+    {\large \@date}%
+    \ifx\@maintainedby\@empty
+    \else
+    \vskip 1em%
+    \fbox{\fbox{\begin{tabular}{@{}l@{}}\@maintainedby\end{tabular}}}%
+    \fi
+  \end{center}%
+  \par
+  \vskip 1.5em}
+\makeatother
 \usepackage{xr}
 \GetFileInfo{xr.sty}
 \begin{document}
@@ -50,44 +85,113 @@
 %
 % \changes{v5.00}{1993/07/07}
 %         {First DPC version (by agreement with J-PD).  New mechanism
-%         (\cmd{\read} instead of \cmd\input).}
+%         (\cs{read} instead of \cs{input}).}
 %
 % \changes{v5.01}{1993/07/20}{Fix bug added by DPC, v5.00 did not import
-%           aux files of \cmd\include'ed files. (Reported by J-PD)}
+%           aux files of \cs{include}'ed files. (Reported by J-PD)}
 %
 % \changes{v5.02}{1994/05/28}{Update for LaTeX2e}
 % \changes{v5.03}{2018/10/01}{Fix for conditionals in aux file}
 % \changes{v5.05}{2019/07/20}{include xcite}
+% \changes{v6.00}{2024/04/10}{merge with xr-hyper}
 %
 %
 % This package implements a system for eXternal References.
-%
+% Version 6.00 merges the \pkg{xr} package and the \pkg{xr-hyper} package.
+% \pkg{xr-hyper} was developed to support the
+% extended label syntax of the \pkg{hyperref} package and to enable active links
+% to the external documents. 
+% In the \LaTeX{} release 2023-06-01 the label syntax of \pkg{hyperref}
+% and the \LaTeX{} kernel have been synchronized and there is no longer
+% a need for two packages. The package \pkg{xr-hyper} will be 
+% deprecated.
+% 
+% The previous version before the merge can be accessed with 
+% \begin{verbatim}
+% \usepackage{xr}[=v5]
+% \end{verbatim}
+% or with a rollback date between 2023-07-04 and 2024-04-09
+% \begin{verbatim}
+% \usepackage{xr}[=2024-04-09] 
+% \end{verbatim}
+% 
+% \section{Usage}
+% 
+% \begin{syntax}
+% \cs{externaldocument}\oarg{prefix}\texttt[nocite\texttt]\marg{document}\oarg{url}
+% \end{syntax}
+% 
 % If one document needs to refer to sections of another, say |aaa.tex|,
 % then this package may be loaded in the main file, and the command\\
 % |\externaldocument{aaa}|\\
 %  given in the preamble.
 %
-% Then you may use |\ref| and |\pageref| to refer to anything which has
+% Then you may use |\ref| and |\pageref| (or |\nameref| if the
+% package \pkg{nameref} has been loaded to refer to anything which has
 % been given a |\label| in either |aaa.tex| or the main document.
+% It is also possible to refer to properties stored with \cs{RecordProperties}.
 % You may declare any number of such external documents.
 %
 % If any of the external documents, or the main document, use the same
 % |\label| then an error will occur as the label will be multiply
 % defined. To overcome this problem |\externaldocument| has an optional
-% argument. If you declare |\externaldocument[A-]{aaa}|, then all
+% argument \meta{prefix}. 
+% If you declare |\externaldocument[A-]{aaa}|, then all
 % references from |aaa| are prefixed by |A-|. So for instance, if a
 % section of |aaa| had |\label{intro}|, then this could be referenced
 % with |\ref{A-intro}|. The prefix need not be |A-|, it can be any
 % string chosen to ensure that all the labels imported from external
-% files are unique. Note however that if your style declares certain
-% active characters (|:| in French, |"| in German) then these
-% characters can not usually be used in |\label|, and similarly may not
-% be used in the optional argument to |\externaldocument|.
+% files are unique. Note however that the prefix is expanded and
+% so should not contain commands that are not safe in this context. 
 %
 % As first suggested in Enrico Gregorio's |xcite| package, the current version
 % also allows |\cite| to reference |\bibitem| in the external document.
 % For compatibility with |xcite|, |\externalcitedocument| is made available
 % as an alias for |\externaldocument|
+% 
+% Many packages have variant citation commands (natbib,
+% biblatex,....) and the external document may or may not have used
+% hyperref. Because of these differences the citation linking may not
+% always work, it can be disabled by specifying \texttt{[nocite]} after the
+% \meta{prefix}:
+% \begin{verbatim}
+%  \externaldocument[][nocite]{aaa}
+% \end{verbatim}  
+% 
+% The `document' referred to by the main argument \meta{document} is the file
+% \file{document.aux} which must be somewhere on TeX's input path.
+% Some packages (eg hyperref) really need to know the location of the
+% final document rather than the aux file. By default this is assumed
+% to be \file{document.pdf}. A package may redefine the command \cs{XR at ext} to
+% change this default extension. However sometimes the final
+% document may be in a position unrelated to the aux file, or the
+% browser may not be able to find files at an arbitrary point in
+% TeX's input path, so the final optional argument \meta{url} allows a full
+% URL to the final document to be specified.
+% \begin{verbatim}
+% \externaldocument{aaa}[https://example.com/this/path/to/aaa.pdf]
+% \end{verbatim}
+% 
+% The package stores the url of the external document in the label data. It can
+% e.g. be retrieved with the \pkg{refcount} package
+% 
+% \begin{verbatim}
+% \usepackage{refcount,xr}
+% \externaldocument{aaa}
+% ...
+% \getrefbykeydefault{intro}{url}{??} %prints aaa.pdf or ??
+% \end{verbatim}
+% 
+% \pkg{xr} supports also the properties introduced in \LaTeX{} 2023-11-01.
+% Here the url of the external document is stored in the \texttt{xr-url} property.
+% 
+% \begin{verbatim}
+% \usepackage{xr}
+% \externaldocument{aaa} %aaa contains \RecordProperties{intro}{page}
+% ...
+% \RefProperty{intro}{page}   %gives page number
+% \RefProperty{intro}{xr-url} %gives aaa.pdf 
+% \end{verbatim}
 %
 % \MaybeStop{}
 %
@@ -98,20 +202,74 @@
 %    \end{macrocode}
 %
 % Check for the optional argument.
+% \changes{v6.00}{2024-04-10}{Copied over extended definition of xr-hyper}
 %    \begin{macrocode}
-\def\externaldocument{\@ifnextchar[\XR@{\XR@[]}}
+\def\externaldocument{\@testopt\XR at cite{}}
 \let\externalcitedocument\externaldocument
+\def\XR at cite[#1]{\@testopt{\XR@[#1]}{}}
+\def\XR@[#1][#2]#3{\@testopt{\XR@@{#1}{#2}{#3}}{#3.\XR at ext}}
 %    \end{macrocode}
 %
-%    Save the optional prefix. Start processing the first |aux| file.
-%  \changes{v5.06}{2020-05-10}{Remove leading and trailing sapces from
+% \subsection{helper definitions}
+% \changes{v6.00}{2024-04-10}{new, copied over from xr-hyper}
+% To test the second optional argument
+%    \begin{macrocode}
+\def\XR@@nocite{nocite}
+%    \end{macrocode}
+% Needed in the processing
+%    \begin{macrocode}
+\long\def\@gobblefour  #1#2#3#4{}
+\long\def\@firstoffour #1#2#3#4{#1}
+\long\def\@secondoffour#1#2#3#4{#2}
+\long\def\@thirdoffour #1#2#3#4{#3}
+\long\def\@fourthoffour #1#2#3#4{#4}
+%    \end{macrocode}
+% The url is added as fifth argument. The command used here is
+% \cs{XR at addURL}. The command is more complicated as needed
+% as it tries to handle also older documents with 
+% \cs{newlabel}'s with two arguments. 
+%    \begin{macrocode}
+\def\XR at addURL#1{\XR@@dURL#1{}{}{}{}\\}
+\def\XR@@dURL#1#2#3#4#5\\{%
+     \unexpanded{{#1}{#2}{#3}{#4}}{\XR at URL}% 
+  }%
+%    \end{macrocode}
+% 
+% \subsection{Variables}
+% \changes{v6.00}{2024-04-10}{new, copied over from xr-hyper}
+% Default file extension:
+%    \begin{macrocode}
+\providecommand\XR at ext{pdf}
+%    \end{macrocode}
+%
+% Save the optional prefix. Start processing the first |aux| file.
+%  \changes{v6.00}{2024-04-10}{copied over the new extended internal command from xr-hyper. 
+%  It prepends the directory name.}
+% Olivier Michel pointed out that
+% if the aux file was not on texinputs you could not always go
+% \cs{externaldocument}{/some/path/to/file}
+% specifically that worked if file.aux was a `simple'  document with
+% one aux file, but if \cs{include} had been used, the `sub' aux files
+% would not be found by xr in the remote directory.
+% This version calls \cs{filename at parse} to get the directory name of the
+% remote directory, which is then explicitly prepended to the names of
+% any included aux files. 
+%  \changes{v5.06}{2020-05-10}{Remove leading and trailing spaces from
 %    the filename (gh/2223)}
 %    \begin{macrocode}
-\def\XR@[#1]#2{{%
+\def\XR@@#1#2#3[#4]{{%
   \makeatletter
   \def\XR at prefix{#1}%
-  \set at curr@file{#2}%
-  \expandafter\XR at next\@curr at file.aux\relax\\}}
+   \def\XR at nocite{#2}%
+   \ifx\XR at nocite\XR@@nocite
+     \let\XR at bibcite\vadjust
+   \else
+     \let\XR at bibcite\bibcite
+   \fi
+  \def\XR at URL{#4}%
+  \set at curr@file{#3}% 
+  \filename at parse\@curr at file 
+  \XR at next\@curr at file.aux\relax\\}}
 %    \end{macrocode}
 %
 % Process the next |aux| file in the list and remove it from the head of
@@ -161,23 +319,40 @@
 %    \end{macrocode}
 %
 % Look at the first token of the line.
-% If it is |\newlabel|, do the |\newlabel|. If it is |\@input|, add the
-% filename to the list of files to process. Otherwise ignore.
+% If it is |\newlabel|, define \cs{r@}\meta{label}, ensure that it has
+% five label data argument and add the url as the last one.  
+% If it is |\@input|, add the
+% filename to the list of files to process. 
+% If it is |\bibcite|, call a |\bibcite|. 
+% If it is |\new at label@record| add the url and then call it.
+% Otherwise ignore.
 % Go around the loop if not at end of file. Finally process the next
 % file in the list.
 %
 % 2018 update: make sure the arguments are handled outside the |\ifx| test,
+% \changes{v6.00}{2024-04-10}{copied over extended definition from xr-hyper}
 %    \begin{macrocode}
 \long\def\XR at test#1#2#3#4\XR@{%
-  \let\XR at tempa\@gobbletwo
+  \let\XR at tempa\@gobblefour
   \ifx#1\newlabel
-    \let\XR at tempa\@firstoftwo
-  \else\ifx#1\bibcite
-    \let\XR at tempa\@firstoftwo
+    \let\XR at tempa\@firstoffour
+  \else\ifx#1\XR at bibcite
+    \let\XR at tempa\@secondoffour
   \else\ifx#1\@input
-     \let\XR at tempa\@secondoftwo
-  \fi\fi\fi
-   \XR at tempa{#1{\XR at prefix#2}{#3}}{\edef\XR at list{\XR at list#2\relax}}%
+     \let\XR at tempa\@thirdoffour
+  \else\ifx#1\new at label@record
+     \let\XR at tempa\@fourthoffour    
+  \fi\fi\fi\fi
+   \XR at tempa
+    {%
+     \expandafter\protected at xdef\csname r@\XR at prefix#2\endcsname{\XR at addURL{#3}}%     
+    }%
+    {\expandafter\bibcite\expandafter{\XR at prefix#2}{#3}}%
+    {\edef\XR at list{\XR at list\filename at area#2\relax}}%
+    {%
+      \edef\next{\noexpand\new at label@record{\XR at prefix#2}{\unexpanded{#3}{xr-url}{\XR at URL}}}%
+      \next
+    }
   \ifeof\@inputcheck\expandafter\XR at aux
   \else\expandafter\XR at read\fi}
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/tools/xspace.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/xspace.dtx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/source/latex/tools/xspace.dtx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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.

Modified: trunk/Master/texmf-dist/tex/latex/amsmath/amsbsy.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/amsmath/amsbsy.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/amsmath/amsbsy.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -7,7 +7,7 @@
 %% amsbsy.dtx 
 %% 
 %% Copyright (C) 1995, 1999 American Mathematical Society.
-%% Copyright (C) 2016-2023 LaTeX Project and American Mathematical Society.
+%% Copyright (C) 2016-2024 LaTeX Project and American Mathematical Society.
 %% 
 %% This work may be distributed and/or modified under the
 %% conditions of the LaTeX Project Public License, either version 1.3c

Modified: trunk/Master/texmf-dist/tex/latex/amsmath/amscd.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/amsmath/amscd.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/amsmath/amscd.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -7,7 +7,7 @@
 %% amscd.dtx 
 %% 
 %% Copyright (C) 1995, 1999 American Mathematical Society.
-%% Copyright (C) 2016-2023  LaTeX Project and American Mathematical Society.
+%% Copyright (C) 2016-2024  LaTeX Project and American Mathematical Society.
 %% 
 %% This work may be distributed and/or modified under the
 %% conditions of the LaTeX Project Public License, either version 1.3c

Modified: trunk/Master/texmf-dist/tex/latex/amsmath/amsgen.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/amsmath/amsgen.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/amsmath/amsgen.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -7,7 +7,7 @@
 %% amsgen.dtx 
 %% 
 %% Copyright (C) 1995, 1999 American Mathematical Society.
-%% Copyright (C) 2016-2023  LaTeX Project and American Mathematical Society.
+%% Copyright (C) 2016-2024  LaTeX Project and American Mathematical Society.
 %% 
 %% This work may be distributed and/or modified under the
 %% conditions of the LaTeX Project Public License, either version 1.3c

Modified: trunk/Master/texmf-dist/tex/latex/amsmath/amsmath-2018-12-01.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/amsmath/amsmath-2018-12-01.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/amsmath/amsmath-2018-12-01.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -1,4 +1,8 @@
 %%
+%% This is an old release of `amsmath.sty' used during rollback operations.
+%% Do not use this file directly.
+%% ==============================
+%%
 %% This is file `amsmath.sty',
 %% generated with the docstrip utility.
 %%
@@ -517,7 +521,7 @@
          \else  % \not \mathxxx
              \@xp\Umathch@\meaning@"0"\Umathch@
              \ifgtest@ % if \Umathchar
-             \else % else not \Umathcar
+             \else % else not \Umathchar
            \@xp\macro@\meaning@@\macro@
            \ifgtest@ % if macro test
              \@xp\not@\meaning@\not@

Modified: trunk/Master/texmf-dist/tex/latex/amsmath/amsmath.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/amsmath/amsmath.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/amsmath/amsmath.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -7,7 +7,7 @@
 %% amsmath.dtx 
 %% 
 %% Copyright (C) 1995, 1999, 2000, 2013 American Mathematical Society.
-%% Copyright (C) 2016-2023  LaTeX Project and American Mathematical Society.
+%% Copyright (C) 2016-2024  LaTeX Project and American Mathematical Society.
 %% 
 %% This work may be distributed and/or modified under the
 %% conditions of the LaTeX Project Public License, either version 1.3c
@@ -23,11 +23,10 @@
 %% 
 \NeedsTeXFormat{LaTeX2e}% LaTeX 2.09 can't be used (nor non-LaTeX)
 [1994/12/01]% LaTeX date must be December 1994 or later
-\providecommand\DeclareRelease[3]{}
-\providecommand\DeclareCurrentRelease[2]{}
+\DeclareRelease{}{1994-06-01}{amsmath-2018-12-01.sty}
 \DeclareRelease{}{2018-12-01}{amsmath-2018-12-01.sty}
 \DeclareCurrentRelease{}{2019-04-01}
-\ProvidesPackage{amsmath}[2023/05/13 v2.17o AMS math features]
+\ProvidesPackage{amsmath}[2024/05/23 v2.17q AMS math features]
 \edef\@temp{\catcode 96=\number\catcode 96 }
 \catcode\string `\`=12
 \def\do#1{\catcode\number`#1=\number\catcode`#1}
@@ -531,7 +530,7 @@
          \else  % \not \mathxxx
              \@xp\Umathch@\meaning@"0"\Umathch@
              \ifgtest@ % if \Umathchar
-             \else % else not \Umathcar
+             \else % else not \Umathchar
            \@xp\macro@\meaning@@\macro@
            \ifgtest@ % if macro test
              \@xp\not@\meaning@\not@
@@ -1627,6 +1626,7 @@
     \make at display@tag
     \ifst at rred\else\global\@eqnswtrue\fi
     \global\advance\row@\@ne
+    \global\lineht@\z@
     \cr
 }
 \def\calc at shift@gather{%

Modified: trunk/Master/texmf-dist/tex/latex/amsmath/amsopn.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/amsmath/amsopn.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/amsmath/amsopn.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -7,7 +7,7 @@
 %% amsopn.dtx 
 %% 
 %% Copyright (C) 1995, 1999 American Mathematical Society.
-%% Copyright (C) 2016-2023  LaTeX Project and American Mathematical Society.
+%% Copyright (C) 2016-2024  LaTeX Project and American Mathematical Society.
 %% 
 %% This work may be distributed and/or modified under the
 %% conditions of the LaTeX Project Public License, either version 1.3c

Modified: trunk/Master/texmf-dist/tex/latex/amsmath/amstext.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/amsmath/amstext.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/amsmath/amstext.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -7,7 +7,7 @@
 %% amstext.dtx 
 %% 
 %% Copyright (C) 1995, 1999 American Mathematical Society.
-%% Copyright (C) 2016-2023  LaTeX Project and American Mathematical Society.
+%% Copyright (C) 2016-2024  LaTeX Project and American Mathematical Society.
 %% 
 %% This work may be distributed and/or modified under the
 %% conditions of the LaTeX Project Public License, either version 1.3c

Modified: trunk/Master/texmf-dist/tex/latex/amsmath/amsxtra.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/amsmath/amsxtra.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/amsmath/amsxtra.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -7,7 +7,7 @@
 %% amsxtra.dtx 
 %% 
 %% Copyright (C) 1995, 1999 American Mathematical Society.
-%% Copyright (C) 2016-2023  LaTeX Project and American Mathematical Society.
+%% Copyright (C) 2016-2024  LaTeX Project and American Mathematical Society.
 %% 
 %% This work may be distributed and/or modified under the
 %% conditions of the LaTeX Project Public License, either version 1.3c

Modified: trunk/Master/texmf-dist/tex/latex/base/alltt.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/alltt.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/alltt.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -49,7 +49,7 @@
 %%
 \NeedsTeXFormat{LaTeX2e}
 \ProvidesPackage{alltt}
-              [2021/01/29 v2.0g defines alltt environment]
+              [2024/02/08 v2.0g defines alltt environment]
 \begingroup
 \lccode`\~=`\'
 \lowercase{\endgroup

Modified: trunk/Master/texmf-dist/tex/latex/base/ansinew.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/ansinew.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/ansinew.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
   \ProvidesFile{ansinew.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textonehalf}{\ensuremath{\frac12}}
 \ProvideTextCommandDefault{\textonequarter}{\ensuremath{\frac14}}

Modified: trunk/Master/texmf-dist/tex/latex/base/applemac.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/applemac.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/applemac.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
   \ProvidesFile{applemac.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textflorin}{\textit{f}}
 \ProvideTextCommandDefault{\textcent}

Modified: trunk/Master/texmf-dist/tex/latex/base/article.cls
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/article.cls	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/article.cls	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 \NeedsTeXFormat{LaTeX2e}[1995/12/01]
 \ProvidesClass{article}
-              [2023/05/17 v1.4n
+              [2024/02/08 v1.4n
  Standard LaTeX document class]
 \newcommand\@ptsize{}
 \newif\if at restonecol

Modified: trunk/Master/texmf-dist/tex/latex/base/ascii.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/ascii.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/ascii.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
  \ProvidesFile{ascii.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \@inpenc at test
 \endinput
 %%

Modified: trunk/Master/texmf-dist/tex/latex/base/atbegshi-ltx.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/atbegshi-ltx.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/atbegshi-ltx.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -46,8 +46,6 @@
 %% Frank Mittelbach, The LaTeX Project
 %%
 %%% From File: ltshipout.dtx
-\providecommand\ltshipoutversion{v1.0n}
-\providecommand\ltshipoutdate{2022/11/08}
 \ProvidesPackage{atbegshi-ltx}
    [2021/01/10 v1.0c
      Emulation of the original atbegshi^^Jpackage with kernel methods]

Modified: trunk/Master/texmf-dist/tex/latex/base/atveryend-ltx.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/atveryend-ltx.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/atveryend-ltx.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -42,8 +42,6 @@
 %% and covered by LPPL is defined by the unpacking scripts (with
 %% extension .ins) which are part of the distribution.
 %%% From File: ltfilehook.dtx
-\providecommand\ltfilehookversion{v1.0o}
-\providecommand\ltfilehookdate{2023/07/10}
 \ProvidesPackage{atveryend-ltx}
    [2020/08/19 v1.0a
      Emulation of the original atveryend package^^Jwith kernel methods]

Modified: trunk/Master/texmf-dist/tex/latex/base/bk10.clo
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/bk10.clo	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/bk10.clo	2024-06-02 20:26:39 UTC (rev 71408)
@@ -42,7 +42,7 @@
 %% and covered by LPPL is defined by the unpacking scripts (with
 %% extension .ins) which are part of the distribution.
 \ProvidesFile{bk10.clo}
-              [2023/05/17 v1.4n
+              [2024/02/08 v1.4n
       Standard LaTeX file (size option)]
 \renewcommand\normalsize{%
    \@setfontsize\normalsize\@xpt\@xiipt

Modified: trunk/Master/texmf-dist/tex/latex/base/bk11.clo
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/bk11.clo	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/bk11.clo	2024-06-02 20:26:39 UTC (rev 71408)
@@ -42,7 +42,7 @@
 %% and covered by LPPL is defined by the unpacking scripts (with
 %% extension .ins) which are part of the distribution.
 \ProvidesFile{bk11.clo}
-              [2023/05/17 v1.4n
+              [2024/02/08 v1.4n
       Standard LaTeX file (size option)]
 \renewcommand\normalsize{%
    \@setfontsize\normalsize\@xipt{13.6}%

Modified: trunk/Master/texmf-dist/tex/latex/base/bk12.clo
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/bk12.clo	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/bk12.clo	2024-06-02 20:26:39 UTC (rev 71408)
@@ -42,7 +42,7 @@
 %% and covered by LPPL is defined by the unpacking scripts (with
 %% extension .ins) which are part of the distribution.
 \ProvidesFile{bk12.clo}
-              [2023/05/17 v1.4n
+              [2024/02/08 v1.4n
       Standard LaTeX file (size option)]
 \renewcommand\normalsize{%
    \@setfontsize\normalsize\@xiipt{14.5}%

Modified: trunk/Master/texmf-dist/tex/latex/base/book.cls
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/book.cls	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/book.cls	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 \NeedsTeXFormat{LaTeX2e}[1995/12/01]
 \ProvidesClass{book}
-              [2023/05/17 v1.4n
+              [2024/02/08 v1.4n
  Standard LaTeX document class]
 \newcommand\@ptsize{}
 \newif\if at restonecol

Added: trunk/Master/texmf-dist/tex/latex/base/checkencodingsubset.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/checkencodingsubset.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/base/checkencodingsubset.tex	2024-06-02 20:26:39 UTC (rev 71408)
@@ -0,0 +1,419 @@
+%%
+%% This is file `checkencodingsubset.tex',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% lttextcomp.dtx  (with options: `TS1check')
+%% 
+%% This is a generated file.
+%% 
+%% The source is maintained by the LaTeX Project team and bug
+%% reports for it can be opened at https://latex-project.org/bugs.html
+%% (but please observe conditions on bug reports sent to that address!)
+%% 
+%% 
+%% Copyright (C) 1993-2024
+%% The LaTeX Project and any individual authors listed elsewhere
+%% in this file.
+%% 
+%% This file was generated from file(s) of the 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".
+%% 
+%% This file may only be distributed together with a copy of the LaTeX
+%% base system. You may however distribute the LaTeX base system without
+%% such generated files.
+%% 
+%% 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.
+%%% From File: lttextcomp.dtx
+\Providesfile{checkencodingsubset.tex}
+ [2024/01/27 v0.5a Figure out safe TS1 encoding subsets]
+\let\typeoutdetails\typeout
+\def\doesglyphexist#1#2{\iffontchar\testFont #1 0\else 1\relax \fi}
+\def\glyphmissingdetails#1#2{\iffontchar\testFont #1 \else
+  \typeoutdetails{\space\space\space ==> \string#2 (#1) is missing}\fi}
+\newif\ifsafesubencodingfound
+\newif\ifcoremisses
+\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
+    {\let\doesglyphexist \glyphmissingdetails #1}%
+    \safesubencodingfoundtrue
+  \fi
+}
+\def\currsubencoding#1{\csname TS1:\ifcsname TS1:#1\endcsname #1\else ?\fi\endcsname}
+\DeclareFixedFont\cmrFont{TS1}{cmr}{m}{n}{10pt}
+\def\testallgroups#1{%
+  \DeclareFixedFont\testFont{TS1}{#1}{m}{n}{10pt}%
+  \ifx\testFont\cmrFont
+    \typeout{***** Font family #1 not found ****}%
+  \else
+    \safesubencodingfoundfalse
+    \coremissesfalse
+    \typeoutdetails{^^J-----------------------------------------}%
+    \typeoutdetails{Testing font family #1^^J(currently TS1-sub-encoding
+      \currsubencoding{#1})}%
+    \typeout{-----------------------------------------}%
+    \testgroup{%
+       \doesglyphexist{21}{\texttwelveudash}%
+       \doesglyphexist{22}{\textthreequartersemdash}%
+       \doesglyphexist{134}{\textbardbl}%
+       \doesglyphexist{137}{\textcelsius}%
+       \doesglyphexist{178}{\texttwosuperior}%
+       \doesglyphexist{179}{\textthreesuperior}%
+       \doesglyphexist{185}{\textonesuperior}%
+    }{8}{9}%
+    \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}%
+    \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}%
+    \ifsafesubencodingfound\else
+      \def\subencodingresult{0}%
+    \fi
+    \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
+}
+\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}
+\testallgroups{zi4}%  {9}
+%% not installed normally
+
+\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}
+}
+\typeout{^^J=====================================================================}
+\typeout{| Enter font family to check (or <enter> for kernel defined families)}
+\typeout{=====================================================================}
+\typein[\FontFamilyToCheck]{}
+\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
+\stop
+
+\endinput
+%%
+%% End of file `checkencodingsubset.tex'.


Property changes on: trunk/Master/texmf-dist/tex/latex/base/checkencodingsubset.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/tex/latex/base/cp1250.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/cp1250.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/cp1250.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
   \ProvidesFile{cp1250.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textcurrency}
    {\TextSymbolUnavailable\textcurrency}

Modified: trunk/Master/texmf-dist/tex/latex/base/cp1252.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/cp1252.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/cp1252.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
   \ProvidesFile{cp1252.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textonehalf}{\ensuremath{\frac12}}
 \ProvideTextCommandDefault{\textonequarter}{\ensuremath{\frac14}}

Modified: trunk/Master/texmf-dist/tex/latex/base/cp1257.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/cp1257.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/cp1257.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
   \ProvidesFile{cp1257.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textonehalf}{\ensuremath{\frac12}}
 \ProvideTextCommandDefault{\textonequarter}{\ensuremath{\frac14}}

Modified: trunk/Master/texmf-dist/tex/latex/base/cp437.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/cp437.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/cp437.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
   \ProvidesFile{cp437.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textflorin}{\textit{f}}
 \ProvideTextCommandDefault{\textpeseta}{Pt}

Modified: trunk/Master/texmf-dist/tex/latex/base/cp437de.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/cp437de.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/cp437de.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
   \ProvidesFile{cp437de.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textflorin}{\textit{f}}
 \ProvideTextCommandDefault{\textpeseta}{Pt}

Modified: trunk/Master/texmf-dist/tex/latex/base/cp850.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/cp850.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/cp850.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
   \ProvidesFile{cp850.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 %%
 %% If you need a Euro symbol, try cp858 instead.
 %%

Modified: trunk/Master/texmf-dist/tex/latex/base/cp852.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/cp852.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/cp852.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
   \ProvidesFile{cp852.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textonehalf}{\ensuremath{\frac12}}
 \ProvideTextCommandDefault{\textonequarter}{\ensuremath{\frac14}}

Modified: trunk/Master/texmf-dist/tex/latex/base/cp858.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/cp858.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/cp858.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
   \ProvidesFile{cp858.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textonehalf}{\ensuremath{\frac12}}
 \ProvideTextCommandDefault{\textonequarter}{\ensuremath{\frac14}}

Modified: trunk/Master/texmf-dist/tex/latex/base/cp865.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/cp865.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/cp865.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
   \ProvidesFile{cp865.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textflorin}{\textit{f}}
 \ProvideTextCommandDefault{\textpeseta}{Pt}

Modified: trunk/Master/texmf-dist/tex/latex/base/decmulti.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/decmulti.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/decmulti.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
  \ProvidesFile{decmulti.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textonehalf}{\ensuremath{\frac12}}
 \ProvideTextCommandDefault{\textonequarter}{\ensuremath{\frac14}}

Modified: trunk/Master/texmf-dist/tex/latex/base/doc.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/doc.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/doc.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,9 +43,8 @@
 %% extension .ins) which are part of the distribution.
 \NeedsTeXFormat{LaTeX2e}[1994/12/01]
 
-\providecommand\DeclareRelease[3]{}
-\providecommand\DeclareCurrentRelease[2]{}
-
+\DeclareRelease{}{1994-06-01}
+                      {doc-2016-02-15.sty}
 \DeclareRelease{v2.1g}{2016-02-15}
                       {doc-2016-02-15.sty}
 \DeclareRelease{v2}{2021-06-01}
@@ -53,11 +52,11 @@
 \DeclareCurrentRelease{v3}{2022-06-01}
 
 \ProvidesPackage{doc}
-  [2022/11/13 v3.0m
+  [2024/04/26 v3.0p
    Standard LaTeX documentation package V3 (FMi)]
 %%
 %% 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.
 
 
 
@@ -119,7 +118,7 @@
                              \blank at linetrue\@@par
                              \penalty\interlinepenalty}
    \obeylines
-   \let\do\do at noligs \verbatim at nolig@list
+   \@noligs
    \let\do\@makeother \dospecials
    \global\@newlistfalse
    \global\@minipagefalse
@@ -1140,6 +1139,10 @@
        Maybe you wanted to use
        '\string\NewDocElement'?}%
 }
+\def\doc at ignoredinfo#1#2{%
+  \PackageInfo{doc}{Doc element '#1/#2' declaration
+    ignored}%
+}
 \newcommand\NewDocElement[3][]{%
   \@ifundefined{Print#2Name}%
       {\@ifundefined{PrintDescribe#2}%
@@ -1152,6 +1155,18 @@
       }\doc at declareerror
   {#2}{#3}%
 }
+\newcommand\ProvideDocElement[3][]{%
+  \@ifundefined{Print#2Name}%
+      {\@ifundefined{PrintDescribe#2}%
+           {\@ifundefined{#3}%
+               {\@ifundefined{end#3}%
+                    {\@NewDocElement{#1}}%
+                    \doc at ignoredinfo
+               }\doc at ignoredinfo
+           }\doc at ignoredinfo
+      }\doc at ignoredinfo
+  {#2}{#3}%
+}
 \newcommand\RenewDocElement[3][]{%
   \@ifundefined{Print#2Name}\doc at notdeclarederror
       {\@ifundefined{PrintDescribe#2}\doc at notdeclarederror

Modified: trunk/Master/texmf-dist/tex/latex/base/docstrip.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/docstrip.tex	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/docstrip.tex	2024-06-02 20:26:39 UTC (rev 71408)
@@ -46,7 +46,7 @@
 \def\filename{docstrip.dtx}
 \def\fileversion{v2.6b}
 \def\filedate{2022-09-03}
-\def\docdate {2023-10-10}
+\def\docdate {2024-02-08}
 %%
 %% The docstrip program for use with TeX.
 %% Copyright (C) 1989-1991 Frank Mittelbach

Modified: trunk/Master/texmf-dist/tex/latex/base/fontenc.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/fontenc.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/fontenc.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -90,7 +90,11 @@
           {}{\PackageError{fontenc}%
            {Encoding file `\reserved at 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

Modified: trunk/Master/texmf-dist/tex/latex/base/fontmath.cfg
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/fontmath.cfg	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/fontmath.cfg	2024-06-02 20:26:39 UTC (rev 71408)
@@ -35,11 +35,11 @@
 %% the system are in the document `cfgguide.tex'.
 %% 
 %% 
-%%% From File: fontdef.dtx
+%%%   From File: fontdef.dtx
 \ProvidesFile{fontmath.cfg}
-           [2021/01/15 v3.0i LaTeX Kernel
-(Uncustomized math
-           font setup)]
+           [2024/02/09 v3.0i LaTeX Kernel
+   (Uncustomized math font setup)
+]
 %%
 %%
 %%

Modified: trunk/Master/texmf-dist/tex/latex/base/fontmath.ltx
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/fontmath.ltx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/fontmath.ltx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -35,11 +35,11 @@
 %% the system are in the document `cfgguide.tex'.
 %% 
 %% 
-%%% From File: fontdef.dtx
+%%%   From File: fontdef.dtx
 \ProvidesFile{fontmath.ltx}
-           [2021/01/15 v3.0i LaTeX Kernel
-(Math
-           font setup)]
+           [2024/02/09 v3.0i LaTeX Kernel
+   (Math font setup)
+]
 \typeout{=== Don't modify this file, use a .cfg file instead ===^^J}
 \DeclareFontEncoding{OML}{}{}
 \DeclareFontEncoding{OMS}{}{}

Modified: trunk/Master/texmf-dist/tex/latex/base/fonttext.cfg
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/fonttext.cfg	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/fonttext.cfg	2024-06-02 20:26:39 UTC (rev 71408)
@@ -35,11 +35,11 @@
 %% the system are in the document `cfgguide.tex'.
 %% 
 %% 
-%%% From File: fontdef.dtx
+%%%   From File: fontdef.dtx
 \ProvidesFile{fonttext.cfg}
-           [2021/01/15 v3.0i LaTeX Kernel
-(Uncustomized text
-           font setup)]
+           [2024/02/09 v3.0i LaTeX Kernel
+   (Uncustomized text font setup)
+]
 %%
 %%
 %%

Modified: trunk/Master/texmf-dist/tex/latex/base/fonttext.ltx
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/fonttext.ltx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/fonttext.ltx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -35,11 +35,11 @@
 %% the system are in the document `cfgguide.tex'.
 %% 
 %% 
-%%% From File: fontdef.dtx
+%%%   From File: fontdef.dtx
 \ProvidesFile{fonttext.ltx}
-           [2021/01/15 v3.0i LaTeX Kernel
-(Text
-           font setup)]
+           [2024/02/09 v3.0i LaTeX Kernel
+   (Text font setup)
+]
 \typeout{=== Don't modify this file, use a .cfg file instead ===^^J}
 \input {omlenc.def}
 \input {omsenc.def}

Modified: trunk/Master/texmf-dist/tex/latex/base/ifthen.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/ifthen.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/ifthen.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -44,12 +44,12 @@
 %%
 %% File `ifthen.dtx'.
 %% Copyright (C) 1991 by Leslie Lamport
-%% Copyright (C) 1994-2001 LaTeX project, David Carlisle
+%% Copyright (C) 1994-2024 LaTeX project, David Carlisle
 %%                       all rights reserved.
 %%
 \NeedsTeXFormat{LaTeX2e}[1994/12/01]
 \ProvidesPackage{ifthen}
-          [2022/04/13 v1.1d Standard LaTeX ifthen package (DPC)]
+          [2024/03/16 v1.1e Standard LaTeX ifthen package (DPC)]
 \def\TE at throw{\@ne=\@ne\noexpand\fi}
 \def\boolean#1#2{%
   \TE at throw\expandafter\noexpand\csname if#1\endcsname#2}
@@ -77,11 +77,24 @@
                   \let\ref\@kernel at ref@exp}}
   {\def\TE at ref@exp{\def\@setref##1##2##3{%
          \ifx##1\relax\z@\else\expandafter##2##1\fi}}}
+\begingroup
+\lccode`\~`\> %
+\catcode`\+\active
+\lccode`\+`\< %
+\catcode`\!\active
+\lccode`\!`\= %
+\lowercase{\endgroup
+\def\TE at repl@active{%
+  \TE at repl~>%
+  \TE at repl+<%
+  \TE at repl!=%
+}
 \long\def\ifthenelse#1{%
   \toks@{#1}%
   \TE at repl\or\TE at or
   \TE at repl\and\TE at and
   \TE at repl\not\TE at neg
+  \TE at repl@active
   \TE at repl\OR\TE at or
   \TE at repl\AND\TE at and
   \TE at repl\NOT\TE at neg
@@ -101,7 +114,8 @@
           \expandafter\@firstoftwo
         \else
           \expandafter\@secondoftwo
-        \fi}
+        \fi}%
+}
 \def\TE at eval{\noexpand\TE at negatefalse\noexpand\iftrue\noexpand\ifnum}
 \newif\ifTE at val
 \newif\ifTE at negate

Modified: trunk/Master/texmf-dist/tex/latex/base/inputenc.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/inputenc.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/inputenc.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -44,7 +44,7 @@
 
 \NeedsTeXFormat{LaTeX2e}[1995/12/01]
 \ProvidesPackage{inputenc}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \def\DeclareInputMath#1{%
    \@inpenc at test
    \bgroup

Modified: trunk/Master/texmf-dist/tex/latex/base/latex.ltx
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/latex.ltx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/latex.ltx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -14,6 +14,7 @@
 %% lthooks.dtx  (with options: `2ekernel')
 %% ltcmdhooks.dtx  (with options: `2ekernel')
 %% ltsockets.dtx  (with options: `2ekernel')
+%% lttemplates.dtx  (with options: `2ekernel')
 %% ltalloc.dtx  (with options: `2ekernel')
 %% ltcntrl.dtx  (with options: `2ekernel')
 %% lterror.dtx  (with options: `2ekernel')
@@ -54,6 +55,7 @@
 %% ltfilehook.dtx  (with options: `2ekernel')
 %% ltshipout.dtx  (with options: `2ekernel')
 %% ltoutput.dtx  (with options: `2ekernel')
+%% lttagging.dtx  (with options: `2ekernel')
 %% ltfinal.dtx  (with options: `2ekernel')
 %% 
 %% This is a generated file.
@@ -693,7 +695,7 @@
   \tracinggroups\z@
   \tracingparagraphs\z@
   \tracingmacros\z@
-  \tracinglostchars\@ne
+  \tracinglostchars\tw@
   \tracingpages\z@
   \tracingstats\z@
 }%
@@ -707,8 +709,8 @@
 %%% From File: ltvers.dtx
 \def\fmtname{LaTeX2e}
 \edef\fmtversion
-   {2023-11-01}
-\def\patch at level{1}
+   {2024-06-01}
+\def\patch at level{0}
 \edef\development at branch@name{}
 \iffalse
 \def\reserved at a#1/#2/#3\@nil{%
@@ -1158,7 +1160,10 @@
 \cs_gset_eq:NN \@expl at cs@to at str@@N \cs_to_str:N
 \cs_gset_eq:NN \@expl at str@if at eq@@nnTF \str_if_eq:nnTF
 \cs_gset_eq:NN \@expl at cs@prefix at spec@@N \cs_prefix_spec:N
-\cs_gset_eq:NN \@expl at cs@argument at spec@@N \cs_argument_spec:N
+\cs_if_exist:NTF \cs_parameter_spec:N
+  { \cs_gset_eq:NN \@expl at cs@parameter at spec@@N \cs_parameter_spec:N }
+  { \cs_gset_eq:NN \@expl at cs@parameter at spec@@N \cs_argument_spec:N }
+\cs_gset_eq:NN \__kernel_cs_parameter_spec:N \@expl at cs@parameter at spec@@N
 \cs_gset_eq:NN \@expl at cs@replacement at spec@@N \cs_replacement_spec:N
 \cs_gset_eq:NN \@expl at str@map at function@@NN \str_map_function:NN
 \cs_gset_eq:NN \@expl at char@generate@@nn \char_generate:nn
@@ -1648,7 +1653,7 @@
 \long\def\@show at newcommand@aux#1#2#3{%
   \typeout{> \string#1=\@expl at cs@prefix at spec@@N#1macro:}%
   #3{default \string##1=\expandafter\detokenize\@gobblethree#2.^^J%
-    \@expl at cs@argument at spec@@N#1->\@expl at cs@replacement at spec@@N#1}}
+    \@expl at cs@parameter at spec@@N#1->\@expl at cs@replacement at spec@@N#1}}
 \long\def\@show at tokens#1{%
   \edef\reserved at a{#1}%
   \showtokens\expandafter
@@ -1679,7 +1684,7 @@
   \@show at environment@end#1}
 \long\def\@show at environment@begin#1{%
   \typeout{> \string\begin{\@expl at cs@to at str@@N#1}=environment:}%
-  \typeout{\@expl at cs@argument at spec@@N#1->%
+  \typeout{\@expl at cs@parameter at spec@@N#1->%
            \@expl at cs@replacement at spec@@N#1.^^J}}
 \long\def\@show at normalenv#1{%
   \@show at environment@begin#1%
@@ -1690,12 +1695,12 @@
 \long\def\@show at environment@end at aux#1#2{%
   \@show at tokens{\string\end{\@expl at cs@to at str@@N#2}%
     \ifx\relax#1=undefined%
-    \else:^^J\@expl at cs@argument at spec@@N#1->%
+    \else:^^J\@expl at cs@parameter at spec@@N#1->%
              \@expl at cs@replacement at spec@@N#1%
     \fi}}
 \def\@show at nonstop#1{%
   \typeout{> \string#1=\@expl at cs@prefix at spec@@N#1macro:^^J%
-   \@expl at cs@argument at spec@@N#1->\@expl at cs@replacement at spec@@N#1.}}
+   \@expl at cs@parameter at spec@@N#1->\@expl at cs@replacement at spec@@N#1.}}
 \def\@show at typeout#1{\typeout{> #1.^^J}}
 \def\@ifundefined#1{%
   \ifcsname#1\endcsname\@ifundefin at d@i\else\@ifundefin at d@ii\fi{#1}}
@@ -1806,8 +1811,8 @@
     \xdef#1{\the\toks@}%
   \endgroup}
 %%% From File: ltcmd.dtx
-\def\ltcmdversion{v1.2a}
-\def\ltcmddate{2023-08-19}
+\def\ltcmdversion{v1.2e}
+\def\ltcmddate{2024-04-17}
 \message{document commands,}
 \ExplSyntaxOn
 \tl_new:N \l__cmd_arg_spec_tl
@@ -1888,8 +1893,6 @@
 \cs_new_protected:Npn \__cmd_declare_cmd_internal:Nnnn #1#2#3#4
   {
     \tl_set:Nx \l__cmd_function_tl { \cs_to_str:N #1 }
-    \tl_set:Nx \l__cmd_fn_tl
-      { \exp_not:c { \l__cmd_function_tl \c_space_tl } }
     \__cmd_normalize_arg_spec:n {#2}
     \exp_args:No \__cmd_prepare_signature:n \l__cmd_arg_spec_tl
     \__cmd_declare_cmd_code:Nnn #1 {#2} {#3}
@@ -1897,12 +1900,60 @@
     \__cmd_break_point:n {#2}
   }
 \cs_new_eq:NN \__cmd_break_point:n \use_none:n
-\cs_new_protected:Npn \__cmd_declare_cmd_code:Nnn
+\cs_new:Npn \__cmd_all_m_check:n #1
+  { \tl_map_function:nN {#1} \__cmd_all_m_check_aux:n }
+\cs_new:Npn \__cmd_all_m_check_aux:n #1
   {
-    \bool_if:NTF \l__cmd_grab_expandably_bool
-      { \__cmd_declare_cmd_code_expandable:Nnn }
-      { \__cmd_declare_cmd_code_aux:Nnn }
+    \str_if_eq:nnF {#1} { m }
+      {
+        \str_if_eq:nnF {#1} { + }
+          { X }
+      }
+  }
+\cs_new_protected:Npn \__cmd_declare_cmd_code:Nnn #1#2
+  {
+    \bool_lazy_any:nTF
+      {
+        { \l__cmd_environment_bool }
+        {
+          \bool_lazy_and_p:nn
+            { \l__cmd_some_short_bool }
+            { \l__cmd_some_long_bool }
+        }
+        { ! \tl_if_blank_p:e { \__cmd_all_m_check:n {#2} } }
+      }
+      {
+        \tl_set:Nx \l__cmd_fn_tl
+          { \exp_not:c { \l__cmd_function_tl \c_space_tl } }
+        \bool_if:NTF \l__cmd_grab_expandably_bool
+          { \__cmd_declare_cmd_code_expandable:Nnn }
+          { \__cmd_declare_cmd_code_aux:Nnn }
+      }
+      { \__cmd_declare_cmd_optimized:Nnn }
+        #1 {#2}
    }
+\cs_new_protected:Npn \__cmd_declare_cmd_optimized:Nnn #1#2#3
+  {
+    \bool_if:NTF \l__cmd_expandable_bool
+      { \cs_set_nopar:Npe }
+      { \cs_set_protected_nopar:Npe }
+        #1
+        {
+          \exp_not:N \__cmd_start_optimized:
+          \exp_not:c { \l__cmd_function_tl \c_space_tl code }
+        }
+    \exp_args:Ncc \cs_generate_from_arg_count:NNnn
+      { \l__cmd_function_tl \c_space_tl code }
+      {
+        cs_set
+        \bool_if:NF \l__cmd_expandable_bool { _protected }
+        \bool_if:NF \l__cmd_some_long_bool { _nopar }
+        :Npn
+      }
+      \l__cmd_current_arg_int
+      {#3}
+  }
+\cs_new:Npn \__cmd_start_optimized: { }
 \cs_new_protected:Npn \__cmd_declare_cmd_code_aux:Nnn #1#2#3
   {
     \cs_generate_from_arg_count:cNnn
@@ -2504,7 +2555,12 @@
     \bool_if:NT \l__cmd_some_obey_spaces_bool
       {
         \msg_error:nnxx { cmd } { invalid-bang }
-          { \__cmd_environment_or_command: } { \tl_to_str:n {#1} }
+          { \__cmd_environment_or_command: }
+          {
+            \bool_if:NTF \l__cmd_obey_spaces_bool
+              { \tl_to_str:n {'#1'} }
+              { an~optional~argument~before~mandatory~ \tl_to_str:n {'#1'} }
+          }
         \__cmd_bad_def:wn
       }
     \tl_clear:N \l__cmd_last_delimiters_tl
@@ -2826,9 +2882,10 @@
     \use:x
       {
         \int_set:Nn \tex_escapechar:D { 92 }
-        \exp_not:N \__cmd_cmd_type_cases:NnnnnF \exp_not:N #2
+        \exp_not:N \__cmd_cmd_type_cases:NnnnnnF \exp_not:N #2
           { \__cmd_copy_command:nnNN }
           { \__cmd_copy_expandable:nnNN }
+          { \__cmd_copy_optimized:nnNN }
           { \__cmd_copy_environment:nnNN }
           { \__cmd_copy_environment_end:nnNN }
           { \__cmd_cant_copy:nwn { non-ltcmd } }
@@ -2881,6 +2938,18 @@
       #3
       { \exp_after:wN \__cmd_copy_expandable:NnNNNNnnn #4 {#1} {#2} }
   }
+\cs_new_protected:Npn \__cmd_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 \__cmd_start_optimized:
+          \exp_not:c { #1 ~ code }
+        }
+  }
 \cs_new:Npn \__cmd_copy_expandable:NnNNNNnnn #1 #2 #3 #4 #5 #6 #7 #8 #9
   {
     \exp_not:N #1 \exp_not:n { {#2} }
@@ -3001,9 +3070,10 @@
     \use:x
       {
         \int_set:Nn \tex_escapechar:D { 92 }
-        \exp_not:N \__cmd_cmd_type_cases:NnnnnF \exp_not:N #1
+        \exp_not:N \__cmd_cmd_type_cases:NnnnnnF \exp_not:N #1
           { \__cmd_show_command:N }
           { \__cmd_show_expandable:N }
+          { \__cmd_show_optimized:N }
           { \__cmd_show_environment:N }
           { \__cmd_show_environment_end:N }
           { \__cmd_cant_copy:nwn { non-ltcmd } }
@@ -3037,6 +3107,43 @@
         -> \cs_replacement_spec:N #4
       }
   }
+\cs_new_protected:Npn \__cmd_show_optimized:N #1
+  {
+    \exp_args:Nc \__cmd_show_optimized:NN
+      { \cs_to_str:N #1 \c_space_tl code }
+      #1
+  }
+\cs_new_protected:Npn \__cmd_show_optimized:NN #1#2
+  {
+    \cs_set:Npe \__cmd_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 }
+          }
+          \__cmd_show_optimized_aux:N
+        ->
+        \cs_replacement_spec:N #1
+      }
+  }
+\cs_generate_variant:Nn \tl_count:n { e }
 \cs_new_protected:Npn \__cmd_show_environment:N #1
   {
     \exp_after:wN \__cmd_show_environment:Nnnw #1 \q__cmd
@@ -3604,7 +3711,12 @@
     \tl_put_right:Nx \l__cmd_v_arg_tl
       {
         \token_if_active:NTF #1
-          { \exp_not:N #1 } { \token_to_str:N #1 }
+          { \exp_not:N #1 }
+          {
+            \int_compare:nNnTF {`#1} = \tex_endlinechar:D
+              { \exp_not:N \obeyedline }
+              { \token_to_str:N #1 }
+          }
       }
   }
 \cs_new_protected:Npn \__cmd_grab_v_token_if_char:NTF #1
@@ -4075,30 +4187,31 @@
     #1 {#2} {#4}
     \__cmd_tl_mapthread_loop:w #1#3 \q_mark
   }
-\cs_new_protected:Npn \__cmd_cmd_type_cases:NnnnnF #1 #2 #3 #4 #5 #6
+\cs_new_protected:Npn \__cmd_cmd_type_cases:NnnnnnF #1 #2 #3 #4 #5 #6 #7
   {
     \exp_args:Ne \str_case_e:nnF
       {
-        \exp_args:Nf \tl_if_empty:nT { \cs_argument_spec:N #1 }
+        \exp_args:Nf \tl_if_empty:nT { \__kernel_cs_parameter_spec:N #1 }
           { \exp_not:N \exp_not:n { \exp_not:e { \tl_head:N #1 } } }
       }
       {
         { \exp_not:N \__cmd_start:nNNnnn } {#2}
         { \exp_not:N \__cmd_start_expandable:nNNNNn } {#3}
-        { \exp_not:N \__cmd_start_env:nnnnn } {#4}
+        { \exp_not:N \__cmd_start_optimized: } {#4}
+        { \exp_not:N \__cmd_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_cmd_type_cases:NnnnnF #1
-      { } { } { } { } { \use_iii:nnn }
+    \__cmd_cmd_type_cases:NnnnnnF #1
+      { } { } { } { } { } { \use_iii:nnn }
     \use_i:nn
   }
 \cs_new_protected:Npn \__cmd_peek_nonspace:NTF
@@ -4154,10 +4267,8 @@
     \bool_if:NTF \l__cmd_environment_bool
       { environment ~ ' \l__cmd_environment_str ' }
       {
-        command ~ '
-        \exp_args:Nf \tl_trim_spaces:n
-          { \exp_after:wN \token_to_str:N \l__cmd_fn_tl }
-        '
+        command ~
+          ' \c_backslash_str \tl_to_str:N \l__cmd_function_tl '
       }
   }
 \msg_new:nnnn { cmd } { arg-after-body }
@@ -4249,7 +4360,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__cmd_ignore_def_tl
   }
 \msg_new:nnnn { cmd } { not-definable }
@@ -4539,8 +4650,6 @@
 \ExplSyntaxOff
 
 %%% From File: lthooks.dtx
-\def\lthooksversion{v1.1f}
-\def\lthooksdate{2023/10/02}
 \ExplSyntaxOn
 \bool_new:N \g__hook_debug_bool
 \cs_new_eq:NN \__hook_debug:n \use_none:n
@@ -4862,7 +4971,8 @@
         \msg_error:nnnnn { hooks } { set-top-level }
           { for } { SetDefaultHookLabel } {#1}
       }
-      { \exp_args:Nx \__hook_set_default_label:n { \__hook_make_name:n {#1} } }
+      { \exp_args:Nx
+        \__hook_set_default_label:n { \__hook_make_name:n {#1} } }
   }
 \cs_new_protected:Npn \__hook_set_default_label:n #1
   {
@@ -4996,7 +5106,8 @@
       \__hook_gput_next_do:nn
         {#1}
   }
-\prg_new_protected_conditional:Npnn \__hook_try_declaring_generic_hook:wn
+\prg_new_protected_conditional:Npnn
+    \__hook_try_declaring_generic_hook:wn
     #1 / #2 / #3 / #4 \scan_stop: #5 { TF }
   {
     \__hook_if_generic:nTF {#5}
@@ -5082,7 +5193,8 @@
             \str_if_eq:nnTF {#2} { top-level }
               { \__hook_toplevel_gset:nn {#1} { } }
               {
-                \prop_gpop:cnNF { g__hook_#1_code_prop } {#2} \l__hook_return_tl
+                \prop_gpop:cnNF { g__hook_#1_code_prop }
+                  {#2} \l__hook_return_tl
                   { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} }
               }
           }
@@ -5093,7 +5205,8 @@
         \__hook_if_deprecated_generic:nTF {#1}
           {
             \__hook_deprecated_generic_warn:n {#1}
-            \__hook_do_deprecated_generic:Nn \__hook_gremove_code:nn {#1} {#2}
+            \__hook_do_deprecated_generic:Nn
+                \__hook_gremove_code:nn {#1} {#2}
           }
           { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} }
       }
@@ -5111,7 +5224,8 @@
         {#1} {#2}
   }
 \cs_new_protected:Npn \__hook_cs_gput_right_fast:nnn #1 #2 #3
-  { \cs_gset:cpx { __hook#1~#2 } { \exp_not:v { __hook#1~#2 } \exp_not:n {#3} } }
+  { \cs_gset:cpx { __hook#1~#2 }
+      { \exp_not:v { __hook#1~#2 } \exp_not:n {#3} } }
 \cs_new_protected:Npn \__hook_cs_gput_right_slow:nnn #1 #2 #3
   {
     \cs_if_exist:cF { __hook#1~#2 }
@@ -5195,7 +5309,8 @@
         }
     \exp_last_unbraced:NNf
     \cs_set:Npn \__hook_tmp:w { \__hook_parameter:n {#1} } { }
-    \tl_set:Ne \l__hook_tmpa_tl { \__hook_braced_cs_parameter:n { __hook_tmp:w } }
+    \tl_set:Ne \l__hook_tmpa_tl
+      { \__hook_braced_cs_parameter:n { __hook_tmp:w } }
     \cs_gset_protected:Npx \__hook_normalise_fn:nn ##1 ##2
       {
         \group_begin:
@@ -5333,27 +5448,34 @@
   }
 \cs_new_protected:Npn \__hook_rule_before_gset:nnn #1#2#3
   {
-    \__hook_tl_gset:cx { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl }
+    \__hook_tl_gset:cx
+      { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl }
       { \__hook_label_ordered:nnTF {#2} {#3} { < } { > } }
   }
 \cs_new_eq:cN { __hook_rule_<_gset:nnn } \__hook_rule_before_gset:nnn
 \cs_new_protected:Npn \__hook_rule_after_gset:nnn #1#2#3
   {
-    \__hook_tl_gset:cx { g__hook_#1_rule_ \__hook_label_pair:nn {#3} {#2} _tl }
+    \__hook_tl_gset:cx
+      { g__hook_#1_rule_ \__hook_label_pair:nn {#3} {#2} _tl }
       { \__hook_label_ordered:nnTF {#3} {#2} { < } { > } }
   }
 \cs_new_eq:cN { __hook_rule_>_gset:nnn } \__hook_rule_after_gset:nnn
 \cs_new_protected:Npn \__hook_rule_voids_gset:nnn #1#2#3
   {
-    \__hook_tl_gset:cx { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl }
+    \__hook_tl_gset:cx
+      { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl }
       { \__hook_label_ordered:nnTF {#2} {#3} { -> } { <- } }
   }
 \cs_new_protected:cpn { __hook_rule_incompatible-error_gset:nnn } #1#2#3
-  { \__hook_tl_gset:cn { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl }
-                   { xE } }
+  { \__hook_tl_gset:cn
+      { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl }
+      { xE }
+  }
 \cs_new_protected:cpn { __hook_rule_incompatible-warning_gset:nnn } #1#2#3
-  { \__hook_tl_gset:cn { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl }
-                   { xW } }
+  { \__hook_tl_gset:cn
+      { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl }
+      { xW }
+  }
 \cs_new_protected:Npn \__hook_rule_unrelated_gset:nnn #1#2#3 { }
 \cs_new_protected:Npn \__hook_rule_gclear:nnn #1#2#3
   { \cs_undefine:c { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl } }
@@ -5415,8 +5537,10 @@
           {
             \__hook_code_gset:ne {#1}
               {
-                \exp_not:c { __hook_toplevel~#1 } \__hook_braced_parameter:n {#1}
-                \exp_not:c { __hook_next~#1 } \__hook_braced_parameter:n {#1}
+                \exp_not:c { __hook_toplevel~#1 }
+                \__hook_braced_parameter:n {#1}
+                \exp_not:c { __hook_next~#1 }
+                \__hook_braced_parameter:n {#1}
               }
           }
           {
@@ -5493,7 +5617,8 @@
             \int_compare:nNnT
                 { \cs:w \__hook_tl_csname:n {##1} \cs_end: } = 0
                 {
-                  \tl_set:cn { \__hook_tl_csname:n { \l__hook_rear_tl } } {##1}
+                  \tl_set:cn
+                    { \__hook_tl_csname:n { \l__hook_rear_tl } } {##1}
                   \tl_set:Nn \l__hook_rear_tl            {##1}
                 }
           }
@@ -5648,7 +5773,7 @@
         hook~'#1'
         \__hook_if_disabled:nF {#1}
           {
-            \exp_args:Nf \__hook_print_args:nn {#1}
+            \exp_args:Nne \__hook_print_args:nn {#1}
               {
                 \int_eval:n
                   { \str_count:e { \__hook_parameter:n {#1} } / 3 }
@@ -5883,12 +6008,14 @@
 \cs_new_protected:Npn \hook_use_once:n #1
   {
     \__hook_if_execute_immediately:nF {#1}
-      { \__hook_normalize_hook_args:Nn \__hook_use_once:nn { \use:n {#1} } { 0 } }
+      { \__hook_normalize_hook_args:Nn \__hook_use_once:nn
+          { \use:n {#1} } { 0 } }
   }
 \cs_new_protected:Npn \hook_use_once:nnw #1 #2
   {
     \__hook_if_execute_immediately:nF {#1}
-      { \__hook_normalize_hook_args:Nn \__hook_use_once:nn { \use:n {#1} } {#2} }
+      { \__hook_normalize_hook_args:Nn \__hook_use_once:nn
+          { \use:n {#1} } {#2} }
   }
 \cs_new_protected:Npn \__hook_use_once:nn #1 #2
   {
@@ -5895,7 +6022,8 @@
     \__hook_preamble_hook:n {#1}
     \__hook_use_once_set:n {#1}
     \__hook_replacing_args_false:
-    \__hook_cs_gput_right:nnn { _next } {#1} { \__hook_use_once_clear:n {#1} }
+    \__hook_cs_gput_right:nnn { _next } {#1}
+      { \__hook_use_once_clear:n {#1} }
     \__hook_replacing_args_reset:
     \__hook_if_usable:nTF {#1}
       { \__hook_use_initialized:n {#1} }
@@ -6083,7 +6211,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.
   }
 \msg_new:nnn { hooks } { empty-label }
@@ -6306,12 +6435,10 @@
               \__hook_curr_name_pop:
 \ExplSyntaxOff
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% File: ltcmdhooks.dtx
+%% From File: ltcmdhooks.dtx
 %% Copyright (C) 2020-2024
 %% Frank Mittelbach, Phelype Oleinik, The LaTeX Project
-%%% From File: ltcmdhooks.dtx
-\def\ltcmdhooksversion{v1.0i}
-\def\ltcmdhooksdate{2023/06/16}
+%%% From File: lthooks.dtx
 \ExplSyntaxOn
 \tl_new:N \g_hook_patch_action_list_tl
 \int_new:N \l__hook_patch_num_args_int
@@ -6449,7 +6576,7 @@
     \__hook_patch_debug:x { ++~command~can~be~patched~without~rescanning }
     \int_set:Nn \l__hook_patch_num_args_int
       {
-        \exp_args:Nf \str_count:n { \cs_argument_spec:N #2 } / 2
+        \exp_args:Nf \str_count:n { \__kernel_cs_parameter_spec:N #2 } / 2
         \bool_if:NT #1 { -1 }
       }
     \int_compare:nNnTF { \l__hook_patch_num_args_int } > { \c_zero_int }
@@ -6589,7 +6716,7 @@
   { ~ \__hook_double_hashes:w }
 \cs_new_protected:Npn \__hook_retokenize_patch:Nnn #1 #2 #3
   {
-    \str_if_eq:eeTF { \cs_argument_spec:N #1 } { }
+    \str_if_eq:eeTF { \__kernel_cs_parameter_spec:N #1 } { }
       { \__hook_patch_expand_redefine:NNnn \c_false_bool #1 {#2} {#3} }
       {
         \__hook_patch_debug:x { ..~command~can~only~be~patched~by~rescanning }
@@ -6752,8 +6879,6 @@
 \ExplSyntaxOff
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%% From File: ltsockets.dtx
-\def\ltsocketsversion{0.9a}
-\def\ltsocketsdate{2023-08-21}
 \ExplSyntaxOn
 \bool_new:N \g__socket_debug_bool
 \cs_new_eq:NN \__socket_debug:n \use_none:n
@@ -6926,6 +7051,1187 @@
 \cs_new_eq:NN \DebugSocketsOff   \socket_debug_off:
 \ExplSyntaxOff
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% From File: lttemplates.dtx
+\message{templates,}
+\ExplSyntaxOn
+\tl_const:Nn \c__template_code_root_tl      { template~code~>~ }
+\tl_const:Nn \c__template_defaults_root_tl  { template~defaults~>~ }
+\tl_const:Nn \c__template_instances_root_tl { template~instance~>~  }
+\tl_const:Nn \c__template_keytypes_root_tl  { template~key~types~>~ }
+\tl_const:Nn \c__template_key_order_root_tl { template~key~order~>~ }
+\tl_const:Nn \c__template_values_root_tl    { template~values~>~ }
+\tl_const:Nn \c__template_vars_root_tl      { template~vars~>~ }
+\seq_const_from_clist:Nn \c__template_keytypes_arg_seq
+  { choice , function , instance }
+\prop_new:N \g__template_type_prop
+\tl_new:N \l__template_assignments_tl
+\tl_new:N \l__template_default_tl
+\bool_new:N \l__template_error_bool
+\bool_new:N \l__template_global_bool
+\tl_new:N \l__template_key_name_tl
+\tl_new:N \l__template_keytype_tl
+\tl_new:N \l__template_keytype_arg_tl
+\tl_new:N \l__template_value_tl
+\tl_new:N \l__template_var_tl
+\prop_new:N \l__template_keytypes_prop
+\seq_new:N \l__template_key_order_seq
+\prop_new:N \l__template_values_prop
+\prop_new:N \l__template_vars_prop
+\clist_new:N \l__template_tmp_clist
+\dim_new:N \l__template_tmp_dim
+\int_new:N \l__template_tmp_int
+\muskip_new:N \l__template_tmp_muskip
+\skip_new:N \l__template_tmp_skip
+\tl_new:N \l__template_tmp_tl
+\scan_new:N \s__template_mark
+\scan_new:N \s__template_stop
+\quark_new:N \q__template_nil
+\__kernel_quark_new_conditional:Nn \__template_quark_if_nil:N { F }
+\cs_new_protected:Npn \__template_execute_if_arg_agree:nnT #1#2#3
+  {
+    \prop_get:NnN \g__template_type_prop {#1} \l__template_tmp_tl
+    \int_compare:nNnTF {#2} = \l__template_tmp_tl
+       {#3}
+       {
+         \msg_error:nneee { template } { argument-number-mismatch }
+           {#1} { \l__template_tmp_tl } {#2}
+       }
+  }
+\cs_new_protected:Npn \__template_execute_if_code_exist:nnT #1#2#3
+  {
+    \cs_if_exist:cTF { \c__template_code_root_tl #1 / #2 }
+      {#3}
+      { \msg_error:nnnn { template } { no-template-code } {#1} {#2} }
+  }
+\cs_new_protected:Npn \__template_execute_if_keytype_exist:nT #1#2
+  {
+    \cs_if_exist:cTF { __template_store_value_ #1 :n }
+      {#2}
+      { \msg_error:nnn { template } { unknown-keytype } {#1} }
+  }
+\cs_generate_variant:Nn \__template_execute_if_keytype_exist:nT { V }
+\cs_new_protected:Npn \__template_execute_if_type_exist:nT #1#2
+  {
+    \prop_if_in:NnTF \g__template_type_prop {#1}
+      {#2}
+      { \msg_error:nnn { template } { unknown-type } {#1} }
+  }
+\cs_new_protected:Npn \__template_if_keys_exist:nnT #1#2#3
+  {
+    \cs_if_exist:cTF { \c__template_keytypes_root_tl #1 / #2 }
+      {#3}
+      { \msg_error:nnnn { template } { unknown-template } {#1} {#2} }
+   }
+\prg_new_conditional:Npnn \__template_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 \__template_if_key_value:n { V } { T , F , TF }
+\prg_new_conditional:Npnn \__template_if_instance_exist:nn #1#2 { T, F, TF }
+  {
+    \cs_if_exist:cTF { \c__template_instances_root_tl #1 / #2 }
+      \prg_return_true:
+      \prg_return_false:
+ }
+\prg_new_conditional:Npnn \__template_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:
+}
+\cs_new_protected:Npn \__template_store_defaults:nn #1#2
+  {
+    \debug_suspend:
+    \prop_gclear_new:c { \c__template_defaults_root_tl #1 / #2  }
+    \prop_gset_eq:cN { \c__template_defaults_root_tl #1 / #2 }
+      \l__template_values_prop
+    \debug_resume:
+  }
+\cs_new_protected:Npn \__template_store_keytypes:nn #1#2
+  {
+    \debug_suspend:
+    \prop_if_exist:cTF { \c__template_keytypes_root_tl #1 / #2 }
+      {
+        \msg_info:nnnn { template } { declare-template-interface } {#1} {#2}
+        \prop_gclear:c { \c__template_keytypes_root_tl #1 / #2 }
+      }
+      { \prop_new:c { \c__template_keytypes_root_tl #1 / #2 } }
+    \prop_gset_eq:cN { \c__template_keytypes_root_tl #1 / #2 }
+      \l__template_keytypes_prop
+    \seq_gclear_new:c { \c__template_key_order_root_tl #1 / #2 }
+    \seq_gset_eq:cN { \c__template_key_order_root_tl #1 / #2 }
+      \l__template_key_order_seq
+    \debug_resume:
+  }
+\cs_new_protected:Npn \__template_store_values:nn #1#2
+  {
+    \debug_suspend:
+    \prop_clear_new:c { \c__template_values_root_tl #1 / #2 }
+    \prop_set_eq:cN { \c__template_values_root_tl #1 / #2 }
+      \l__template_values_prop
+    \debug_resume:
+  }
+\cs_new_protected:Npn \__template_store_vars:nn #1#2
+  {
+   \debug_suspend:
+    \prop_gclear_new:c { \c__template_vars_root_tl #1 / #2 }
+    \prop_gset_eq:cN { \c__template_vars_root_tl #1 / #2 }
+      \l__template_vars_prop
+    \debug_resume:
+  }
+\cs_new_protected:Npn \__template_recover_defaults:nn #1#2
+  {
+    \prop_if_exist:cTF
+      { \c__template_defaults_root_tl #1 / #2 }
+      {
+        \prop_set_eq:Nc \l__template_values_prop
+          { \c__template_defaults_root_tl #1 / #2 }
+      }
+      { \prop_clear:N \l__template_values_prop }
+  }
+\cs_new_protected:Npn \__template_recover_keytypes:nn #1#2
+  {
+    \prop_if_exist:cTF
+      { \c__template_keytypes_root_tl #1 / #2 }
+      {
+        \prop_set_eq:Nc \l__template_keytypes_prop
+          { \c__template_keytypes_root_tl #1 / #2 }
+      }
+      { \prop_clear:N \l__template_keytypes_prop }
+    \seq_if_exist:cTF { \c__template_key_order_root_tl #1 / #2 }
+      {
+        \seq_set_eq:Nc \l__template_key_order_seq
+          { \c__template_key_order_root_tl #1 / #2 }
+      }
+      { \seq_clear:N \l__template_key_order_seq }
+  }
+\cs_new_protected:Npn \__template_recover_values:nn #1#2
+  {
+    \prop_if_exist:cTF
+      { \c__template_values_root_tl #1 / #2 }
+      {
+        \prop_set_eq:Nc \l__template_values_prop
+          { \c__template_values_root_tl #1 / #2 }
+      }
+      { \prop_clear:N \l__template_values_prop }
+  }
+\cs_new_protected:Npn \__template_recover_vars:nn #1#2
+  {
+    \prop_if_exist:cTF
+      { \c__template_vars_root_tl #1 / #2 }
+      {
+        \prop_set_eq:Nc \l__template_vars_prop
+          { \c__template_vars_root_tl #1 / #2 }
+      }
+      { \prop_clear:N \l__template_vars_prop }
+  }
+\cs_new_protected:Npn \__template_define_type:nn #1#2
+  {
+    \prop_if_in:NnTF \g__template_type_prop {#1}
+      { \msg_error:nnn { template } { type-already-defined } {#1} }
+      { \__template_declare_type:nn {#1} {#2} }
+  }
+\cs_new_protected:Npn \__template_declare_type:nn #1#2
+  {
+    \int_set:Nn \l__template_tmp_int {#2}
+    \int_compare:nTF { 0 <= \l__template_tmp_int <= 9 }
+      {
+        \msg_info:nnnV { template } { declare-type }
+          {#1} \l__template_tmp_int
+        \prop_gput:NnV \g__template_type_prop {#1}
+          \l__template_tmp_int
+      }
+      {
+        \msg_error:nnnV { template } { bad-number-of-arguments }
+          {#1} \l__template_tmp_int
+      }
+  }
+\cs_new_protected:Npn \__template_declare_template_keys:nnnn #1#2#3#4
+  {
+    \__template_execute_if_type_exist:nT {#1}
+      {
+        \__template_execute_if_arg_agree:nnT {#1} {#3}
+          {
+            \prop_clear:N \l__template_values_prop
+            \prop_clear:N \l__template_keytypes_prop
+            \seq_clear:N \l__template_key_order_seq
+            \keyval_parse:NNn
+              \__template_parse_keys_elt:n \__template_parse_keys_elt:nn {#4}
+            \__template_store_defaults:nn {#1} {#2}
+            \__template_store_keytypes:nn {#1} {#2}
+          }
+      }
+  }
+\cs_new_protected:Npn \__template_parse_keys_elt:n #1
+  {
+    \__template_split_keytype:n {#1}
+    \bool_if:NF \l__template_error_bool
+      {
+        \__template_execute_if_keytype_exist:VT \l__template_keytype_tl
+          {
+            \seq_map_function:NN \c__template_keytypes_arg_seq
+              \__template_parse_keys_elt_aux:n
+            \bool_if:NF \l__template_error_bool
+              {
+                \seq_if_in:NoTF \l__template_key_order_seq
+                  \l__template_key_name_tl
+                  {
+                    \msg_error:nnV { template } { duplicate-key-interface }
+                      \l__template_key_name_tl
+                  }
+                  { \__template_parse_keys_elt_aux: }
+              }
+          }
+      }
+  }
+\cs_new_protected:Npn \__template_parse_keys_elt_aux:n #1
+  {
+    \str_if_eq:VnT \l__template_keytype_tl {#1}
+      {
+        \tl_if_empty:NT \l__template_keytype_arg_tl
+          {
+            \msg_error:nnn { template } { keytype-requires-argument } {#1}
+            \bool_set_true:N \l__template_error_bool
+            \seq_map_break:
+          }
+      }
+  }
+\cs_new_protected:Npn \__template_parse_keys_elt_aux:
+  {
+    \tl_set:Ne \l__template_tmp_tl
+      {
+        \l__template_keytype_tl
+        \tl_if_empty:NF \l__template_keytype_arg_tl
+          { { \l__template_keytype_arg_tl } }
+      }
+    \prop_put:NVV \l__template_keytypes_prop \l__template_key_name_tl
+      \l__template_tmp_tl
+    \seq_put_right:NV \l__template_key_order_seq \l__template_key_name_tl
+    \str_if_eq:VnT \l__template_keytype_tl { choice }
+      {
+        \clist_if_in:NnT \l__template_keytype_arg_tl { unknown }
+          { \msg_error:nn { template } { choice-unknown-reserved } }
+      }
+  }
+\cs_new_protected:Npn \__template_parse_keys_elt:nn #1#2
+  {
+    \__template_parse_keys_elt:n {#1}
+    \use:c { __template_store_value_ \l__template_keytype_tl :n } {#2}
+  }
+\cs_new_protected:Npe \__template_split_keytype:n #1
+  {
+    \exp_not:N \bool_set_false:N \exp_not:N \l__template_error_bool
+    \tl_set:Nn \exp_not:N \l__template_tmp_tl {#1}
+    \tl_replace_all:Nnn \exp_not:N \l__template_tmp_tl { : } { \token_to_str:N : }
+    \tl_if_in:VnTF \exp_not:N \l__template_tmp_tl { \token_to_str:N : }
+      {
+        \exp_not:n
+          {
+            \tl_clear:N \l__template_key_name_tl
+            \exp_after:wN \__template_split_keytype_aux:w
+              \l__template_tmp_tl \s__template_stop
+          }
+      }
+      {
+        \exp_not:N \bool_set_true:N \exp_not:N \l__template_error_bool
+        \msg_error:nnn { template } { missing-keytype } {#1}
+      }
+  }
+\use:e
+  {
+    \cs_new_protected:Npn \exp_not:N \__template_split_keytype_aux:w
+      #1 \token_to_str:N : #2 \s__template_stop
+      {
+        \tl_put_right:Ne \exp_not:N \l__template_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__template_key_name_tl
+              { \token_to_str:N : }
+            \exp_not:N \__template_split_keytype_aux:w #2 \s__template_stop
+          }
+          {
+            \exp_not:N \tl_if_empty:NTF \exp_not:N \l__template_key_name_tl
+              {
+                \msg_error:nnn { template } { empty-key-name }
+                  { \token_to_str:N : #2 }
+              }
+              { \exp_not:N \__template_split_keytype_arg:n {#2} }
+          }
+      }
+  }
+\cs_new_protected:Npn \__template_split_keytype_arg:n #1
+  {
+    \tl_set:Ne \l__template_keytype_tl { \tl_trim_spaces:n {#1} }
+    \tl_clear:N \l__template_keytype_arg_tl
+    \cs_set_protected:Npn \__template_split_keytype_arg_aux:n ##1
+      {
+        \tl_if_in:nnT {#1} {##1}
+          {
+            \cs_set:Npn \__template_split_keytype_arg_aux:w
+              ####1 ##1 ####2 \s__template_stop
+              {
+                \tl_if_blank:nT {####1}
+                  {
+                    \tl_set:Ne \l__template_keytype_tl
+                      { \tl_trim_spaces:n {##1} }
+                    \tl_if_blank:nF {####2}
+                      {
+                        \tl_set:Ne \l__template_keytype_arg_tl
+                          { \use:n ####2 }
+                      }
+                    \seq_map_break:
+                  }
+              }
+            \__template_split_keytype_arg_aux:w #1 \s__template_stop
+          }
+      }
+    \seq_map_function:NN \c__template_keytypes_arg_seq
+      \__template_split_keytype_arg_aux:n
+  }
+\cs_generate_variant:Nn \__template_split_keytype_arg:n { V }
+\cs_new:Npn \__template_split_keytype_arg_aux:n #1 { }
+\cs_new:Npn \__template_split_keytype_arg_aux:w #1 \s__template_stop { }
+\cs_new_protected:Npn \__template_store_value_boolean:n #1
+  { \prop_put:Non \l__template_values_prop \l__template_key_name_tl {#1} }
+\cs_new_protected:Npn \__template_store_value:n #1
+  { \prop_put:Non \l__template_values_prop \l__template_key_name_tl {#1} }
+\cs_new_eq:NN \__template_store_value_choice:n    \__template_store_value:n
+\cs_new_eq:NN \__template_store_value_function:n  \__template_store_value:n
+\cs_new_eq:NN \__template_store_value_instance:n  \__template_store_value:n
+\cs_new_protected:Npn \__template_store_value_aux:Nn #1#2
+  { \prop_put:Non \l__template_values_prop \l__template_key_name_tl {#2} }
+\cs_new_protected:Npn \__template_store_value_integer:n
+  { \__template_store_value_aux:Nn \int_eval:n }
+\cs_new_protected:Npn \__template_store_value_length:n
+  { \__template_store_value_aux:Nn \dim_eval:n }
+\cs_new_protected:Npn \__template_store_value_muskip:n
+  { \__template_store_value_aux:Nn \muskip_eval:n }
+\cs_new_protected:Npn \__template_store_value_real:n
+  { \__template_store_value_aux:Nn \fp_eval:n }
+\cs_new_protected:Npn \__template_store_value_skip:n
+  { \__template_store_value_aux:Nn \skip_eval:n }
+\cs_new_protected:Npn \__template_store_value_tokenlist:n
+  { \__template_store_value_aux:Nn \use:n }
+\cs_new_eq:NN \__template_store_value_commalist:n \__template_store_value_tokenlist:n
+\cs_new_protected:Npn \__template_declare_template_code:nnnnn #1#2#3#4#5
+  {
+    \__template_execute_if_type_exist:nT {#1}
+      {
+        \__template_execute_if_arg_agree:nnT {#1} {#3}
+          {
+            \__template_if_keys_exist:nnT {#1} {#2}
+              {
+                \__template_store_key_implementation:nnn {#1} {#2} {#4}
+                \regex_match:nnTF { \c { AssignTemplateKeys } } {#5}
+                  { \__template_declare_template_code:nnnn {#1} {#2} {#3} {#5} }
+                  {
+                    \__template_declare_template_code:nnnn
+                      {#1} {#2} {#3} { \AssignTemplateKeys #5 }
+                  }
+              }
+           }
+      }
+   }
+\cs_new_protected:Npn \__template_declare_template_code:nnnn #1#2#3#4
+  {
+    \cs_if_exist:cT { \c__template_code_root_tl #1 / #2 }
+      { \msg_info:nnnn { template } { declare-template-code } {#1} {#2} }
+    \cs_generate_from_arg_count:cNnn
+      { \c__template_code_root_tl #1 / #2 }
+      \cs_gset_protected:Npn {#3} {#4}
+  }
+\cs_new_protected:Npn \__template_store_key_implementation:nnn #1#2#3
+  {
+    \__template_recover_defaults:nn {#1} {#2}
+    \__template_recover_keytypes:nn {#1} {#2}
+    \prop_clear:N \l__template_vars_prop
+    \keyval_parse:nnn
+      { \__template_parse_vars_elt:n } { \__template_parse_vars_elt:nnn { #1 / #2 } } {#3}
+    \__template_store_vars:nn {#1} {#2}
+    \prop_map_inline:Nn \l__template_keytypes_prop
+      { \msg_error:nnnnn { template } { key-not-implemented } {##1} {#2} {#1} }
+  }
+\cs_new_protected:Npn \__template_parse_vars_elt:n #1
+  { \msg_error:nnn { template } { key-no-variable } {#1} }
+\cs_new_protected:Npn \__template_parse_vars_elt:nnn #1#2#3
+ {
+    \tl_set:Ne \l__template_key_name_tl
+      { \tl_trim_spaces:e { \tl_to_str:n {#2} } }
+    \prop_get:NVNTF \l__template_keytypes_prop
+      \l__template_key_name_tl
+      \l__template_keytype_tl
+      {
+        \__template_split_keytype_arg:V \l__template_keytype_tl
+        \__template_parse_vars_elt_aux:nn {#1} {#3}
+        \prop_remove:NV \l__template_keytypes_prop \l__template_key_name_tl
+      }
+      { \msg_error:nnn { template } { unknown-key } {#2} }
+  }
+\cs_new_protected:Npn \__template_parse_vars_elt_aux:nn #1#2
+  {
+    \__template_parse_vars_elt_aux:nw {#1} #2 global global \s__template_stop
+  }
+\cs_new_protected:Npn \__template_parse_vars_elt_aux:nw
+  #1#2 global #3 global #4 \s__template_stop
+  {
+    \tl_if_blank:nTF {#4}
+      { \__template_parse_vars_elt_aux:nnn {#1} { } {#2} }
+      {
+        \tl_if_blank:nTF {#2}
+          {
+            \__template_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 \__template_parse_vars_elt_aux:nnn #1#2#3
+  {
+    \str_case:VnF \l__template_keytype_tl
+      {
+        { choice } { \__template_implement_choices:nn {#1} {#3} }
+        { function }
+          {
+            \cs_if_exist:NF #3
+              { \cs_new:Npn #3 { } }
+            \__template_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__template_keytype_arg_tl }
+                      {##1}
+                  }
+              }
+            \prop_put:NVn \l__template_vars_prop
+              \l__template_key_name_tl {#2#3}
+          }
+        { instance }
+          {
+            \__template_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__template_vars_prop
+              \l__template_key_name_tl {#2#3}
+          }
+      }
+      {
+        \tl_if_single:nTF {#3}
+          {
+            \cs_if_exist:NF #3
+              { \use:c { \__template_map_var_type: _new:N } #3 }
+            \__template_parse_vars_elt_key:nn {#1}
+              {
+                . \__template_map_var_type:
+                  _ \str_if_eq:nnT {#1} { global } { g } set:N
+                    = \exp_not:N #3
+              }
+            \prop_put:NVn \l__template_vars_prop
+              \l__template_key_name_tl {#2#3}
+          }
+          { \msg_error:nnn { template } { bad-variable } {#2#3} }
+      }
+  }
+\cs_generate_variant:Nn \__template_parse_vars_elt_aux:nnn { nne }
+\cs_new_protected:Npn \__template_parse_vars_elt_key:nn #1#2
+  {
+    \keys_define:ne { template / #1 }
+      { \l__template_key_name_tl #2 }
+  }
+\cs_new:Npn \__template_map_var_type:
+  {
+    \str_case:Vn \l__template_keytype_tl
+      {
+        { boolean }   { bool }
+        { commalist } { clist }
+        { integer }   { int }
+        { length }    { dim }
+        { muskip }    { muskip }
+        { real }      { fp }
+        { skip }      { skip }
+        { tokenlist } { tl }
+      }
+  }
+\cs_new_protected:Npn \__template_implement_choices:nn #1#2
+  {
+    \clist_set:NV \l__template_tmp_clist \l__template_keytype_arg_tl
+    \prop_put:NVn \l__template_vars_prop \l__template_key_name_tl { }
+    \keys_define:ne { template / #1 } { \l__template_key_name_tl .choice: }
+    \keyval_parse:nnn
+      { \__template_implement_choice_elt:n }
+      { \__template_implement_choice_elt:nnn {#1} }
+      {#2}
+    \prop_get:NVNT \l__template_values_prop \l__template_key_name_tl
+      \l__template_tmp_tl
+      { \__template_implement_choices_default: }
+    \clist_if_empty:NF \l__template_tmp_clist
+      {
+        \clist_map_inline:Nn \l__template_tmp_clist
+          { \msg_error:nnn { template } { choice-not-implemented } {##1} }
+      }
+  }
+\cs_new_protected:Npn \__template_implement_choices_default:
+  {
+    \tl_set:Ne \l__template_tmp_tl
+      { \l__template_key_name_tl \c_space_tl \l__template_tmp_tl }
+    \prop_if_in:NVF \l__template_vars_prop \l__template_tmp_tl
+      {
+        \tl_set:Ne \l__template_tmp_tl
+          { \l__template_key_name_tl \c_space_tl \l__template_tmp_tl }
+        \prop_if_in:NVF \l__template_vars_prop \l__template_tmp_tl
+          {
+            \prop_get:NVN \l__template_keytypes_prop \l__template_key_name_tl
+              \l__template_tmp_tl
+            \__template_split_keytype_arg:V \l__template_tmp_tl
+            \prop_get:NVN \l__template_values_prop \l__template_key_name_tl
+              \l__template_tmp_tl
+            \msg_error:nnVV { template } { unknown-default-choice }
+              \l__template_key_name_tl
+              \l__template_key_name_tl
+          }
+      }
+  }
+\cs_new_protected:Npn \__template_implement_choice_elt:nnn #1#2#3
+  {
+    \clist_if_empty:NTF \l__template_tmp_clist
+      {
+        \str_if_eq:nnTF {#2} { unknown }
+          { \__template_implement_choice_elt_aux:nnn {#1} {#2} {#3} }
+          { \__template_implement_choice_elt_aux:n {#2} }
+      }
+      {
+        \clist_if_in:NnTF \l__template_tmp_clist {#2}
+          {
+            \clist_remove_all:Nn \l__template_tmp_clist {#2}
+            \__template_implement_choice_elt_aux:nnn {#1} {#2} {#3}
+          }
+          { \__template_implement_choice_elt_aux:n {#2} }
+      }
+  }
+\cs_new_protected:Npn \__template_implement_choice_elt_aux:n #1
+  {
+    \prop_get:NVN \l__template_keytypes_prop \l__template_key_name_tl
+      \l__template_tmp_tl
+    \__template_split_keytype_arg:V \l__template_tmp_tl
+    \msg_error:nnVn { template } { unknown-choice } \l__template_key_name_tl {#1}
+  }
+\cs_new_protected:Npn \__template_implement_choice_elt_aux:nnn #1#2#3
+  {
+    \keys_define:ne { template / #1 }
+      { \l__template_key_name_tl / #2 .code:n = { \exp_not:n {#3} } }
+    \tl_set:Ne \l__template_tmp_tl
+      { \l__template_key_name_tl \c_space_tl #2 }
+    \prop_put:NVn \l__template_vars_prop \l__template_tmp_tl {#3}
+  }
+\cs_new_protected:Npn \__template_implement_choice_elt:n #1
+  {
+    \msg_error:nnVn { template } { choice-requires-code }
+      \l__template_key_name_tl {#1}
+  }
+\cs_new_protected:Npn \__template_edit_defaults:nnn #1#2#3
+  {
+    \__template_if_keys_exist:nnT {#1} {#2}
+      {
+        \__template_recover_defaults:nn {#1} {#2}
+        \__template_parse_values:nnn {#1} {#2} {#3}
+        \__template_store_defaults:nn {#1} {#2}
+      }
+  }
+\cs_new_protected:Npn \__template_parse_values:nnn #1#2#3
+  {
+    \__template_recover_keytypes:nn {#1} {#2}
+    \keyval_parse:NNn
+      \__template_parse_values_elt:n \__template_parse_values_elt:nn {#3}
+  }
+\cs_new_protected:Npn \__template_parse_values_elt:n #1
+  {
+    \bool_set_true:N \l__template_error_bool
+    \msg_error:nnn { template } { key-no-value } {#1}
+  }
+\cs_new_protected:Npn \__template_parse_values_elt:nn #1#2
+  {
+    \tl_set:Ne \l__template_key_name_tl
+      { \tl_trim_spaces:e { \tl_to_str:n {#1} } }
+    \prop_get:NVNTF \l__template_keytypes_prop \l__template_key_name_tl
+      \l__template_tmp_tl
+      { \__template_parse_values_elt_aux:n {#2} }
+      { \msg_error:nnV { template } { unknown-key } \l__template_key_name_tl }
+  }
+\cs_new_protected:Npn \__template_parse_values_elt_aux:n #1
+  {
+    \__template_split_keytype_arg:V \l__template_tmp_tl
+    \use:c { __template_store_value_ \l__template_keytype_tl :n } {#1}
+  }
+\cs_new_protected:Npn \__template_template_set_eq:nnn #1#2#3
+  {
+    \__template_recover_defaults:nn {#1} {#3}
+    \__template_store_defaults:nn {#1} {#2}
+    \__template_recover_keytypes:nn {#1} {#3}
+    \__template_store_keytypes:nn {#1} {#2}
+    \__template_recover_vars:nn {#1} {#3}
+    \__template_store_vars:nn {#1} {#2}
+    \cs_if_exist:cT { \c__template_code_root_tl #1 / #2 }
+      { \msg_info:nnnn { template } { declare-template-code } {#1} {#2} }
+    \cs_gset_eq:cc { \c__template_code_root_tl #1 / #2 }
+      { \c__template_code_root_tl #1 / #3 }
+  }
+\cs_new_protected:Npn \__template_declare_instance:nnnn #1#2#3#4
+  {
+    \__template_execute_if_code_exist:nnT {#1} {#2}
+      {
+        \__template_recover_defaults:nn {#1} {#2}
+        \__template_recover_vars:nn {#1} {#2}
+        \__template_declare_instance_aux:nnnn {#1} {#2} {#3} {#4}
+      }
+  }
+\cs_new_protected:Npn \__template_declare_instance_aux:nnnn #1#2#3#4
+  {
+    \bool_set_false:N \l__template_error_bool
+    \__template_parse_values:nnn {#1} {#2} {#4}
+    \bool_if:NF \l__template_error_bool
+      {
+        \prop_put:Nnn \l__template_values_prop { from~template } {#2}
+        \__template_store_values:nn {#1} {#3}
+        \__template_convert_to_assignments:
+        \cs_if_exist:cT { \c__template_instances_root_tl #1 / #3 }
+          { \msg_info:nnnn { template } { declare-instance } {#3} {#1} }
+        \cs_set_protected:cpe { \c__template_instances_root_tl #1 / #3 }
+          {
+            \exp_not:N \__template_assignments_push:n
+              { \exp_not:V \l__template_assignments_tl }
+            \exp_not:c { \c__template_code_root_tl #1 / #2 }
+          }
+      }
+  }
+\cs_new_protected:Npn \__template_instance_set_eq:nnn #1#2#3
+  {
+    \__template_if_instance_exist:nnTF {#1} {#3}
+      {
+        \__template_recover_values:nn {#1} {#3}
+        \__template_store_values:nn {#1} {#2}
+        \cs_if_exist:cT { \c__template_instances_root_tl #1 / #2 }
+          { \msg_info:nnnn { template } { declare-instance } {#2} {#1} }
+        \cs_set_eq:cc { \c__template_instances_root_tl #1 / #2 }
+          { \c__template_instances_root_tl #1 / #3 }
+      }
+      { \msg_error:nnnn { template } { unknown-instance } {#1} {#3} }
+  }
+\cs_new_protected:Npn \__template_edit_instance:nnn #1#2#3
+  {
+    \__template_if_instance_exist:nnTF {#1} {#2}
+      {
+        \__template_recover_values:nn {#1}  {#2}
+        \prop_get:NnN \l__template_values_prop { from~template }
+          \l__template_tmp_tl
+        \__template_edit_instance_aux:nVnn
+          {#1} \l__template_tmp_tl {#2} {#3}
+      }
+      { \msg_error:nnnn { template } { unknown-instance } {#1} {#2} }
+  }
+\cs_new_protected:Npn \__template_edit_instance_aux:nnnn #1#2#3#4
+  {
+    \__template_recover_vars:nn {#1} {#2}
+    \__template_declare_instance_aux:nnnn {#1} {#2} {#3} {#4}
+  }
+\cs_generate_variant:Nn \__template_edit_instance_aux:nnnn { nV }
+\cs_new_protected:Npn \__template_convert_to_assignments:
+  {
+    \tl_clear:N \l__template_assignments_tl
+    \seq_map_function:NN \l__template_key_order_seq
+      \__template_convert_to_assignments_aux:n
+  }
+\cs_new_protected:Npn \__template_convert_to_assignments_aux:n #1
+  {
+    \prop_get:NnN \l__template_keytypes_prop {#1} \l__template_tmp_tl
+    \__template_convert_to_assignments_aux:nV {#1} \l__template_tmp_tl
+  }
+\cs_new_protected:Npn \__template_convert_to_assignments_aux:nn #1#2
+  {
+    \prop_get:NnNT \l__template_values_prop {#1} \l__template_value_tl
+      {
+        \prop_get:NnNTF \l__template_vars_prop {#1} \l__template_var_tl
+          {
+            \__template_split_keytype_arg:n {#2}
+            \str_if_eq:VnF \l__template_keytype_tl { choice }
+              {
+                \str_if_eq:VnF \l__template_keytype_tl { code }
+                  { \__template_find_global: }
+              }
+            \tl_set:Nn \l__template_key_name_tl {#1}
+            \cs_if_exist_use:cF { __template_assign_ \l__template_keytype_tl : }
+              { \__template_assign_variable: }
+          }
+          { \msg_error:nnn { template } { unknown-attribute } {#1} }
+      }
+  }
+\cs_generate_variant:Nn \__template_convert_to_assignments_aux:nn { nV }
+\cs_new_protected:Npn \__template_find_global:
+  {
+    \bool_set_false:N \l__template_global_bool
+    \tl_if_in:onT \l__template_var_tl { global }
+      {
+        \exp_after:wN \__template_find_global_aux:w \l__template_var_tl \s__template_stop
+      }
+  }
+\cs_new_protected:Npn \__template_find_global_aux:w  #1 global #2 \s__template_stop
+  {
+    \tl_set:Nn \l__template_var_tl {#2}
+    \bool_set_true:N \l__template_global_bool
+  }
+\cs_new_protected:Npn \__template_use_template:nnn #1#2#3
+  {
+    \__template_execute_if_code_exist:nnT {#1} {#2}
+      {
+        \__template_recover_defaults:nn {#1} {#2}
+        \__template_recover_vars:nn {#1} {#2}
+        \__template_parse_values:nnn {#1} {#2} {#3}
+        \__template_convert_to_assignments:
+        \use:c { \c__template_code_root_tl #1 / #2  }
+      }
+  }
+\cs_new_protected:Npn \__template_assign_boolean:
+  {
+    \bool_if:NTF \l__template_global_bool
+      { \__template_assign_boolean_aux:n { bool_gset } }
+      { \__template_assign_boolean_aux:n { bool_set } }
+  }
+\cs_new_protected:Npn \__template_assign_boolean_aux:n #1
+  {
+    \__template_if_key_value:VTF \l__template_value_tl
+      {
+        \__template_key_to_value:
+        \tl_put_right:Ne \l__template_assignments_tl
+          {
+            \exp_not:c { #1 _eq:NN }
+            \exp_not:V \l__template_var_tl
+            \exp_not:V \l__template_value_tl
+          }
+      }
+      {
+        \tl_put_right:Ne \l__template_assignments_tl
+          {
+            \exp_not:c { #1 _ \l__template_value_tl :N }
+            \exp_not:V \l__template_var_tl
+          }
+      }
+  }
+\cs_new_protected:Npn \__template_assign_choice:
+  {
+    \__template_assign_choice_aux:eF
+      { \l__template_key_name_tl \c_space_tl \l__template_value_tl }
+      {
+        \__template_assign_choice_aux:eF
+          { \l__template_key_name_tl \c_space_tl unknown }
+          {
+            \prop_get:NVN \l__template_keytypes_prop \l__template_key_name_tl
+              \l__template_tmp_tl
+            \__template_split_keytype_arg:V \l__template_tmp_tl
+            \msg_error:nnVV { template } { unknown-choice }
+              \l__template_key_name_tl
+              \l__template_value_tl
+          }
+      }
+  }
+\cs_new_protected:Npn \__template_assign_choice_aux:nF #1
+  {
+    \prop_get:NnNTF \l__template_vars_prop {#1} \l__template_tmp_tl
+      { \tl_put_right:NV \l__template_assignments_tl \l__template_tmp_tl }
+  }
+\cs_generate_variant:Nn \__template_assign_choice_aux:nF { e }
+\cs_new_protected:Npn \__template_assign_function:
+  {
+    \bool_if:NTF \l__template_global_bool
+      { \__template_assign_function_aux:N \cs_gset:Npn }
+      { \__template_assign_function_aux:N \cs_set:Npn  }
+  }
+\cs_new_protected:Npn \__template_assign_function_aux:N #1
+  {
+    \tl_put_right:Ne \l__template_assignments_tl
+      {
+        \cs_generate_from_arg_count:NNnn
+          \exp_not:V \l__template_var_tl
+          \exp_not:N #1
+          { \exp_not:V \l__template_keytype_arg_tl }
+          { \exp_not:V \l__template_value_tl }
+      }
+  }
+\cs_new_protected:Npn \__template_assign_instance:
+  {
+    \bool_if:NTF \l__template_global_bool
+      { \__template_assign_instance_aux:N \cs_gset_protected:Npn }
+      { \__template_assign_instance_aux:N \cs_set_protected:Npn  }
+  }
+\cs_new_protected:Npn \__template_assign_instance_aux:N #1
+  {
+    \tl_put_right:Ne \l__template_assignments_tl
+      {
+        \exp_not:N #1 \exp_not:V \l__template_var_tl
+          {
+            \__template_use_instance:nn
+              { \exp_not:V \l__template_keytype_arg_tl }
+              { \exp_not:V \l__template_value_tl }
+          }
+      }
+  }
+\cs_new_protected:Npn \__template_assign_variable:
+  {
+    \__template_assign_variable:c
+      {
+        \__template_map_var_type: _
+        \bool_if:NT \l__template_global_bool { g } set:Nn
+      }
+  }
+\cs_new_protected:Npn \__template_assign_variable:N #1
+  {
+    \__template_if_key_value:VT \l__template_value_tl
+      { \__template_key_to_value: }
+    \tl_put_right:Ne \l__template_assignments_tl
+      {
+        #1 \exp_not:V \l__template_var_tl
+         { \exp_not:V \l__template_value_tl }
+      }
+  }
+\cs_generate_variant:Nn \__template_assign_variable:N { c }
+\cs_new_protected:Npn \__template_key_to_value:
+  { \exp_after:wN \__template_key_to_value_auxi:w \l__template_value_tl }
+\cs_new_protected:Npn \__template_key_to_value_auxi:w \KeyValue #1
+  {
+    \tl_set:Ne \l__template_tmp_tl { \tl_trim_spaces:e { \tl_to_str:n {#1} } }
+    \prop_get:NVNTF \l__template_vars_prop \l__template_tmp_tl
+      \l__template_value_tl
+      {
+        \exp_after:wN \__template_key_to_value_auxii:w \l__template_value_tl
+          \s__template_mark global \q__template_nil \s__template_stop
+      }
+      { \msg_error:nnV { template } { unknown-attribute } \l__template_tmp_tl }
+  }
+\cs_new_protected:Npn \__template_key_to_value_auxii:w #1 global #2#3 \s__template_stop
+  {
+    \__template_quark_if_nil:NF #2
+      { \tl_set:Nn \l__template_value_tl {#2} }
+  }
+\cs_new_protected:Npn \__template_use_instance:nn #1#2
+  {
+    \__template_if_use_template:nTF {#2}
+      { \__template_use_instance_aux:nNnnn {#1} #2 }
+      { \__template_use_instance_aux:nn {#1} {#2} }
+  }
+\cs_new_protected:Npn \__template_use_instance_aux:nNnnn #1#2#3#4#5
+  {
+    \str_if_eq:nnTF {#1} {#3}
+      { \__template_use_template:nnn {#3} {#4} {#5} }
+      { \msg_error:nnnn { template } { type-mismatch } {#1} {#3} }
+}
+\cs_new_protected:Npn \__template_use_instance_aux:nn #1#2
+  {
+    \__template_if_instance_exist:nnTF {#1} {#2}
+      { \use:c { \c__template_instances_root_tl #1 / #2 } }
+      { \msg_error:nnnn { template } { unknown-instance } {#1} {#2} }
+  }
+\cs_new:Npn \__template_assignments_pop: { \l__template_assignments_tl }
+\cs_new_protected:Npn \__template_assignments_push:n #1
+  { \tl_set:Nn \l__template_assignments_tl {#1} }
+\cs_new_protected:Npn \__template_show_code:nn #1#2
+  { \cs_show:c { \c__template_code_root_tl #1 / #2 } }
+\cs_new_protected:Npn \__template_show_defaults:nn #1#2
+  {
+    \__template_if_keys_exist:nnT {#1} {#2}
+      {
+        \__template_recover_defaults:nn {#1} {#2}
+        \__template_show:Nnnn \l__template_values_prop
+          {#1} {#2} { default~values }
+      }
+  }
+\cs_new_protected:Npn \__template_show_keytypes:nn #1#2
+  {
+    \__template_if_keys_exist:nnT {#1} {#2}
+      {
+        \__template_recover_keytypes:nn {#1} {#2}
+        \__template_show:Nnnn \l__template_keytypes_prop
+          {#1} {#2} { interface }
+      }
+  }
+\cs_new_protected:Npn \__template_show_vars:nn #1#2
+  {
+     \__template_execute_if_code_exist:nnT {#1} {#2}
+      {
+        \__template_recover_vars:nn {#1} {#2}
+        \__template_show:Nnnn \l__template_vars_prop
+          {#1} {#2} { variable~mapping }
+      }
+  }
+\cs_new_protected:Npn \__template_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 }
+  }
+\cs_new_protected:Npn \__template_show_values:nn #1#2
+  {
+    \__template_if_instance_exist:nnT {#1} {#2}
+      {
+        \__template_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__template_values_prop
+              \msg_show_item_unbraced:nn
+          }
+      }
+  }
+\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'.
+  }
+\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 }
+  }
+\prop_gput:Nnn \g_msg_module_type_prop { template } { LaTeX }
+\cs_new_protected:Npn \NewTemplateType #1#2
+  { \__template_define_type:nn {#1} {#2} }
+\cs_new_protected:Npn \DeclareTemplateInterface #1#2#3#4
+  { \__template_declare_template_keys:nnnn {#1} {#2} {#3} {#4} }
+\cs_new_protected:Npn \DeclareTemplateCode #1#2#3#4#5
+  { \__template_declare_template_code:nnnnn {#1} {#2} {#3} {#4} {#5} }
+\cs_new_protected:Npn \DeclareTemplateCopy #1#2#3
+  { \__template_template_set_eq:nnn {#1} {#2} {#3} }
+\cs_new_protected:Npn \EditTemplateDefaults #1#2#3
+  { \__template_edit_defaults:nnn {#1} {#2} {#3} }
+\cs_new_protected:Npn \UseTemplate #1#2#3
+  { \__template_use_template:nnn {#1} {#2} {#3} }
+\cs_new_protected:Npn \DeclareInstance #1#2#3#4
+  { \__template_declare_instance:nnnn {#1} {#3} {#2} {#4} }
+\cs_new_protected:Npn \DeclareInstanceCopy #1#2#3
+  { \__template_instance_set_eq:nnn {#1} {#2} {#3} }
+\cs_new_protected:Npn \EditInstance #1#2#3
+  { \__template_edit_instance:nnn {#1} {#2} {#3} }
+\cs_new_protected:Npn \UseInstance #1#2
+  { \__template_use_instance:nn {#1} {#2} }
+\cs_new_protected:Npn \ShowTemplateCode #1#2
+  { \__template_show_code:nn {#1} {#2} }
+\cs_new_protected:Npn \ShowTemplateDefaults #1#2
+  { \__template_show_defaults:nn {#1} {#2} }
+\cs_new_protected:Npn \ShowTemplateInterface #1#2
+  { \__template_show_keytypes:nn {#1} {#2} }
+\cs_new_protected:Npn \ShowTemplateVariables #1#2
+  { \__template_show_vars:nn {#1} {#2} }
+\cs_new_protected:Npn \ShowInstanceValues #1#2
+  { \__template_show_values:nn {#1} {#2} }
+\cs_new:Npn \IfInstanceExistsTF #1#2
+  { \__template_if_instance_exist:nnTF {#1} {#2} }
+\cs_new:Npn \IfInstanceExistsT #1#2
+  { \__template_if_instance_exist:nnT {#1} {#2} }
+\cs_new:Npn \IfInstanceExistsF #1#2
+  { \__template_if_instance_exist:nnF {#1} {#2} }
+\cs_new_protected:Npn \KeyValue #1 {#1}
+\cs_new_protected:Npn \AssignTemplateKeys { \__template_assignments_pop: }
+\cs_new_protected:Npn \SetTemplateKeys #1#2#3
+  { \keys_set_known:nnN { template / #1 / #2 } {#3} \l__template_tmp_clist }
+\ExplSyntaxOff
 %%% From File: ltalloc.dtx
 \chardef\@xxxii=32
 \mathchardef\@Mi=10001
@@ -7246,8 +8552,6 @@
 %% Copyright (C) 2020-2024
 %% Frank Mittelbach, The LaTeX Project
 %%% From File: ltpara.dtx
-\def\ltparaversion{v1.0l}
-\def\ltparadate{2023/01/30}
 
 
 \ExplSyntaxOn
@@ -7276,7 +8580,7 @@
   \@kernel at before@para at begin
   \hook_use:n {para/begin}
   \if_mode_horizontal: \else:
-    \msg_error:nnnn { hooks }{ para-mode }{begin}{vertical} \fi:
+    \msg_error:nnnn { hooks }{ para-mode }{begin}{horizontal} \fi:
   \__para_handle_indent:
 }
 \tex_everypar:D{\g__para_standard_everypar_tl}
@@ -7347,7 +8651,7 @@
 \cs_set_eq:NN \par     \para_end:
 \cs_set_eq:NN \@@par   \para_end:
 \cs_set_eq:NN \endgraf \para_end:
-\everypar{\@nodocument} %% To get an error if text appears before the
+\everypar{\@nodocument} %% To get an error if text appears before the \document
 \msg_new:nnnn { hooks } { para-mode }
   {
     Illegal~mode~ change~ in~ hook~ 'para/#1'.\\
@@ -7377,8 +8681,6 @@
 %% Copyright (C) 2021-2024
 %% Frank Mittelbach, The LaTeX Project
 %%% From File: ltmeta.dtx
-\def\ltmetaversion{v1.0b}
-\def\ltmetadate{2022/05/18}
 \let \IfDocumentMetadataTF \@secondoftwo
 \protected\def\DocumentMetadata{%
   \InputIfFileExists{documentmetadata-support.ltx}%
@@ -7963,7 +9265,15 @@
    \@latex at warning@no at line{inputting `#1' instead of obsolete `#2'}}
 \@onlypreamble\@obsoletefile
 \let\@filelist\@gobble
-\def\listfiles{%
+\ExplSyntaxOn
+\keys_define:nn { __kernel / listfiles }
+  {
+    hashes .legacy_if_set:n = @listfiles at hashes ,
+    sizes .legacy_if_set:n  = @listfiles at sizes
+  }
+\ExplSyntaxOff
+\NewDocumentCommand\listfiles{O{}}{%
+  \SetKeys[__kernel/listfiles]{#1}%
   \let\listfiles\relax
   \def\@listfiles##1##2##3##4##5##6##7##8##9\@@{%
      \def\reserved at d{\\}%
@@ -7988,8 +9298,30 @@
              \filename at area\filename at base\\\\\\\\\\\\\\\\\\\@@
        \typeout{%
          \filename at area\reserved at a
-         \ifx\reserved at b\relax\else\@spaces\reserved at b\fi}}%
+         \ifx\reserved at b\relax\else\@spaces\reserved at b\fi
+         \ifnum0%
+           \if at listfiles@hashes1\fi
+           \if at listfiles@sizes1\fi
+             >0 %
+             ^^J\@spaces
+             (%
+               \if at listfiles@sizes
+                 size \@dofilelist at size\@currname
+                 \if at listfiles@hashes
+                   , %
+                 \fi
+               \fi
+               \if at listfiles@hashes
+                 hash \@dofilelist at hash\@currname
+               \fi
+             )%
+         \fi
+      }}%
      \typeout{ ***********^^J}}}
+\ExplSyntaxOn
+\cs_new_eq:NN \@dofilelist at hash \file_mdfive_hash:n
+\cs_new_eq:NN \@dofilelist at size \file_size:n
+\ExplSyntaxOff
 \@onlypreamble\listfiles
 \let\@dofilelist\relax
 %%% From File: ltoutenc.dtx
@@ -8294,8 +9626,14 @@
      \@addtoreset{#1}{@ckpt}%
      \global\expandafter\let\csname p@#1\endcsname\@empty
      \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 at warning{Command `\string\the#1' already
+                       defined -- not changed}%
+     \fi}
 \def\@addtoreset#1#2{\expandafter\@cons\csname cl@#2\endcsname {{#1}}}
 \def\@removefromreset#1#2{%
   \@ifundefined{c@#2}\relax
@@ -8918,7 +10256,7 @@
  \def\@xxvpt{24.88}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%% From File: ltfssaxes.dtx
-%% Copyright (C) 1999-2020 Frank Mittelbach
+%% Copyright (C) 2019-2020 Frank Mittelbach
 \def\DeclareFontSeriesChangeRule#1#2#3#4{%
   \@namedef{series@#1@#2}{{#3}{#4}}}
 \DeclareFontSeriesChangeRule {bc}{b}{bc}{}
@@ -11691,8 +13029,7 @@
 \DeclareEncodingSubset{TS1}{lmss}    {1}
 \DeclareEncodingSubset{TS1}{lmssq}   {1}
 \DeclareEncodingSubset{TS1}{lmvtt}   {1}
-\DeclareEncodingSubset{TS1}{lmtt}    {1} % missing TM, SM and
-                                         % pertenthousand for some reason
+\DeclareEncodingSubset{TS1}{lmtt}    {1} % missing TM, SM and pertenthousand
 \DeclareEncodingSubset{TS1}{ptmx}    {2}
 \DeclareEncodingSubset{TS1}{ptmj}    {2}
 \DeclareEncodingSubset{TS1}{ul8}     {2}
@@ -11730,23 +13067,31 @@
 \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
+\DeclareEncodingSubset{TS1}{fbb-*}        {2}  % missing centoldstyle
 \DeclareEncodingSubset{TS1}{Alegreya-*}               {2}
 \DeclareEncodingSubset{TS1}{AlegreyaSans-*}           {2}
+\DeclareEncodingSubset{TS1}{BaskervilleF-*}           {2}
 \DeclareEncodingSubset{TS1}{DejaVuSans-TLF}           {2}
 \DeclareEncodingSubset{TS1}{DejaVuSansCondensed-TLF}  {2}
 \DeclareEncodingSubset{TS1}{DejaVuSansMono-TLF}       {2}
 \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}
 \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}
@@ -11761,6 +13106,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}
@@ -11773,7 +13119,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}
@@ -11790,12 +13135,12 @@
 \DeclareEncodingSubset{TS1}{Rosario-*}                {4}
 \DeclareEncodingSubset{TS1}{SticksTooText-*}          {4}
 \DeclareEncodingSubset{TS1}{UniversalisADFStd-LF}     {4}
-\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}
@@ -11802,10 +13147,9 @@
 \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}
@@ -11812,35 +13156,29 @@
 \DeclareEncodingSubset{TS1}{TheanoModern-TOsF}        {5}
 \DeclareEncodingSubset{TS1}{TheanoOldStyle-TLF}       {5}
 \DeclareEncodingSubset{TS1}{TheanoOldStyle-TOsF}      {5}
+\DeclareEncodingSubset{TS1}{charssil-TLF}             {5}
 \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}
+\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}
 \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}{Cochineal-*}              {8}
+\DeclareEncodingSubset{TS1}{Quattro-LF}               {7}
+\DeclareEncodingSubset{TS1}{QuattroSans-LF}           {7}
+\DeclareEncodingSubset{TS1}{Frm-LF}                   {7}  % the superiors are missing
+\DeclareEncodingSubset{TS1}{LibertinusMono-TLF}       {8}
 \DeclareEncodingSubset{TS1}{AlgolRevived-TLF}         {9}
 \def\UseLegacyTextSymbols{%
   \DeclareTextSymbolDefault{\textasteriskcentered}{OMS}%
@@ -11874,7 +13212,6 @@
 \DeclareTextSymbolDefault{\textlegacysection}{OMS}
 
 
-
 %%% From File: ltpageno.dtx
 \message{page nos.,}
 \countdef\c at page=0 \c at page=1
@@ -11949,12 +13286,7 @@
 \NewDocumentCommand\Ref{s}
    {\IfBooleanTF{#1}{\@kernel at sRef}{\@kernel at Ref}}
 \def\@currentlabel{}
-%% File: ltproperties.dtx
-\def\ltpropertiesversion{1.0c}
-\def\ltpropertiesdate{2023-10-15}
-
-
-
+%%% From File: ltproperties.dtx
 \ExplSyntaxOn
 \cs_new_protected:Npn \property_new:nnnn #1#2#3#4
   {
@@ -12007,7 +13339,7 @@
   {
     \legacy_if:nT { @filesw }
       {
-        \iow_shipout_x:Nx \@auxout
+        \protected at write \@auxout {}
           {
             \token_to_str:N \new at label@record
               {#1}
@@ -12119,7 +13451,9 @@
       }
   }
 \prg_generate_conditional_variant:Nnn \property_if_exist:n {e} {TF}
-\cs_new_eq:NN \IfPropertyExistTF \property_if_exist:eTF
+\cs_new_eq:NN \IfPropertyExistsTF \property_if_exist:eTF
+\cs_new:Npn   \IfPropertyExistsT #1#2 {\property_if_exist:eTF {#1}{#2}{} }
+\cs_new:Npn   \IfPropertyExistsF #1   {\property_if_exist:eTF {#1}{} }
 \prg_new_conditional:Npnn \property_if_recorded:n #1 { p , T , F,  TF }
   % #1 label
   {
@@ -12132,7 +13466,9 @@
       }
   }
 \prg_generate_conditional_variant:Nnn \property_if_recorded:n {e} {TF}
-\cs_new_eq:NN \IfLabelExistTF \property_if_recorded:eTF
+\cs_new_eq:NN \IfLabelExistsTF \property_if_recorded:eTF
+\cs_new:Npn   \IfLabelExistsT #1#2 {\property_if_exist:eTF {#1}{#2}{} }
+\cs_new:Npn   \IfLabelExistsF #1   {\property_if_exist:eTF {#1}{} }
 \prg_new_conditional:Npnn \property_if_recorded:nn #1#2 { p , T , F,  TF }
   % #1 label #2 property
   {
@@ -13334,7 +14670,16 @@
     \box\@tempboxa
   \@end at tempboxa}
 \def\@finalstrut#1{%
-  \unskip\ifhmode\nobreak\fi\vrule\@width\z@\@height\z@\@depth\dp#1}
+  \unskip
+  \ifhmode \nobreak \vrule
+  \else
+    \ifdim \prevdepth=-\@m\p@
+    \else
+      \vskip-\prevdepth
+    \fi
+    \hrule
+  \fi
+  \@width\z@\@height\z@\@depth\dp#1}
 \def\@@line{\hb at xt@\hsize}
 \DeclareRobustCommand\leftline[1]{\@@line{#1\hss}}
 \DeclareRobustCommand\rightline[1]{\@@line{\hss#1}}
@@ -14129,7 +15474,7 @@
   \global\@namedef{#1}{\@thm{#2}{#3}}%
   \global\@namedef{end#1}{\@endtheorem}}}}
 \def\@thm#1#2{%
-  \refstepcounter{#1}%
+  \@kernel at refstepcounter{#1}%
   \@ifnextchar[{\@ythm{#1}{#2}}{\@xthm{#1}{#2}}}
 \def\@xthm#1#2{%
   \@begintheorem{#2}{\csname the#1\endcsname}\ignorespaces}
@@ -14138,9 +15483,9 @@
 \def\@thmcounter#1{\noexpand\arabic{#1}}
 \def\@thmcountersep{.}
 \def\@begintheorem#1#2{\trivlist
-   \item[\hskip \labelsep{\bfseries #1\ #2}]\itshape}
+   \item[\MakeLinkTarget{\@currentcounter}\hskip \labelsep{\bfseries #1\ #2}]\itshape}
 \def\@opargbegintheorem#1#2#3{\trivlist
-      \item[\hskip \labelsep{\bfseries #1\ #2\ (#3)}]\itshape}
+      \item[\MakeLinkTarget{\@currentcounter}\hskip \labelsep{\bfseries #1\ #2\ (#3)}]\itshape}
 \def\@endtheorem{\endtrivlist}
 %%% From File: ltsect.dtx
 \message{title,}
@@ -14731,8 +16076,6 @@
 %% Copyright (C) 2022-2024
 %% Frank Mittelbach, The LaTeX Project
 %%% From File: ltmarks.dtx
-\def\ltmarksversion{v1.0d}
-\def\ltmarksdate{2022/06/01}
 %% \end{function}
 
 \ExplSyntaxOn
@@ -14770,42 +16113,87 @@
   \tl_new:c   { g__mark_last-column_top_    #1 _tl }
   \tl_new:c   { g__mark_last-column_first_  #1 _tl }
   \tl_new:c   { g__mark_last-column_last_   #1 _tl }
+  \tl_set:cn   { g__mark_page_top_   #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_page_first_ #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_page_last_  #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_previous-page_top_   #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_previous-page_first_ #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_previous-page_last_  #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_column_top_   #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_column_first_ #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_column_last_  #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_previous-column_top_   #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_previous-column_first_ #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_previous-column_last_  #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_first-column_top_   #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_first-column_first_ #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_first-column_last_  #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_last-column_top_    #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_last-column_first_  #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_last-column_last_   #1 _tl }{ \__mark_id:n{0} }
 }
 \box_new:N \l__mark_box
+\box_new:N \l__mark_ii_box
 \tl_new:N  \g__mark_tmp_tl
 \tl_new:N  \g__mark_new_top_tl
-\cs_new_protected:Npn \__mark_update_structure:nn #1#2
-  {
-    \__mark_update_structure_alias:nn { previous-#1 } {#1}
+\cs_new_protected:Npn \__mark_extract_and_handle_marks:nn #1#2 {
     \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
-      \vbox_set_to_ht:Nnn \l__mark_box { -.5\c_max_dim }
+      \__mark_prepare_and_extract:nn {#1} {#2}
+    \group_end:
+  }
+\cs_new_protected:Npn \__mark_prepare_and_extract:nn #1#2 {
+  \vbox_set:Nn \l__mark_box
+    {
+      #2
+      \tex_unskip:D
+      \box_set_to_last:N \l__mark_box
+      \int_compare:nNnT \tex_lastnodetype:D < 0
         {
-          #2
-          \tex_unskip:D
-          \box_set_to_last:N \l__mark_box
-          \int_compare:nNnT \tex_lastnodetype:D < 0
-            {
-              \box_if_vertical:NT \l__mark_box
-                {
-                  \vbox_set_to_ht:Nnn \l__mark_box { -.5\c_max_dim }
-                    {
-                      \vbox_unpack:N \l__mark_box
-                      \tex_kern:D \c_zero_dim % ensure that box
-                                              % is not empty
-                    }
-                    \int_compare:nNnT \tex_badness:D > 0
-                      { \vbox_unpack:N \l__mark_box }
-                  }
-            }
-          \tex_kern:D \c_zero_dim
+          \box_if_vertical:NT \l__mark_box
+            { \vbox_unpack:N \l__mark_box }
         }
-      \int_compare:nNnTF \tex_badness:D > 0
-        {
-          \vbox_set_split_to_ht:NNn \l__mark_box \l__mark_box \c_max_dim
-          \seq_map_inline:Nn \g__mark_classes_seq
+    }
+    \__mark_vbox_set_split_to_maxdimen:NN \l__mark_ii_box \l__mark_box
+    \box_if_empty:NTF \l__mark_box
+      { #1 }
+      {
+        \__mark_debug:n { \iow_term:x
+          { Marks:~ mark~ extraction~needs~ recursion~
+            \msg_line_context: } }
+        \__mark_prepare_and_extract:nn {#1}
+           { \vbox_unpack:N \l__mark_ii_box
+             \vbox_unpack:N \l__mark_box    }
+      }
+}
+\cs_set_eq:cN {Infinite~shrink~error~above~ignored~!}\c_max_dim
+\cs_new_protected:Npx \__mark_vbox_set_split_to_maxdimen:NN #1#2 {
+  \tl_set:Ne \exp_not:N \l__mark_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:
+     }
+  \tex_escapechar:D     -1 \scan_stop:
+  \tex_interactionmode:D 0 \scan_stop:
+  \tex_setbox:D #1 \tex_vsplit:D #2 to
+      \exp_not:N \use:n {
+        \use:c{Infinite~shrink~error~above~ignored~!}
+      }
+  \exp_not:N \l__mark_saved_parameters_tl
+}
+\tl_new:N \l__mark_saved_parameters_tl
+\cs_new_protected:Npn \__mark_update_structure_from_material:nn #1#2 {
+  \__mark_extract_and_handle_marks:nn
+     { \__mark_update_structure_from_splitmarks:n {#1} }
+     { #2 }
+}
+\cs_new_protected:Npn \__mark_update_structure_from_splitmarks:n #1 {
+  \__mark_update_structure_alias:nn { previous-#1 } {#1}
+  \seq_map_inline:Nn \g__mark_classes_seq
             {
               \tl_gset_eq:Nc \g__mark_new_top_tl { g__mark_#1_last_##1_tl }
               \tl_gset_eq:cN { g__mark_#1_top_##1_tl } \g__mark_new_top_tl
@@ -14827,19 +16215,49 @@
                     }
                 }
             }
-        }
-        {
-          \msg_error:nnn { mark } { infinite-shrinkage } {#1}
-          \seq_map_inline:Nn \g__mark_classes_seq
+}
+\cs_new_protected:Npn \__mark_get_marks_for_reinsertion:nNN #1#2#3 {
+  \tl_clear:N \g__mark_first_marks_tl
+  \tl_clear:N \g__mark_last_marks_tl
+  \__mark_extract_and_handle_marks:nn
+     \__mark_get_from_splitmarks:
+     { #1 }
+  \tl_set_eq:NN #2 \g__mark_first_marks_tl
+  \tl_set_eq:NN #3 \g__mark_last_marks_tl
+}
+\cs_new_protected:Npn  \__mark_get_from_splitmarks:  {
+  \seq_map_inline:Nn \g__mark_classes_seq
             {
-              \tl_gset_eq:cc { g__mark_#1_top_  ##1_tl }
-                             { g__mark_#1_last_ ##1_tl }
-              \tl_gset_eq:cc { g__mark_#1_first_##1_tl }
-                             { g__mark_#1_last_ ##1_tl }
+              \tl_gset:No \g__mark_tmp_tl
+                { \tex_splitbotmarks:D \use:c { c__mark_class_##1_mark } }
+
+              \tl_if_empty:NTF \g__mark_tmp_tl
+                {
+                  \__mark_debug:n { \iow_term:x { Marks:~no~ marks~
+                      for~ class~ '##1'~\msg_line_context: } }
+                }
+                {
+                  \__mark_debug:n { \iow_term:x { Marks:~ extract~ last~
+                       mark~ for~ class~ '##1'~ =~  \g__mark_tmp_tl } }
+                  \tl_gput_right:Ne \g__mark_last_marks_tl
+                     { \mark_insert:nn {##1} { \g__mark_tmp_tl } }
+                  \__mark_debug:n { \iow_term:x { Marks:~ extract~ first~
+                      mark~ for~ class~ '##1'~ =~
+                      \tex_splitfirstmarks:D
+                        \use:c { c__mark_class_##1_mark }
+                  } }
+                  \tl_gput_right:Ne \g__mark_first_marks_tl
+                     { \mark_insert:nn {##1}
+                       {
+                         \tex_splitfirstmarks:D
+                         \use:c { c__mark_class_##1_mark }
+                       }
+                     }
+                }
             }
-        }
-    \group_end:
-  }
+}
+\tl_new:N  \g__mark_first_marks_tl
+\tl_new:N  \g__mark_last_marks_tl
 \cs_new_protected:Npn \__mark_update_structure_alias:nn #1#2 {
   \seq_map_inline:Nn \g__mark_classes_seq
     {
@@ -14869,14 +16287,16 @@
         \group_begin:
           \@kernel at before@insertmark
           \hook_use:n { insertmark }
-          \unrestored at protected@xdef \g__mark_tmp_tl {#2}
+          \unrestored at protected@xdef \g__mark_tmp_tl
+               {
+                 \__mark_id:n{ \int_use:N\g__mark_int }
+                 #2
+               }
           \__mark_debug:n{ \iow_term:x { Marks:~ set~#1~<-~
               '\tl_to_str:V \g__mark_tmp_tl' ~ \msg_line_context: } }
           \tex_marks:D \use:c { c__mark_class_ #1 _mark }
             {
-              \tl_if_empty:NTF \g__mark_tmp_tl
-                { \exp_not:n { \prg_do_nothing: } }
-                { \exp_not:o { \g__mark_tmp_tl } }
+              \exp_not:o { \g__mark_tmp_tl }
             }
         \group_end:
         \if at nobreak\ifvmode\nobreak\fi\fi
@@ -14886,15 +16306,23 @@
           { \tl_to_str:n {#1} }
       }
 }
+\cs_new_protected:Npn \__mark_id:n #1 { }
+\int_new:N \g__mark_int
 \cs_new:Npn \@kernel at before@insertmark {
           \cs_set_eq:NN \label    \scan_stop:
           \cs_set_eq:NN \index    \scan_stop:
           \cs_set_eq:NN \glossary \scan_stop:
+          \int_compare:nNnTF \g__mark_int < {99999}
+              { \int_gincr:N \g__mark_int }
+              { \int_gzero:N \g__mark_int }
+
 }
 \hook_new:n {insertmark}
-\cs_new:Npn \mark_use_first:nn #1#2 { \exp_not:v { g__mark_#1_first_#2_tl } }
-\cs_new:Npn \mark_use_last:nn #1#2  { \exp_not:v { g__mark_#1_last_#2_tl }  }
-\cs_new:Npn \mark_use_top:nn #1#2   { \exp_not:v { g__mark_#1_top_#2_tl }   }
+\cs_new:Npn \mark_use_first:nn #1#2 { \__mark_use:v { g__mark_#1_first_#2_tl } }
+\cs_new:Npn \mark_use_last:nn #1#2  { \__mark_use:v { g__mark_#1_last_#2_tl }  }
+\cs_new:Npn \mark_use_top:nn #1#2   { \__mark_use:v { g__mark_#1_top_#2_tl }   }
+\cs_new:Npn \__mark_use:n #1 { \exp_not:o { \use_none:nn #1 } }
+\cs_generate_variant:Nn \__mark_use:n { v }
 \prg_new_conditional:Npnn \mark_if_eq:nnnn #1#2#3#4 { T , F , TF }
 {
   \tl_if_eq:ccTF { g__mark_ #1 _#3_ #2 _tl }
@@ -14934,15 +16362,6 @@
     all~columns~have~been~assembled.
     \c__msg_return_text_tl
   }
-\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.
-  }
 \bool_new:N \g__mark_debug_bool
 \cs_new_eq:NN \__mark_debug:n \use_none:n
 \cs_new_protected:Npn \mark_debug_on:
@@ -14995,6 +16414,9 @@
     \seq_map_inline:Nn \g__mark_classes_seq
       { \__mark_class_status:nn {#1} {##1} }
   }
+\cs_new_protected:Npn \ShowMarksAt #1 {
+     \__mark_debug:n { \__mark_status:n {#1} }
+}
 \cs_new_eq:NN  \NewMarkClass \mark_new_class:n
 \@onlypreamble \NewMarkClass
 \cs_new_eq:NN \InsertMark  \mark_insert:nn
@@ -15010,11 +16432,11 @@
 \cs_new_protected:Npn \__mark_update_singlecol_structures: {
   \box_if_vertical:NTF \@outputbox
       {
-        \__mark_update_structure:nn {page}
+        \__mark_update_structure_from_material:nn {page}
            { \vbox_unpack:N  \@outputbox }
       }
       {
-        \__mark_update_structure:nn {page}
+        \__mark_update_structure_from_material:nn {page}
            { \hbox_unpack:N  \@outputbox }
       }
   \__mark_update_structure_alias:nn {previous-column}{previous-page}
@@ -15038,11 +16460,11 @@
 \cs_new_protected:Npn \__mark_update_dblcol_structures: {
   \box_if_vertical:NTF \@outputbox
       {
-        \__mark_update_structure:nn {column}
+        \__mark_update_structure_from_material:nn {column}
            { \vbox_unpack:N  \@outputbox }
       }
       {
-        \__mark_update_structure:nn {column}
+        \__mark_update_structure_from_material:nn {column}
            { \hbox_unpack:N  \@outputbox }
       }
   \legacy_if:nTF {@firstcolumn}
@@ -15062,10 +16484,19 @@
                          { g__mark_page_last_           ##1 _tl }
           \tl_gset_eq:cc { g__mark_page_top_           ##1 _tl }
                          { g__mark_first-column_top_   ##1 _tl }
-          \tl_gset_eq:cc { g__mark_ page_first_        ##1 _tl }
+
+          \tl_if_eq:ccTF { g__mark_first-column_top_   ##1 _tl }
                          { g__mark_first-column_first_ ##1 _tl }
-          \tl_gset_eq:cc { g__mark_page_last_          ##1 _tl }
-                         { g__mark_last-column_last_   ##1 _tl }
+             {
+               \tl_gset_eq:cc { g__mark_page_first_        ##1 _tl }
+                              { g__mark_last-column_first_ ##1 _tl }
+             }
+             {
+               \tl_gset_eq:cc { g__mark_page_first_         ##1 _tl }
+                              { g__mark_first-column_first_ ##1 _tl }
+             }
+          \tl_gset_eq:cc { g__mark_page_last_        ##1 _tl }
+                         { g__mark_last-column_last_ ##1 _tl }
         }
     }
      \__mark_debug:n
@@ -15255,6 +16686,30 @@
 \let \IfClassLoadedTF              \@ifclassloaded
 \let \IfPackageLoadedWithOptionsTF \@ifpackagewith
 \let \IfClassLoadedWithOptionsTF   \@ifclasswith
+\def\IfPackageLoadedT #1#2{\IfPackageLoadedTF{#1}{#2}{}}
+\def\IfPackageLoadedF   #1{\IfPackageLoadedTF{#1}{}}
+\def\IfClassLoadedT   #1#2{\IfClassLoadedTF{#1}{#2}{}}
+\def\IfClassLoadedF     #1{\IfClassLoadedTF{#1}{}}
+\def\IfPackageAtLeastT#1#2#3{\IfPackageAtLeastTF{#1}{#2}{#3}{}}
+\def\IfPackageAtLeastF  #1#2{\IfPackageAtLeastTF{#1}{#2}{}}
+\def\IfClassAtLeastT  #1#2#3{\IfClassAtLeastTF{#1}{#2}{#3}{}}
+\def\IfClassAtLeastF    #1#2{\IfClassAtLeastTF{#1}{#2}{}}
+\def\IfFileAtLeastT   #1#2#3{\IfFileAtLeastTF{#1}{#2}{#3}{}}
+\def\IfFileAtLeastF     #1#2{\IfFileAtLeastTF{#1}{#2}{}}
+\def\IfFormatAtLeastT   #1#2{\IfFormatAtLeastTF{#1}{#2}{}}
+\def\IfFormatAtLeastF     #1{\IfFormatAtLeastTF{#1}{}}
+\def\IfPackageLoadedWithOptionsT #1#2#3{\IfPackageLoadedWithOptionsTF{#1}{#2}{#3}{}}
+\def\IfPackageLoadedWithOptionsF   #1#2{\IfPackageLoadedWithOptionsTF{#1}{#2}{}}
+\def\IfClassLoadedWithOptionsT #1#2#3{\IfClassLoadedWithOptionsTF{#1}{#2}{#3}{}}
+\def\IfClassLoadedWithOptionsF   #1#2{\IfClassLoadedWithOptionsTF{#1}{#2}{}}
+\def\IfFileLoadedTF#1{%
+  \expandafter\ifx\csname ver@#1\endcsname\relax
+    \expandafter\@secondoftwo
+  \else
+    \expandafter\@firstoftwo
+  \fi}
+\def\IfFileLoadedT#1#2{\IfFileLoadedTF{#1}{#2}{}}
+\def\IfFileLoadedF  #1{\IfFileLoadedTF{#1}{}}
 \def\ProvidesPackage#1{%
   \xdef\@gtempa{#1}%
   \@expandtwoargs\@expl at str@if at eq@@nnTF
@@ -15305,11 +16760,11 @@
   \expandafter\let
     \csname opt@#3.#1\expandafter\endcsname
     \csname opt@\reserved at a\endcsname
-    \@ifundefined{@raw at opt@#3.#1}%
-      {\expandafter\gdef\csname @raw at opt@#3.#1\expandafter\endcsname
-                \expandafter{#2}}%
-      {\expandafter\g at addto@macro\csname @raw at opt@#3.#1\expandafter\endcsname
-                \expandafter{\expandafter,#2}}%
+  \@ifundefined{@raw at opt@#3.#1}%
+    {\expandafter\gdef\csname @raw at opt@#3.#1\expandafter\endcsname
+              \expandafter{#2}}%
+    {\expandafter\g at addto@macro\csname @raw at opt@#3.#1\expandafter\endcsname
+              \expandafter{\expandafter,#2}}%
 }
 \@onlypreamble\@pass at ptions
 \def\PassOptionsToPackage{\@pass at ptions\@pkgextension}
@@ -15474,6 +16929,11 @@
   \ifx#2\@empty\else\expandafter\zap at space\fi
   #2}
 \def\@fileswithoptions#1{%
+    \ifnum\currentgrouplevel>\z@
+     \@latex at error
+      {Loading a class or package in a group}%
+      {Classes and packages should only be loaded at the top level}%
+  \fi
   \@ifnextchar[%]
     {\@fileswith at ptions#1}%
     {\@fileswith at ptions#1[]}}
@@ -15524,9 +16984,12 @@
       \@ifundefined{opt at handler@\@currname.\@currext}
         {\@onefilewithoptions at clashchk{#2}}
         {%
-          \expandafter\protected at edef\csname opt@\@currname.\@currext\endcsname
+          \expandafter\protected at edef
+            \csname opt@\@currname.\@currext\endcsname
             {\zap at space#2 \@empty}%
-          \@namedef{@raw at opt@\@currname.\@currext}{#2}%
+          \expandafter\def
+            \csname @raw at opt@\@currname.\@currext\expandafter\endcsname
+            \expandafter{#2}%
           \@nameuse{opt at handler@\@currname.\@currext}%
         }%
     }%
@@ -16260,8 +17723,6 @@
   { \__keys_options_expand_module:Nn \keys_set:nn {#1} {#2} }
 \ExplSyntaxOff
 %%% From File: ltfilehook.dtx
-\providecommand\ltfilehookversion{v1.0o}
-\providecommand\ltfilehookdate{2023/07/10}
 \ExplSyntaxOn
 \tl_new:N \CurrentFile
 \tl_new:N \CurrentFilePath
@@ -16551,8 +18012,6 @@
 %% Frank Mittelbach, The LaTeX Project
 %%
 %%% From File: ltshipout.dtx
-\providecommand\ltshipoutversion{v1.0n}
-\providecommand\ltshipoutdate{2022/11/08}
 \ExplSyntaxOn
 \bool_new:N \g__shipout_debug_bool
 \cs_new_eq:NN \__shipout_debug:n  \use_none:n
@@ -18070,6 +19529,198 @@
 \let\topfigrule=\relax
 \let\botfigrule=\relax
 \let\dblfigrule=\relax
+%%% From File: lttagging.dtx
+\ExplSyntaxOn
+\cs_new_eq:NN \SuspendTagging \use_none:n
+\cs_new_eq:NN \ResumeTagging  \use_none:n
+\AddToHook{begindocument/before}{
+  \cs_if_exist:NT \tag_stop:n
+  {
+    \cs_set:Npn \SuspendTagging #1 {
+      \tag_stop:n {#1}
+    }
+    \cs_set:Npn \ResumeTagging #1 { \tag_start:n {#1} }
+  }
+}
+\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: }
+     }
+}
+\cs_new_protected:Npn \tag_socket_use:n #1 { }
+\cs_new_protected:Npn \tag_socket_use:nn #1#2 { }
+\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
+         }
+         \ERRORusetaggingsocket  % that should get a proper error message
+}
+\ExplSyntaxOff
+\NewSocket{tagsupport/tbl/cell/begin}{0}
+\NewSocket{tagsupport/tbl/cell/end}{0}
+\NewSocket{tagsupport/tbl/row/begin}{0}
+\NewSocket{tagsupport/tbl/row/end}{0}
+\NewSocket{tagsupport/tbl/pcell/begin}{0}
+\NewSocket{tagsupport/tbl/pcell/end}{0}
+\NewSocket{tagsupport/tbl/init}{0}
+\NewSocket{tagsupport/tbl/finalize}{0}
+
+\NewSocket{tagsupport/tbl/colspan}{1}
+
+\NewSocket{tagsupport/tbl/hmode/begin}{0}
+\NewSocket{tagsupport/tbl/hmode/end}{0}
+\NewSocket{tagsupport/tbl/vmode/begin}{0}
+\NewSocket{tagsupport/tbl/vmode/end}{0}
+\NewSocket{tagsupport/tbl/longtable/init}{0}
+\NewSocket{tagsupport/tbl/longtable/finalize}{0}
+\NewSocket{tagsupport/tbl/longtable/head}{0}
+\NewSocket{tagsupport/tbl/longtable/foot}{0}
+\ExplSyntaxOn
+\int_new:N \g__tbl_col_int
+\int_new:N \g__tbl_row_int
+\tl_new:N  \g__tbl_span_tl
+\tl_new:N  \g__tbl_table_cols_tl
+
+\tl_gset:Nn \g__tbl_span_tl {1}
+\tl_gset:Nn \g__tbl_table_cols_tl {0}  % indicates outer level
+\tl_new:N \l__tbl_saved_col_tl
+\tl_new:N \l__tbl_saved_row_tl
+\tl_new:N \l__tbl_saved_span_tl
+\tl_new:N \l__tbl_saved_table_cols_tl
+
+\tl_set:Nn \l__tbl_saved_col_tl{0}
+\tl_set:Nn \l__tbl_saved_row_tl{0}
+\tl_set:Nn \l__tbl_saved_span_tl{1}
+\tl_set:Nn \l__tbl_saved_table_cols_tl{0}  % indicates outer level
+\int_new:N \g__tbl_missing_cells_int
+\def\DebugTablesOn{
+  \cs_set_eq:NN \__tbl_trace:n \typeout
+}
+\def\DebugTablesOff{
+  \cs_set_eq:NN \__tbl_trace:n \use_none:n
+}
+\cs_new_eq:NN \__tbl_trace:n \use_none:n
+\cs_new_protected:Npn \tbl_update_cell_data: {
+        \int_gadd:Nn \g__tbl_col_int { \g__tbl_span_tl }
+        \tl_gset:Nn  \g__tbl_span_tl {1}
+}
+\cs_new:Npn \tbl_count_table_cols:  {
+  \seq_set_split:NnV\l__tbl_tmpa_seq {&}\@preamble
+  \tl_gset:Ne \g__tbl_table_cols_tl { \seq_count:N \l__tbl_tmpa_seq }
+  \__tbl_trace:n { ==>~ Table~ has~ \g__tbl_table_cols_tl \space columns }
+}
+\seq_new:N \l__tbl_tmpa_seq
+\cs_new:Npn \tbl_count_missing_cells:n #1 {
+  \tag_if_active:T {
+    \int_compare:nNnT \g__tbl_col_int > 0
+      {
+        \int_gset:Nn \g__tbl_missing_cells_int
+            {
+              \g__tbl_table_cols_tl
+            - \g__tbl_col_int
+            - \g__tbl_span_tl
+            + 1
+            }
+        \int_compare:nNnT \g__tbl_missing_cells_int < 0 \ERRORmissingcells % should not happen
+        \__tbl_trace:n{==>~
+          (#1)~
+          This~ row~ needs~
+          \int_use:N \g__tbl_missing_cells_int \space
+          additional~ cell(s)
+        }
+      }
+  }
+}
+\cs_new_protected:Npn \tbl_save_outer_table_cols: {
+  \tl_set_eq:NN \l__tbl_saved_table_cols_tl  \g__tbl_table_cols_tl
+}
+\cs_new_protected:Npn \tbl_init_cell_data_for_table: {
+  \tl_set:No \l__tbl_saved_col_tl {\int_use:N \g__tbl_col_int }
+  \tl_set:No \l__tbl_saved_row_tl {\int_use:N \g__tbl_row_int }
+  \tl_set_eq:NN \l__tbl_saved_span_tl  \g__tbl_span_tl
+  \__tbl_trace:n { ==>~ saved~cell~data:~
+                \l__tbl_saved_row_tl,
+                \l__tbl_saved_col_tl,
+                \l__tbl_saved_span_tl \space
+                (
+                \int_compare:nNnTF \l__tbl_saved_table_cols_tl = 0
+                    { outer~ level }
+                    { max:~ \l__tbl_saved_table_cols_tl }
+                )
+          }
+  \int_gzero:N \g__tbl_row_int
+  \int_gzero:N \g__tbl_col_int
+  \tl_gset:Nn  \g__tbl_span_tl {1}
+}
+\cs_new_protected:Npn \tbl_update_cell_data_for_next_row: {
+      \int_gincr:N \g__tbl_row_int          % this row about to start
+      \int_gzero:N \g__tbl_col_int          % we are before first col
+}
+\cs_new_protected:Npn \tbl_init_cell_data_for_row: {
+        \int_gset:Nn \g__tbl_col_int {1}
+        \tl_gset:Nn  \g__tbl_span_tl {1}
+}
+\cs_new:Npn \tbl_if_row_was_started:T {
+      \int_compare:nNnT \g__tbl_col_int > 0
+}
+\cs_new:Npn \tbl_if_row_was_started:TF {
+      \int_compare:nNnTF \g__tbl_col_int > 0
+}
+\cs_new_protected:Npn \tbl_gzero_row_count: {
+  \int_gzero:N \g__tbl_row_int
+}
+\cs_new_protected:Npn \tbl_gincr_row_count: {
+  \int_gincr:N \g__tbl_row_int
+}
+\cs_new_protected:Npn \tbl_gdecr_row_count: {
+  \int_gdecr:N \g__tbl_row_int
+}
+\cs_new_protected:Npn \tbl_inbetween_rows: {
+       \int_gzero:N  \g__tbl_col_int
+}
+\cs_new_protected:Npn \tbl_restore_outer_cell_data: {
+  \int_gset:Nn \g__tbl_col_int { \l__tbl_saved_col_tl }
+  \int_gset:Nn \g__tbl_row_int { \l__tbl_saved_row_tl }
+  \tl_gset_eq:NN \g__tbl_span_tl \l__tbl_saved_span_tl
+  \tl_gset_eq:NN \g__tbl_table_cols_tl   \l__tbl_saved_table_cols_tl
+  \__tbl_trace:n { ==>~ restored~cell~data:~
+                \int_use:N \g__tbl_row_int,
+                \int_use:N \g__tbl_col_int,
+                \l__tbl_saved_span_tl \space
+                (
+                \int_compare:nNnTF \g__tbl_table_cols_tl = 0
+                    { outer~ level }
+                    { max:~ \g__tbl_table_cols_tl }
+                )
+              }
+}
+\cs_new_protected:Npn \tbl_update_multicolumn_cell_data:n #1 {
+   \int_compare:nNnTF \g__tbl_col_int = 0
+       {
+         \UseTaggingSocket{tbl/row/begin}
+         \int_gset:Nn \g__tbl_col_int {1}
+       }
+       {
+         \int_gadd:Nn \g__tbl_col_int { \g__tbl_span_tl }
+       }
+   \tl_gset:Nn \g__tbl_span_tl {#1}
+}
+\cs_new:Npn \tbl_crcr:n #1 {
+    \int_compare:nNnT \g__tbl_col_int > 0
+        {
+          \tbl_count_missing_cells:n {#1}
+          \cr
+        }
+}
+\ExplSyntaxOff
+\let\@kernel at refstepcounter\refstepcounter
+\def\hyper at nopatch@longtable{}
 %%% From File: ltfinal.dtx
 \tracingstats1
 \newcount\@lowpenalty

Modified: trunk/Master/texmf-dist/tex/latex/base/latexrelease.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/latexrelease.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/latexrelease.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -16,6 +16,7 @@
 %% lthooks.dtx  (with options: `latexrelease')
 %% ltcmdhooks.dtx  (with options: `latexrelease')
 %% ltsockets.dtx  (with options: `latexrelease')
+%% lttemplates.dtx  (with options: `latexrelease')
 %% ltalloc.dtx  (with options: `latexrelease')
 %% ltcntrl.dtx  (with options: `latexrelease')
 %% lterror.dtx  (with options: `latexrelease')
@@ -292,7 +293,7 @@
 }
 %%% From File: ltvers.dtx
 \edef\latexreleaseversion
-   {2023-11-01}
+   {2024-06-01}
 \newif\if at includeinrelease
 \@includeinreleasefalse
 \def\IncludeInRelease#1{%
@@ -570,25 +571,6 @@
     "luatex",
     tex.extraprimitives("core","omega", "aleph", "luatex")
   )
-  local i
-  local t = { }
-  for _,i in pairs(tex.extraprimitives("luatex")) do
-    if not string.match(i,"^U") then
-      if not string.match(i, "^luatex") then
-        table.insert(t,i)
-      end
-    else
-      if string.match(i,"^Uchar$") then
-        table.insert(t,i)
-      end
-    end
-  end
-  for _,i in pairs(t) do
-    tex.print(
-      "\noexpand\\let\noexpand\\" .. i
-        .. "\noexpand\\undefined"
-    )
-  end
 }
 \EndIncludeInRelease
 \fi
@@ -985,7 +967,7 @@
   \tracinggroups\z@
   \tracingparagraphs\z@
   \tracingmacros\z@
-  \tracinglostchars\@ne
+  \tracinglostchars\tw@
   \tracingpages\z@
   \tracingstats\z@
 }%
@@ -1362,7 +1344,10 @@
 \cs_gset_eq:NN \@expl at cs@to at str@@N \cs_to_str:N
 \cs_gset_eq:NN \@expl at str@if at eq@@nnTF \str_if_eq:nnTF
 \cs_gset_eq:NN \@expl at cs@prefix at spec@@N \cs_prefix_spec:N
-\cs_gset_eq:NN \@expl at cs@argument at spec@@N \cs_argument_spec:N
+\cs_if_exist:NTF \cs_parameter_spec:N
+  { \cs_gset_eq:NN \@expl at cs@parameter at spec@@N \cs_parameter_spec:N }
+  { \cs_gset_eq:NN \@expl at cs@parameter at spec@@N \cs_argument_spec:N }
+\cs_gset_eq:NN \__kernel_cs_parameter_spec:N \@expl at cs@parameter at spec@@N
 \cs_gset_eq:NN \@expl at cs@replacement at spec@@N \cs_replacement_spec:N
 \cs_gset_eq:NN \@expl at str@map at function@@NN \str_map_function:NN
 \cs_gset_eq:NN \@expl at char@generate@@nn \char_generate:nn
@@ -1373,7 +1358,7 @@
 \let \@expl at cs@to at str@@N \@undefined
 \let \@expl at str@if at eq@@nnTF \@undefined
 \let \@expl at cs@prefix at spec@@N \@undefined
-\let \@expl at cs@argument at spec@@N \@undefined
+\let \@expl at cs@parameter at spec@@N \@undefined
 \let \@expl at cs@replacement at spec@@N \@undefined
 \let \@expl at str@map at function@@NN \@undefined
 \EndIncludeInRelease
@@ -1796,7 +1781,7 @@
 \long\def\@show at newcommand@aux#1#2#3{%
   \typeout{> \string#1=\@expl at cs@prefix at spec@@N#1macro:}%
   #3{default \string##1=\expandafter\detokenize\@gobblethree#2.^^J%
-    \@expl at cs@argument at spec@@N#1->\@expl at cs@replacement at spec@@N#1}}
+    \@expl at cs@parameter at spec@@N#1->\@expl at cs@replacement at spec@@N#1}}
 \long\def\@show at tokens#1{%
   \edef\reserved at a{#1}%
   \showtokens\expandafter
@@ -1844,7 +1829,7 @@
   \@show at environment@end#1}
 \long\def\@show at environment@begin#1{%
   \typeout{> \string\begin{\@expl at cs@to at str@@N#1}=environment:}%
-  \typeout{\@expl at cs@argument at spec@@N#1->%
+  \typeout{\@expl at cs@parameter at spec@@N#1->%
            \@expl at cs@replacement at spec@@N#1.^^J}}
 \long\def\@show at normalenv#1{%
   \@show at environment@begin#1%
@@ -1855,12 +1840,12 @@
 \long\def\@show at environment@end at aux#1#2{%
   \@show at tokens{\string\end{\@expl at cs@to at str@@N#2}%
     \ifx\relax#1=undefined%
-    \else:^^J\@expl at cs@argument at spec@@N#1->%
+    \else:^^J\@expl at cs@parameter at spec@@N#1->%
              \@expl at cs@replacement at spec@@N#1%
     \fi}}
 \def\@show at nonstop#1{%
   \typeout{> \string#1=\@expl at cs@prefix at spec@@N#1macro:^^J%
-   \@expl at cs@argument at spec@@N#1->\@expl at cs@replacement at spec@@N#1.}}
+   \@expl at cs@parameter at spec@@N#1->\@expl at cs@replacement at spec@@N#1.}}
 \def\@show at typeout#1{\typeout{> #1.^^J}}
 \EndIncludeInRelease
 \IncludeInRelease{0000-00-00}{\ShowEnvironment}
@@ -1997,8 +1982,8 @@
 
 \EndIncludeInRelease
 %%% From File: ltcmd.dtx
-\def\ltcmdversion{v1.2a}
-\def\ltcmddate{2023-08-19}
+\def\ltcmdversion{v1.2e}
+\def\ltcmddate{2024-04-17}
 \edef\@latexrelease at catcode@null{\the\catcode`\^^@ }
 \catcode`\^^@=12
 \ExplSyntaxOn
@@ -2082,8 +2067,6 @@
 \cs_new_protected:Npn \__cmd_declare_cmd_internal:Nnnn #1#2#3#4
   {
     \tl_set:Nx \l__cmd_function_tl { \cs_to_str:N #1 }
-    \tl_set:Nx \l__cmd_fn_tl
-      { \exp_not:c { \l__cmd_function_tl \c_space_tl } }
     \__cmd_normalize_arg_spec:n {#2}
     \exp_args:No \__cmd_prepare_signature:n \l__cmd_arg_spec_tl
     \__cmd_declare_cmd_code:Nnn #1 {#2} {#3}
@@ -2091,12 +2074,60 @@
     \__cmd_break_point:n {#2}
   }
 \cs_new_eq:NN \__cmd_break_point:n \use_none:n
-\cs_new_protected:Npn \__cmd_declare_cmd_code:Nnn
+\cs_new:Npn \__cmd_all_m_check:n #1
+  { \tl_map_function:nN {#1} \__cmd_all_m_check_aux:n }
+\cs_new:Npn \__cmd_all_m_check_aux:n #1
   {
-    \bool_if:NTF \l__cmd_grab_expandably_bool
-      { \__cmd_declare_cmd_code_expandable:Nnn }
-      { \__cmd_declare_cmd_code_aux:Nnn }
+    \str_if_eq:nnF {#1} { m }
+      {
+        \str_if_eq:nnF {#1} { + }
+          { X }
+      }
+  }
+\cs_new_protected:Npn \__cmd_declare_cmd_code:Nnn #1#2
+  {
+    \bool_lazy_any:nTF
+      {
+        { \l__cmd_environment_bool }
+        {
+          \bool_lazy_and_p:nn
+            { \l__cmd_some_short_bool }
+            { \l__cmd_some_long_bool }
+        }
+        { ! \tl_if_blank_p:e { \__cmd_all_m_check:n {#2} } }
+      }
+      {
+        \tl_set:Nx \l__cmd_fn_tl
+          { \exp_not:c { \l__cmd_function_tl \c_space_tl } }
+        \bool_if:NTF \l__cmd_grab_expandably_bool
+          { \__cmd_declare_cmd_code_expandable:Nnn }
+          { \__cmd_declare_cmd_code_aux:Nnn }
+      }
+      { \__cmd_declare_cmd_optimized:Nnn }
+        #1 {#2}
    }
+\cs_new_protected:Npn \__cmd_declare_cmd_optimized:Nnn #1#2#3
+  {
+    \bool_if:NTF \l__cmd_expandable_bool
+      { \cs_set_nopar:Npe }
+      { \cs_set_protected_nopar:Npe }
+        #1
+        {
+          \exp_not:N \__cmd_start_optimized:
+          \exp_not:c { \l__cmd_function_tl \c_space_tl code }
+        }
+    \exp_args:Ncc \cs_generate_from_arg_count:NNnn
+      { \l__cmd_function_tl \c_space_tl code }
+      {
+        cs_set
+        \bool_if:NF \l__cmd_expandable_bool { _protected }
+        \bool_if:NF \l__cmd_some_long_bool { _nopar }
+        :Npn
+      }
+      \l__cmd_current_arg_int
+      {#3}
+  }
+\cs_new:Npn \__cmd_start_optimized: { }
 \cs_new_protected:Npn \__cmd_declare_cmd_code_aux:Nnn #1#2#3
   {
     \cs_generate_from_arg_count:cNnn
@@ -2698,7 +2729,12 @@
     \bool_if:NT \l__cmd_some_obey_spaces_bool
       {
         \msg_error:nnxx { cmd } { invalid-bang }
-          { \__cmd_environment_or_command: } { \tl_to_str:n {#1} }
+          { \__cmd_environment_or_command: }
+          {
+            \bool_if:NTF \l__cmd_obey_spaces_bool
+              { \tl_to_str:n {'#1'} }
+              { an~optional~argument~before~mandatory~ \tl_to_str:n {'#1'} }
+          }
         \__cmd_bad_def:wn
       }
     \tl_clear:N \l__cmd_last_delimiters_tl
@@ -3022,9 +3058,10 @@
     \use:x
       {
         \int_set:Nn \tex_escapechar:D { 92 }
-        \exp_not:N \__cmd_cmd_type_cases:NnnnnF \exp_not:N #2
+        \exp_not:N \__cmd_cmd_type_cases:NnnnnnF \exp_not:N #2
           { \__cmd_copy_command:nnNN }
           { \__cmd_copy_expandable:nnNN }
+          { \__cmd_copy_optimized:nnNN }
           { \__cmd_copy_environment:nnNN }
           { \__cmd_copy_environment_end:nnNN }
           { \__cmd_cant_copy:nwn { non-ltcmd } }
@@ -3100,6 +3137,18 @@
 \IncludeInRelease{2020/10/01}{\__cmd_copy_expandable:nnNN}%
   {Support~\NewCommandCopy~in~ltcmd}
 \EndIncludeInRelease
+\cs_new_protected:Npn \__cmd_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 \__cmd_start_optimized:
+          \exp_not:c { #1 ~ code }
+        }
+  }
 \IncludeInRelease{2021/11/15}{\__cmd_copy:NN (part 2)}%
   {Support~\NewCommandCopy~in~ltcmd}
 \cs_new:Npn \__cmd_copy_expandable:NnNNNNnnn #1 #2 #3 #4 #5 #6 #7 #8 #9
@@ -3228,9 +3277,10 @@
     \use:x
       {
         \int_set:Nn \tex_escapechar:D { 92 }
-        \exp_not:N \__cmd_cmd_type_cases:NnnnnF \exp_not:N #1
+        \exp_not:N \__cmd_cmd_type_cases:NnnnnnF \exp_not:N #1
           { \__cmd_show_command:N }
           { \__cmd_show_expandable:N }
+          { \__cmd_show_optimized:N }
           { \__cmd_show_environment:N }
           { \__cmd_show_environment_end:N }
           { \__cmd_cant_copy:nwn { non-ltcmd } }
@@ -3284,6 +3334,43 @@
         -> \cs_replacement_spec:N #4
       }
   }
+\cs_new_protected:Npn \__cmd_show_optimized:N #1
+  {
+    \exp_args:Nc \__cmd_show_optimized:NN
+      { \cs_to_str:N #1 \c_space_tl code }
+      #1
+  }
+\cs_new_protected:Npn \__cmd_show_optimized:NN #1#2
+  {
+    \cs_set:Npe \__cmd_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 }
+          }
+          \__cmd_show_optimized_aux:N
+        ->
+        \cs_replacement_spec:N #1
+      }
+  }
+\cs_generate_variant:Nn \tl_count:n { e }
 \cs_new_protected:Npn \__cmd_show_environment:N #1
   {
     \exp_after:wN \__cmd_show_environment:Nnnw #1 \q__cmd
@@ -3850,14 +3937,33 @@
         \__cmd_add_arg:o \c_novalue_tl
       }
   }
+\IncludeInRelease{2024/06/01}{\__cmd_grab_v_aux_put:N}%
+  {Endlines~as~\obeyedline}
 \cs_new_protected:Npn \__cmd_grab_v_aux_put:N #1
   {
     \tl_put_right:Nx \l__cmd_v_arg_tl
       {
         \token_if_active:NTF #1
+          { \exp_not:N #1 }
+          {
+            \int_compare:nNnTF {`#1} = \tex_endlinechar:D
+              { \exp_not:N \obeyedline }
+              { \token_to_str:N #1 }
+          }
+      }
+  }
+\EndIncludeInRelease
+\IncludeInRelease{2020/10/01}{\__cmd_grab_v_aux_put:N}%
+  {Endlines~as~\obeyedline}
+\cs_new_protected:Npn \__cmd_grab_v_aux_put:N #1
+  {
+    \tl_put_right:Nx \l__cmd_v_arg_tl
+      {
+        \token_if_active:NTF #1
           { \exp_not:N #1 } { \token_to_str:N #1 }
       }
   }
+\EndIncludeInRelease
 \cs_new_protected:Npn \__cmd_grab_v_token_if_char:NTF #1
   { \str_if_eq:eeTF { } { \str_tail:n {#1} } }
 \cs_new_protected:Npn \__cmd_add_arg:n #1
@@ -4326,30 +4432,31 @@
     #1 {#2} {#4}
     \__cmd_tl_mapthread_loop:w #1#3 \q_mark
   }
-\cs_new_protected:Npn \__cmd_cmd_type_cases:NnnnnF #1 #2 #3 #4 #5 #6
+\cs_new_protected:Npn \__cmd_cmd_type_cases:NnnnnnF #1 #2 #3 #4 #5 #6 #7
   {
     \exp_args:Ne \str_case_e:nnF
       {
-        \exp_args:Nf \tl_if_empty:nT { \cs_argument_spec:N #1 }
+        \exp_args:Nf \tl_if_empty:nT { \__kernel_cs_parameter_spec:N #1 }
           { \exp_not:N \exp_not:n { \exp_not:e { \tl_head:N #1 } } }
       }
       {
         { \exp_not:N \__cmd_start:nNNnnn } {#2}
         { \exp_not:N \__cmd_start_expandable:nNNNNn } {#3}
-        { \exp_not:N \__cmd_start_env:nnnnn } {#4}
+        { \exp_not:N \__cmd_start_optimized: } {#4}
+        { \exp_not:N \__cmd_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_cmd_type_cases:NnnnnF #1
-      { } { } { } { } { \use_iii:nnn }
+    \__cmd_cmd_type_cases:NnnnnnF #1
+      { } { } { } { } { } { \use_iii:nnn }
     \use_i:nn
   }
 \cs_new_protected:Npn \__cmd_peek_nonspace:NTF
@@ -4405,10 +4512,8 @@
     \bool_if:NTF \l__cmd_environment_bool
       { environment ~ ' \l__cmd_environment_str ' }
       {
-        command ~ '
-        \exp_args:Nf \tl_trim_spaces:n
-          { \exp_after:wN \token_to_str:N \l__cmd_fn_tl }
-        '
+        command ~
+          ' \c_backslash_str \tl_to_str:N \l__cmd_function_tl '
       }
   }
 \msg_new:nnnn { cmd } { arg-after-body }
@@ -4500,7 +4605,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__cmd_ignore_def_tl
   }
 \msg_new:nnnn { cmd } { not-definable }
@@ -4809,8 +4914,6 @@
 \catcode`\^^@=\@latexrelease at catcode@null\relax
 
 %%% From File: lthooks.dtx
-\def\lthooksversion{v1.1f}
-\def\lthooksdate{2023/10/02}
 \ExplSyntaxOn
 \NewModuleRelease{2020/10/01}{lthooks}
                  {The~hook~management~system}
@@ -5281,7 +5384,8 @@
         \msg_error:nnnnn { hooks } { set-top-level }
           { for } { SetDefaultHookLabel } {#1}
       }
-      { \exp_args:Nx \__hook_set_default_label:n { \__hook_make_name:n {#1} } }
+      { \exp_args:Nx
+        \__hook_set_default_label:n { \__hook_make_name:n {#1} } }
   }
 \cs_new_protected:Npn \__hook_set_default_label:n #1
   {
@@ -5388,7 +5492,8 @@
 \IncludeInRelease{2020/10/01}{\hook_gput_code:nnn}
                  {Providing~hooks}
 \cs_gset_protected:Npn \hook_gput_code:nnn #1 #2
-  { \__hook_normalize_hook_args:Nnn \__hook_gput_code:nnn {#1} {#2} }
+  { \__hook_normalize_hook_args:Nnn
+        \__hook_gput_code:nnn {#1} {#2} }
 \cs_gset_protected:Npn \__hook_gput_code:nnn #1 #2 #3
   {
     \__hook_if_execute_immediately:nTF {#1}
@@ -5402,7 +5507,8 @@
           {
             \__hook_if_disabled:nTF {#1}
               { \msg_error:nnn { hooks } { hook-disabled } {#1} }
-              { \__hook_try_declaring_generic_hook:nnn {#1} {#2} {#3} }
+              { \__hook_try_declaring_generic_hook:nnn
+                  {#1} {#2} {#3} }
           }
       }
   }
@@ -5414,7 +5520,8 @@
                       \on at line\space <-~ \tl_to_str:n{#3}} }
     \str_if_eq:nnTF {#2} { top-level }
       {
-        \str_if_eq:eeTF { top-level } { \__hook_currname_or_default: }
+        \str_if_eq:eeTF { top-level }
+                        { \__hook_currname_or_default: }
           {
             \__hook_init_structure:n {#1}
             \__hook_tl_gput_right:cn { __hook_toplevel~#1 } {#3}
@@ -5422,7 +5529,8 @@
           { \msg_error:nnn { hooks } { misused-top-level } {#1} }
       }
       {
-        \prop_get:cnNTF { g__hook_#1_code_prop } {#2} \l__hook_return_tl
+        \prop_get:cnNTF
+          { g__hook_#1_code_prop } {#2} \l__hook_return_tl
           {
             \prop_gput:cno { g__hook_#1_code_prop } {#2}
               { \l__hook_return_tl #3 }
@@ -5458,7 +5566,8 @@
     \__hook_init_structure:n {#1}
     \__hook_hook_gput_code_do:nnn {#1} {#2} {#3}
   }
-\IncludeInRelease{2023/06/01}{\__hook_try_declaring_generic_hook:nnn}
+\IncludeInRelease{2023/06/01}
+                 {\__hook_try_declaring_generic_hook:nnn}
                  {Hooks~with~args}
 \cs_new_protected:Npn \__hook_try_declaring_generic_hook:nnn #1
   {
@@ -5475,31 +5584,38 @@
         {#1}
   }
 \EndIncludeInRelease
-\IncludeInRelease{2021/11/15}{\__hook_try_declaring_generic_hook:nnn}
+\IncludeInRelease{2021/11/15}
+                 {\__hook_try_declaring_generic_hook:nnn}
                  {Standardise~generic~hook~names}
 \cs_gset_protected:Npn \__hook_try_declaring_generic_hook:nnn #1
   {
-    \__hook_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1}
+    \__hook_try_declaring_generic_hook:wnTF #1 / / / \scan_stop:
+      {#1}
       \hook_gput_code:nnn
       \__hook_gput_undeclared_hook:nnn
         {#1}
   }
-\cs_gset_protected:Npn \__hook_try_declaring_generic_next_hook:nn #1
+\cs_gset_protected:Npn
+  \__hook_try_declaring_generic_next_hook:nn #1
   {
-    \__hook_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1}
+    \__hook_try_declaring_generic_hook:wnTF #1 / / / \scan_stop:
+      {#1}
       \hook_gput_next_code:nn
       \__hook_gput_next_do:nn
         {#1}
   }
 \EndIncludeInRelease
-\IncludeInRelease{2020/10/01}{\__hook_try_declaring_generic_hook:nnn}
+\IncludeInRelease{2020/10/01}
+                 {\__hook_try_declaring_generic_hook:nnn}
                  {Standardise~generic~hook~names}
-\cs_new_protected:Npn \__hook_try_declaring_generic_hook:nnn #1
+\cs_new_protected:Npn
+  \__hook_try_declaring_generic_hook:nnn #1
   {
     \__hook_try_declaring_generic_hook:nNNnn {#1}
       \hook_gput_code:nnn \__hook_gput_undeclared_hook:nnn
   }
-\cs_new_protected:Npn \__hook_try_declaring_generic_next_hook:nn #1
+\cs_new_protected:Npn
+  \__hook_try_declaring_generic_next_hook:nn #1
   {
     \__hook_try_declaring_generic_hook:nNNnn {#1}
       \hook_gput_next_code:nn \__hook_gput_next_do:nn
@@ -5506,23 +5622,28 @@
   }
 \cs_new_protected:Npn \__hook_try_declaring_generic_hook:nNNnn #1
   {
-    \__hook_if_file_hook:wTF #1 / \s__hook_mark
+    \__hook_if_file_hook:wTF #1 / / \s__hook_mark
       {
-        \exp_args:Ne \__hook_try_declaring_generic_hook_split:nNNnn
+        \exp_args:Ne
+        \__hook_try_declaring_generic_hook_split:nNNnn
           { \exp_args:Ne \__hook_file_hook_normalize:n {#1} }
       }
       { \__hook_try_declaring_generic_hook_split:nNNnn {#1} }
   }
-\cs_new_protected:Npn \__hook_try_declaring_generic_hook_split:nNNnn #1 #2 #3
+\cs_new_protected:Npn
+    \__hook_try_declaring_generic_hook_split:nNNnn #1 #2 #3
   {
-    \__hook_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1}
+    \__hook_try_declaring_generic_hook:wnTF #1 / / / \scan_stop:
+      {#1}
       { #2 }
       { #3 } {#1}
   }
 \EndIncludeInRelease
-\IncludeInRelease{2023/06/01}{\__hook_try_declaring_generic_hook:wn}
+\IncludeInRelease{2023/06/01}
+                 {\__hook_try_declaring_generic_hook:wn}
                  {Hooks~with~args}
-\prg_new_protected_conditional:Npnn \__hook_try_declaring_generic_hook:wn
+\prg_new_protected_conditional:Npnn
+    \__hook_try_declaring_generic_hook:wn
     #1 / #2 / #3 / #4 \scan_stop: #5 { TF }
   {
     \__hook_if_generic:nTF {#5}
@@ -5576,9 +5697,11 @@
       #1 #2 { #3 / #5 / #4 }
   }
 \EndIncludeInRelease
-\IncludeInRelease{2021/11/15}{\__hook_try_declaring_generic_hook:wn}
+\IncludeInRelease{2021/11/15}
+                 {\__hook_try_declaring_generic_hook:wn}
                  {Standardise~generic~hook~names}
-\prg_new_protected_conditional:Npnn \__hook_try_declaring_generic_hook:wn
+\prg_new_protected_conditional:Npnn
+    \__hook_try_declaring_generic_hook:wn
     #1 / #2 / #3 / #4 \scan_stop: #5 { TF }
   {
     \__hook_if_generic:nTF {#5}
@@ -5604,9 +5727,11 @@
       }
   }
 \EndIncludeInRelease
-\IncludeInRelease{2021/06/01}{\__hook_try_declaring_generic_hook:wn}
+\IncludeInRelease{2021/06/01}
+                 {\__hook_try_declaring_generic_hook:wn}
                  {Support~cmd~hooks}
-\prg_new_protected_conditional:Npnn \__hook_try_declaring_generic_hook:wn
+\prg_new_protected_conditional:Npnn
+    \__hook_try_declaring_generic_hook:wn
     #1 / #2 / #3 / #4 \scan_stop: #5 { TF }
   {
     \tl_if_empty:nTF {#2}
@@ -5620,10 +5745,12 @@
                   { \__hook_try_put_cmd_hook:n {#5} }
                 \__hook_make_usable:n {#5}
               }
-            \prop_if_in:NnTF \c__hook_generics_reversed_ii_prop {#2}
+            \prop_if_in:NnTF
+              \c__hook_generics_reversed_ii_prop {#2}
               { \tl_gset:cn { g__hook_#5_reversed_tl } { - } }
               {
-                \prop_if_in:NnT \c__hook_generics_reversed_iii_prop {#3}
+                \prop_if_in:NnT
+                  \c__hook_generics_reversed_iii_prop {#3}
                   { \tl_gset:cn { g__hook_#5_reversed_tl } { - } }
               }
             \prg_return_true:
@@ -5632,9 +5759,11 @@
       }
   }
 \EndIncludeInRelease
-\IncludeInRelease{2020/10/01}{\__hook_try_declaring_generic_hook:wn}
+\IncludeInRelease{2020/10/01}
+                 {\__hook_try_declaring_generic_hook:wn}
                  {Support~cmd~hooks}
-\prg_new_protected_conditional:Npnn \__hook_try_declaring_generic_hook:wn
+\prg_new_protected_conditional:Npnn
+    \__hook_try_declaring_generic_hook:wn
     #1 / #2 / #3 / #4 \scan_stop: #5 { TF }
   {
     \tl_if_empty:nTF {#2}
@@ -5643,10 +5772,12 @@
         \prop_if_in:NnTF \c__hook_generics_prop {#1}
           {
             \__hook_if_declared:nF {#5} { \hook_new:n {#5} }
-            \prop_if_in:NnTF \c__hook_generics_reversed_ii_prop {#2}
+            \prop_if_in:NnTF
+              \c__hook_generics_reversed_ii_prop {#2}
               { \tl_gset:cn { g__hook_#5_reversed_tl } { - } }
               {
-                \prop_if_in:NnT \c__hook_generics_reversed_iii_prop {#3}
+                \prop_if_in:NnT
+                  \c__hook_generics_reversed_iii_prop {#3}
                   { \tl_gset:cn { g__hook_#5_reversed_tl } { - } }
               }
             \prg_return_true:
@@ -5687,11 +5818,11 @@
   { \__hook_strip_double_slash:n {#1} }
 \cs_new:Npn \__hook_strip_double_slash:n #1
   { \__hook_strip_double_slash:w #1 // \s__hook_mark }
-\cs_new:Npn \__hook_strip_double_slash:w #1/#2/#3 // #4 \s__hook_mark
+\cs_new:Npn \__hook_strip_double_slash:w #1/#2/#3//#4\s__hook_mark
   {
     \tl_if_empty:nTF {#4}
       { #1/#2/#3 }
-      { \__hook_strip_double_slash:w #1/#2/#3 / #4 \s__hook_mark }
+      { \__hook_strip_double_slash:w #1/#2/#3 /#4\s__hook_mark }
   }
 \EndIncludeInRelease
 \IncludeInRelease{2021/11/15}{\c__hook_generics_prop}
@@ -5722,9 +5853,12 @@
 \EndIncludeInRelease
 \IncludeInRelease{2020/10/01}{\c__hook_generics_reversed_ii_prop}
                  {Standardise~generic~hook~names}
-\prop_const_from_keyval:Nn \c__hook_generics_reversed_ii_prop {after=,end=}
-\prop_const_from_keyval:Nn \c__hook_generics_reversed_iii_prop {after=}
-\prop_const_from_keyval:Nn \c__hook_generics_file_prop {before=,after=}
+\prop_const_from_keyval:Nn
+    \c__hook_generics_reversed_ii_prop {after=,end=}
+\prop_const_from_keyval:Nn
+    \c__hook_generics_reversed_iii_prop {after=}
+\prop_const_from_keyval:Nn
+    \c__hook_generics_file_prop {before=,after=}
 \EndIncludeInRelease
 \IncludeInRelease{2023/06/01}{\c__hook_parameter_cmd/./before_tl}
                  {Hooks~with~args}
@@ -5752,7 +5886,8 @@
             \str_if_eq:nnTF {#2} { top-level }
               { \__hook_toplevel_gset:nn {#1} { } }
               {
-                \prop_gpop:cnNF { g__hook_#1_code_prop } {#2} \l__hook_return_tl
+                \prop_gpop:cnNF { g__hook_#1_code_prop }
+                  {#2} \l__hook_return_tl
                   { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} }
               }
           }
@@ -5763,7 +5898,8 @@
         \__hook_if_deprecated_generic:nTF {#1}
           {
             \__hook_deprecated_generic_warn:n {#1}
-            \__hook_do_deprecated_generic:Nn \__hook_gremove_code:nn {#1} {#2}
+            \__hook_do_deprecated_generic:Nn
+                \__hook_gremove_code:nn {#1} {#2}
           }
           { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} }
       }
@@ -5785,8 +5921,10 @@
             \str_if_eq:nnTF {#2} { top-level }
               { \__hook_tl_gclear:c { __hook_toplevel~#1 } }
               {
-                \prop_gpop:cnNF { g__hook_#1_code_prop } {#2} \l__hook_return_tl
-                  { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} }
+                \prop_gpop:cnNF { g__hook_#1_code_prop }
+                  {#2} \l__hook_return_tl
+                  { \msg_warning:nnnn { hooks } { cannot-remove }
+                                      {#1} {#2} }
               }
           }
         \__hook_if_usable:nT {#1}
@@ -5796,9 +5934,11 @@
         \__hook_if_deprecated_generic:nTF {#1}
           {
             \__hook_deprecated_generic_warn:n {#1}
-            \__hook_do_deprecated_generic:Nn \__hook_gremove_code:nn {#1} {#2}
+            \__hook_do_deprecated_generic:Nn
+                \__hook_gremove_code:nn {#1} {#2}
           }
-          { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} }
+          { \msg_warning:nnnn { hooks } { cannot-remove }
+                              {#1} {#2} }
       }
   }
 \EndIncludeInRelease
@@ -5817,7 +5957,8 @@
         {#1} {#2}
   }
 \cs_new_protected:Npn \__hook_cs_gput_right_fast:nnn #1 #2 #3
-  { \cs_gset:cpx { __hook#1~#2 } { \exp_not:v { __hook#1~#2 } \exp_not:n {#3} } }
+  { \cs_gset:cpx { __hook#1~#2 }
+      { \exp_not:v { __hook#1~#2 } \exp_not:n {#3} } }
 \cs_new_protected:Npn \__hook_cs_gput_right_slow:nnn #1 #2 #3
   {
     \cs_if_exist:cF { __hook#1~#2 }
@@ -5928,7 +6069,8 @@
         }
     \exp_last_unbraced:NNf
     \cs_set:Npn \__hook_tmp:w { \__hook_parameter:n {#1} } { }
-    \tl_set:Ne \l__hook_tmpa_tl { \__hook_braced_cs_parameter:n { __hook_tmp:w } }
+    \tl_set:Ne \l__hook_tmpa_tl
+      { \__hook_braced_cs_parameter:n { __hook_tmp:w } }
     \cs_gset_protected:Npx \__hook_normalise_fn:nn ##1 ##2
       {
         \group_begin:
@@ -6114,8 +6256,8 @@
     \__hook_if_deprecated_generic:nT {#1}
       {
         \__hook_deprecated_generic_warn:n {#1}
-        \__hook_do_deprecated_generic:Nn \__hook_gset_rule:nnnn {#1}
-          {#2} {#3} {#4}
+        \__hook_do_deprecated_generic:Nn \__hook_gset_rule:nnnn
+          {#1} {#2} {#3} {#4}
         \exp_after:wN \use_none:nnnnnnnnn \use_none:n
       }
     \__hook_init_structure:n {#1}
@@ -6133,27 +6275,34 @@
 \EndIncludeInRelease
 \cs_new_protected:Npn \__hook_rule_before_gset:nnn #1#2#3
   {
-    \__hook_tl_gset:cx { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl }
+    \__hook_tl_gset:cx
+      { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl }
       { \__hook_label_ordered:nnTF {#2} {#3} { < } { > } }
   }
 \cs_new_eq:cN { __hook_rule_<_gset:nnn } \__hook_rule_before_gset:nnn
 \cs_new_protected:Npn \__hook_rule_after_gset:nnn #1#2#3
   {
-    \__hook_tl_gset:cx { g__hook_#1_rule_ \__hook_label_pair:nn {#3} {#2} _tl }
+    \__hook_tl_gset:cx
+      { g__hook_#1_rule_ \__hook_label_pair:nn {#3} {#2} _tl }
       { \__hook_label_ordered:nnTF {#3} {#2} { < } { > } }
   }
 \cs_new_eq:cN { __hook_rule_>_gset:nnn } \__hook_rule_after_gset:nnn
 \cs_new_protected:Npn \__hook_rule_voids_gset:nnn #1#2#3
   {
-    \__hook_tl_gset:cx { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl }
+    \__hook_tl_gset:cx
+      { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl }
       { \__hook_label_ordered:nnTF {#2} {#3} { -> } { <- } }
   }
 \cs_new_protected:cpn { __hook_rule_incompatible-error_gset:nnn } #1#2#3
-  { \__hook_tl_gset:cn { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl }
-                   { xE } }
+  { \__hook_tl_gset:cn
+      { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl }
+      { xE }
+  }
 \cs_new_protected:cpn { __hook_rule_incompatible-warning_gset:nnn } #1#2#3
-  { \__hook_tl_gset:cn { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl }
-                   { xW } }
+  { \__hook_tl_gset:cn
+      { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl }
+      { xW }
+  }
 \cs_new_protected:Npn \__hook_rule_unrelated_gset:nnn #1#2#3 { }
 \cs_new_protected:Npn \__hook_rule_gclear:nnn #1#2#3
   { \cs_undefine:c { g__hook_#1_rule_ \__hook_label_pair:nn {#2} {#3} _tl } }
@@ -6211,7 +6360,8 @@
                  {Hooks~with~args}
 \cs_gset_protected:Npn \__hook_initialize_all:
   {
-    \cs_gset_eq:NN \__hook_update_hook_code:n \__hook_initialize_hook_code:n
+    \cs_gset_eq:NN \__hook_update_hook_code:n
+                   \__hook_initialize_hook_code:n
     \__hook_debug:n { \prop_gclear:N \g__hook_used_prop }
     \seq_map_inline:Nn \g__hook_all_seq
       { \__hook_update_hook_code:n {##1} }
@@ -6221,7 +6371,8 @@
         \prop_map_inline:Nn \g__hook_used_prop
           {
             \iow_term:x
-              { ^^J ~ ##1 ~ -> ~ \cs_replacement_spec:c { __hook~##1 } ~ }
+              { ^^J ~ ##1 ~ -> ~
+                \cs_replacement_spec:c { __hook~##1 } ~ }
           }
       }
     \cs_gset_eq:NN \hook_use:n \__hook_use_initialized:n
@@ -6243,8 +6394,10 @@
           {
             \__hook_code_gset:ne {#1}
               {
-                \exp_not:c { __hook_toplevel~#1 } \__hook_braced_parameter:n {#1}
-                \exp_not:c { __hook_next~#1 } \__hook_braced_parameter:n {#1}
+                \exp_not:c { __hook_toplevel~#1 }
+                \__hook_braced_parameter:n {#1}
+                \exp_not:c { __hook_next~#1 }
+                \__hook_braced_parameter:n {#1}
               }
           }
           {
@@ -6267,7 +6420,8 @@
 \cs_gset_protected:Npn \__hook_initialize_hook_code:n #1
   {
     \__hook_debug:n
-      { \iow_term:x { ^^J Update~code~for~hook~'#1' \on at line :^^J } }
+      { \iow_term:x { ^^J Update~code~for~hook~'#1'
+                      \on at line :^^J } }
     \__hook_include_legacy_code_chunk:n {#1}
     \__hook_if_usable:nT {#1}
       {
@@ -6281,15 +6435,21 @@
           }
           {
             \__hook_if_reversed:nTF {#1}
-              { \cs_set_eq:NN \__hook_tl_gput:Nn    \__hook_tl_gput_left:Nn
-                \cs_set_eq:NN \__hook_clist_gput:NV \clist_gput_left:NV  }
-              { \cs_set_eq:NN \__hook_tl_gput:Nn    \__hook_tl_gput_right:Nn
-                \cs_set_eq:NN \__hook_clist_gput:NV \clist_gput_right:NV }
-            \prop_set_eq:Nc \l__hook_work_prop { g__hook_#1_code_prop }
+              { \cs_set_eq:NN \__hook_tl_gput:Nn
+                              \__hook_tl_gput_left:Nn
+                \cs_set_eq:NN \__hook_clist_gput:NV
+                              \clist_gput_left:NV  }
+              { \cs_set_eq:NN \__hook_tl_gput:Nn
+                              \__hook_tl_gput_right:Nn
+                \cs_set_eq:NN \__hook_clist_gput:NV
+                              \clist_gput_right:NV }
+            \prop_set_eq:Nc \l__hook_work_prop
+              { g__hook_#1_code_prop }
             \__hook_initialize_single:ccn
               { __hook~#1 } { g__hook_#1_labels_clist } {#1}
             \__hook_debug:n
-              { \exp_args:NNx \prop_gput:Nnn \g__hook_used_prop {#1} { } }
+              { \exp_args:NNx \prop_gput:Nnn \g__hook_used_prop
+                    {#1} { } }
           }
       }
   }
@@ -6356,7 +6516,8 @@
             \int_compare:nNnT
                 { \cs:w \__hook_tl_csname:n {##1} \cs_end: } = 0
                 {
-                  \tl_set:cn { \__hook_tl_csname:n { \l__hook_rear_tl } } {##1}
+                  \tl_set:cn
+                    { \__hook_tl_csname:n { \l__hook_rear_tl } } {##1}
                   \tl_set:Nn \l__hook_rear_tl            {##1}
                 }
           }
@@ -6407,42 +6568,50 @@
                   {#3}
           }
       }
-    \__hook_debug:n { \__hook_debug_label_data:N \l__hook_work_prop }
+    \__hook_debug:n
+      { \__hook_debug_label_data:N \l__hook_work_prop }
     \tl_set:Nn \l__hook_rear_tl { 0 }
     \tl_set:cn { \__hook_tl_csname:n { 0 } } { 0 }
     \seq_map_inline:Nn \l__hook_labels_seq
       {
-        \int_compare:nNnT { \cs:w \__hook_tl_csname:n {##1} \cs_end: } = 0
-            {
-              \tl_set:cn { \__hook_tl_csname:n { \l__hook_rear_tl } }{##1}
-              \tl_set:Nn \l__hook_rear_tl {##1}
-            }
+        \int_compare:nNnT
+          { \cs:w \__hook_tl_csname:n {##1} \cs_end: } = 0
+          {
+            \tl_set:cn { \__hook_tl_csname:n
+                           { \l__hook_rear_tl } } {##1}
+            \tl_set:Nn \l__hook_rear_tl           {##1}
+          }
       }
     \tl_set_eq:Nc \l__hook_front_tl { \__hook_tl_csname:n { 0 } }
     \__hook_tl_gclear:N #1
     \clist_gclear:N #2
-    \bool_while_do:nn { ! \str_if_eq_p:Vn \l__hook_front_tl { 0 } }
+    \bool_while_do:nn
+      { ! \str_if_eq_p:Vn \l__hook_front_tl { 0 } }
       {
         \int_decr:N \l__hook_labels_int
-        \prop_get:NVN \l__hook_work_prop \l__hook_front_tl \l__hook_return_tl
+        \prop_get:NVN \l__hook_work_prop
+            \l__hook_front_tl \l__hook_return_tl
         \exp_args:NNV \__hook_tl_gput:Nn #1 \l__hook_return_tl
         \__hook_clist_gput:NV #2 \l__hook_front_tl
-        \__hook_debug:n{ \iow_term:x{Handled~ code~ for~ \l__hook_front_tl} }
-        \seq_map_inline:cn { \__hook_seq_csname:n { \l__hook_front_tl } }
+        \__hook_debug:n{ \iow_term:x
+              {Handled~ code~ for~ \l__hook_front_tl} }
+        \seq_map_inline:cn
+              { \__hook_seq_csname:n { \l__hook_front_tl } }
           {
             \tl_set:cx { \__hook_tl_csname:n {##1} }
-                       { \int_eval:n
-                           { \cs:w \__hook_tl_csname:n {##1} \cs_end: - 1 }
-                       }
+              { \int_eval:n
+                { \cs:w \__hook_tl_csname:n {##1} \cs_end: - 1 }
+              }
             \int_compare:nNnT
-                { \cs:w \__hook_tl_csname:n {##1} \cs_end: } = 0
-                {
-                  \tl_set:cn { \__hook_tl_csname:n { \l__hook_rear_tl } } {##1}
-                  \tl_set:Nn \l__hook_rear_tl            {##1}
-                }
+              { \cs:w \__hook_tl_csname:n {##1} \cs_end: } = 0
+              {
+                \tl_set:cn { \__hook_tl_csname:n
+                               { \l__hook_rear_tl } } {##1}
+                \tl_set:Nn \l__hook_rear_tl           {##1}
+              }
           }
         \tl_set_eq:Nc \l__hook_front_tl
-                      { \__hook_tl_csname:n { \l__hook_front_tl } }
+          { \__hook_tl_csname:n { \l__hook_front_tl } }
       }
     \int_compare:nNnF \l__hook_labels_int = 0
       {
@@ -6451,7 +6620,8 @@
         \__hook_debug_label_data:N \l__hook_work_prop
         \iow_term:x{====================}
       }
-    \exp_args:NNo \__hook_tl_gput:Nn #1 { \cs:w __hook_toplevel~#3 \cs_end: }
+    \exp_args:NNo \__hook_tl_gput:Nn #1
+                    { \cs:w __hook_toplevel~#3 \cs_end: }
     \__hook_tl_gput_right:No #1 { \cs:w __hook_next~#3 \cs_end: }
   }
 \cs_generate_variant:Nn \__hook_tl_gput_right:Nn { No }
@@ -6588,7 +6758,7 @@
         hook~'#1'
         \__hook_if_disabled:nF {#1}
           {
-            \exp_args:Nf \__hook_print_args:nn {#1}
+            \exp_args:Nne \__hook_print_args:nn {#1}
               {
                 \int_eval:n
                   { \str_count:e { \__hook_parameter:n {#1} } / 3 }
@@ -6697,7 +6867,8 @@
       }
     \__hook_preamble_hook:n {#1}
     \__hook_log_cmd:x
-      { ^^J ->~The~ \__hook_if_generic:nT {#1} { generic~ } hook~'#1': }
+      { ^^J ->~The~ \__hook_if_generic:nT
+                      {#1} { generic~ } hook~'#1': }
     \__hook_if_usable:nF {#1}
       { \__hook_log_line:x { The~hook~is~not~declared. } }
     \__hook_if_disabled:nT {#1}
@@ -6710,19 +6881,22 @@
           { \__hook_log_line_indent:x { --- } }
           {
             \prop_map_inline:cn { g__hook_#1_code_prop }
-              { \__hook_log_line_indent:x { ##1~->~\tl_to_str:n {##2} } }
+              { \__hook_log_line_indent:x
+                  { ##1~->~\tl_to_str:n {##2} } }
           }
         \__hook_log_line:x
           {
             Document-level~(top-level)~code
             \__hook_if_usable:nT {#1}
-              { ~(executed~\__hook_if_reversed:nTF {#1} {first} {last} ) } :
+              { ~(executed~
+                \__hook_if_reversed:nTF {#1} {first} {last} ) } :
           }
         \__hook_log_line_indent:x
           {
             \tl_if_empty:cTF { __hook_toplevel~#1 }
               { --- }
-              { -> ~ \exp_args:Nv \tl_to_str:n { __hook_toplevel~#1 } }
+              { -> ~ \exp_args:Nv \tl_to_str:n
+                                  { __hook_toplevel~#1 } }
           }
         \__hook_log_line:x { Extra~code~for~next~invocation: }
         \__hook_log_line_indent:x
@@ -6729,7 +6903,8 @@
           {
             \tl_if_empty:cTF { __hook_next~#1 }
               { --- }
-              { ->~ \exp_args:Nv \__hook_log_next_code:n { __hook_next~#1 } }
+              { ->~ \exp_args:Nv \__hook_log_next_code:n
+                                   { __hook_next~#1 } }
           }
         \__hook_log_line:x { Rules: }
         \bool_set_true:N \l__hook_tmpa_bool
@@ -6753,7 +6928,8 @@
               {
                 Execution~order
                 \bool_if:NTF \l__hook_tmpa_bool
-                  { \__hook_if_reversed:nT {#1} { ~(after~reversal) } }
+                  { \__hook_if_reversed:nT
+                       {#1}{ ~(after~reversal) } }
                   { ~(after~
                     \__hook_if_reversed:nT {#1} { reversal~and~ }
                     applying~rules)
@@ -6764,7 +6940,8 @@
                 \@spaces
                 \clist_if_empty:cTF { g__hook_#1_labels_clist }
                   { --- }
-                  { \clist_use:cn { g__hook_#1_labels_clist } { ,~ } }
+                  { \clist_use:cn
+                      { g__hook_#1_labels_clist } { ,~ } }
               }
           }
           {
@@ -6771,9 +6948,11 @@
             \__hook_log_line:x { Execution~order: }
             #2
               {
-                \@spaces Not~set~because~the~hook~ \__hook_if_usable:nTF {#1}
+                \@spaces Not~set~because~the~hook~
+                    \__hook_if_usable:nTF {#1}
                   { code~pool~is~empty }
-                  { is~\__hook_if_disabled:nTF {#1} {disabled} {undeclared} }
+                  { is~\__hook_if_disabled:nTF
+                      {#1} {disabled} {undeclared} }
               }
           }
       }
@@ -6863,7 +7042,8 @@
 \IncludeInRelease{2020/10/01}{\hook_gput_next_code:nn}
                  {Hooks~with~args}
 \cs_gset_protected:Npn \hook_gput_next_code:nn #1
-  { \__hook_normalize_hook_args:Nn \__hook_gput_next_code:nn {#1} }
+  { \__hook_normalize_hook_args:Nn
+        \__hook_gput_next_code:nn {#1} }
 \cs_gset_protected:Npn \hook_gput_next_code_with_args:nn #1 #2 { }
 \EndIncludeInRelease
 \cs_new_protected:Npn \__hook_gput_next_code:nn #1 #2
@@ -6979,7 +7159,8 @@
     \fi:
     \cs:w __hook~#1 \__hook_use_end:
   }
-\cs_new:Npn \__hook_use_undefined:w #1 #2 __hook~#3 \__hook_use_end:
+\cs_new:Npn \__hook_use_undefined:w
+    #1 #2 __hook~#3 \__hook_use_end:
   {
     #1 % fi
     \__hook_use:wn #3 / \s__hook_mark {#3}
@@ -7039,12 +7220,13 @@
   }
 \cs_new_protected:Npn \__hook_try_file_hook:n #1
   {
-    \__hook_if_file_hook:wTF #1 / \s__hook_mark
+    \__hook_if_file_hook:wTF #1 / / \s__hook_mark
       {
         \exp_args:Ne \__hook_if_usable_use:n
           { \exp_args:Ne \__hook_file_hook_normalize:n {#1} }
       }
-      { \__hook_if_usable_use:n {#1} } % file/ generic hook (e.g. file/before)
+      { \__hook_if_usable_use:n {#1} }
+            % file/ generic hook (e.g. file/before)
   }
 \cs_new_protected:Npn \__hook_if_usable_use:n #1
   {
@@ -7060,12 +7242,14 @@
 \cs_new_protected:Npn \hook_use_once:n #1
   {
     \__hook_if_execute_immediately:nF {#1}
-      { \__hook_normalize_hook_args:Nn \__hook_use_once:nn { \use:n {#1} } { 0 } }
+      { \__hook_normalize_hook_args:Nn \__hook_use_once:nn
+          { \use:n {#1} } { 0 } }
   }
 \cs_new_protected:Npn \hook_use_once:nnw #1 #2
   {
     \__hook_if_execute_immediately:nF {#1}
-      { \__hook_normalize_hook_args:Nn \__hook_use_once:nn { \use:n {#1} } {#2} }
+      { \__hook_normalize_hook_args:Nn \__hook_use_once:nn
+          { \use:n {#1} } {#2} }
   }
 \EndIncludeInRelease
 \IncludeInRelease{2020/10/01}{\hook_use_once:nnw}
@@ -7073,7 +7257,8 @@
 \cs_gset_protected:Npn \hook_use_once:n #1
   {
     \__hook_if_execute_immediately:nF {#1}
-      { \__hook_normalize_hook_args:Nn \__hook_use_once:n { \use:n {#1} } }
+      { \__hook_normalize_hook_args:Nn \__hook_use_once:n
+          { \use:n {#1} } }
   }
 \cs_gset:Npn \hook_use_once:nnw #1 #2
   { \use:c { use_none: \prg_replicate:nn {#2} { n } } }
@@ -7085,7 +7270,8 @@
     \__hook_preamble_hook:n {#1}
     \__hook_use_once_set:n {#1}
     \__hook_replacing_args_false:
-    \__hook_cs_gput_right:nnn { _next } {#1} { \__hook_use_once_clear:n {#1} }
+    \__hook_cs_gput_right:nnn { _next } {#1}
+      { \__hook_use_once_clear:n {#1} }
     \__hook_replacing_args_reset:
     \__hook_if_usable:nTF {#1}
       { \__hook_use_initialized:n {#1} }
@@ -7333,7 +7519,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.
   }
 \msg_new:nnn { hooks } { empty-label }
@@ -7442,7 +7629,7 @@
                  {Hooks~with~args}
 \cs_new_protected:Npn \NewHookWithArguments #1 #2 { }
 \cs_new_protected:Npn \NewReversedHookWithArguments #1 #2 { }
-\cs_new_protected:Npn \NewMirroredHookPairWithArguments #1 #2 #3 { }
+\cs_new_protected:Npn \NewMirroredHookPairWithArguments #1 #2 #3{}
 \EndIncludeInRelease
 \IncludeInRelease{2021/06/01}{\ActivateGenericHook}
                  {Providing~hooks}
@@ -7644,7 +7831,8 @@
             \exp_args:No \exp_not:o
               {
                 \cs:w __hook#1~#2 \exp_last_unbraced:Ne \cs_end:
-                  { \__hook_braced_cs_parameter:n { __hook#1~#2 } }
+                  { \__hook_braced_cs_parameter:n
+                      { __hook#1~#2 } }
               }
           }
       }
@@ -7659,12 +7847,10 @@
   }
 \ExplSyntaxOff
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-%% File: ltcmdhooks.dtx
+%% From File: ltcmdhooks.dtx
 %% Copyright (C) 2020-2024
 %% Frank Mittelbach, Phelype Oleinik, The LaTeX Project
-%%% From File: ltcmdhooks.dtx
-\def\ltcmdhooksversion{v1.0i}
-\def\ltcmdhooksdate{2023/06/16}
+%%% From File: lthooks.dtx
 \ExplSyntaxOn
 \NewModuleRelease{2021/06/01}{ltcmdhooks}
                  {The~hook~management~system~for~commands}
@@ -7823,7 +8009,7 @@
     \__hook_patch_debug:x { ++~command~can~be~patched~without~rescanning }
     \int_set:Nn \l__hook_patch_num_args_int
       {
-        \exp_args:Nf \str_count:n { \cs_argument_spec:N #2 } / 2
+        \exp_args:Nf \str_count:n { \__kernel_cs_parameter_spec:N #2 } / 2
         \bool_if:NT #1 { -1 }
       }
     \int_compare:nNnTF { \l__hook_patch_num_args_int } > { \c_zero_int }
@@ -7898,7 +8084,7 @@
     \__hook_patch_debug:x { ++~command~can~be~patched~without~rescanning }
     \int_set:Nn \l__hook_patch_num_args_int
       {
-        \exp_args:Nf \str_count:n { \cs_argument_spec:N #2 } / 2
+        \exp_args:Nf \str_count:n { \__kernel_cs_parameter_spec:N #2 } / 2
         \bool_if:NT #1 { -1 }
       }
     \int_compare:nNnTF { \l__hook_patch_num_args_int } > { \c_zero_int }
@@ -8031,7 +8217,7 @@
   { ~ \__hook_double_hashes:w }
 \cs_new_protected:Npn \__hook_retokenize_patch:Nnn #1 #2 #3
   {
-    \str_if_eq:eeTF { \cs_argument_spec:N #1 } { }
+    \str_if_eq:eeTF { \__kernel_cs_parameter_spec:N #1 } { }
       { \__hook_patch_expand_redefine:NNnn \c_false_bool #1 {#2} {#3} }
       {
         \__hook_patch_debug:x { ..~command~can~only~be~patched~by~rescanning }
@@ -8274,8 +8460,6 @@
 \ExplSyntaxOff
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%% From File: ltsockets.dtx
-\def\ltsocketsversion{0.9a}
-\def\ltsocketsdate{2023-08-21}
 \ExplSyntaxOn
 \NewModuleRelease{2023/11/01}{ltsockets}
                  {The~socket~management~system}
@@ -8465,6 +8649,1192 @@
 \EndModuleRelease
 \ExplSyntaxOff
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%% From File: lttemplates.dtx
+\ExplSyntaxOn
+\NewModuleRelease{2024/06/01}{lttemplates}
+                 {Prototype~document~commands}%
+\tl_const:Nn \c__template_code_root_tl      { template~code~>~ }
+\tl_const:Nn \c__template_defaults_root_tl  { template~defaults~>~ }
+\tl_const:Nn \c__template_instances_root_tl { template~instance~>~  }
+\tl_const:Nn \c__template_keytypes_root_tl  { template~key~types~>~ }
+\tl_const:Nn \c__template_key_order_root_tl { template~key~order~>~ }
+\tl_const:Nn \c__template_values_root_tl    { template~values~>~ }
+\tl_const:Nn \c__template_vars_root_tl      { template~vars~>~ }
+\seq_const_from_clist:Nn \c__template_keytypes_arg_seq
+  { choice , function , instance }
+\prop_new:N \g__template_type_prop
+\tl_new:N \l__template_assignments_tl
+\tl_new:N \l__template_default_tl
+\bool_new:N \l__template_error_bool
+\bool_new:N \l__template_global_bool
+\tl_new:N \l__template_key_name_tl
+\tl_new:N \l__template_keytype_tl
+\tl_new:N \l__template_keytype_arg_tl
+\tl_new:N \l__template_value_tl
+\tl_new:N \l__template_var_tl
+\prop_new:N \l__template_keytypes_prop
+\seq_new:N \l__template_key_order_seq
+\prop_new:N \l__template_values_prop
+\prop_new:N \l__template_vars_prop
+\clist_new:N \l__template_tmp_clist
+\dim_new:N \l__template_tmp_dim
+\int_new:N \l__template_tmp_int
+\muskip_new:N \l__template_tmp_muskip
+\skip_new:N \l__template_tmp_skip
+\tl_new:N \l__template_tmp_tl
+\scan_new:N \s__template_mark
+\scan_new:N \s__template_stop
+\quark_new:N \q__template_nil
+\__kernel_quark_new_conditional:Nn \__template_quark_if_nil:N { F }
+\cs_new_protected:Npn \__template_execute_if_arg_agree:nnT #1#2#3
+  {
+    \prop_get:NnN \g__template_type_prop {#1} \l__template_tmp_tl
+    \int_compare:nNnTF {#2} = \l__template_tmp_tl
+       {#3}
+       {
+         \msg_error:nneee { template } { argument-number-mismatch }
+           {#1} { \l__template_tmp_tl } {#2}
+       }
+  }
+\cs_new_protected:Npn \__template_execute_if_code_exist:nnT #1#2#3
+  {
+    \cs_if_exist:cTF { \c__template_code_root_tl #1 / #2 }
+      {#3}
+      { \msg_error:nnnn { template } { no-template-code } {#1} {#2} }
+  }
+\cs_new_protected:Npn \__template_execute_if_keytype_exist:nT #1#2
+  {
+    \cs_if_exist:cTF { __template_store_value_ #1 :n }
+      {#2}
+      { \msg_error:nnn { template } { unknown-keytype } {#1} }
+  }
+\cs_generate_variant:Nn \__template_execute_if_keytype_exist:nT { V }
+\cs_new_protected:Npn \__template_execute_if_type_exist:nT #1#2
+  {
+    \prop_if_in:NnTF \g__template_type_prop {#1}
+      {#2}
+      { \msg_error:nnn { template } { unknown-type } {#1} }
+  }
+\cs_new_protected:Npn \__template_if_keys_exist:nnT #1#2#3
+  {
+    \cs_if_exist:cTF { \c__template_keytypes_root_tl #1 / #2 }
+      {#3}
+      { \msg_error:nnnn { template } { unknown-template } {#1} {#2} }
+   }
+\prg_new_conditional:Npnn \__template_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 \__template_if_key_value:n { V } { T , F , TF }
+\prg_new_conditional:Npnn \__template_if_instance_exist:nn #1#2 { T, F, TF }
+  {
+    \cs_if_exist:cTF { \c__template_instances_root_tl #1 / #2 }
+      \prg_return_true:
+      \prg_return_false:
+ }
+\prg_new_conditional:Npnn \__template_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:
+}
+\cs_new_protected:Npn \__template_store_defaults:nn #1#2
+  {
+    \debug_suspend:
+    \prop_gclear_new:c { \c__template_defaults_root_tl #1 / #2  }
+    \prop_gset_eq:cN { \c__template_defaults_root_tl #1 / #2 }
+      \l__template_values_prop
+    \debug_resume:
+  }
+\cs_new_protected:Npn \__template_store_keytypes:nn #1#2
+  {
+    \debug_suspend:
+    \prop_if_exist:cTF { \c__template_keytypes_root_tl #1 / #2 }
+      {
+        \msg_info:nnnn { template } { declare-template-interface } {#1} {#2}
+        \prop_gclear:c { \c__template_keytypes_root_tl #1 / #2 }
+      }
+      { \prop_new:c { \c__template_keytypes_root_tl #1 / #2 } }
+    \prop_gset_eq:cN { \c__template_keytypes_root_tl #1 / #2 }
+      \l__template_keytypes_prop
+    \seq_gclear_new:c { \c__template_key_order_root_tl #1 / #2 }
+    \seq_gset_eq:cN { \c__template_key_order_root_tl #1 / #2 }
+      \l__template_key_order_seq
+    \debug_resume:
+  }
+\cs_new_protected:Npn \__template_store_values:nn #1#2
+  {
+    \debug_suspend:
+    \prop_clear_new:c { \c__template_values_root_tl #1 / #2 }
+    \prop_set_eq:cN { \c__template_values_root_tl #1 / #2 }
+      \l__template_values_prop
+    \debug_resume:
+  }
+\cs_new_protected:Npn \__template_store_vars:nn #1#2
+  {
+   \debug_suspend:
+    \prop_gclear_new:c { \c__template_vars_root_tl #1 / #2 }
+    \prop_gset_eq:cN { \c__template_vars_root_tl #1 / #2 }
+      \l__template_vars_prop
+    \debug_resume:
+  }
+\cs_new_protected:Npn \__template_recover_defaults:nn #1#2
+  {
+    \prop_if_exist:cTF
+      { \c__template_defaults_root_tl #1 / #2 }
+      {
+        \prop_set_eq:Nc \l__template_values_prop
+          { \c__template_defaults_root_tl #1 / #2 }
+      }
+      { \prop_clear:N \l__template_values_prop }
+  }
+\cs_new_protected:Npn \__template_recover_keytypes:nn #1#2
+  {
+    \prop_if_exist:cTF
+      { \c__template_keytypes_root_tl #1 / #2 }
+      {
+        \prop_set_eq:Nc \l__template_keytypes_prop
+          { \c__template_keytypes_root_tl #1 / #2 }
+      }
+      { \prop_clear:N \l__template_keytypes_prop }
+    \seq_if_exist:cTF { \c__template_key_order_root_tl #1 / #2 }
+      {
+        \seq_set_eq:Nc \l__template_key_order_seq
+          { \c__template_key_order_root_tl #1 / #2 }
+      }
+      { \seq_clear:N \l__template_key_order_seq }
+  }
+\cs_new_protected:Npn \__template_recover_values:nn #1#2
+  {
+    \prop_if_exist:cTF
+      { \c__template_values_root_tl #1 / #2 }
+      {
+        \prop_set_eq:Nc \l__template_values_prop
+          { \c__template_values_root_tl #1 / #2 }
+      }
+      { \prop_clear:N \l__template_values_prop }
+  }
+\cs_new_protected:Npn \__template_recover_vars:nn #1#2
+  {
+    \prop_if_exist:cTF
+      { \c__template_vars_root_tl #1 / #2 }
+      {
+        \prop_set_eq:Nc \l__template_vars_prop
+          { \c__template_vars_root_tl #1 / #2 }
+      }
+      { \prop_clear:N \l__template_vars_prop }
+  }
+\cs_new_protected:Npn \__template_define_type:nn #1#2
+  {
+    \prop_if_in:NnTF \g__template_type_prop {#1}
+      { \msg_error:nnn { template } { type-already-defined } {#1} }
+      { \__template_declare_type:nn {#1} {#2} }
+  }
+\cs_new_protected:Npn \__template_declare_type:nn #1#2
+  {
+    \int_set:Nn \l__template_tmp_int {#2}
+    \int_compare:nTF { 0 <= \l__template_tmp_int <= 9 }
+      {
+        \msg_info:nnnV { template } { declare-type }
+          {#1} \l__template_tmp_int
+        \prop_gput:NnV \g__template_type_prop {#1}
+          \l__template_tmp_int
+      }
+      {
+        \msg_error:nnnV { template } { bad-number-of-arguments }
+          {#1} \l__template_tmp_int
+      }
+  }
+\cs_new_protected:Npn \__template_declare_template_keys:nnnn #1#2#3#4
+  {
+    \__template_execute_if_type_exist:nT {#1}
+      {
+        \__template_execute_if_arg_agree:nnT {#1} {#3}
+          {
+            \prop_clear:N \l__template_values_prop
+            \prop_clear:N \l__template_keytypes_prop
+            \seq_clear:N \l__template_key_order_seq
+            \keyval_parse:NNn
+              \__template_parse_keys_elt:n \__template_parse_keys_elt:nn {#4}
+            \__template_store_defaults:nn {#1} {#2}
+            \__template_store_keytypes:nn {#1} {#2}
+          }
+      }
+  }
+\cs_new_protected:Npn \__template_parse_keys_elt:n #1
+  {
+    \__template_split_keytype:n {#1}
+    \bool_if:NF \l__template_error_bool
+      {
+        \__template_execute_if_keytype_exist:VT \l__template_keytype_tl
+          {
+            \seq_map_function:NN \c__template_keytypes_arg_seq
+              \__template_parse_keys_elt_aux:n
+            \bool_if:NF \l__template_error_bool
+              {
+                \seq_if_in:NoTF \l__template_key_order_seq
+                  \l__template_key_name_tl
+                  {
+                    \msg_error:nnV { template } { duplicate-key-interface }
+                      \l__template_key_name_tl
+                  }
+                  { \__template_parse_keys_elt_aux: }
+              }
+          }
+      }
+  }
+\cs_new_protected:Npn \__template_parse_keys_elt_aux:n #1
+  {
+    \str_if_eq:VnT \l__template_keytype_tl {#1}
+      {
+        \tl_if_empty:NT \l__template_keytype_arg_tl
+          {
+            \msg_error:nnn { template } { keytype-requires-argument } {#1}
+            \bool_set_true:N \l__template_error_bool
+            \seq_map_break:
+          }
+      }
+  }
+\cs_new_protected:Npn \__template_parse_keys_elt_aux:
+  {
+    \tl_set:Ne \l__template_tmp_tl
+      {
+        \l__template_keytype_tl
+        \tl_if_empty:NF \l__template_keytype_arg_tl
+          { { \l__template_keytype_arg_tl } }
+      }
+    \prop_put:NVV \l__template_keytypes_prop \l__template_key_name_tl
+      \l__template_tmp_tl
+    \seq_put_right:NV \l__template_key_order_seq \l__template_key_name_tl
+    \str_if_eq:VnT \l__template_keytype_tl { choice }
+      {
+        \clist_if_in:NnT \l__template_keytype_arg_tl { unknown }
+          { \msg_error:nn { template } { choice-unknown-reserved } }
+      }
+  }
+\cs_new_protected:Npn \__template_parse_keys_elt:nn #1#2
+  {
+    \__template_parse_keys_elt:n {#1}
+    \use:c { __template_store_value_ \l__template_keytype_tl :n } {#2}
+  }
+\cs_new_protected:Npe \__template_split_keytype:n #1
+  {
+    \exp_not:N \bool_set_false:N \exp_not:N \l__template_error_bool
+    \tl_set:Nn \exp_not:N \l__template_tmp_tl {#1}
+    \tl_replace_all:Nnn \exp_not:N \l__template_tmp_tl { : } { \token_to_str:N : }
+    \tl_if_in:VnTF \exp_not:N \l__template_tmp_tl { \token_to_str:N : }
+      {
+        \exp_not:n
+          {
+            \tl_clear:N \l__template_key_name_tl
+            \exp_after:wN \__template_split_keytype_aux:w
+              \l__template_tmp_tl \s__template_stop
+          }
+      }
+      {
+        \exp_not:N \bool_set_true:N \exp_not:N \l__template_error_bool
+        \msg_error:nnn { template } { missing-keytype } {#1}
+      }
+  }
+\use:e
+  {
+    \cs_new_protected:Npn \exp_not:N \__template_split_keytype_aux:w
+      #1 \token_to_str:N : #2 \s__template_stop
+      {
+        \tl_put_right:Ne \exp_not:N \l__template_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__template_key_name_tl
+              { \token_to_str:N : }
+            \exp_not:N \__template_split_keytype_aux:w #2 \s__template_stop
+          }
+          {
+            \exp_not:N \tl_if_empty:NTF \exp_not:N \l__template_key_name_tl
+              {
+                \msg_error:nnn { template } { empty-key-name }
+                  { \token_to_str:N : #2 }
+              }
+              { \exp_not:N \__template_split_keytype_arg:n {#2} }
+          }
+      }
+  }
+\cs_new_protected:Npn \__template_split_keytype_arg:n #1
+  {
+    \tl_set:Ne \l__template_keytype_tl { \tl_trim_spaces:n {#1} }
+    \tl_clear:N \l__template_keytype_arg_tl
+    \cs_set_protected:Npn \__template_split_keytype_arg_aux:n ##1
+      {
+        \tl_if_in:nnT {#1} {##1}
+          {
+            \cs_set:Npn \__template_split_keytype_arg_aux:w
+              ####1 ##1 ####2 \s__template_stop
+              {
+                \tl_if_blank:nT {####1}
+                  {
+                    \tl_set:Ne \l__template_keytype_tl
+                      { \tl_trim_spaces:n {##1} }
+                    \tl_if_blank:nF {####2}
+                      {
+                        \tl_set:Ne \l__template_keytype_arg_tl
+                          { \use:n ####2 }
+                      }
+                    \seq_map_break:
+                  }
+              }
+            \__template_split_keytype_arg_aux:w #1 \s__template_stop
+          }
+      }
+    \seq_map_function:NN \c__template_keytypes_arg_seq
+      \__template_split_keytype_arg_aux:n
+  }
+\cs_generate_variant:Nn \__template_split_keytype_arg:n { V }
+\cs_new:Npn \__template_split_keytype_arg_aux:n #1 { }
+\cs_new:Npn \__template_split_keytype_arg_aux:w #1 \s__template_stop { }
+\cs_new_protected:Npn \__template_store_value_boolean:n #1
+  { \prop_put:Non \l__template_values_prop \l__template_key_name_tl {#1} }
+\cs_new_protected:Npn \__template_store_value:n #1
+  { \prop_put:Non \l__template_values_prop \l__template_key_name_tl {#1} }
+\cs_new_eq:NN \__template_store_value_choice:n    \__template_store_value:n
+\cs_new_eq:NN \__template_store_value_function:n  \__template_store_value:n
+\cs_new_eq:NN \__template_store_value_instance:n  \__template_store_value:n
+\cs_new_protected:Npn \__template_store_value_aux:Nn #1#2
+  { \prop_put:Non \l__template_values_prop \l__template_key_name_tl {#2} }
+\cs_new_protected:Npn \__template_store_value_integer:n
+  { \__template_store_value_aux:Nn \int_eval:n }
+\cs_new_protected:Npn \__template_store_value_length:n
+  { \__template_store_value_aux:Nn \dim_eval:n }
+\cs_new_protected:Npn \__template_store_value_muskip:n
+  { \__template_store_value_aux:Nn \muskip_eval:n }
+\cs_new_protected:Npn \__template_store_value_real:n
+  { \__template_store_value_aux:Nn \fp_eval:n }
+\cs_new_protected:Npn \__template_store_value_skip:n
+  { \__template_store_value_aux:Nn \skip_eval:n }
+\cs_new_protected:Npn \__template_store_value_tokenlist:n
+  { \__template_store_value_aux:Nn \use:n }
+\cs_new_eq:NN \__template_store_value_commalist:n \__template_store_value_tokenlist:n
+\cs_new_protected:Npn \__template_declare_template_code:nnnnn #1#2#3#4#5
+  {
+    \__template_execute_if_type_exist:nT {#1}
+      {
+        \__template_execute_if_arg_agree:nnT {#1} {#3}
+          {
+            \__template_if_keys_exist:nnT {#1} {#2}
+              {
+                \__template_store_key_implementation:nnn {#1} {#2} {#4}
+                \regex_match:nnTF { \c { AssignTemplateKeys } } {#5}
+                  { \__template_declare_template_code:nnnn {#1} {#2} {#3} {#5} }
+                  {
+                    \__template_declare_template_code:nnnn
+                      {#1} {#2} {#3} { \AssignTemplateKeys #5 }
+                  }
+              }
+           }
+      }
+   }
+\cs_new_protected:Npn \__template_declare_template_code:nnnn #1#2#3#4
+  {
+    \cs_if_exist:cT { \c__template_code_root_tl #1 / #2 }
+      { \msg_info:nnnn { template } { declare-template-code } {#1} {#2} }
+    \cs_generate_from_arg_count:cNnn
+      { \c__template_code_root_tl #1 / #2 }
+      \cs_gset_protected:Npn {#3} {#4}
+  }
+\cs_new_protected:Npn \__template_store_key_implementation:nnn #1#2#3
+  {
+    \__template_recover_defaults:nn {#1} {#2}
+    \__template_recover_keytypes:nn {#1} {#2}
+    \prop_clear:N \l__template_vars_prop
+    \keyval_parse:nnn
+      { \__template_parse_vars_elt:n } { \__template_parse_vars_elt:nnn { #1 / #2 } } {#3}
+    \__template_store_vars:nn {#1} {#2}
+    \prop_map_inline:Nn \l__template_keytypes_prop
+      { \msg_error:nnnnn { template } { key-not-implemented } {##1} {#2} {#1} }
+  }
+\cs_new_protected:Npn \__template_parse_vars_elt:n #1
+  { \msg_error:nnn { template } { key-no-variable } {#1} }
+\cs_new_protected:Npn \__template_parse_vars_elt:nnn #1#2#3
+ {
+    \tl_set:Ne \l__template_key_name_tl
+      { \tl_trim_spaces:e { \tl_to_str:n {#2} } }
+    \prop_get:NVNTF \l__template_keytypes_prop
+      \l__template_key_name_tl
+      \l__template_keytype_tl
+      {
+        \__template_split_keytype_arg:V \l__template_keytype_tl
+        \__template_parse_vars_elt_aux:nn {#1} {#3}
+        \prop_remove:NV \l__template_keytypes_prop \l__template_key_name_tl
+      }
+      { \msg_error:nnn { template } { unknown-key } {#2} }
+  }
+\cs_new_protected:Npn \__template_parse_vars_elt_aux:nn #1#2
+  {
+    \__template_parse_vars_elt_aux:nw {#1} #2 global global \s__template_stop
+  }
+\cs_new_protected:Npn \__template_parse_vars_elt_aux:nw
+  #1#2 global #3 global #4 \s__template_stop
+  {
+    \tl_if_blank:nTF {#4}
+      { \__template_parse_vars_elt_aux:nnn {#1} { } {#2} }
+      {
+        \tl_if_blank:nTF {#2}
+          {
+            \__template_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 \__template_parse_vars_elt_aux:nnn #1#2#3
+  {
+    \str_case:VnF \l__template_keytype_tl
+      {
+        { choice } { \__template_implement_choices:nn {#1} {#3} }
+        { function }
+          {
+            \cs_if_exist:NF #3
+              { \cs_new:Npn #3 { } }
+            \__template_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__template_keytype_arg_tl }
+                      {##1}
+                  }
+              }
+            \prop_put:NVn \l__template_vars_prop
+              \l__template_key_name_tl {#2#3}
+          }
+        { instance }
+          {
+            \__template_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__template_vars_prop
+              \l__template_key_name_tl {#2#3}
+          }
+      }
+      {
+        \tl_if_single:nTF {#3}
+          {
+            \cs_if_exist:NF #3
+              { \use:c { \__template_map_var_type: _new:N } #3 }
+            \__template_parse_vars_elt_key:nn {#1}
+              {
+                . \__template_map_var_type:
+                  _ \str_if_eq:nnT {#1} { global } { g } set:N
+                    = \exp_not:N #3
+              }
+            \prop_put:NVn \l__template_vars_prop
+              \l__template_key_name_tl {#2#3}
+          }
+          { \msg_error:nnn { template } { bad-variable } {#2#3} }
+      }
+  }
+\cs_generate_variant:Nn \__template_parse_vars_elt_aux:nnn { nne }
+\cs_new_protected:Npn \__template_parse_vars_elt_key:nn #1#2
+  {
+    \keys_define:ne { template / #1 }
+      { \l__template_key_name_tl #2 }
+  }
+\cs_new:Npn \__template_map_var_type:
+  {
+    \str_case:Vn \l__template_keytype_tl
+      {
+        { boolean }   { bool }
+        { commalist } { clist }
+        { integer }   { int }
+        { length }    { dim }
+        { muskip }    { muskip }
+        { real }      { fp }
+        { skip }      { skip }
+        { tokenlist } { tl }
+      }
+  }
+\cs_new_protected:Npn \__template_implement_choices:nn #1#2
+  {
+    \clist_set:NV \l__template_tmp_clist \l__template_keytype_arg_tl
+    \prop_put:NVn \l__template_vars_prop \l__template_key_name_tl { }
+    \keys_define:ne { template / #1 } { \l__template_key_name_tl .choice: }
+    \keyval_parse:nnn
+      { \__template_implement_choice_elt:n }
+      { \__template_implement_choice_elt:nnn {#1} }
+      {#2}
+    \prop_get:NVNT \l__template_values_prop \l__template_key_name_tl
+      \l__template_tmp_tl
+      { \__template_implement_choices_default: }
+    \clist_if_empty:NF \l__template_tmp_clist
+      {
+        \clist_map_inline:Nn \l__template_tmp_clist
+          { \msg_error:nnn { template } { choice-not-implemented } {##1} }
+      }
+  }
+\cs_new_protected:Npn \__template_implement_choices_default:
+  {
+    \tl_set:Ne \l__template_tmp_tl
+      { \l__template_key_name_tl \c_space_tl \l__template_tmp_tl }
+    \prop_if_in:NVF \l__template_vars_prop \l__template_tmp_tl
+      {
+        \tl_set:Ne \l__template_tmp_tl
+          { \l__template_key_name_tl \c_space_tl \l__template_tmp_tl }
+        \prop_if_in:NVF \l__template_vars_prop \l__template_tmp_tl
+          {
+            \prop_get:NVN \l__template_keytypes_prop \l__template_key_name_tl
+              \l__template_tmp_tl
+            \__template_split_keytype_arg:V \l__template_tmp_tl
+            \prop_get:NVN \l__template_values_prop \l__template_key_name_tl
+              \l__template_tmp_tl
+            \msg_error:nnVV { template } { unknown-default-choice }
+              \l__template_key_name_tl
+              \l__template_key_name_tl
+          }
+      }
+  }
+\cs_new_protected:Npn \__template_implement_choice_elt:nnn #1#2#3
+  {
+    \clist_if_empty:NTF \l__template_tmp_clist
+      {
+        \str_if_eq:nnTF {#2} { unknown }
+          { \__template_implement_choice_elt_aux:nnn {#1} {#2} {#3} }
+          { \__template_implement_choice_elt_aux:n {#2} }
+      }
+      {
+        \clist_if_in:NnTF \l__template_tmp_clist {#2}
+          {
+            \clist_remove_all:Nn \l__template_tmp_clist {#2}
+            \__template_implement_choice_elt_aux:nnn {#1} {#2} {#3}
+          }
+          { \__template_implement_choice_elt_aux:n {#2} }
+      }
+  }
+\cs_new_protected:Npn \__template_implement_choice_elt_aux:n #1
+  {
+    \prop_get:NVN \l__template_keytypes_prop \l__template_key_name_tl
+      \l__template_tmp_tl
+    \__template_split_keytype_arg:V \l__template_tmp_tl
+    \msg_error:nnVn { template } { unknown-choice } \l__template_key_name_tl {#1}
+  }
+\cs_new_protected:Npn \__template_implement_choice_elt_aux:nnn #1#2#3
+  {
+    \keys_define:ne { template / #1 }
+      { \l__template_key_name_tl / #2 .code:n = { \exp_not:n {#3} } }
+    \tl_set:Ne \l__template_tmp_tl
+      { \l__template_key_name_tl \c_space_tl #2 }
+    \prop_put:NVn \l__template_vars_prop \l__template_tmp_tl {#3}
+  }
+\cs_new_protected:Npn \__template_implement_choice_elt:n #1
+  {
+    \msg_error:nnVn { template } { choice-requires-code }
+      \l__template_key_name_tl {#1}
+  }
+\cs_new_protected:Npn \__template_edit_defaults:nnn #1#2#3
+  {
+    \__template_if_keys_exist:nnT {#1} {#2}
+      {
+        \__template_recover_defaults:nn {#1} {#2}
+        \__template_parse_values:nnn {#1} {#2} {#3}
+        \__template_store_defaults:nn {#1} {#2}
+      }
+  }
+\cs_new_protected:Npn \__template_parse_values:nnn #1#2#3
+  {
+    \__template_recover_keytypes:nn {#1} {#2}
+    \keyval_parse:NNn
+      \__template_parse_values_elt:n \__template_parse_values_elt:nn {#3}
+  }
+\cs_new_protected:Npn \__template_parse_values_elt:n #1
+  {
+    \bool_set_true:N \l__template_error_bool
+    \msg_error:nnn { template } { key-no-value } {#1}
+  }
+\cs_new_protected:Npn \__template_parse_values_elt:nn #1#2
+  {
+    \tl_set:Ne \l__template_key_name_tl
+      { \tl_trim_spaces:e { \tl_to_str:n {#1} } }
+    \prop_get:NVNTF \l__template_keytypes_prop \l__template_key_name_tl
+      \l__template_tmp_tl
+      { \__template_parse_values_elt_aux:n {#2} }
+      { \msg_error:nnV { template } { unknown-key } \l__template_key_name_tl }
+  }
+\cs_new_protected:Npn \__template_parse_values_elt_aux:n #1
+  {
+    \__template_split_keytype_arg:V \l__template_tmp_tl
+    \use:c { __template_store_value_ \l__template_keytype_tl :n } {#1}
+  }
+\cs_new_protected:Npn \__template_template_set_eq:nnn #1#2#3
+  {
+    \__template_recover_defaults:nn {#1} {#3}
+    \__template_store_defaults:nn {#1} {#2}
+    \__template_recover_keytypes:nn {#1} {#3}
+    \__template_store_keytypes:nn {#1} {#2}
+    \__template_recover_vars:nn {#1} {#3}
+    \__template_store_vars:nn {#1} {#2}
+    \cs_if_exist:cT { \c__template_code_root_tl #1 / #2 }
+      { \msg_info:nnnn { template } { declare-template-code } {#1} {#2} }
+    \cs_gset_eq:cc { \c__template_code_root_tl #1 / #2 }
+      { \c__template_code_root_tl #1 / #3 }
+  }
+\cs_new_protected:Npn \__template_declare_instance:nnnn #1#2#3#4
+  {
+    \__template_execute_if_code_exist:nnT {#1} {#2}
+      {
+        \__template_recover_defaults:nn {#1} {#2}
+        \__template_recover_vars:nn {#1} {#2}
+        \__template_declare_instance_aux:nnnn {#1} {#2} {#3} {#4}
+      }
+  }
+\cs_new_protected:Npn \__template_declare_instance_aux:nnnn #1#2#3#4
+  {
+    \bool_set_false:N \l__template_error_bool
+    \__template_parse_values:nnn {#1} {#2} {#4}
+    \bool_if:NF \l__template_error_bool
+      {
+        \prop_put:Nnn \l__template_values_prop { from~template } {#2}
+        \__template_store_values:nn {#1} {#3}
+        \__template_convert_to_assignments:
+        \cs_if_exist:cT { \c__template_instances_root_tl #1 / #3 }
+          { \msg_info:nnnn { template } { declare-instance } {#3} {#1} }
+        \cs_set_protected:cpe { \c__template_instances_root_tl #1 / #3 }
+          {
+            \exp_not:N \__template_assignments_push:n
+              { \exp_not:V \l__template_assignments_tl }
+            \exp_not:c { \c__template_code_root_tl #1 / #2 }
+          }
+      }
+  }
+\cs_new_protected:Npn \__template_instance_set_eq:nnn #1#2#3
+  {
+    \__template_if_instance_exist:nnTF {#1} {#3}
+      {
+        \__template_recover_values:nn {#1} {#3}
+        \__template_store_values:nn {#1} {#2}
+        \cs_if_exist:cT { \c__template_instances_root_tl #1 / #2 }
+          { \msg_info:nnnn { template } { declare-instance } {#2} {#1} }
+        \cs_set_eq:cc { \c__template_instances_root_tl #1 / #2 }
+          { \c__template_instances_root_tl #1 / #3 }
+      }
+      { \msg_error:nnnn { template } { unknown-instance } {#1} {#3} }
+  }
+\cs_new_protected:Npn \__template_edit_instance:nnn #1#2#3
+  {
+    \__template_if_instance_exist:nnTF {#1} {#2}
+      {
+        \__template_recover_values:nn {#1}  {#2}
+        \prop_get:NnN \l__template_values_prop { from~template }
+          \l__template_tmp_tl
+        \__template_edit_instance_aux:nVnn
+          {#1} \l__template_tmp_tl {#2} {#3}
+      }
+      { \msg_error:nnnn { template } { unknown-instance } {#1} {#2} }
+  }
+\cs_new_protected:Npn \__template_edit_instance_aux:nnnn #1#2#3#4
+  {
+    \__template_recover_vars:nn {#1} {#2}
+    \__template_declare_instance_aux:nnnn {#1} {#2} {#3} {#4}
+  }
+\cs_generate_variant:Nn \__template_edit_instance_aux:nnnn { nV }
+\cs_new_protected:Npn \__template_convert_to_assignments:
+  {
+    \tl_clear:N \l__template_assignments_tl
+    \seq_map_function:NN \l__template_key_order_seq
+      \__template_convert_to_assignments_aux:n
+  }
+\cs_new_protected:Npn \__template_convert_to_assignments_aux:n #1
+  {
+    \prop_get:NnN \l__template_keytypes_prop {#1} \l__template_tmp_tl
+    \__template_convert_to_assignments_aux:nV {#1} \l__template_tmp_tl
+  }
+\cs_new_protected:Npn \__template_convert_to_assignments_aux:nn #1#2
+  {
+    \prop_get:NnNT \l__template_values_prop {#1} \l__template_value_tl
+      {
+        \prop_get:NnNTF \l__template_vars_prop {#1} \l__template_var_tl
+          {
+            \__template_split_keytype_arg:n {#2}
+            \str_if_eq:VnF \l__template_keytype_tl { choice }
+              {
+                \str_if_eq:VnF \l__template_keytype_tl { code }
+                  { \__template_find_global: }
+              }
+            \tl_set:Nn \l__template_key_name_tl {#1}
+            \cs_if_exist_use:cF { __template_assign_ \l__template_keytype_tl : }
+              { \__template_assign_variable: }
+          }
+          { \msg_error:nnn { template } { unknown-attribute } {#1} }
+      }
+  }
+\cs_generate_variant:Nn \__template_convert_to_assignments_aux:nn { nV }
+\cs_new_protected:Npn \__template_find_global:
+  {
+    \bool_set_false:N \l__template_global_bool
+    \tl_if_in:onT \l__template_var_tl { global }
+      {
+        \exp_after:wN \__template_find_global_aux:w \l__template_var_tl \s__template_stop
+      }
+  }
+\cs_new_protected:Npn \__template_find_global_aux:w  #1 global #2 \s__template_stop
+  {
+    \tl_set:Nn \l__template_var_tl {#2}
+    \bool_set_true:N \l__template_global_bool
+  }
+\cs_new_protected:Npn \__template_use_template:nnn #1#2#3
+  {
+    \__template_execute_if_code_exist:nnT {#1} {#2}
+      {
+        \__template_recover_defaults:nn {#1} {#2}
+        \__template_recover_vars:nn {#1} {#2}
+        \__template_parse_values:nnn {#1} {#2} {#3}
+        \__template_convert_to_assignments:
+        \use:c { \c__template_code_root_tl #1 / #2  }
+      }
+  }
+\cs_new_protected:Npn \__template_assign_boolean:
+  {
+    \bool_if:NTF \l__template_global_bool
+      { \__template_assign_boolean_aux:n { bool_gset } }
+      { \__template_assign_boolean_aux:n { bool_set } }
+  }
+\cs_new_protected:Npn \__template_assign_boolean_aux:n #1
+  {
+    \__template_if_key_value:VTF \l__template_value_tl
+      {
+        \__template_key_to_value:
+        \tl_put_right:Ne \l__template_assignments_tl
+          {
+            \exp_not:c { #1 _eq:NN }
+            \exp_not:V \l__template_var_tl
+            \exp_not:V \l__template_value_tl
+          }
+      }
+      {
+        \tl_put_right:Ne \l__template_assignments_tl
+          {
+            \exp_not:c { #1 _ \l__template_value_tl :N }
+            \exp_not:V \l__template_var_tl
+          }
+      }
+  }
+\cs_new_protected:Npn \__template_assign_choice:
+  {
+    \__template_assign_choice_aux:eF
+      { \l__template_key_name_tl \c_space_tl \l__template_value_tl }
+      {
+        \__template_assign_choice_aux:eF
+          { \l__template_key_name_tl \c_space_tl unknown }
+          {
+            \prop_get:NVN \l__template_keytypes_prop \l__template_key_name_tl
+              \l__template_tmp_tl
+            \__template_split_keytype_arg:V \l__template_tmp_tl
+            \msg_error:nnVV { template } { unknown-choice }
+              \l__template_key_name_tl
+              \l__template_value_tl
+          }
+      }
+  }
+\cs_new_protected:Npn \__template_assign_choice_aux:nF #1
+  {
+    \prop_get:NnNTF \l__template_vars_prop {#1} \l__template_tmp_tl
+      { \tl_put_right:NV \l__template_assignments_tl \l__template_tmp_tl }
+  }
+\cs_generate_variant:Nn \__template_assign_choice_aux:nF { e }
+\cs_new_protected:Npn \__template_assign_function:
+  {
+    \bool_if:NTF \l__template_global_bool
+      { \__template_assign_function_aux:N \cs_gset:Npn }
+      { \__template_assign_function_aux:N \cs_set:Npn  }
+  }
+\cs_new_protected:Npn \__template_assign_function_aux:N #1
+  {
+    \tl_put_right:Ne \l__template_assignments_tl
+      {
+        \cs_generate_from_arg_count:NNnn
+          \exp_not:V \l__template_var_tl
+          \exp_not:N #1
+          { \exp_not:V \l__template_keytype_arg_tl }
+          { \exp_not:V \l__template_value_tl }
+      }
+  }
+\cs_new_protected:Npn \__template_assign_instance:
+  {
+    \bool_if:NTF \l__template_global_bool
+      { \__template_assign_instance_aux:N \cs_gset_protected:Npn }
+      { \__template_assign_instance_aux:N \cs_set_protected:Npn  }
+  }
+\cs_new_protected:Npn \__template_assign_instance_aux:N #1
+  {
+    \tl_put_right:Ne \l__template_assignments_tl
+      {
+        \exp_not:N #1 \exp_not:V \l__template_var_tl
+          {
+            \__template_use_instance:nn
+              { \exp_not:V \l__template_keytype_arg_tl }
+              { \exp_not:V \l__template_value_tl }
+          }
+      }
+  }
+\cs_new_protected:Npn \__template_assign_variable:
+  {
+    \__template_assign_variable:c
+      {
+        \__template_map_var_type: _
+        \bool_if:NT \l__template_global_bool { g } set:Nn
+      }
+  }
+\cs_new_protected:Npn \__template_assign_variable:N #1
+  {
+    \__template_if_key_value:VT \l__template_value_tl
+      { \__template_key_to_value: }
+    \tl_put_right:Ne \l__template_assignments_tl
+      {
+        #1 \exp_not:V \l__template_var_tl
+         { \exp_not:V \l__template_value_tl }
+      }
+  }
+\cs_generate_variant:Nn \__template_assign_variable:N { c }
+\cs_new_protected:Npn \__template_key_to_value:
+  { \exp_after:wN \__template_key_to_value_auxi:w \l__template_value_tl }
+\cs_new_protected:Npn \__template_key_to_value_auxi:w \KeyValue #1
+  {
+    \tl_set:Ne \l__template_tmp_tl { \tl_trim_spaces:e { \tl_to_str:n {#1} } }
+    \prop_get:NVNTF \l__template_vars_prop \l__template_tmp_tl
+      \l__template_value_tl
+      {
+        \exp_after:wN \__template_key_to_value_auxii:w \l__template_value_tl
+          \s__template_mark global \q__template_nil \s__template_stop
+      }
+      { \msg_error:nnV { template } { unknown-attribute } \l__template_tmp_tl }
+  }
+\cs_new_protected:Npn \__template_key_to_value_auxii:w #1 global #2#3 \s__template_stop
+  {
+    \__template_quark_if_nil:NF #2
+      { \tl_set:Nn \l__template_value_tl {#2} }
+  }
+\cs_new_protected:Npn \__template_use_instance:nn #1#2
+  {
+    \__template_if_use_template:nTF {#2}
+      { \__template_use_instance_aux:nNnnn {#1} #2 }
+      { \__template_use_instance_aux:nn {#1} {#2} }
+  }
+\cs_new_protected:Npn \__template_use_instance_aux:nNnnn #1#2#3#4#5
+  {
+    \str_if_eq:nnTF {#1} {#3}
+      { \__template_use_template:nnn {#3} {#4} {#5} }
+      { \msg_error:nnnn { template } { type-mismatch } {#1} {#3} }
+}
+\cs_new_protected:Npn \__template_use_instance_aux:nn #1#2
+  {
+    \__template_if_instance_exist:nnTF {#1} {#2}
+      { \use:c { \c__template_instances_root_tl #1 / #2 } }
+      { \msg_error:nnnn { template } { unknown-instance } {#1} {#2} }
+  }
+\cs_new:Npn \__template_assignments_pop: { \l__template_assignments_tl }
+\cs_new_protected:Npn \__template_assignments_push:n #1
+  { \tl_set:Nn \l__template_assignments_tl {#1} }
+\cs_new_protected:Npn \__template_show_code:nn #1#2
+  { \cs_show:c { \c__template_code_root_tl #1 / #2 } }
+\cs_new_protected:Npn \__template_show_defaults:nn #1#2
+  {
+    \__template_if_keys_exist:nnT {#1} {#2}
+      {
+        \__template_recover_defaults:nn {#1} {#2}
+        \__template_show:Nnnn \l__template_values_prop
+          {#1} {#2} { default~values }
+      }
+  }
+\cs_new_protected:Npn \__template_show_keytypes:nn #1#2
+  {
+    \__template_if_keys_exist:nnT {#1} {#2}
+      {
+        \__template_recover_keytypes:nn {#1} {#2}
+        \__template_show:Nnnn \l__template_keytypes_prop
+          {#1} {#2} { interface }
+      }
+  }
+\cs_new_protected:Npn \__template_show_vars:nn #1#2
+  {
+     \__template_execute_if_code_exist:nnT {#1} {#2}
+      {
+        \__template_recover_vars:nn {#1} {#2}
+        \__template_show:Nnnn \l__template_vars_prop
+          {#1} {#2} { variable~mapping }
+      }
+  }
+\cs_new_protected:Npn \__template_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 }
+  }
+\cs_new_protected:Npn \__template_show_values:nn #1#2
+  {
+    \__template_if_instance_exist:nnT {#1} {#2}
+      {
+        \__template_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__template_values_prop
+              \msg_show_item_unbraced:nn
+          }
+      }
+  }
+\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'.
+  }
+\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 }
+  }
+\prop_gput:Nnn \g_msg_module_type_prop { template } { LaTeX }
+\cs_new_protected:Npn \NewTemplateType #1#2
+  { \__template_define_type:nn {#1} {#2} }
+\cs_new_protected:Npn \DeclareTemplateInterface #1#2#3#4
+  { \__template_declare_template_keys:nnnn {#1} {#2} {#3} {#4} }
+\cs_new_protected:Npn \DeclareTemplateCode #1#2#3#4#5
+  { \__template_declare_template_code:nnnnn {#1} {#2} {#3} {#4} {#5} }
+\cs_new_protected:Npn \DeclareTemplateCopy #1#2#3
+  { \__template_template_set_eq:nnn {#1} {#2} {#3} }
+\cs_new_protected:Npn \EditTemplateDefaults #1#2#3
+  { \__template_edit_defaults:nnn {#1} {#2} {#3} }
+\cs_new_protected:Npn \UseTemplate #1#2#3
+  { \__template_use_template:nnn {#1} {#2} {#3} }
+\cs_new_protected:Npn \DeclareInstance #1#2#3#4
+  { \__template_declare_instance:nnnn {#1} {#3} {#2} {#4} }
+\cs_new_protected:Npn \DeclareInstanceCopy #1#2#3
+  { \__template_instance_set_eq:nnn {#1} {#2} {#3} }
+\cs_new_protected:Npn \EditInstance #1#2#3
+  { \__template_edit_instance:nnn {#1} {#2} {#3} }
+\cs_new_protected:Npn \UseInstance #1#2
+  { \__template_use_instance:nn {#1} {#2} }
+\cs_new_protected:Npn \ShowTemplateCode #1#2
+  { \__template_show_code:nn {#1} {#2} }
+\cs_new_protected:Npn \ShowTemplateDefaults #1#2
+  { \__template_show_defaults:nn {#1} {#2} }
+\cs_new_protected:Npn \ShowTemplateInterface #1#2
+  { \__template_show_keytypes:nn {#1} {#2} }
+\cs_new_protected:Npn \ShowTemplateVariables #1#2
+  { \__template_show_vars:nn {#1} {#2} }
+\cs_new_protected:Npn \ShowInstanceValues #1#2
+  { \__template_show_values:nn {#1} {#2} }
+\cs_new:Npn \IfInstanceExistsTF #1#2
+  { \__template_if_instance_exist:nnTF {#1} {#2} }
+\cs_new:Npn \IfInstanceExistsT #1#2
+  { \__template_if_instance_exist:nnT {#1} {#2} }
+\cs_new:Npn \IfInstanceExistsF #1#2
+  { \__template_if_instance_exist:nnF {#1} {#2} }
+\cs_new_protected:Npn \KeyValue #1 {#1}
+\cs_new_protected:Npn \AssignTemplateKeys { \__template_assignments_pop: }
+\cs_new_protected:Npn \SetTemplateKeys #1#2#3
+  { \keys_set_known:nnN { template / #1 / #2 } {#3} \l__template_tmp_clist }
+\IncludeInRelease{0000/00/00}{lttemplates}%
+                 {Prototype~document~commands}%
+
+\EndModuleRelease
+\ExplSyntaxOff
 %%% From File: ltalloc.dtx
 %%% From File: ltcntrl.dtx
 %%% From File: lterror.dtx
@@ -8514,8 +9884,6 @@
 %% Copyright (C) 2020-2024
 %% Frank Mittelbach, The LaTeX Project
 %%% From File: ltpara.dtx
-\def\ltparaversion{v1.0l}
-\def\ltparadate{2023/01/30}
 
 
 \ExplSyntaxOn
@@ -8548,7 +9916,7 @@
   \@kernel at before@para at begin
   \hook_use:n {para/begin}
   \if_mode_horizontal: \else:
-    \msg_error:nnnn { hooks }{ para-mode }{begin}{vertical} \fi:
+    \msg_error:nnnn { hooks }{ para-mode }{begin}{horizontal} \fi:
   \__para_handle_indent:
 }
 \EndIncludeInRelease
@@ -8572,7 +9940,7 @@
   \@kernel at before@para at begin
   \hook_use:n {para/begin}
   \if_mode_horizontal: \else:
-    \msg_error:nnnn { hooks }{ para-mode }{begin}{vertical} \fi:
+    \msg_error:nnnn { hooks }{ para-mode }{begin}{horizontal} \fi:
   \__para_handle_indent:
 }
 \cs_set:Npn \__para_tmp:w #1#2#3#4#5 { }
@@ -8651,7 +10019,7 @@
 \cs_set_eq:NN \par     \para_end:
 \cs_set_eq:NN \@@par   \para_end:
 \cs_set_eq:NN \endgraf \para_end:
-\everypar{\@nodocument} %% To get an error if text appears before the
+\everypar{\@nodocument} %% To get an error if text appears before the \document
 \msg_new:nnnn { hooks } { para-mode }
   {
     Illegal~mode~ change~ in~ hook~ 'para/#1'.\\
@@ -8698,8 +10066,6 @@
 %% Copyright (C) 2021-2024
 %% Frank Mittelbach, The LaTeX Project
 %%% From File: ltmeta.dtx
-\def\ltmetaversion{v1.0b}
-\def\ltmetadate{2022/05/18}
 \NewModuleRelease{2022/06/01}{ltmeta}
                  {Document Metadata handling}
 \let \IfDocumentMetadataTF \@secondoftwo
@@ -10346,7 +11712,7 @@
 \EndIncludeInRelease
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%% From File: ltfssaxes.dtx
-%% Copyright (C) 1999-2020 Frank Mittelbach
+%% Copyright (C) 2019-2020 Frank Mittelbach
 \IncludeInRelease{2020/02/02}%
    {\DeclareFontSeriesChangeRule}{Series change rules}%
 \def\DeclareFontSeriesChangeRule#1#2#3#4{%
@@ -12227,7 +13593,7 @@
 \let\@defaultfamilyhook\@undefined
 
 \EndIncludeInRelease
-%%% From File: fontdef.dtx
+%%%   From File: fontdef.dtx
 \IncludeInRelease{2017/01/01}%
                  {\encodingdefault}{TU encoding default}%
 \ifx\Umathcode\@undefined
@@ -12725,8 +14091,7 @@
 \DeclareEncodingSubset{TS1}{lmss}    {1}
 \DeclareEncodingSubset{TS1}{lmssq}   {1}
 \DeclareEncodingSubset{TS1}{lmvtt}   {1}
-\DeclareEncodingSubset{TS1}{lmtt}    {1} % missing TM, SM and
-                                         % pertenthousand for some reason
+\DeclareEncodingSubset{TS1}{lmtt}    {1} % missing TM, SM and pertenthousand
 \DeclareEncodingSubset{TS1}{ptmx}    {2}
 \DeclareEncodingSubset{TS1}{ptmj}    {2}
 \DeclareEncodingSubset{TS1}{ul8}     {2}
@@ -12764,23 +14129,31 @@
 \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
+\DeclareEncodingSubset{TS1}{fbb-*}        {2}  % missing centoldstyle
 \DeclareEncodingSubset{TS1}{Alegreya-*}               {2}
 \DeclareEncodingSubset{TS1}{AlegreyaSans-*}           {2}
+\DeclareEncodingSubset{TS1}{BaskervilleF-*}           {2}
 \DeclareEncodingSubset{TS1}{DejaVuSans-TLF}           {2}
 \DeclareEncodingSubset{TS1}{DejaVuSansCondensed-TLF}  {2}
 \DeclareEncodingSubset{TS1}{DejaVuSansMono-TLF}       {2}
 \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}
 \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}
@@ -12795,6 +14168,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}
@@ -12807,7 +14181,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}
@@ -12824,12 +14197,12 @@
 \DeclareEncodingSubset{TS1}{Rosario-*}                {4}
 \DeclareEncodingSubset{TS1}{SticksTooText-*}          {4}
 \DeclareEncodingSubset{TS1}{UniversalisADFStd-LF}     {4}
-\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}
@@ -12836,10 +14209,9 @@
 \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}
@@ -12846,35 +14218,29 @@
 \DeclareEncodingSubset{TS1}{TheanoModern-TOsF}        {5}
 \DeclareEncodingSubset{TS1}{TheanoOldStyle-TLF}       {5}
 \DeclareEncodingSubset{TS1}{TheanoOldStyle-TOsF}      {5}
+\DeclareEncodingSubset{TS1}{charssil-TLF}             {5}
 \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}
+\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}
 \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}{Cochineal-*}              {8}
+\DeclareEncodingSubset{TS1}{Quattro-LF}               {7}
+\DeclareEncodingSubset{TS1}{QuattroSans-LF}           {7}
+\DeclareEncodingSubset{TS1}{Frm-LF}                   {7}  % the superiors are missing
+\DeclareEncodingSubset{TS1}{LibertinusMono-TLF}       {8}
 \DeclareEncodingSubset{TS1}{AlgolRevived-TLF}         {9}
 \def\UseLegacyTextSymbols{%
   \DeclareTextSymbolDefault{\textasteriskcentered}{OMS}%
@@ -13112,7 +14478,6 @@
 
 \EndModuleRelease
 
-
 %%% From File: ltpageno.dtx
 %%% From File: ltxref.dtx
 \IncludeInRelease{2023/06/01}%
@@ -13260,12 +14625,7 @@
 \let\Ref\@undefined
 
 \EndIncludeInRelease
-%% File: ltproperties.dtx
-\def\ltpropertiesversion{1.0c}
-\def\ltpropertiesdate{2023-10-15}
-
-
-
+%%% From File: ltproperties.dtx
 \ExplSyntaxOn
 \NewModuleRelease{2023/11/01}{ltproperties}
                  {Cross-referencing~properties}
@@ -13320,7 +14680,7 @@
   {
     \legacy_if:nT { @filesw }
       {
-        \iow_shipout_x:Nx \@auxout
+        \protected at write \@auxout {}
           {
             \token_to_str:N \new at label@record
               {#1}
@@ -13432,7 +14792,9 @@
       }
   }
 \prg_generate_conditional_variant:Nnn \property_if_exist:n {e} {TF}
-\cs_new_eq:NN \IfPropertyExistTF \property_if_exist:eTF
+\cs_new_eq:NN \IfPropertyExistsTF \property_if_exist:eTF
+\cs_new:Npn   \IfPropertyExistsT #1#2 {\property_if_exist:eTF {#1}{#2}{} }
+\cs_new:Npn   \IfPropertyExistsF #1   {\property_if_exist:eTF {#1}{} }
 \prg_new_conditional:Npnn \property_if_recorded:n #1 { p , T , F,  TF }
   % #1 label
   {
@@ -13445,7 +14807,9 @@
       }
   }
 \prg_generate_conditional_variant:Nnn \property_if_recorded:n {e} {TF}
-\cs_new_eq:NN \IfLabelExistTF \property_if_recorded:eTF
+\cs_new_eq:NN \IfLabelExistsTF \property_if_recorded:eTF
+\cs_new:Npn   \IfLabelExistsT #1#2 {\property_if_exist:eTF {#1}{#2}{} }
+\cs_new:Npn   \IfLabelExistsF #1   {\property_if_exist:eTF {#1}{} }
 \prg_new_conditional:Npnn \property_if_recorded:nn #1#2 { p , T , F,  TF }
   % #1 label #2 property
   {
@@ -13534,8 +14898,8 @@
 \let \RefProperty \@undefined
 \let \RefUndefinedWarn  \@undefined
 
-\let \IfPropertyExistTF \@undefined
-\let \IfLabelExistTF \@undefined
+\let \IfPropertyExistsTF \@undefined
+\let \IfLabelExistsTF \@undefined
 \let \IfPropertyRecordedTF  \@undefined
 
 \let\new at label@record \@undefined
@@ -14651,6 +16015,27 @@
   \@ifnextchar[{\@rsbox{#1}}{\@irsbox{#1}[]}}
 \expandafter\let\csname raisebox \endcsname\@undefined
 \EndIncludeInRelease
+\IncludeInRelease{2024/06/01}%
+                 {\@finalstrut}{final strut correction}%
+\def\@finalstrut#1{%
+  \unskip
+  \ifhmode \nobreak \vrule
+  \else
+    \ifdim \prevdepth=-\@m\p@
+    \else
+      \vskip-\prevdepth
+    \fi
+    \hrule
+  \fi
+  \@width\z@\@height\z@\@depth\dp#1}
+\EndIncludeInRelease
+\IncludeInRelease{0000/00/00}%
+                 {\@finalstrut}{final strut correction}%
+\def\@finalstrut#1{%
+  \unskip\ifhmode\nobreak\fi
+  \vrule\@width\z@\@height\z@\@depth\dp#1}
+
+\EndIncludeInRelease
 %%% From File: lttab.dtx
 \IncludeInRelease{2020/10/01}%
                  {\@itabcr}{Tabbing calc syntax}%
@@ -15283,6 +16668,32 @@
 
 \EndIncludeInRelease
 %%% From File: ltthm.dtx
+\IncludeInRelease{2024/03/18}%
+                 {\@thm}{no link target}%
+\def\@thm#1#2{%
+  \@kernel at refstepcounter{#1}%
+  \@ifnextchar[{\@ythm{#1}{#2}}{\@xthm{#1}{#2}}}
+\EndIncludeInRelease
+\IncludeInRelease{0000/00/00}%
+                 {\@thm}{no link target}%
+\def\@thm#1#2{%
+  \refstepcounter{#1}%
+  \@ifnextchar[{\@ythm{#1}{#2}}{\@xthm{#1}{#2}}}
+\EndIncludeInRelease
+\IncludeInRelease{2024/03/18}%
+                 {\@begintheorem}{add link targets}%
+\def\@begintheorem#1#2{\trivlist
+   \item[\MakeLinkTarget{\@currentcounter}\hskip \labelsep{\bfseries #1\ #2}]\itshape}
+\def\@opargbegintheorem#1#2#3{\trivlist
+      \item[\MakeLinkTarget{\@currentcounter}\hskip \labelsep{\bfseries #1\ #2\ (#3)}]\itshape}
+\EndIncludeInRelease
+\IncludeInRelease{0000/00/00}%
+                 {\@begintheorem}{add link targets}%
+\def\@begintheorem#1#2{\trivlist
+   \item[\hskip \labelsep{\bfseries #1\ #2}]\itshape}
+\def\@opargbegintheorem#1#2#3{\trivlist
+   \item[\hskip \labelsep{\bfseries #1\ #2\ (#3)}]\itshape}
+\EndIncludeInRelease
 %%% From File: ltsect.dtx
 \IncludeInRelease{2019/10/01}%
                  {\title}{Make commands robust}%
@@ -15773,8 +17184,6 @@
 %% Copyright (C) 2022-2024
 %% Frank Mittelbach, The LaTeX Project
 %%% From File: ltmarks.dtx
-\def\ltmarksversion{v1.0d}
-\def\ltmarksdate{2022/06/01}
 %% \end{function}
 
 \ExplSyntaxOn
@@ -15813,42 +17222,84 @@
   \tl_new:c   { g__mark_last-column_top_    #1 _tl }
   \tl_new:c   { g__mark_last-column_first_  #1 _tl }
   \tl_new:c   { g__mark_last-column_last_   #1 _tl }
+  \tl_set:cn   { g__mark_page_top_   #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_page_first_ #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_page_last_  #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_previous-page_top_   #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_previous-page_first_ #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_previous-page_last_  #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_column_top_   #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_column_first_ #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_column_last_  #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_previous-column_top_   #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_previous-column_first_ #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_previous-column_last_  #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_first-column_top_   #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_first-column_first_ #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_first-column_last_  #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_last-column_top_    #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_last-column_first_  #1 _tl }{ \__mark_id:n{0} }
+  \tl_set:cn   { g__mark_last-column_last_   #1 _tl }{ \__mark_id:n{0} }
 }
 \box_new:N \l__mark_box
+\box_new:N \l__mark_ii_box
 \tl_new:N  \g__mark_tmp_tl
 \tl_new:N  \g__mark_new_top_tl
-\cs_new_protected:Npn \__mark_update_structure:nn #1#2
-  {
-    \__mark_update_structure_alias:nn { previous-#1 } {#1}
+\cs_new_protected:Npn \__mark_extract_and_handle_marks:nn #1#2 {
     \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
-      \vbox_set_to_ht:Nnn \l__mark_box { -.5\c_max_dim }
+      \__mark_prepare_and_extract:nn {#1} {#2}
+    \group_end:
+  }
+\cs_new_protected:Npn \__mark_prepare_and_extract:nn #1#2 {
+  \vbox_set:Nn \l__mark_box
+    {
+      #2
+      \tex_unskip:D
+      \box_set_to_last:N \l__mark_box
+      \int_compare:nNnT \tex_lastnodetype:D < 0
         {
-          #2
-          \tex_unskip:D
-          \box_set_to_last:N \l__mark_box
-          \int_compare:nNnT \tex_lastnodetype:D < 0
-            {
-              \box_if_vertical:NT \l__mark_box
-                {
-                  \vbox_set_to_ht:Nnn \l__mark_box { -.5\c_max_dim }
-                    {
-                      \vbox_unpack:N \l__mark_box
-                      \tex_kern:D \c_zero_dim % ensure that box
-                                              % is not empty
-                    }
-                    \int_compare:nNnT \tex_badness:D > 0
-                      { \vbox_unpack:N \l__mark_box }
-                  }
-            }
-          \tex_kern:D \c_zero_dim
+          \box_if_vertical:NT \l__mark_box
+            { \vbox_unpack:N \l__mark_box }
         }
-      \int_compare:nNnTF \tex_badness:D > 0
-        {
-          \vbox_set_split_to_ht:NNn \l__mark_box \l__mark_box \c_max_dim
-          \seq_map_inline:Nn \g__mark_classes_seq
+    }
+    \__mark_vbox_set_split_to_maxdimen:NN \l__mark_ii_box \l__mark_box
+    \box_if_empty:NTF \l__mark_box
+      { #1 }
+      {
+        \__mark_prepare_and_extract:nn {#1}
+           { \vbox_unpack:N \l__mark_ii_box
+             \vbox_unpack:N \l__mark_box    }
+      }
+}
+\cs_set_eq:cN {Infinite~shrink~error~above~ignored~!}\c_max_dim
+\cs_new_protected:Npx \__mark_vbox_set_split_to_maxdimen:NN #1#2 {
+  \tl_set:Ne \exp_not:N \l__mark_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:
+     }
+  \tex_escapechar:D     -1 \scan_stop:
+  \tex_interactionmode:D 0 \scan_stop:
+  \tex_setbox:D #1 \tex_vsplit:D #2 to
+      \exp_not:N \use:n {
+        \use:c{Infinite~shrink~error~above~ignored~!}
+      }
+  \exp_not:N \l__mark_saved_parameters_tl
+}
+\tl_new:N \l__mark_saved_parameters_tl
+\cs_new_protected:Npn \__mark_update_structure_from_material:nn #1#2 {
+  \__mark_extract_and_handle_marks:nn
+     { \__mark_update_structure_from_splitmarks:n {#1} }
+     { #2 }
+}
+\cs_new_protected:Npn \__mark_update_structure_from_splitmarks:n #1 {
+  \__mark_update_structure_alias:nn { previous-#1 } {#1}
+  \seq_map_inline:Nn \g__mark_classes_seq
             {
               \tl_gset_eq:Nc \g__mark_new_top_tl { g__mark_#1_last_##1_tl }
               \tl_gset_eq:cN { g__mark_#1_top_##1_tl } \g__mark_new_top_tl
@@ -15870,19 +17321,40 @@
                     }
                 }
             }
-        }
-        {
-          \msg_error:nnn { mark } { infinite-shrinkage } {#1}
-          \seq_map_inline:Nn \g__mark_classes_seq
+}
+\cs_new_protected:Npn \__mark_get_marks_for_reinsertion:nNN #1#2#3 {
+  \tl_clear:N \g__mark_first_marks_tl
+  \tl_clear:N \g__mark_last_marks_tl
+  \__mark_extract_and_handle_marks:nn
+     \__mark_get_from_splitmarks:
+     { #1 }
+  \tl_set_eq:NN #2 \g__mark_first_marks_tl
+  \tl_set_eq:NN #3 \g__mark_last_marks_tl
+}
+\cs_new_protected:Npn  \__mark_get_from_splitmarks:  {
+  \seq_map_inline:Nn \g__mark_classes_seq
             {
-              \tl_gset_eq:cc { g__mark_#1_top_  ##1_tl }
-                             { g__mark_#1_last_ ##1_tl }
-              \tl_gset_eq:cc { g__mark_#1_first_##1_tl }
-                             { g__mark_#1_last_ ##1_tl }
+              \tl_gset:No \g__mark_tmp_tl
+                { \tex_splitbotmarks:D \use:c { c__mark_class_##1_mark } }
+
+              \tl_if_empty:NTF \g__mark_tmp_tl
+                {
+                }
+                {
+                  \tl_gput_right:Ne \g__mark_last_marks_tl
+                     { \mark_insert:nn {##1} { \g__mark_tmp_tl } }
+                  \tl_gput_right:Ne \g__mark_first_marks_tl
+                     { \mark_insert:nn {##1}
+                       {
+                         \tex_splitfirstmarks:D
+                         \use:c { c__mark_class_##1_mark }
+                       }
+                     }
+                }
             }
-        }
-    \group_end:
-  }
+}
+\tl_new:N  \g__mark_first_marks_tl
+\tl_new:N  \g__mark_last_marks_tl
 \cs_new_protected:Npn \__mark_update_structure_alias:nn #1#2 {
   \seq_map_inline:Nn \g__mark_classes_seq
     {
@@ -15912,12 +17384,14 @@
         \group_begin:
           \@kernel at before@insertmark
           \hook_use:n { insertmark }
-          \unrestored at protected@xdef \g__mark_tmp_tl {#2}
+          \unrestored at protected@xdef \g__mark_tmp_tl
+               {
+                 \__mark_id:n{ \int_use:N\g__mark_int }
+                 #2
+               }
           \tex_marks:D \use:c { c__mark_class_ #1 _mark }
             {
-              \tl_if_empty:NTF \g__mark_tmp_tl
-                { \exp_not:n { \prg_do_nothing: } }
-                { \exp_not:o { \g__mark_tmp_tl } }
+              \exp_not:o { \g__mark_tmp_tl }
             }
         \group_end:
         \if at nobreak\ifvmode\nobreak\fi\fi
@@ -15927,15 +17401,23 @@
           { \tl_to_str:n {#1} }
       }
 }
+\cs_new_protected:Npn \__mark_id:n #1 { }
+\int_new:N \g__mark_int
 \cs_new:Npn \@kernel at before@insertmark {
           \cs_set_eq:NN \label    \scan_stop:
           \cs_set_eq:NN \index    \scan_stop:
           \cs_set_eq:NN \glossary \scan_stop:
+          \int_compare:nNnTF \g__mark_int < {99999}
+              { \int_gincr:N \g__mark_int }
+              { \int_gzero:N \g__mark_int }
+
 }
 \hook_new:n {insertmark}
-\cs_new:Npn \mark_use_first:nn #1#2 { \exp_not:v { g__mark_#1_first_#2_tl } }
-\cs_new:Npn \mark_use_last:nn #1#2  { \exp_not:v { g__mark_#1_last_#2_tl }  }
-\cs_new:Npn \mark_use_top:nn #1#2   { \exp_not:v { g__mark_#1_top_#2_tl }   }
+\cs_new:Npn \mark_use_first:nn #1#2 { \__mark_use:v { g__mark_#1_first_#2_tl } }
+\cs_new:Npn \mark_use_last:nn #1#2  { \__mark_use:v { g__mark_#1_last_#2_tl }  }
+\cs_new:Npn \mark_use_top:nn #1#2   { \__mark_use:v { g__mark_#1_top_#2_tl }   }
+\cs_new:Npn \__mark_use:n #1 { \exp_not:o { \use_none:nn #1 } }
+\cs_generate_variant:Nn \__mark_use:n { v }
 \prg_new_conditional:Npnn \mark_if_eq:nnnn #1#2#3#4 { T , F , TF }
 {
   \tl_if_eq:ccTF { g__mark_ #1 _#3_ #2 _tl }
@@ -15975,15 +17457,6 @@
     all~columns~have~been~assembled.
     \c__msg_return_text_tl
   }
-\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.
-  }
 \bool_new:N \g__mark_debug_bool
 \cs_new_eq:NN \__mark_debug:n \use_none:n
 \cs_new_protected:Npn \mark_debug_on:
@@ -16003,6 +17476,8 @@
   }
 \cs_new_eq:NN \DebugMarksOn   \mark_debug_on:
 \cs_new_eq:NN \DebugMarksOff  \mark_debug_off:
+\cs_new_protected:Npn \ShowMarksAt #1 {
+}
 \cs_new_eq:NN  \NewMarkClass \mark_new_class:n
 \@onlypreamble \NewMarkClass
 \cs_new_eq:NN \InsertMark  \mark_insert:nn
@@ -16018,11 +17493,11 @@
 \cs_new_protected:Npn \__mark_update_singlecol_structures: {
   \box_if_vertical:NTF \@outputbox
       {
-        \__mark_update_structure:nn {page}
+        \__mark_update_structure_from_material:nn {page}
            { \vbox_unpack:N  \@outputbox }
       }
       {
-        \__mark_update_structure:nn {page}
+        \__mark_update_structure_from_material:nn {page}
            { \hbox_unpack:N  \@outputbox }
       }
   \__mark_update_structure_alias:nn {previous-column}{previous-page}
@@ -16033,11 +17508,11 @@
 \cs_new_protected:Npn \__mark_update_dblcol_structures: {
   \box_if_vertical:NTF \@outputbox
       {
-        \__mark_update_structure:nn {column}
+        \__mark_update_structure_from_material:nn {column}
            { \vbox_unpack:N  \@outputbox }
       }
       {
-        \__mark_update_structure:nn {column}
+        \__mark_update_structure_from_material:nn {column}
            { \hbox_unpack:N  \@outputbox }
       }
   \legacy_if:nTF {@firstcolumn}
@@ -16057,10 +17532,19 @@
                          { g__mark_page_last_           ##1 _tl }
           \tl_gset_eq:cc { g__mark_page_top_           ##1 _tl }
                          { g__mark_first-column_top_   ##1 _tl }
-          \tl_gset_eq:cc { g__mark_ page_first_        ##1 _tl }
+
+          \tl_if_eq:ccTF { g__mark_first-column_top_   ##1 _tl }
                          { g__mark_first-column_first_ ##1 _tl }
-          \tl_gset_eq:cc { g__mark_page_last_          ##1 _tl }
-                         { g__mark_last-column_last_   ##1 _tl }
+             {
+               \tl_gset_eq:cc { g__mark_page_first_        ##1 _tl }
+                              { g__mark_last-column_first_ ##1 _tl }
+             }
+             {
+               \tl_gset_eq:cc { g__mark_page_first_         ##1 _tl }
+                              { g__mark_first-column_first_ ##1 _tl }
+             }
+          \tl_gset_eq:cc { g__mark_page_last_        ##1 _tl }
+                         { g__mark_last-column_last_ ##1 _tl }
         }
     }
 }
@@ -16323,8 +17807,8 @@
  }%
  \reserved at a}
 \EndIncludeInRelease
-\IncludeInRelease{2021/11/15}%
-                 {\IfPackageLoadedtTF}{Test package loading}%
+\IncludeInRelease{2024/06/01}%
+                 {\IfPackageLoadedTF}{Test package loading}%
 \let \IfPackageLoadedTF            \@ifpackageloaded
 \let \IfClassLoadedTF              \@ifclassloaded
 \let \IfPackageLoadedWithOptionsTF \@ifpackagewith
@@ -16331,7 +17815,7 @@
 \let \IfClassLoadedWithOptionsTF   \@ifclasswith
 \EndIncludeInRelease
 \IncludeInRelease{0000/00/00}%
-                 {\IfPackageLoadedtTF}{Test package loading}%
+                 {\IfPackageLoadedTF}{Test package loading}%
 
 \let \IfPackageLoadedTF            \@ifpackageloaded
 \let \IfClassLoadedTF              \@ifclassloaded
@@ -16339,6 +17823,63 @@
 \let \IfClassLoadedWithOptionsTF   \@ifclasswith
 
 \EndIncludeInRelease
+\IncludeInRelease{2024/06/01}%
+                 {\IfPackageLoadedT}{More conditionals}%
+\def\IfPackageLoadedT #1#2{\IfPackageLoadedTF{#1}{#2}{}}
+\def\IfPackageLoadedF   #1{\IfPackageLoadedTF{#1}{}}
+\def\IfClassLoadedT   #1#2{\IfClassLoadedTF{#1}{#2}{}}
+\def\IfClassLoadedF     #1{\IfClassLoadedTF{#1}{}}
+\def\IfPackageAtLeastT#1#2#3{\IfPackageAtLeastTF{#1}{#2}{#3}{}}
+\def\IfPackageAtLeastF  #1#2{\IfPackageAtLeastTF{#1}{#2}{}}
+\def\IfClassAtLeastT  #1#2#3{\IfClassAtLeastTF{#1}{#2}{#3}{}}
+\def\IfClassAtLeastF    #1#2{\IfClassAtLeastTF{#1}{#2}{}}
+\def\IfFileAtLeastT   #1#2#3{\IfFileAtLeastTF{#1}{#2}{#3}{}}
+\def\IfFileAtLeastF     #1#2{\IfFileAtLeastTF{#1}{#2}{}}
+\def\IfFormatAtLeastT   #1#2{\IfFormatAtLeastTF{#1}{#2}{}}
+\def\IfFormatAtLeastF     #1{\IfFormatAtLeastTF{#1}{}}
+\def\IfPackageLoadedWithOptionsT #1#2#3{\IfPackageLoadedWithOptionsTF{#1}{#2}{#3}{}}
+\def\IfPackageLoadedWithOptionsF   #1#2{\IfPackageLoadedWithOptionsTF{#1}{#2}{}}
+\def\IfClassLoadedWithOptionsT #1#2#3{\IfClassLoadedWithOptionsTF{#1}{#2}{#3}{}}
+\def\IfClassLoadedWithOptionsF   #1#2{\IfClassLoadedWithOptionsTF{#1}{#2}{}}
+\def\IfFileLoadedTF#1{%
+  \expandafter\ifx\csname ver@#1\endcsname\relax
+    \expandafter\@secondoftwo
+  \else
+    \expandafter\@firstoftwo
+  \fi}
+\def\IfFileLoadedT#1#2{\IfFileLoadedTF{#1}{#2}{}}
+\def\IfFileLoadedF  #1{\IfFileLoadedTF{#1}{}}
+\EndIncludeInRelease
+\IncludeInRelease{0000/00/00}%
+                 {\IfPackageLoadedT}{More conditionals}%
+
+\def\IfPackageLoadedT #1#2{\IfPackageLoadedTF{#1}{#2}{}}
+\def\IfPackageLoadedF   #1{\IfPackageLoadedTF{#1}{}}
+\def\IfClassLoadedT   #1#2{\IfClassLoadedTF{#1}{#2}{}}
+\def\IfClassLoadedF     #1{\IfClassLoadedTF{#1}{}}
+\def\IfPackageAtLeastT#1#2#3{\IfPackageAtLeastTF{#1}{#2}{#3}{}}
+\def\IfPackageAtLeastF  #1#2{\IfPackageAtLeastTF{#1}{#2}{}}
+\def\IfClassAtLeastT  #1#2#3{\IfClassAtLeastTF{#1}{#2}{#3}{}}
+\def\IfClassAtLeastF    #1#2{\IfClassAtLeastTF{#1}{#2}{}}
+\def\IfFileAtLeastT   #1#2#3{\IfFileAtLeastTF{#1}{#2}{#3}{}}
+\def\IfFileAtLeastF     #1#2{\IfFileAtLeastTF{#1}{#2}{}}
+\def\IfFormatAtLeastT   #1#2{\IfFormatAtLeastTF{#1}{#2}{}}
+\def\IfFormatAtLeastF     #1{\IfFormatAtLeastTF{#1}{}}
+\def\IfPackageLoadedWithOptionsT #1#2#3{\IfPackageLoadedWithOptionsTF{#1}{#2}{#3}{}}
+\def\IfPackageLoadedWithOptionsF   #1#2{\IfPackageLoadedWithOptionsTF{#1}{#2}{}}
+\def\IfClassLoadedWithOptionsT #1#2#3{\IfClassLoadedWithOptionsTF{#1}{#2}{#3}{}}
+\def\IfClassLoadedWithOptionsF   #1#2{\IfClassLoadedWithOptionsTF{#1}{#2}{}}
+
+\def\IfFileLoadedTF#1{%
+  \expandafter\ifx\csname ver@#1\endcsname\relax
+    \expandafter\@secondoftwo
+  \else
+    \expandafter\@firstoftwo
+  \fi}
+\def\IfFileLoadedT#1#2{\IfFileLoadedTF{#1}{#2}{}}
+\def\IfFileLoadedF  #1{\IfFileLoadedTF{#1}{}}
+
+\EndIncludeInRelease
 \IncludeInRelease{2020/10/01}%
   {\ProvidesPackage}{Check name with \strcmp}%
 \def\ProvidesPackage#1{%
@@ -16425,11 +17966,11 @@
   \expandafter\let
     \csname opt@#3.#1\expandafter\endcsname
     \csname opt@\reserved at a\endcsname
-    \@ifundefined{@raw at opt@#3.#1}%
-      {\expandafter\gdef\csname @raw at opt@#3.#1\expandafter\endcsname
-                \expandafter{#2}}%
-      {\expandafter\g at addto@macro\csname @raw at opt@#3.#1\expandafter\endcsname
-                \expandafter{\expandafter,#2}}%
+  \@ifundefined{@raw at opt@#3.#1}%
+    {\expandafter\gdef\csname @raw at opt@#3.#1\expandafter\endcsname
+              \expandafter{#2}}%
+    {\expandafter\g at addto@macro\csname @raw at opt@#3.#1\expandafter\endcsname
+              \expandafter{\expandafter,#2}}%
 }
 \EndIncludeInRelease
 \IncludeInRelease{2020/10/01}{\@pass at ptions}
@@ -16607,6 +18148,25 @@
   \AtEndOfPackage{\let\@unprocessedoptions\relax}%
   \@loadwithoptions\@pkgextension\RequirePackage}
 \EndIncludeInRelease
+\IncludeInRelease{2024/06/01}%
+                 {\@fileswithoptions}{Check Group}%
+\def\@fileswithoptions#1{%
+    \ifnum\currentgrouplevel>\z@
+     \@latex at error
+      {Loading a class or package in a group}%
+      {Classes and packages should only be loaded at the top level}%
+  \fi
+  \@ifnextchar[%]
+    {\@fileswith at ptions#1}%
+    {\@fileswith at ptions#1[]}}
+\EndIncludeInRelease
+\IncludeInRelease{0000/00/00}%
+                 {\@fileswithoptions}{Check Group}%
+\def\@fileswithoptions#1{%
+  \@ifnextchar[%]
+    {\@fileswith at ptions#1}%
+    {\@fileswith at ptions#1[]}}
+\EndIncludeInRelease
 \IncludeInRelease{2020/10/01}%
         {\@fileswith at pti@ns}{ifx tests in \@fileswith at pti@ns}%
 \def\@fileswith at pti@ns#1[#2]#3[#4]{%
@@ -16707,9 +18267,12 @@
       \@ifundefined{opt at handler@\@currname.\@currext}
         {\@onefilewithoptions at clashchk{#2}}
         {%
-          \expandafter\protected at edef\csname opt@\@currname.\@currext\endcsname
+          \expandafter\protected at edef
+            \csname opt@\@currname.\@currext\endcsname
             {\zap at space#2 \@empty}%
-          \@namedef{@raw at opt@\@currname.\@currext}{#2}%
+          \expandafter\def
+            \csname @raw at opt@\@currname.\@currext\expandafter\endcsname
+            \expandafter{#2}%
           \@nameuse{opt at handler@\@currname.\@currext}%
         }%
     }%
@@ -17255,8 +18818,6 @@
 \endgroup%
 \EndIncludeInRelease
 %%% From File: ltfilehook.dtx
-\providecommand\ltfilehookversion{v1.0o}
-\providecommand\ltfilehookdate{2023/07/10}
 \IncludeInRelease{2020/10/01}%
                  {\CurrentFile}{Hook management file}%
 \ExplSyntaxOn
@@ -17744,8 +19305,6 @@
 %% Frank Mittelbach, The LaTeX Project
 %%
 %%% From File: ltshipout.dtx
-\providecommand\ltshipoutversion{v1.0n}
-\providecommand\ltshipoutdate{2022/11/08}
 \IncludeInRelease{2020/10/01}%
                  {\shipout}{Hook management (shipout)}%
 \ExplSyntaxOn

Modified: trunk/Master/texmf-dist/tex/latex/base/latin1.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/latin1.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/latin1.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
  \ProvidesFile{latin1.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textonehalf}{\ensuremath{\frac12}}
 \ProvideTextCommandDefault{\textonequarter}{\ensuremath{\frac14}}

Modified: trunk/Master/texmf-dist/tex/latex/base/latin10.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/latin10.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/latin10.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
  \ProvidesFile{latin10.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\texteuro}
    {\TextSymbolUnavailable\texteuro}

Modified: trunk/Master/texmf-dist/tex/latex/base/latin2.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/latin2.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/latin2.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
  \ProvidesFile{latin2.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textcurrency}
    {\TextSymbolUnavailable\textcurrency}

Modified: trunk/Master/texmf-dist/tex/latex/base/latin3.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/latin3.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/latin3.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
  \ProvidesFile{latin3.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textonehalf}{\ensuremath{\frac12}}
 \ProvideTextCommandDefault{\textcurrency}

Modified: trunk/Master/texmf-dist/tex/latex/base/latin4.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/latin4.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/latin4.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
  \ProvidesFile{latin4.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textcurrency}
    {\TextSymbolUnavailable\textcurrency}

Modified: trunk/Master/texmf-dist/tex/latex/base/latin5.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/latin5.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/latin5.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
  \ProvidesFile{latin5.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textonehalf}{\ensuremath{\frac12}}
 \ProvideTextCommandDefault{\textonequarter}{\ensuremath{\frac14}}

Modified: trunk/Master/texmf-dist/tex/latex/base/latin9.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/latin9.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/latin9.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
  \ProvidesFile{latin9.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textcent}
    {\TextSymbolUnavailable\textcent}

Modified: trunk/Master/texmf-dist/tex/latex/base/ltluatex.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/ltluatex.tex	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/ltluatex.tex	2024-06-02 20:26:39 UTC (rev 71408)
@@ -46,9 +46,9 @@
   \ProvidesFile\undefined\begingroup\def\ProvidesFile
   #1#2[#3]{\endgroup\immediate\write-1{File: #1 #3}}
 \fi
-\ProvidesFile{ltluatex.tex}%
-[2023/08/03 v1.2c
-  LuaTeX support for plain TeX (core)
+\ProvidesFile{ltluatex.tex}
+[2024/02/11 v1.2c
+   LuaTeX support for plain TeX (core)%
 ]
 \edef\etatcatcode{\the\catcode`\@}
 \catcode`\@=11

Modified: trunk/Master/texmf-dist/tex/latex/base/ltxdoc.cls
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/ltxdoc.cls	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/ltxdoc.cls	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 \NeedsTeXFormat{LaTeX2e}
 \ProvidesClass{ltxdoc}
-         [2023/03/28 v2.1j Standard LaTeX documentation class]
+         [2024/02/08 v2.1j Standard LaTeX documentation class]
 \DeclareOption{a5paper}{\@latexerr{Option not supported}%
    {}}
 \newif\ifltxdoc at load@cfg@ \ltxdoc at load@cfg at true

Modified: trunk/Master/texmf-dist/tex/latex/base/macce.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/macce.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/macce.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
   \ProvidesFile{macce.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textdiv}
    {\TextSymbolUnavailable\textdiv}

Modified: trunk/Master/texmf-dist/tex/latex/base/next.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/next.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/next.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 
   \ProvidesFile{next.def}
-   [2021/02/14 v1.3d Input encoding file]
+   [2024/02/08 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textonehalf}{\ensuremath{\frac12}}
 \ProvideTextCommandDefault{\textonequarter}{\ensuremath{\frac14}}

Modified: trunk/Master/texmf-dist/tex/latex/base/nfssfont.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/nfssfont.tex	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/nfssfont.tex	2024-06-02 20:26:39 UTC (rev 71408)
@@ -41,8 +41,8 @@
 %% 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.
-\def\nfssfontfileversion{v2.2e}
-\def\nfssfontfiledate{2020/11/26}
+\def\nfssfontfileversion{v2.2f}
+\def\nfssfontfiledate{2023/11/07}
 
 
 \documentclass{article}
@@ -100,7 +100,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

Modified: trunk/Master/texmf-dist/tex/latex/base/omllcmm.fd
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/omllcmm.fd	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/omllcmm.fd	2024-06-02 20:26:39 UTC (rev 71408)
@@ -46,7 +46,7 @@
 %% making successful document exchange impossible.
 %% 
 \ProvidesFile{omllcmm.fd}
-        [2019/07/09 v2.2f Standard LaTeX slide font definitions]
+        [2023/12/02 v2.2f Standard LaTeX slide font definitions]
 \DeclareFontFamily{OML}{lcmm}{\skewchar\font'177}
 \DeclareFontShape{OML}{lcmm}{m}{it}{%
   <7><8><10><12><13.82><16.59><19.907><23.89><28.66><34.4><41.28>cmmi8%

Modified: trunk/Master/texmf-dist/tex/latex/base/omslcmsy.fd
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/omslcmsy.fd	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/omslcmsy.fd	2024-06-02 20:26:39 UTC (rev 71408)
@@ -46,7 +46,7 @@
 %% making successful document exchange impossible.
 %% 
 \ProvidesFile{omslcmsy.fd}
-        [2019/07/09 v2.2f Standard LaTeX slide font definitions]
+        [2023/12/02 v2.2f Standard LaTeX slide font definitions]
 \DeclareFontFamily{OMS}{lcmsy}{\skewchar\font'60}
 \DeclareFontShape{OMS}{lcmsy}{m}{n}{%
   <7><8><10><12><13.82><16.59><19.907><23.89><28.66><34.4><41.28>cmsy8%

Modified: trunk/Master/texmf-dist/tex/latex/base/omxlcmex.fd
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/omxlcmex.fd	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/omxlcmex.fd	2024-06-02 20:26:39 UTC (rev 71408)
@@ -46,7 +46,7 @@
 %% making successful document exchange impossible.
 %% 
 \ProvidesFile{omxlcmex.fd}
-        [2019/07/09 v2.2f Standard LaTeX slide font definitions]
+        [2023/12/02 v2.2f Standard LaTeX slide font definitions]
 \DeclareFontFamily{OMX}{lcmex}{}
 \DeclareFontShape{OMX}{lcmex}{m}{n}{%
        <->sfixed*[17.28]cmex10%

Modified: trunk/Master/texmf-dist/tex/latex/base/ot1lcmss.fd
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/ot1lcmss.fd	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/ot1lcmss.fd	2024-06-02 20:26:39 UTC (rev 71408)
@@ -46,7 +46,7 @@
 %% making successful document exchange impossible.
 %% 
 \ProvidesFile{ot1lcmss.fd}
-        [2019/07/09 v2.2f Standard LaTeX slide font definitions]
+        [2023/12/02 v2.2f Standard LaTeX slide font definitions]
  \DeclareFontFamily{OT1}{lcmss}{\hyphenchar\font45 }
  \DeclareFontShape{OT1}{lcmss}{m}{n}{%
   <7><8><10><12><13.82><16.59><19.907><23.89><28.66><34.4><41.28>%

Modified: trunk/Master/texmf-dist/tex/latex/base/ot1lcmtt.fd
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/ot1lcmtt.fd	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/ot1lcmtt.fd	2024-06-02 20:26:39 UTC (rev 71408)
@@ -46,7 +46,7 @@
 %% making successful document exchange impossible.
 %% 
 \ProvidesFile{ot1lcmtt.fd}
-        [2019/07/09 v2.2f Standard LaTeX slide font definitions]
+        [2023/12/02 v2.2f Standard LaTeX slide font definitions]
  \DeclareFontFamily{OT1}{lcmtt}{\hyphenchar\font\m at ne}
  \DeclareFontShape{OT1}{lcmtt}{m}{n}{%
       <13.82><16.59><19.907><23.89><28.66><34.4><41.28>%

Modified: trunk/Master/texmf-dist/tex/latex/base/preload.cfg
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/preload.cfg	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/preload.cfg	2024-06-02 20:26:39 UTC (rev 71408)
@@ -35,11 +35,11 @@
 %% the system are in the document `cfgguide.tex'.
 %% 
 %% 
-%%% From File: fontdef.dtx
+%%%   From File: fontdef.dtx
 \ProvidesFile{preload.cfg}
-           [2021/01/15 v3.0i LaTeX Kernel
-(Uncustomized preload
-           font setup)]
+           [2024/02/09 v3.0i LaTeX Kernel
+   (Uncustomized preload font setup)
+]
 %%
 %%
 %%

Modified: trunk/Master/texmf-dist/tex/latex/base/report.cls
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/report.cls	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/report.cls	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 \NeedsTeXFormat{LaTeX2e}[1995/12/01]
 \ProvidesClass{report}
-              [2023/05/17 v1.4n
+              [2024/02/08 v1.4n
  Standard LaTeX document class]
 \newcommand\@ptsize{}
 \newif\if at restonecol

Modified: trunk/Master/texmf-dist/tex/latex/base/sfonts.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/sfonts.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/sfonts.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -36,7 +36,7 @@
 %% 
 %% 
 \ProvidesFile{sfonts.def}
-        [2019/07/09 v2.2f Standard LaTeX slide font definitions]
+        [2023/12/02 v2.2f Standard LaTeX slide font definitions]
 \DeclareErrorFont{OT1}{lcmss}{m}{n}{19.907}
 \DeclareFontSubstitution{OT1}{lcmss}{m}{n}
 \input ot1lcmss.fd

Modified: trunk/Master/texmf-dist/tex/latex/base/shortvrb.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/shortvrb.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/shortvrb.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,11 +43,11 @@
 %% extension .ins) which are part of the distribution.
 \NeedsTeXFormat{LaTeX2e}[1994/12/01]
 \ProvidesPackage{shortvrb}
-  [2022/11/13 v3.0m
+  [2024/04/26 v3.0p
    Standard LaTeX documentation package V3 (FMi)]
 %%
 %% 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.
 
 
 

Modified: trunk/Master/texmf-dist/tex/latex/base/size10.clo
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/size10.clo	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/size10.clo	2024-06-02 20:26:39 UTC (rev 71408)
@@ -42,7 +42,7 @@
 %% and covered by LPPL is defined by the unpacking scripts (with
 %% extension .ins) which are part of the distribution.
 \ProvidesFile{size10.clo}
-              [2023/05/17 v1.4n
+              [2024/02/08 v1.4n
       Standard LaTeX file (size option)]
 \renewcommand\normalsize{%
    \@setfontsize\normalsize\@xpt\@xiipt

Modified: trunk/Master/texmf-dist/tex/latex/base/size11.clo
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/size11.clo	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/size11.clo	2024-06-02 20:26:39 UTC (rev 71408)
@@ -42,7 +42,7 @@
 %% and covered by LPPL is defined by the unpacking scripts (with
 %% extension .ins) which are part of the distribution.
 \ProvidesFile{size11.clo}
-              [2023/05/17 v1.4n
+              [2024/02/08 v1.4n
       Standard LaTeX file (size option)]
 \renewcommand\normalsize{%
    \@setfontsize\normalsize\@xipt{13.6}%

Modified: trunk/Master/texmf-dist/tex/latex/base/size12.clo
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/size12.clo	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/size12.clo	2024-06-02 20:26:39 UTC (rev 71408)
@@ -42,7 +42,7 @@
 %% and covered by LPPL is defined by the unpacking scripts (with
 %% extension .ins) which are part of the distribution.
 \ProvidesFile{size12.clo}
-              [2023/05/17 v1.4n
+              [2024/02/08 v1.4n
       Standard LaTeX file (size option)]
 \renewcommand\normalsize{%
    \@setfontsize\normalsize\@xiipt{14.5}%

Modified: trunk/Master/texmf-dist/tex/latex/base/source2edoc.cls
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/source2edoc.cls	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/source2edoc.cls	2024-06-02 20:26:39 UTC (rev 71408)
@@ -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 at partsw
-      \@tempswafalse
-      \cs_set:Npx \@tempb {#1}
-      \clist_map_inline:Nn \@partlist
-        {
-          \if_meaning:w \@tempa \@tempb
-            \@tempswatrue
-          \fi:
-        }
-    \fi
-    \if at tempswa
-      \cs_set_eq:NN \@auxout                 \@partaux
-      \immediate\openout\@partaux #1.aux
-      \immediate\write\@partaux{\relax}
-      \cs_set_eq:NN \@ltxdoc at PrintIndex      \PrintIndex
-      \cs_set_eq:NN \PrintIndex              \relax
-      \cs_set_eq:NN \@ltxdoc at PrintChanges    \PrintChanges
-      \cs_set_eq:NN \PrintChanges            \relax
-      \cs_set_eq:NN \@ltxdoc at theglossary     \theglossary
-      \cs_set_eq:NN \@ltxdoc at 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 at PrintIndex
-      \cs_set_eq:NN \PrintChanges            \@ltxdoc at PrintChanges
-      \cs_set_eq:NN \theglossary             \@ltxdoc at theglossary
-      \cs_set_eq:NN \endtheglossary          \@ltxdoc at 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 at addto@macro\index at prologue{%
     \gdef\@oddfoot{\parbox[t]{\textwidth}{\strut\footnotesize
@@ -303,6 +225,9 @@
 \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%

Modified: trunk/Master/texmf-dist/tex/latex/base/structuredlog.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/structuredlog.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/structuredlog.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -42,8 +42,8 @@
 %% and covered by LPPL is defined by the unpacking scripts (with
 %% extension .ins) which are part of the distribution.
 %%% From File: ltfilehook.dtx
-\providecommand\ltfilehookversion{v1.0o}
-\providecommand\ltfilehookdate{2023/07/10}
+\def\ltfilehookdate{2024/03/13}
+\def\ltfilehookversion{v1.0o}
 \ProvidesExplPackage
     {structuredlog}{\ltfilehookdate}{\ltfilehookversion}
     {Structuring the TeX transcript file}

Modified: trunk/Master/texmf-dist/tex/latex/base/syntonly.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/syntonly.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/syntonly.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 %%
 \ProvidesPackage{syntonly}
-              [2017/06/30 v2.1e Standard LaTeX2e package]
+              [2024/02/08 v2.1e Standard LaTeX2e package]
 \font\dummyft@=dummy \relax
 \newif\ifsyntax@
 \syntax at false

Modified: trunk/Master/texmf-dist/tex/latex/base/t1lcmss.fd
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/t1lcmss.fd	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/t1lcmss.fd	2024-06-02 20:26:39 UTC (rev 71408)
@@ -46,7 +46,7 @@
 %% making successful document exchange impossible.
 %% 
 \ProvidesFile{t1lcmss.fd}
-        [2019/07/09 v2.2f Standard LaTeX slide font definitions]
+        [2023/12/02 v2.2f Standard LaTeX slide font definitions]
   \DeclareFontFamily{T1}{lcmss}{}
   \DeclareFontShape{T1}{lcmss}{m}{n}{%
   <7><8><10><12><13.82><16.59><19.907><23.89><28.66><34.4><41.28>%

Modified: trunk/Master/texmf-dist/tex/latex/base/t1lcmtt.fd
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/t1lcmtt.fd	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/t1lcmtt.fd	2024-06-02 20:26:39 UTC (rev 71408)
@@ -46,7 +46,7 @@
 %% making successful document exchange impossible.
 %% 
 \ProvidesFile{t1lcmtt.fd}
-        [2019/07/09 v2.2f Standard LaTeX slide font definitions]
+        [2023/12/02 v2.2f Standard LaTeX slide font definitions]
   \DeclareFontFamily{T1}{lcmtt}{\hyphenchar\font\m at ne}
  \DeclareFontShape{T1}{lcmtt}{m}{n}{%
       <13.82><16.59><19.907><23.89><28.66><34.4><41.28>%

Modified: trunk/Master/texmf-dist/tex/latex/base/textcomp-2018-08-11.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/textcomp-2018-08-11.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/textcomp-2018-08-11.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -408,7 +408,6 @@
   {\PackageInfo{textcomp}{Local configuration file used}}{}
 \fi
 
-
 \endinput
 %%
 %% End of file `textcomp-2018-08-11.sty'.

Modified: trunk/Master/texmf-dist/tex/latex/base/textcomp.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/textcomp.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/textcomp.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -42,14 +42,12 @@
 %% and covered by LPPL is defined by the unpacking scripts (with
 %% extension .ins) which are part of the distribution.
 %%% From File: lttextcomp.dtx
-\providecommand\DeclareRelease[3]{}
-\providecommand\DeclareCurrentRelease[2]{}
-
+\DeclareRelease{}{1997-12-01}{textcomp-2018-08-11.sty}
 \DeclareRelease{}{2018-08-11}{textcomp-2018-08-11.sty}
 \DeclareCurrentRelease{}{2020-02-02}
 
 \ProvidesPackage{textcomp}
- [2020/02/02 v2.0n Standard LaTeX package]
+ [2024/04/24 v2.1b Standard LaTeX package]
 \NeedsTeXFormat{LaTeX2e}[2020/02/02]
 \DeclareOption{full}{\DeclareEncodingSubset{TS1}{?}{0}}
 \DeclareOption{almostfull}{\DeclareEncodingSubset{TS1}{?}{1}}
@@ -74,12 +72,10 @@
      {#1{#2}}{#3}%
      #5}%
 }
-\ExecuteOptions{info}
 \ProcessOptions\relax
 \InputIfFileExists{textcomp.cfg}
   {\PackageInfo{textcomp}{Local configuration file used}}{}
 
-
 \endinput
 %%
 %% End of file `textcomp.sty'.

Modified: trunk/Master/texmf-dist/tex/latex/base/ullasy.fd
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/ullasy.fd	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/base/ullasy.fd	2024-06-02 20:26:39 UTC (rev 71408)
@@ -46,7 +46,7 @@
 %% making successful document exchange impossible.
 %% 
 \ProvidesFile{ullasy.fd}
-        [2019/07/09 v2.2f Standard LaTeX slide font definitions]
+        [2023/12/02 v2.2f Standard LaTeX slide font definitions]
 \DeclareFontFamily{U}{llasy}{}
 \DeclareFontShape{U}{llasy}{m}{n}{%
       <12><13.82><16.59><19.907><23.89><28.66><34.4><41.28>lasy8%

Modified: trunk/Master/texmf-dist/tex/latex/cyrillic/t2aenc.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/cyrillic/t2aenc.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/cyrillic/t2aenc.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -38,7 +38,7 @@
 %% 
 \NeedsTeXFormat{LaTeX2e}[1998/12/01]
 \ProvidesFile{t2aenc.def}
-  [2022/06/11 v1.0j Cyrillic encoding definition file]
+  [2023/11/07 v1.0k Cyrillic encoding definition file]
 \DeclareFontEncoding{T2A}{}{}
 \DeclareFontSubstitution{\LastDeclaredEncoding}{cmr}{m}{n}
 \DeclareTextAccent{\`}{\LastDeclaredEncoding}{0}
@@ -66,7 +66,7 @@
    {\hmode at bgroup
     \o at lign{\relax#1\crcr\hidewidth\ltx at sh@ft{-1ex}.\hidewidth}\egroup}
 \DeclareTextCommand{\k}{\LastDeclaredEncoding}[1]
-   {\oalign{\null#1\crcr\hidewidth\char12}}
+   {\hmode at bgroup\oalign{\null#1\crcr\hidewidth\char12}\egroup}
 \DeclareTextCommand{\textperthousand}{\LastDeclaredEncoding}
    {\%\char 24 }
 \DeclareTextCommand{\textpertenthousand}{\LastDeclaredEncoding}

Modified: trunk/Master/texmf-dist/tex/latex/cyrillic/t2benc.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/cyrillic/t2benc.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/cyrillic/t2benc.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -38,7 +38,7 @@
 %% 
 \NeedsTeXFormat{LaTeX2e}[1998/12/01]
 \ProvidesFile{t2benc.def}
-  [2022/06/11 v1.0j Cyrillic encoding definition file]
+  [2023/11/07 v1.0k Cyrillic encoding definition file]
 \DeclareFontEncoding{T2B}{}{}
 \DeclareFontSubstitution{\LastDeclaredEncoding}{cmr}{m}{n}
 \DeclareTextAccent{\`}{\LastDeclaredEncoding}{0}
@@ -66,7 +66,7 @@
    {\hmode at bgroup
     \o at lign{\relax#1\crcr\hidewidth\ltx at sh@ft{-1ex}.\hidewidth}\egroup}
 \DeclareTextCommand{\k}{\LastDeclaredEncoding}[1]
-   {\oalign{\null#1\crcr\hidewidth\char12}}
+   {\hmode at bgroup\oalign{\null#1\crcr\hidewidth\char12}\egroup}
 \DeclareTextCommand{\textperthousand}{\LastDeclaredEncoding}
    {\%\char 24 }
 \DeclareTextCommand{\textpertenthousand}{\LastDeclaredEncoding}

Modified: trunk/Master/texmf-dist/tex/latex/cyrillic/t2cenc.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/cyrillic/t2cenc.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/cyrillic/t2cenc.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -38,7 +38,7 @@
 %% 
 \NeedsTeXFormat{LaTeX2e}[1998/12/01]
 \ProvidesFile{t2cenc.def}
-  [2022/06/11 v1.0j Cyrillic encoding definition file]
+  [2023/11/07 v1.0k Cyrillic encoding definition file]
 \DeclareFontEncoding{T2C}{}{}
 \DeclareFontSubstitution{\LastDeclaredEncoding}{cmr}{m}{n}
 \DeclareTextAccent{\`}{\LastDeclaredEncoding}{0}
@@ -66,7 +66,7 @@
    {\hmode at bgroup
     \o at lign{\relax#1\crcr\hidewidth\ltx at sh@ft{-1ex}.\hidewidth}\egroup}
 \DeclareTextCommand{\k}{\LastDeclaredEncoding}[1]
-   {\oalign{\null#1\crcr\hidewidth\char12}}
+   {\hmode at bgroup\oalign{\null#1\crcr\hidewidth\char12}\egroup}
 \DeclareTextCommand{\textperthousand}{\LastDeclaredEncoding}
    {\%\char 24 }
 \DeclareTextCommand{\textpertenthousand}{\LastDeclaredEncoding}

Modified: trunk/Master/texmf-dist/tex/latex/cyrillic/x2enc.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/cyrillic/x2enc.def	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/cyrillic/x2enc.def	2024-06-02 20:26:39 UTC (rev 71408)
@@ -38,7 +38,7 @@
 %% 
 \NeedsTeXFormat{LaTeX2e}[1998/12/01]
 \ProvidesFile{x2enc.def}
-  [2022/06/11 v1.0j Cyrillic encoding definition file]
+  [2023/11/07 v1.0k Cyrillic encoding definition file]
 \DeclareFontEncoding{X2}{}{}
 \DeclareFontSubstitution{\LastDeclaredEncoding}{cmr}{m}{n}
 \DeclareTextAccent{\`}{\LastDeclaredEncoding}{0}
@@ -66,7 +66,7 @@
    {\hmode at bgroup
     \o at lign{\relax#1\crcr\hidewidth\ltx at sh@ft{-1ex}.\hidewidth}\egroup}
 \DeclareTextCommand{\k}{\LastDeclaredEncoding}[1]
-   {\oalign{\null#1\crcr\hidewidth\char12}}
+   {\hmode at bgroup\oalign{\null#1\crcr\hidewidth\char12}\egroup}
 \DeclareTextCommand{\textperthousand}{\LastDeclaredEncoding}
    {\%\char 24 }
 \DeclareTextCommand{\textpertenthousand}{\LastDeclaredEncoding}

Modified: trunk/Master/texmf-dist/tex/latex/firstaid/filehook-ltx.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/firstaid/filehook-ltx.sty	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/firstaid/filehook-ltx.sty	2024-06-02 20:26:39 UTC (rev 71408)
@@ -11,7 +11,7 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 2020-2023
+%% Copyright (C) 2020-2024
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
@@ -30,7 +30,7 @@
 %% `First Aid Bundle'. You may however distribute the LaTeX `First Aid Bundle'
 %% without such generated files.
 %% 
-%% File: latex2e-first-aid-for-external-files.dtx (C) Copyright 2020-2023
+%% File: latex2e-first-aid-for-external-files.dtx (C) Copyright 2020-2024
 %%
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.

Modified: trunk/Master/texmf-dist/tex/latex/firstaid/latex2e-first-aid-for-external-files.ltx
===================================================================
--- trunk/Master/texmf-dist/tex/latex/firstaid/latex2e-first-aid-for-external-files.ltx	2024-06-02 20:24:10 UTC (rev 71407)
+++ trunk/Master/texmf-dist/tex/latex/firstaid/latex2e-first-aid-for-external-files.ltx	2024-06-02 20:26:39 UTC (rev 71408)
@@ -11,7 +11,7 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 2020-2023
+%% Copyright (C) 2020-2024
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
@@ -30,12 +30,12 @@
 %% `First Aid Bundle'. You may however distribute the LaTeX `First Aid Bundle'
 %% without such generated files.
 %% 
-%% File: latex2e-first-aid-for-external-files.dtx (C) Copyright 2020-2023
+%% File: latex2e-first-aid-for-external-files.dtx (C) Copyright 2020-2024
 %%
 %% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
-\def\LaTeXFirstAidDate{2024/02/29}
-\def\LaTeXFirstAidVersion{v1.1c}
+\def\LaTeXFirstAidDate{2024/03/20}
+\def\LaTeXFirstAidVersion{v1.1e}
 \ProvidesFile{latex2e-first-aid-for-external-files.ltx}
              [\LaTeXFirstAidDate\space \LaTeXFirstAidVersion\space
                LaTeX kernel fixes to external files and packages]
@@ -170,16 +170,66 @@
 \AddToHook{file/underscore.sty/after}[firstaid]{%
   \FirstAidNeededT{underscore}{sty}{2006/09/13}{\RequirePackage{underscore-ltx}}}
 \AddToHook{package/acro/after}[firstaid]{%
-  \FirstAidNeededT{acro}{sty}{2022/04/01 v3.8 typeset acronyms and other abbreviations (CN)}
-    {\UseName{prop_new:c}{l__acro_tmpa_prop}}%
+  \FirstAidNeededT{acro}{sty}{2022/04/01 v3.8 typeset acronyms
+                              and other abbreviations (CN)}
+     {\UseName{prop_new:c}{l__acro_tmpa_prop}%
+       \acsetup{patch/longtable=false}%
+     }%
 }
 \AddToHook{package/chemformula/before}[firstaid]{%
   \RequirePackage{l3keys2e}%
 }
 \AddToHook{package/chemnum/after}[firstaid]{%
-  \FirstAidNeededT{chemnum}{sty}{2021/01/21 v1.3a a comprehensive approach for the numbering of chemical compounds (CN)}

@@ Diff output truncated at 1234567 characters. @@


More information about the tex-live-commits mailing list.