texlive[59424] Master/texmf-dist: latex2e (1jun21)

commits+karl at tug.org commits+karl at tug.org
Tue Jun 1 23:12:15 CEST 2021


Revision: 59424
          http://tug.org/svn/texlive?view=revision&revision=59424
Author:   karl
Date:     2021-06-01 23:12:14 +0200 (Tue, 01 Jun 2021)
Log Message:
-----------
latex2e (1jun21)

Modified Paths:
--------------
    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/bugs.txt
    trunk/Master/texmf-dist/doc/latex/base/cfgguide.pdf
    trunk/Master/texmf-dist/doc/latex/base/cfgguide.tex
    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.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/cyrguide.tex
    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/encguide.tex
    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/latexchanges.pdf
    trunk/Master/texmf-dist/doc/latex/base/latexchanges.tex
    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/legal.txt
    trunk/Master/texmf-dist/doc/latex/base/letter.pdf
    trunk/Master/texmf-dist/doc/latex/base/lgc2.err
    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/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/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/ltnews01.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews02.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews02.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews03.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews03.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews04.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews04.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews05.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews05.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews06.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews06.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews07.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews07.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews08.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews08.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews09.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews09.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews10.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews10.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews11.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews11.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews12.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews12.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews13.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews13.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews14.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews14.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews15.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews15.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews16.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews16.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews17.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews17.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews18.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews18.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews19.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews19.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews20.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews20.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews21.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews21.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews22.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews22.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews23.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews23.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews24.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews24.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews25.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews25.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews26.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews26.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews27.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews27.tex
    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/ltnews29.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews30.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews30.tex
    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/ltnews32.tex
    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/ltx3info.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltx3info.tex
    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/manifest.txt
    trunk/Master/texmf-dist/doc/latex/base/manual.pdf
    trunk/Master/texmf-dist/doc/latex/base/modguide.pdf
    trunk/Master/texmf-dist/doc/latex/base/modguide.tex
    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/texpert.txt
    trunk/Master/texmf-dist/doc/latex/base/tlc2.err
    trunk/Master/texmf-dist/doc/latex/base/tlc2.pdf
    trunk/Master/texmf-dist/doc/latex/base/tulm.pdf
    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/usrguide3.pdf
    trunk/Master/texmf-dist/doc/latex/base/usrguide3.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/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/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/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/manifest.txt
    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/source/latex/base/alltt.dtx
    trunk/Master/texmf-dist/source/latex/base/alltt.ins
    trunk/Master/texmf-dist/source/latex/base/classes.dtx
    trunk/Master/texmf-dist/source/latex/base/classes.ins
    trunk/Master/texmf-dist/source/latex/base/cmextra.ins
    trunk/Master/texmf-dist/source/latex/base/cmfonts.fdd
    trunk/Master/texmf-dist/source/latex/base/cmfonts.ins
    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/docstrip.ins
    trunk/Master/texmf-dist/source/latex/base/ec.ins
    trunk/Master/texmf-dist/source/latex/base/exscale.dtx
    trunk/Master/texmf-dist/source/latex/base/exscale.ins
    trunk/Master/texmf-dist/source/latex/base/fix-cm.dtx
    trunk/Master/texmf-dist/source/latex/base/fix-cm.ins
    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/graphpap.dtx
    trunk/Master/texmf-dist/source/latex/base/graphpap.ins
    trunk/Master/texmf-dist/source/latex/base/ifthen.dtx
    trunk/Master/texmf-dist/source/latex/base/ifthen.ins
    trunk/Master/texmf-dist/source/latex/base/inputenc.dtx
    trunk/Master/texmf-dist/source/latex/base/inputenc.ins
    trunk/Master/texmf-dist/source/latex/base/latex209.dtx
    trunk/Master/texmf-dist/source/latex/base/latex209.ins
    trunk/Master/texmf-dist/source/latex/base/latexrelease.dtx
    trunk/Master/texmf-dist/source/latex/base/latexrelease.ins
    trunk/Master/texmf-dist/source/latex/base/latexsym.dtx
    trunk/Master/texmf-dist/source/latex/base/latexsym.ins
    trunk/Master/texmf-dist/source/latex/base/letter.dtx
    trunk/Master/texmf-dist/source/latex/base/letter.ins
    trunk/Master/texmf-dist/source/latex/base/ltalloc.dtx
    trunk/Master/texmf-dist/source/latex/base/ltbibl.dtx
    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/ltcntrl.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/lterror.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/ltfsscmp.dtx
    trunk/Master/texmf-dist/source/latex/base/ltfssdcl.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/lthyphen.dtx
    trunk/Master/texmf-dist/source/latex/base/ltidxglo.dtx
    trunk/Master/texmf-dist/source/latex/base/ltlength.dtx
    trunk/Master/texmf-dist/source/latex/base/ltlists.dtx
    trunk/Master/texmf-dist/source/latex/base/ltlogos.dtx
    trunk/Master/texmf-dist/source/latex/base/ltluatex.dtx
    trunk/Master/texmf-dist/source/latex/base/ltmath.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/ltoutenc.ins
    trunk/Master/texmf-dist/source/latex/base/ltoutput.dtx
    trunk/Master/texmf-dist/source/latex/base/ltpage.dtx
    trunk/Master/texmf-dist/source/latex/base/ltpageno.dtx
    trunk/Master/texmf-dist/source/latex/base/ltpar.dtx
    trunk/Master/texmf-dist/source/latex/base/ltpictur.dtx
    trunk/Master/texmf-dist/source/latex/base/ltplain.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/ltspace.dtx
    trunk/Master/texmf-dist/source/latex/base/lttab.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/ltxref.dtx
    trunk/Master/texmf-dist/source/latex/base/makeindx.dtx
    trunk/Master/texmf-dist/source/latex/base/makeindx.ins
    trunk/Master/texmf-dist/source/latex/base/newdc.ins
    trunk/Master/texmf-dist/source/latex/base/newlfont.dtx
    trunk/Master/texmf-dist/source/latex/base/nfssfont.dtx
    trunk/Master/texmf-dist/source/latex/base/nfssfont.ins
    trunk/Master/texmf-dist/source/latex/base/olddc.ins
    trunk/Master/texmf-dist/source/latex/base/oldlfont.dtx
    trunk/Master/texmf-dist/source/latex/base/preload.dtx
    trunk/Master/texmf-dist/source/latex/base/proc.dtx
    trunk/Master/texmf-dist/source/latex/base/proc.ins
    trunk/Master/texmf-dist/source/latex/base/slides.dtx
    trunk/Master/texmf-dist/source/latex/base/slides.ins
    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/syntonly.ins
    trunk/Master/texmf-dist/source/latex/base/tulm.fdd
    trunk/Master/texmf-dist/source/latex/base/tulm.ins
    trunk/Master/texmf-dist/source/latex/base/unpack.ins
    trunk/Master/texmf-dist/source/latex/base/utf8ienc.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/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/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/article.sty
    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/bezier.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/book.sty
    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/exscale.sty
    trunk/Master/texmf-dist/tex/latex/base/fix-cm.sty
    trunk/Master/texmf-dist/tex/latex/base/fixltx2e.sty
    trunk/Master/texmf-dist/tex/latex/base/flafter.sty
    trunk/Master/texmf-dist/tex/latex/base/fleqn.clo
    trunk/Master/texmf-dist/tex/latex/base/fleqn.sty
    trunk/Master/texmf-dist/tex/latex/base/fltrace.sty
    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/graphpap.sty
    trunk/Master/texmf-dist/tex/latex/base/hyphen.ltx
    trunk/Master/texmf-dist/tex/latex/base/idx.tex
    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/lablst.tex
    trunk/Master/texmf-dist/tex/latex/base/latex.ltx
    trunk/Master/texmf-dist/tex/latex/base/latex209.def
    trunk/Master/texmf-dist/tex/latex/base/latexrelease.sty
    trunk/Master/texmf-dist/tex/latex/base/latexsym.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/lcyenc.dfu
    trunk/Master/texmf-dist/tex/latex/base/leqno.clo
    trunk/Master/texmf-dist/tex/latex/base/leqno.sty
    trunk/Master/texmf-dist/tex/latex/base/letter.cls
    trunk/Master/texmf-dist/tex/latex/base/letter.sty
    trunk/Master/texmf-dist/tex/latex/base/ltluatex.lua
    trunk/Master/texmf-dist/tex/latex/base/ltluatex.tex
    trunk/Master/texmf-dist/tex/latex/base/ltnews.cls
    trunk/Master/texmf-dist/tex/latex/base/ltxcheck.tex
    trunk/Master/texmf-dist/tex/latex/base/ltxdoc.cls
    trunk/Master/texmf-dist/tex/latex/base/ltxguide.cls
    trunk/Master/texmf-dist/tex/latex/base/ly1enc.dfu
    trunk/Master/texmf-dist/tex/latex/base/macce.def
    trunk/Master/texmf-dist/tex/latex/base/makeidx.sty
    trunk/Master/texmf-dist/tex/latex/base/minimal.cls
    trunk/Master/texmf-dist/tex/latex/base/newlfont.sty
    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/oldlfont.sty
    trunk/Master/texmf-dist/tex/latex/base/omlcmm.fd
    trunk/Master/texmf-dist/tex/latex/base/omlcmr.fd
    trunk/Master/texmf-dist/tex/latex/base/omlenc.def
    trunk/Master/texmf-dist/tex/latex/base/omllcmm.fd
    trunk/Master/texmf-dist/tex/latex/base/omscmr.fd
    trunk/Master/texmf-dist/tex/latex/base/omscmsy.fd
    trunk/Master/texmf-dist/tex/latex/base/omsenc.def
    trunk/Master/texmf-dist/tex/latex/base/omsenc.dfu
    trunk/Master/texmf-dist/tex/latex/base/omslcmsy.fd
    trunk/Master/texmf-dist/tex/latex/base/omxcmex.fd
    trunk/Master/texmf-dist/tex/latex/base/omxlcmex.fd
    trunk/Master/texmf-dist/tex/latex/base/openbib.sty
    trunk/Master/texmf-dist/tex/latex/base/ot1cmdh.fd
    trunk/Master/texmf-dist/tex/latex/base/ot1cmfib.fd
    trunk/Master/texmf-dist/tex/latex/base/ot1cmfr.fd
    trunk/Master/texmf-dist/tex/latex/base/ot1cmr.fd
    trunk/Master/texmf-dist/tex/latex/base/ot1cmss.fd
    trunk/Master/texmf-dist/tex/latex/base/ot1cmtt.fd
    trunk/Master/texmf-dist/tex/latex/base/ot1cmvtt.fd
    trunk/Master/texmf-dist/tex/latex/base/ot1enc.def
    trunk/Master/texmf-dist/tex/latex/base/ot1enc.dfu
    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/ot2enc.dfu
    trunk/Master/texmf-dist/tex/latex/base/ot4enc.def
    trunk/Master/texmf-dist/tex/latex/base/preload.cfg
    trunk/Master/texmf-dist/tex/latex/base/preload.ltx
    trunk/Master/texmf-dist/tex/latex/base/proc.cls
    trunk/Master/texmf-dist/tex/latex/base/proc.sty
    trunk/Master/texmf-dist/tex/latex/base/report.cls
    trunk/Master/texmf-dist/tex/latex/base/report.sty
    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/showidx.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/slides.cls
    trunk/Master/texmf-dist/tex/latex/base/slides.def
    trunk/Master/texmf-dist/tex/latex/base/slides.sty
    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/t1cmdh.fd
    trunk/Master/texmf-dist/tex/latex/base/t1cmfib.fd
    trunk/Master/texmf-dist/tex/latex/base/t1cmfr.fd
    trunk/Master/texmf-dist/tex/latex/base/t1cmr.fd
    trunk/Master/texmf-dist/tex/latex/base/t1cmss.fd
    trunk/Master/texmf-dist/tex/latex/base/t1cmtt.fd
    trunk/Master/texmf-dist/tex/latex/base/t1cmvtt.fd
    trunk/Master/texmf-dist/tex/latex/base/t1enc.def
    trunk/Master/texmf-dist/tex/latex/base/t1enc.dfu
    trunk/Master/texmf-dist/tex/latex/base/t1enc.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/t2aenc.dfu
    trunk/Master/texmf-dist/tex/latex/base/t2benc.dfu
    trunk/Master/texmf-dist/tex/latex/base/t2cenc.dfu
    trunk/Master/texmf-dist/tex/latex/base/testpage.tex
    trunk/Master/texmf-dist/tex/latex/base/texsys.cfg
    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/tracefnt.sty
    trunk/Master/texmf-dist/tex/latex/base/ts1cmr.fd
    trunk/Master/texmf-dist/tex/latex/base/ts1cmss.fd
    trunk/Master/texmf-dist/tex/latex/base/ts1cmtt.fd
    trunk/Master/texmf-dist/tex/latex/base/ts1cmvtt.fd
    trunk/Master/texmf-dist/tex/latex/base/ts1enc.def
    trunk/Master/texmf-dist/tex/latex/base/ts1enc.dfu
    trunk/Master/texmf-dist/tex/latex/base/tuenc.def
    trunk/Master/texmf-dist/tex/latex/base/tulmdh.fd
    trunk/Master/texmf-dist/tex/latex/base/tulmr.fd
    trunk/Master/texmf-dist/tex/latex/base/tulmss.fd
    trunk/Master/texmf-dist/tex/latex/base/tulmssq.fd
    trunk/Master/texmf-dist/tex/latex/base/tulmtt.fd
    trunk/Master/texmf-dist/tex/latex/base/tulmvtt.fd
    trunk/Master/texmf-dist/tex/latex/base/ucmr.fd
    trunk/Master/texmf-dist/tex/latex/base/ucmss.fd
    trunk/Master/texmf-dist/tex/latex/base/ucmtt.fd
    trunk/Master/texmf-dist/tex/latex/base/ulasy.fd
    trunk/Master/texmf-dist/tex/latex/base/ullasy.fd
    trunk/Master/texmf-dist/tex/latex/base/utf8-2018.def
    trunk/Master/texmf-dist/tex/latex/base/utf8.def
    trunk/Master/texmf-dist/tex/latex/base/utf8enc.dfu
    trunk/Master/texmf-dist/tex/latex/base/x2enc.dfu
    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/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.sty
    trunk/Master/texmf-dist/tex/latex/tools/multicol-2017-04-11.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.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/ltcmdhooks-code.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-code.tex
    trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-doc.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-doc.tex
    trunk/Master/texmf-dist/doc/latex/base/ltnews33.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltnews33.tex
    trunk/Master/texmf-dist/doc/latex/base/ltpara-code.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltpara-code.tex
    trunk/Master/texmf-dist/doc/latex/base/ltpara-doc.pdf
    trunk/Master/texmf-dist/doc/latex/base/ltpara-doc.tex
    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/ltpara.dtx
    trunk/Master/texmf-dist/tex/latex/base/doc-v3beta.sty
    trunk/Master/texmf-dist/tex/latex/tools/longtable-2020-01-07.sty

Removed Paths:
-------------
    trunk/Master/texmf-dist/tex/latex/base/everyshi-ltx.sty

Modified: trunk/Master/texmf-dist/doc/latex/base/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/README.md	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/README.md	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 The LaTeX kernel
 ================
 
-Release 2020-10-01 patch level 4
+Release 2021-06-01
 
 Overview
 --------

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

Modified: trunk/Master/texmf-dist/doc/latex/base/bugs.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/bugs.txt	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/bugs.txt	2021-06-01 21:12:14 UTC (rev 59424)
@@ -21,7 +21,7 @@
      https://www.latex-project.org/bugs.html
 
  * The error is not caused by software other than the core LaTeX
-   software that is produced and maintained by the LaTeX3 project
+   software that is produced and maintained by the LaTeX Project
    team. Please report problems with other software to the authors
    or suppliers of that software, and not to us!
 
@@ -30,9 +30,9 @@
 
    Also, the test file demonstrating the error should not use any
    classes or packages other than those authored and supported by the
-   LaTeX3 team.  The files for the package or class will tell you how
+   LaTeX Project team.  The files for the package or class will tell you how
    it is supported. The test file should use the package latexbug to
-   check that all packages in the file are supported by the LaTeX3
+   check that all packages in the file are supported by the LaTeX
    Project (see the discussion on the website why this is important).
 
  * The error is not caused by using an obsolete version of any file or
@@ -85,4 +85,4 @@
 Please *do not* send such reports to the latex-bugs address.
 
 
---- Copyright 1997,1998,2006,2008,2017,2020 the LaTeX3 project.  All rights reserved ---
+--- Copyright (C) 1997-2021 the LaTeX Project.  All rights reserved ---

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

Modified: trunk/Master/texmf-dist/doc/latex/base/cfgguide.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/cfgguide.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/cfgguide.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -39,7 +39,7 @@
 
 \title{Configuration options for \LaTeXe}
 
-\author{\copyright~Copyright 1998, 2001, 2003 \LaTeX3 Project Team.\\
+\author{\copyright~Copyright 1998, 2001, 2003 \LaTeX\ Project Team.\\
    All rights reserved.}
 
 \date{14 February 2003}
@@ -146,7 +146,7 @@
      portable only in the sense of being processable at a different
      site---the actual formatting will not be the same if different
      fonts are used.
-   \item The \LaTeX3 project team will not be able to support you in
+   \item The \LaTeX\ Project team will not be able to support you in
      diagnosing problems if these cannot be reproduced with a format
      that does not use any configuration files.
    \end{itemize}
@@ -288,7 +288,7 @@
      portable only in the sense of being processable at a different
      site---the actual formatting will not be the same if different
      fonts are used.
-   \item The \LaTeX3 project team will not be able to support you in
+   \item The \LaTeX\ Project team will not be able to support you in
      diagnosing problems if these cannot be reproduced with a format
      that does not use any customised font definition files.
    \end{itemize}
@@ -370,7 +370,7 @@
    \item Documents are portable only in the sense of being processable
      at a different site---the actual formatting will not be the same
      if different fonts are used.
-   \item The \LaTeX3 project team will not be able to support you in
+   \item The \LaTeX\ Project team will not be able to support you in
      diagnosing problems if these cannot be reproduced with a format
      that does not use this configuration file.
    \end{itemize}

Modified: trunk/Master/texmf-dist/doc/latex/base/changes.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/changes.txt	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/changes.txt	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,4 +1,4 @@
-================================================================================
+================================================================================
 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
@@ -10,7 +10,398 @@
 All changes above are only part of the development branch for the next release.
 ================================================================================
 
+#########################
+# 2020-06-01 Release
+#########################
 
+2021-05-31  David Carlisle  <David.Carlisle at latex-project.org>
+
+	* ltclass.dtx: Initialise \@raw at classoptionslist to \relax to
+	match \@classoptionslist
+
+2021-05-30  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* doc.dtx (subsection{Macros for the `documentation parts'}):
+	Use same error message text as in format
+
+2021-05-26  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltdefns.dtx (subsection{Robust commands and protect}):
+	Normalize error message in \MakeRobust
+
+2021-05-26  Phelype Oleinik  <phelype.oleinik at latex-project.org>
+
+	* lthooks.dtx:
+	Remove deprecated \DeclareDefaultHookLabel for good.
+
+2021-05-25  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* lthooks.dtx, ltfilehook.dtx:
+	Normalized some error message texts
+
+2021-05-24  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltcmd.dtx, ltcmdhooks.dtx, ltfilehook.dtx, lthooks.dtx, ltpara.dtx:
+	Use \msg_... instead of \__kernel_msg... commands for normalized
+	error and warning commands.
+
+2021-05-14  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltoutput.dtx: normalize the error commands, always use
+	\@latex at error not \@latexerr
+
+2021-04-29  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* lthooks.dtx (subsection{\LaTeXe{} package interface commands}):
+	Add \ProvideHook and related commands.
+
+2021-04-29  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* lthooks.dtx, ltfilehook.dtx:
+	Switch to kernel (not package) errors.
+
+2021-04-29  Marcel Krüger  <Marcel.Krueger at latex-project.org>
+
+	* ltoutenc.dtx (subsection{Definitions for the TU encoding}):
+	Declare Unicode composites for \'\ae, \'\AE and add æ/Æ equivalents for
+	\ae/\AE composites
+
+
+2021-04-26  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltfsstrc.dtx (subsection{General font loading}):
+	Unset the forced series boolean when reaching \selectfont (gh/444)
+
+	* ltfssini.dtx (subsection{Miscellaneous}):
+	Unconditionally switch to the requested	font face with \normalfont (gh/444)
+
+	* ltfssbas.dtx (subsection{Macros for the user}):
+	Unconditionally switch to the requested	font face with \usefont (gh/444)
+
+
+2021-04-20  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltexpl.dtx (subsection{Loader}): Don't empty kernel hooks on rollback
+
+	* ltcmd.dtx (subsection{Utilities}):
+	Renamed \__cmd_cmd_if_xparse:NTF to \__kernel_cmd_if_xparse:NTF
+	for cross-module usage
+
+	* ltcmdhooks.dtx:  Module added to provide support for cmd hooks
+
+	* lthooks.dtx: Support for cmd hooks added
+
+
+2021-04-20  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* lttab.dtx (subsection{array and tabular environments}):
+	Use \protected for \\ variant (gh/548)}
+
+	* ltmath.dtx (subsection{Math Environments}):
+	Use \protected for \\ variant (gh/548)}
+
+	* ltpictur.dtx (section{Picture Mode}):
+	Use \protected for \\ variant (gh/548)}
+
+
+2021-04-18  Phelype Oleinik  <phelype.oleinik at latex-project.org>
+
+	* ltfilehook.dtx:
+	Ensure that ~ expands to the character ~ in file names.
+
+2021-04-18  Phelype Oleinik  <phelype.oleinik at latex-project.org>
+
+	* ltplain.dtx:
+	Add support for \tracingstacklevels and \tracinglostchars=3.
+
+2021-04-16  Phelype Oleinik  <phelype.oleinik at latex-project.org>
+
+	* latexrelease.dtx, ltcmd.dtx, lthooks.dtx, ltpara.dtx,
+	lttextcomp.dtx, ltvers.dtx:
+	Change argument signature of \NewModuleRelease to be the same
+		as \IncludeInRelease (date, name, message).
+
+2021-04-13  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltpara.dtx: Updated the integration of ltpara module;
+	enabled rollback; some command name changes compared to the initial
+	prototype.
+
+2021-03-18  Phelype Oleinik  <phelype.oleinik at latex-project.org>
+
+	* ltclass.dtx:
+	Do not rollback expl3 file stack management (gh/504).
+
+2021-03-26  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltplain.dtx (section{Plain \TeX}):
+	Allocate \@inputcheck and \@unused early
+        so that they are before expl3 allocates more streams.
+	In the past this was done in ltfiles  (gh/538).
+
+2021-03-18  Phelype Oleinik  <phelype.oleinik at latex-project.org>
+
+	* ltvers.dtx:
+	Add \NewModuleRelease and support mechanism to define a new module
+		for proper behaviour when rolling backwards/forwards (gh/479).
+
+	* latexrelease.dtx:
+	Avoid errors when defining commands that already exist.
+
+	* ltcmd.dtx:
+	Use \NewModuleRelease to declare itself in latexrelease.sty.
+
+	* lthooks.dtx:
+	Use \NewModuleRelease to declare itself in latexrelease.sty.
+	Take care when reloading not to mess with the default name stack.
+
+	* ltfilehook.dtx:
+	Take care when reloading not to mess with the default name stack.
+
+	* ltfssaxes.dtx, ltfssini.dtx:
+	Minor corrections to rollback and rollforward.
+
+2021-03-12  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltfiles.dtx (subsection{Safe Input Macros}):
+	Allow for unbalanced conditionals inside arguments #2 and #3
+	of \IfFileExists (gh/530)
+
+2021-03-05  David Carlisle  <David.Carlisle at latex-project.org>
+
+	* base/ltclass.dtx: Modify \ProcessOption* handling so key=value
+	terms can be safely skipped (gh/513)
+
+2021-03-03  Phelype Oleinik  <phelype.oleinik at latex-project.org>
+
+	* ltclass.dtx:
+	Fix overwrite check for files with UTF-8 (gh/415).
+
+2021-02-25  Marcel Krüger  <Marcel.Krueger at latex-project.org>
+
+	* ltfinal.dtx:
+	Improve speed of compatibility code for preloading \pdfglyphtounicode
+	into \everyjob
+
+2021-02-19  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltoutenc.dtx (subsection{Definitions for the TU encoding}):
+	Add \textnonbreakinghyphen, \textfiguredash and \texthorizontalbar
+	to OT1, T1 and TU encoding (gh/404)
+
+	* doc-v3beta.sty: File added, currently for internal documentation
+	only; to be replaced in a later release.
+
+2021-02-18  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltclass.dtx: save raw package/class option lists to improve
+	key/val usage in optional argument of \usepackage and
+	\documentclass.
+
+2021-02-17  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltoutenc.dtx (subsection{Definitions for the TS1 encoding}):
+	Special definition for \textasteriskcentered when missing in TS1 (gh/502)
+
+	* ltoutenc.dtx (subsection{Definitions for the TU encoding}):
+	Adjust values for \textasteriskcentered To match TS1 definition (gh/502)
+
+2021-02-16  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltpara.dtx: providing paragraph hooks,; full integration into
+	latex.ltx will happen at a later point in time. For documentation
+	see ltpara-doc.pdf.
+
+2021-02-16  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltfloat.dtx (subsection{Footnotes}):
+	\footref added
+
+2021-02-15  David Carlisle  <David.Carlisle at latex-project.org>
+
+	* ltfssdcl.dtx: two additional \expandafter to avoid infinite
+	loop on not in math error. (gh/501)
+
+2021-02-11  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* classes.dtx (subsubsection{Itemize}):
+	Drop incorrect space in \labelitemiv (gh/496)
+	Document use of \labelitemfont in ltnews33 (gh/497)
+
+2021-02-10  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltoutenc.dtx (subsection{Definitions for the TU encoding}):
+	Add \textnonbreakinghyphen}, \textfiguredash and
+	\texthorizontalbar (gh/404)
+
+2021-02-10  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltboxes.dtx (section{\LaTeX\ Box commands}):
+	Explicitly run \par at the end of footnote text in preparation
+	for paragraph hooks
+
+	* ltfloat.dtx (subsection{Footnotes}):
+	Explicitly run \par at the end of footnote text in preparation
+	for paragraph hooks
+
+2021-02-08  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltfilehook.dtx (subsection{Patching \LaTeX{}'s \InputIfFileExists command}):
+	Undo the internal for robust \InputIfFileExists in rollback (gh/494)
+
+2021-02-08  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltmiscen.dtx (subsection{Environments}):
+	Undo the internals for \begin and \end as well when
+	rolling back (gh/494)
+
+2021-02-04  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltboxes.dtx (section{\LaTeX\ Box commands}):
+	Always add the color groups (gh/488)
+
+2021-02-03  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltfloat.dtx (subsection{Floating Environments}):
+	Explicitly end the \marginpar argument with \par to support
+	tagging (gh/489)
+
+2021-01-31  David Carlisle  <David.Carlisle at latex-project.org>
+
+	* ltfilehook.dtx: set \protect to \string to avoid bad
+          expansion and possible non termination. github/481
+
+2021-01-27  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* utf8ienc.dtx (subsection{The mapping table}):
+	Support various Unicode characters with dot accents for
+	Indic transliterations (gh/484)
+
+2021-01-22  Marcel Krüger  <Marcel.Krueger at latex-project.org>
+
+	* ltshipout.dtx:
+	Define and call Lua callback pre_shipout_filter.
+
+2021-01-21  Marcel Krüger  <Marcel.Krueger at latex-project.org>
+
+	* ltfinal.dtx:
+	For pdfTeX enable automatic generation of ToUnicode maps.
+	For pdfTeX versions which do not support dumping these into the format,
+	all \pdfglyphtounicode instructions will be dumped into \everyjob
+
+2021-01-19  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltshipout.dtx: Reordered execution of shipout hooks so that code
+	in one can influence code in later ones in a more natural manner.
+
+2020-01-16  Joseph Wright  <Joseph.Wright at latex-project.org>
+
+	* ltexpl.dtx
+	Adjust for full xparse integration
+
+	* ltcmd.dtx
+	New file to replace loading xparse
+
+2021-01-12  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltshipout.dtx: Make sure that the shipout/firstpage hook material
+	is not stored inside \ShipoutBox, in case that gets reused, e.g. via
+	\RawShipout but is only ever added to the very first page shipped out.
+
+2021-01-10  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltshipout.dtx:
+	Added internal \@kernel at after@shipout at background hook.
+	Added public shipout/after hook
+
+	(subsection{Overloading the \shipout primitive}):
+	Add \RawShipout for shipping out while bypassing most hooks.
+
+	(subsection{Emulating atbegshi}): Added
+	\AtBeginShipoutOriginalShipout to the emulation of atbegshi.
+
+2021-01-08  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltshipout.dtx (subsection{Package \pkg{everyshi} emulation}):
+	The emulation is no longer needed so taken out (gh440)
+
+2020-12-22  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltfssaxes.dtx (subsection{Changing to a new series}):
+	Distangle series and shape update by delaying the font series
+	and font shape merging (gh/444)
+
+	Move the rollback info for \normalshape after its main definition
+	otherwise it will not be undone	(gh/458)
+
+2020-12-22  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltfsstrc.dtx (subsection{General font loading}):
+	Alter \selectfont to do the delayed merging of  font series
+	and font shape (gh/444)
+
+2020-12-27  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* letter.dtx (subsubsection{Page breaking control}):
+	The \opening argument was splitting name and address using \\
+	but did not allow to use \\[...] for this (gh/427)
+
+2020-12-10  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltbibl.dtx (section{Bibliography Generation}):
+	Delay any \cs{nocite} in the preamble instead of raising
+	an error (gh/424)
+
+2020-12-06  Johannes Braams  <Johannes.Braams at latex-project.org>
+
+	* miscelaneous files: gh/428, gh/429 and gh/430 list a number of
+	typing mistakes and missing documentation that have crept in over
+	the years. The following files were affected and have been
+	corrected:
+	alltt.dtx, classes.dtx, doc.dtx, docstrip.dtx, fix-cm.dtx,
+	fontdef.dtx, ifthen.dtx, inputenc.dtx, latex209.dtx,
+	latexrelease.dtx, ltbibl.dtx, ltboxes.dtx, ltclass.dtx,
+	ltcntrl.dtx, ltcounts.dtx, ltdefns.dtx, ltdirchk.dtx, ltexpl.dtx,
+	ltfilehook.dtx, ltfiles.dtx, ltfinal.dtx, ltfloat.dtx,
+	ltfntcmd.dtx, ltfssaxes.dtx, ltfssbas.dtx, ltfsscmp.dtx,
+	ltfssdcl.dtx, ltfssini.dtx, ltfsstrc.dtx, lthooks.dtx,
+	ltlength.dtx, ltlists.dtx, ltluatex.dtx, ltmath.dtx, ltmiscen.dtx,
+	ltoutenc.dtx, ltoutput.dtx, ltpage.dtx, ltpageno.dtx,
+	ltpictur.dtx, ltplain.dtx, ltsect.dtx, ltshipout.dtx,
+	lttextcomp.dtx, ltvers.dtx, ltxdoc.dtx, ltxref.dtx, nfssfont.dtx,
+	proc.dtx, slides.dtx, utf8ienc.dtx.
+
+2020-12-04  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltfilehook.dtx (subsection{Declaring a file substitution}):
+	Don't drop file substitution declarations when rolling back
+	just render them no-ops
+
+2020-12-04  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+	Add a hook to \selectfont to be executed after the switch to the
+	new font. This implements the functionality formerly in the everysel
+	package.
+
+2020-12-04  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltfinal.dtx (subsection{File substitutions}):
+	Emulate everysel package
+
+2020-12-04  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltfssini.dtx (subsection{Miscellaneous}):
+	Setting up \f at series and \f at shape default values directly (gh/444)
+
+2020-11-23  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltshipout.dtx:
+	Check for both kernel and user hooks and execute if either is non-empty (gh/431)}
+
+2020-10-26  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* ltmiscen.dtx (subsection{Environments}):
+	\enddocument should always start out in vmode (gh/385)
+
 #########################
 # 2020-10-01 PL 4 Release
 #########################
@@ -33,8 +424,8 @@
 
 2020-12-03  Joseph Wright  <Joseph.Wright at latex-project.org>
 
-        * usrguide3.tex
-          New file to cover creation of document commands
+	* usrguide3.tex
+	New file to cover creation of document commands
 
 
 #########################
@@ -495,7 +886,7 @@
 
 	* ltclass.dtx (section{Implementation}):
 	Add \IfFormatAtLeastTF to test if the current format is equal or later than
-	the given date (gh/168)
+	the given date (gh/186)
 	Also add \IfClassAtLeastTF and \IfPackageAtLeastTF as a suggested
 	alternative to \@ifpackagelater and \@ifclasslater (which have a wrong
 	name, because it is really "later or equal") (gh/186)

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

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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/clsguide.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -34,7 +34,7 @@
 
 \title{\LaTeXe~for class and package writers}
 
-\author{Copyright \copyright~1995--2006 The \LaTeX3 Project\\
+\author{Copyright \copyright~1995--2006 The \LaTeX\ Project\\
    All rights reserved}
 
 \date{15 February 2006}

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/cyrguide.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/cyrguide.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/cyrguide.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -33,7 +33,7 @@
 \title{Cyrillic languages support in \LaTeX}
 
 \author{\copyright~Copyright 1998--1999,\\ Vladimir Volovich,
-        Werner Lemberg and \LaTeX3 Project Team.\\ All rights reserved.}
+        Werner Lemberg and \LaTeX\ Project Team.\\ All rights reserved.}
 
 \date{12 March 1999}
 
@@ -381,7 +381,7 @@
 experimental \textsf{mathtext} package, which is also in the
 \textsf{T2}~bundle.  Note that this package uses up at least one
 additional math alphabet per font encoding.  For this and other
-reasons, The \LaTeX3 Project Team considers that this experimental
+reasons, The \LaTeX\ Project Team considers that this experimental
 extension to \LaTeX{}'s glyph-handling mechanisms should be used with
 caution; but please try it out and send us your opinions and ideas.
 Note that it is not included in the core of \LaTeX{} because both the

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/encguide.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/encguide.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/encguide.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -188,7 +188,7 @@
 \title{\LaTeX{} font encodings}
 
 \author{Frank Mittelbach \and Robin
-   Fairbairns \and Werner Lemberg \and \LaTeX3 Project Team.}
+   Fairbairns \and Werner Lemberg \and \LaTeX\ Project Team.}
 
 \date{\copyright~Copyright 1995--2016 \\[5pt] 18 February 2016}
 
@@ -286,7 +286,7 @@
 
 Independently, a first proposal (the so-called \emph{Aston proposal}) was worked
 out by Justin Ziegler together with Frank Mittelbach and other members of the
-\LaTeX3 project team~\cite{ziegler}. A first implementation of
+\LaTeX\ Project team~\cite{ziegler}. A first implementation of
 this propsal was realized by Matthias Clasen und Ulrik
 Vieth~\cite{clasen,clasen-vieth}.
 
@@ -345,7 +345,7 @@
 Names for encoding schemes are strings of up to three letters (all
 upper case) plus digits.
 
-The \LaTeX3 project reserves the use of encoding names starting with the
+The \LaTeX\ Project reserves the use of encoding names starting with the
 following letters: |T| (standard 256-long text encodings), |TS|
 (symbols that are designed to extend a corresponding |T| encoding),
 |X| (text encodings that do not conform to the strict requirements for

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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/fntguide.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -37,12 +37,12 @@
 
 \title{\LaTeXe{} font selection}
 
-\author{\copyright~Copyright 1995--2020, \LaTeX3 Project
+\author{\copyright~Copyright 1995--2021, \LaTeX\ Project
   Team.\thanks{Thanks to Arash Esbati for documenting the
     newer NFSS features of 2020}\\
    All rights reserved.}
 
-\date{November 2020}
+\date{March 2021}
 
 \begin{document}
 
@@ -311,6 +311,11 @@
     \end{tabular}
   \end{minipage}
 \end{center}
+and there is also |ui| for upright italic, i.e., an italic shape but
+artifically turned upright. This is sometimes useful and available in
+some fonts.
+
+
 The font size is specified as a dimension, for example |10pt| or |1.5in|
 or |3mm|; if no unit is specified, |pt| is assumed.  These five
 parameters specify every \LaTeX{} font, for example:
@@ -1800,7 +1805,7 @@
   Names for encoding schemes are strings of up to three letters (all
   upper case) plus digits.
 
-  The \LaTeX3 project reserves the use of encodings starting with the
+  The \LaTeX\ Project reserves the use of encodings starting with the
   following letters: |T| (standard 256-long text encodings), |TS|
   (symbols that are designed to extend a corresponding |T| encoding),
   |X| (text encodings that do not conform to the strict requirements for

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/latexchanges.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/latexchanges.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/latexchanges.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/latexchanges.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 2015-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 2015-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -38,7 +38,7 @@
 
 \title{Changes to the \LaTeXe{} format}
 
-\author{\copyright~Copyright 2015--2021, \LaTeX3 Project Team.\\
+\author{\copyright~Copyright 2015--2021, \LaTeX\ Project Team.\\
    All rights reserved.}
 
 \date{2021-01-08}
@@ -985,7 +985,7 @@
 reliable test for math mode that doesn't destroy
 kerning. Fortunately this problem can be solved when using e\TeX\ so
 if you use this as engine for your \LaTeX\ format, as recommended by
-the \LaTeX3 Project, you will get a fully functioning |\TextOrMath|
+the \LaTeX\ Project, you will get a fully functioning |\TextOrMath|
 command with no side effects. If you use regular \TeX\ as engine for
 your \LaTeX\ format then we have to choose between the lesser of two
 evils: 1)~breaking ligatures and preventing kerning or 2)~face the

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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/lb2.err	2021-06-01 21:12:14 UTC (rev 59424)
@@ -19,7 +19,7 @@
 
 \begin{filecontents}{ttcterrata.cls}
 %%
-%% Copyright (C) 1997,2004,2005,2007, 2014 Frank Mittelbach
+%% Copyright (C) 1997-2021 Frank Mittelbach
 %% This class file is licenced under LPPL latest version;
 %% see https://www.latex-project.org/lppl
 %
@@ -35,9 +35,10 @@
 % Changes:
 %
 % v1.0a - changed name from errata.cls to ttcterrata.cls
+% v1.0b - added \arraybackslash
 
 \ProvidesClass{ttcterrata}
-  [2007/11/10 v1.0a Mini class for errata files; subject to change (FMi)]
+  [2021/04/22 v1.0b Mini class for errata files; subject to change (FMi)]
 
 \LoadClass{article}
 
@@ -164,7 +165,7 @@
   \multicolumn{4}{l}{\framebox[10cm][l]{\textbf{\normalsize\strut#1}}} \\}
 
 \newenvironment{erratalist}
-  {\begin{longtable}{r>{\raggedright}p{2cm}l>{\raggedright}p{10cm}l}}
+  {\begin{longtable}{r>{\raggedright\arraybackslash}p{2cm}l>{\raggedright\arraybackslash}p{10cm}l}}
   {\endgobble\end{longtable}}
 
 \newcommand\erratatitle[2]

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

Modified: trunk/Master/texmf-dist/doc/latex/base/legal.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/legal.txt	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/legal.txt	2021-06-01 21:12:14 UTC (rev 59424)
@@ -7,9 +7,8 @@
 =========
 
 This distribution is
-Copyright 1993 1994 1995 1996 1997 1998 1999 2000 2001 2002 2003 2004 2005
-          2006 2007 2008 2009 2011 2014 2015 2016
-The LaTeX3 Project and the individual authors:
+Copyright (C) 1993-2021
+The LaTeX Project and the individual authors:
 
    Leslie Lamport
    Johannes Braams

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

Modified: trunk/Master/texmf-dist/doc/latex/base/lgc2.err
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/lgc2.err	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/lgc2.err	2021-06-01 21:12:14 UTC (rev 59424)
@@ -17,7 +17,7 @@
 
 \begin{filecontents}{ttcterrata.cls}
 %%
-%% Copyright (C) 1997,2004,2005,2007 Frank Mittelbach
+%% Copyright (C) 1997-2021 Frank Mittelbach
 %% This class file is licenced under LPPL latest version;
 %% see https://www.latex-project.org/lppl
 %
@@ -33,9 +33,10 @@
 % Changes:
 %
 % v1.0a - changed name from errata.cls to ttcterrata.cls
+% v1.0b - added \arraybackslash
 
 \ProvidesClass{ttcterrata}
-  [2007/11/10 v1.0a Mini class for errata files; subject to change (FMi)]
+  [2021/04/22 v1.0b Mini class for errata files; subject to change (FMi)]
 
 \LoadClass{article}
 
@@ -162,7 +163,7 @@
   \multicolumn{4}{l}{\framebox[10cm][l]{\textbf{\normalsize\strut#1}}} \\}
 
 \newenvironment{erratalist}
-  {\begin{longtable}{r>{\raggedright}p{2cm}l>{\raggedright}p{10cm}l}}
+  {\begin{longtable}{r>{\raggedright\arraybackslash}p{2cm}l>{\raggedright\arraybackslash}p{10cm}l}}
   {\endgobble\end{longtable}}
 
 \newcommand\erratatitle[2]

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)

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

Index: trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-code.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-code.pdf	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-code.pdf	2021-06-01 21:12:14 UTC (rev 59424)

Property changes on: trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-code.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-code.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-code.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-code.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -0,0 +1,4 @@
+% this will typeset documentation + code
+
+\AtBeginDocument{\AlsoImplementation}
+\input{ltcmdhooks.dtx}


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

Index: trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-doc.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-doc.pdf	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-doc.pdf	2021-06-01 21:12:14 UTC (rev 59424)

Property changes on: trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-doc.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-doc.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-doc.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-doc.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -0,0 +1,6 @@
+% this will typeset only documentation but not the code
+
+\AtBeginDocument{\OnlyDescription
+                 \let\tableofcontents\relax
+                 }
+\input{ltcmdhooks.dtx}


Property changes on: trunk/Master/texmf-dist/doc/latex/base/ltcmdhooks-doc.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
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/ltnews.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,9 @@
 % \iffalse meta-comment
 %
-% Copyright 2006, 2009, 2011, 2014 Heiko Oberdiek
-% Copyright (C) 2014-2020 The LaTeX3 Project
+% Copyright (C) 2006, 2009, 2011, 2014 Heiko Oberdiek
+% Copyright (C) 2014-2021 
+% The LaTeX Project and any individual authors listed elsewhere
+% in this file.
 %
 % This file is part of the LaTeX base system.
 % -------------------------------------------
@@ -36,9 +38,9 @@
 
 \NeedsTeXFormat{LaTeX2e}
 \ProvidesFile{ltnews.tex}%
-  [2020/04/13 v1.4d Master file for ltnews*.tex (LaTeX Project)]
+  [2020/10/25 v1.4d Master file for ltnews*.tex (LaTeX Project)]
 
-\providecommand*{\lastissue}{32}
+\providecommand*{\lastissue}{33}
 
 \InputIfFileExists{ltnews-lastissue.cfg}{}{}
 
@@ -175,6 +177,11 @@
     \egroup
   }
 
+\ExplSyntaxOn
+\newcommand \acro [1]
+  { \textsc { \text_lowercase:n {#1} } }
+\ExplSyntaxOff
+
 \makeatother
 
 

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews01.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews01.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews01.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -52,8 +52,8 @@
 
 The most important news is the release of \LaTeXe, the new version of
 the \LaTeX{} software.  This version has better support for fonts,
-graphics and colour, and will be actively maintained by the \LaTeX3
-project team.  Upgrades will be issued every six months, in June and
+graphics and colour, and will be actively maintained by the \LaTeX\
+Project team.  Upgrades will be issued every six months, in June and
 December.
 
 \section{Why a new \LaTeX?}
@@ -110,7 +110,7 @@
 \item[graphics] for including images.
 \item[mfnfss] for using bitmap fonts.
 \item[psnfss] for using Type~1 fonts.
-\item[tools]  other packages by the \LaTeX3 team.
+\item[tools]  other packages by the \LaTeX\ Project team.
 \end{citations}
 The packages come with full documentation, and are also described in
 \emph{\LaTeX: A Document Processing System} or

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews02.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews02.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews02.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews03.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews03.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews03.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews04.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews04.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews04.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews05.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews05.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews05.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews06.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews06.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews06.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews07.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews07.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews07.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews08.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews08.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews08.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews09.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews09.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews09.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -47,7 +47,7 @@
 
 \section{New math font encodings}
 
-A joint working group of the \TeX{} Users Group and the \LaTeX3
+A joint working group of the \TeX{} Users Group and the \LaTeX\
 Project is developing a new 8-bit math font encoding for \TeX{}.
 It is designed to overcome several limitations and implementation
 problems of the old math font encodings and to simplify switching

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews10.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews10.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews10.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews11.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews11.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews11.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -110,7 +110,7 @@
 \section{New math font encodings}
 
 As we announced in \LaTeX{} News~9, a joint working group of the
-\TeX{} Users Group and the \LaTeX3 Project has developed a new
+\TeX{} Users Group and the \LaTeX\ Project has developed a new
 \mbox{8-bit} math font encoding for \TeX{}.
 The reason why this work is not yet released is because of other
 exciting developments in the world of math fonts and math characters.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews12.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews12.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews12.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -40,8 +40,7 @@
 \publicationyear{1999}
 \publicationissue{12}
 
-% Should go to .cls:
-\newcommand{\acro}[1]{\textsc{\MakeLowercase{#1}}}
+\providecommand{\acro}[1]{\textsc{\MakeLowercase{#1}}}
 
 \begin{document}
 

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews13.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews13.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews13.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews14.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews14.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews14.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews15.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews15.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews15.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews16.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews16.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews16.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -49,7 +49,7 @@
 \section{Anniversary news}
 
 This anniversary \textit{Issue~16} takes a brief look into the future work of
-the \LaTeX3 Project Team, both short and longer range.  Please let
+the \LaTeX\ Project Team, both short and longer range.  Please let
 us know if you want %\newline
 to get involved with us in any of this work (see below).
 

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews17.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews17.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews17.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews18.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews18.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews18.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews19.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews19.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews19.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews20.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews20.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews20.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
 % Copyright 1993--2019
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews21.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews21.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews21.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
 % Copyright 2019
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews22.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews22.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews22.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 2015-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 2015-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews23.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews23.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews23.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 2015-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 2015-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews24.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews24.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews24.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 2015-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 2015-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews25.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews25.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews25.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 2016-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 2016-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews26.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews26.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews26.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 2017-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 2017-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews27.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews27.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews27.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 2017-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 2017-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews28.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 2017-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 2017-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -353,7 +353,7 @@
   In: TUGboat, 38\#2, 2017.
   \url{https://www.latex-project.org/publications/}
 
-\bibitem{amsldoc} American Mathematical Society and The \LaTeX3 Project:
+\bibitem{amsldoc} American Mathematical Society and The \LaTeX\ Project:
   \emph{User's Guide for the \texttt{amsmath} package} (Version 2.1).
   April 2018.
   Available from

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews29.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews29.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews29.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 2018-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 2018-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -513,7 +513,7 @@
   \emph{\LaTeX{} Project publications on the \LaTeX{} Project Website}.\\
   \url{https://latex-project.org/publications/}
 
-\bibitem{29:amsldoc} American Mathematical Society and The \LaTeX3 Project:
+\bibitem{29:amsldoc} American Mathematical Society and The \LaTeX\ Project:
   \emph{User's Guide for the \texttt{amsmath} Package} (Version 2.1).
   April 2018.
   Available from

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews30.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews30.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews30.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
 % Copyright 2019
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews31.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
 % Copyright 2019-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/ltnews32.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews32.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews32.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
 % Copyright 2019-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -278,7 +278,7 @@
 in \texttt{picture} mode are non-stretchy).
 
 So, valid uses include \verb|\put(2,2)| as previously,
- but now also uses such as\tubcommand\\\verb|\put(\textwidth-5cm,0.4\textheight)|.
+ but now also uses such as\tubcommand\\ \verb|\put(\textwidth-5cm,0.4\textheight)|.
 
 Note that you can only use expressions with lengths; \verb|\put(1+2,0)| is not
 supported.

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

Index: trunk/Master/texmf-dist/doc/latex/base/ltnews33.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews33.pdf	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews33.pdf	2021-06-01 21:12:14 UTC (rev 59424)

Property changes on: trunk/Master/texmf-dist/doc/latex/base/ltnews33.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/base/ltnews33.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltnews33.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/base/ltnews33.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -0,0 +1,942 @@
+% \iffalse meta-comment
+%
+% Copyright 2019-2021
+% The LaTeX Project and any individual authors listed elsewhere
+% in this file.
+%
+% This file is part of the LaTeX base system.
+% -------------------------------------------
+%
+% It may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3c
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+%    https://www.latex-project.org/lppl.txt
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2008 or later.
+%
+% This file has the LPPL maintenance status "maintained".
+%
+% The list of all files belonging to the LaTeX base distribution is
+% given in the file `manifest.txt'. See also `legal.txt' for additional
+% information.
+%
+% The list of derived (unpacked) files belonging to the distribution
+% and covered by LPPL is defined by the unpacking scripts (with
+% extension .ins) which are part of the distribution.
+%
+% \fi
+% Filename: ltnews33.tex
+%
+% This is issue 33 of LaTeX News.
+
+\NeedsTeXFormat{LaTeX2e}[2020-02-02]
+
+\documentclass{ltnews}
+
+%%CCC  Temporary definitions:
+\providecommand\Dash {\unskip ---}
+
+
+
+%% NOTE:  Chris' preferred hyphens!
+%%\showhyphens{parameters}
+\hyphenation{because para-me-ters}
+
+\usepackage[T1]{fontenc}
+
+\usepackage{lmodern,url,hologo}
+
+\usepackage{csquotes}
+\usepackage{multicol}
+
+\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}
+
+% 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\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
+
+
+\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}%
+}
+\newcommand\colonize[1]{#1:}
+\makeatother
+
+\let\finalvspace\vspace          % for document layout fixes
+
+
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\providecommand\tubcommand[1]{}
+\tubcommand{\input{tubltmac}}
+
+\publicationmonth{June}
+\publicationyear{2021}  %% --- Draft Version 3p
+
+\publicationissue{33}
+
+\begin{document}
+
+\tubcommand{\addtolength\textheight{4.2pc}}   % only for TUB
+
+\maketitle
+{\hyphenpenalty=10000 \spaceskip=3.33pt \hbadness=10000 \tableofcontents}
+
+\setlength\rightskip{0pt plus 3em}
+
+
+\medskip
+
+
+\section{Introduction}
+
+The focus of the June 2021 release is to provide further important
+building blocks for the future production of
+reliable tagged PDF output
+(see \cite{33:blueprint}); these enhancements
+are discussed in the next two
+sections. 
+
+Subsequent sections describe quite a number of recent smaller
+enhancements and fixes.  As usual, more detail on individual changes
+can be found in the \texttt{changes.txt} files in the distribution
+and, of course, in the documented sources~\cite{33:source2e}.
+
+
+
+\section{Extending the hook concept to paragraphs}
+
+Largely triggered by the need for better control of paragraph text
+processing, in particular when producing tagged PDF output, we have
+changed \LaTeX{} so that the kernel gains control both at the start
+and at the end of each paragraph. This is done in a manner that is (or
+should be) transparent to both packages and documents.
+
+Besides the addition of internal control points for the exclusive use
+of the \LaTeX{} kernel, we also implemented four public hooks that can
+be used in packages or documents (via the normal hook management
+declarations) to achieve special effects, etc.  Until now, such
+enhancements required redefinitions of \cs{everypar} or \cs{par},
+which led to the usual issues since such changes can easily conflict
+with changes made by other packages.
+
+The documentation of these new \enquote{paragraph hooks}, together
+with a few examples, is in \file{ltpara-doc.pdf} and, for those who
+want to study it, the (quite interesting) code can be found in
+\file{ltpara-code.pdf}. Additionally, both of these files are included
+as part of the full kernel documentation in \file{source2e.pdf}.
+
+
+
+\section{Extending the hook concept to commands}
+
+Up to now, hook management covered hooks for only a few core areas,
+such as the hooks for the \cs{shipout} process or those in the
+\env{document} environment, as well as some \enquote {generic} hooks,
+both for file loading (helpful for patching such files) and for
+arbitrary environments (the hooks executed within \cs{begin} and
+\cs{end}).  This concept of \enquote{generic hooks} has now been
+extended to provide \hook{/before} and \hook{/after} hooks for any
+(document-level) command\Dash in theory at least.
+
+
+In practice, these new generic \hook{cmd} hooks, especially the
+\hook{cmd/.../after}, hooks may fail with commands that are too
+complex to be automatically patched, breaking if the hook contains any
+code.  These restrictions are documented in
+\texttt{ltcmdhooks-doc.pdf}.
+%   
+However, given that these hooks are mainly meant for developers who
+wish to provide better interoperability between different packages,
+and between packages and the \LaTeX{} kernel, these restrictions are,
+we hope, of minor importance.  Indeed, for commands where this
+mechanism can't be applied, one is in the same situation as before;
+and for all others there will be a noticeable improvement.
+
+These hooks will be especially important for our current project to
+provide accessible and tagged PDF output~\cite{33:blueprint} because
+we will eventually have to patch many third-party packages, and this
+must be done in controlled and standardized ways.
+
+
+
+
+\section{Other hook business}
+
+
+\subsection{Shipping out a page while bypassing hooks}
+
+In the 2020 October release, several hooks were added to control the
+process of constructing and shipping out a page box: these support,
+for example, the addition of background or foreground material 
+to some or all pages.
+
+ 
+We have now added a command, called \cs{RawShipout}, which does not do
+any rebuilding of the page box and so does not run most of these
+hooks.  When using this new command, essential internal book-keeping
+is still carried out, such as updating the \texttt{totalpages} counter
+and adding \texttt{shipout/firstpage} or \texttt{shipout/lastpage}
+material when appropriate.
+
+
+\subsection{A new Lua callback in \pkg{ltshipout},
+for custom attributes}
+
+For use just before shipping out a page, there is now a \LuaTeX{}
+callback \texttt{pre\_shipout\_filter} to contain final adjustments to
+the box being shipped out.  This is particularly useful for
+Lua\TeX\ packages which flag (using, for example, attributes or
+properties) elements on a page in order to apply effects (such as the
+insertion of \enquote{color commands}) to these elements at shipout.
+
+
+
+\section{Improved handling of file names}
+
+\subsection[File names with spaces, multiple dots or\\
+            \acro{utf-8} characters]
+           {File names with spaces, multiple dots or \acro{utf-8} characters}
+
+In one of the recent \LaTeX{} releases we improved the interface
+for specifying file names so that they can now safely contain spaces
+(as is common these days),
+more than one dot character, and also \acro{utf-8} characters
+outside the \acro{ascii} range. 
+In the past this was only possible by applying a special syntax
+in the case of spaces, 
+while file names with several dots often failed, 
+as did most \acro{utf-8} characters.
+
+
+\subsubsection{Consequences for file names in \cs{include}}
+
+\TeX{} has a built-in rule saying that you can normally leave out the
+extension if it is \texttt{.tex}.  Thus \verb=\input{file}= and
+\verb=\input{file.tex}= both load \file{file.tex} (if it exists).
+While this is convenient most of the time, it is a little awkward in
+some scenarios (for example, when both \file{file} and \file{file.tex}
+exist) and also when you manually try to implement the rule.
+
+\LaTeX{} therefore had one special syntax for \cs{include} and
+\cs{includeonly}: they always expected that 
+their arguments contain a
+file name\footnote{In the case of \cs{includeonly}, a comma-separated list of such names.} 
+with no extension given,
+  so that it had to be \texttt{.tex}.  Thus,
+ when you mistakenly wrote
+\verb=\include{mychap.tex}= (for example,
+because you changed from \cs{input}
+to \cs{include}),
+\LaTeX{} went ahead and looked for the
+file \file{mychap.tex.tex} for inclusion and tried to
+use the file \file{mychap.tex.aux} for internal (auxiliary) information.  The reason was that
+\cs{include} had to construct both
+of these file names from the given
+argument and it didn't bother to do
+anything special
+with the supplied 
+extension \texttt{.tex}.
+
+With the new implementation this has
+changed:
+the extension \texttt{.tex}
+now gets removed/ignored if it was
+supplied.
+Thus \verb=\include{mychap.tex}= now 
+no longer looks for \file{mychap.tex.tex} 
+but loads
+\file{mychap.tex} 
+and uses \file{mychap.aux}.
+%
+\githubissue{486}
+
+
+
+\subsection{Normalization of robust commands in file names}
+
+The handling of file names has been modified so that \verb|\string| is
+applied to normalize robust commands within the file name.
+Previously, for example, \verb|\input{\sqrt{2}}| would cause
+\LaTeX\ to loop indefinitely whereas with 
+the new normalization
+it looks for the file named \verb|sqrt {2}.tex|
+(and therefore very likely reports ``file not found'').
+%
+\githubissue{481}
+
+
+
+
+\subsection{Fix for \env{filecontents} with \acro{utf-8} 
+  chars in the file name}
+
+Since a few releases back, the \env{filecontents} environment has
+allowed \acro{utf-8} characters in the file name.  There was, however,
+a bug that would not allow \emph{over}writing a file with \acro{utf-8}
+characters in its name.  This has been fixed and now
+\env{filecontents} allows any characters in the file name.
+%
+\githubissue{415}
+
+
+
+\section{Updates to the font selection scheme}
+
+
+\subsection{A new hook in \cs{selectfont}}
+
+After \cs{selectfont} has changed the font, we now run a hook (\hook{selectfont})
+so that packages can make final \mbox{adjustments}. This functionality was
+originally provided by the \pkg{everysel} package but our
+implementation is slightly different and uses the standard hook
+management.
+%
+\githubissue{444}
+
+
+\subsection{Change of font series/shape delayed until \cs{selectfont}}
+
+With the NFSS extensions introduced in 2020, the font series and shape
+settings can be influenced by changes to the font family.  The
+settings of these two are now therefore delayed until \cs{selectfont}
+is executed; this avoids unnecessary or incorrect substitutions that
+may otherwise happen due to the order of declarations.
+%
+\githubissue{444}
+
+
+
+\section{Glyphs, characters \& encodings}
+
+\subsection{Improved copy\,\&\,paste for \pdfTeX{} documents}
+
+When compiling with \pdfTeX{}, additional information
+(from the file \texttt{glyphtounicode.tex}) is now added automatically
+to the PDF file in order to improve copying from, and searching in,
+text.
+
+In particular, this allows the most common ligatures to be copied as
+intended from all generated PDF files without the need to explicitly
+load the package \pkg{cmap}.  
+%
+\githubissue{465}
+
+
+
+
+
+\subsection{Support for more Unicode characters}
+
+
+\LaTeX\ is quite capable of typesetting characters such as
+\enquote{\d{m}}, but until now it could not access some Unicode
+characters from the Latin Extended Additional block.  This meant that,
+for example, there were no Unicode mappings for some characters that
+are used to write Sanskrit words in Latin transliteration (as seen in
+books about yoga, Buddhist philosophy, etc.).
+%
+These characters have now been added so that they can be entered
+directly instead of using \verb=\d{m}=, etc.
+%
+\githubissue{484}
+
+
+
+
+
+\subsection{More ``dashes'' in encodings \texttt{OT1},
+  \texttt{T1} and \texttt{TU}}
+
+When pasting in text from external sources, one can encounter these
+three Unicode characters
+%
+\texttt{"2011} (non-breaking hyphen),
+\texttt{"2012} (figure dash) and
+\texttt{"2015} (horizontal bar),
+%
+in addition to the more common 
+%
+\texttt{"2013} (en-dash) and \texttt{"2014} (em-dash).
+%
+In the past, these first three produced an error message when used
+with \pdfTeX{} (since they are not available in \texttt{OT1} or
+\texttt{T1} encoded fonts).  They now typeset an approximation to the
+glyph: e.g., the ``figure dash'' is approximated by an en-dash.
+
+With Unicode engines they either work (when the glyph is contained in
+the selected Unicode font) or they typeset nothing, producing a
+``Missing character'' warning in the log file.
+
+With all engines these characters can also now be accessed using the
+command names \cs{textnonbreakinghyphen}, \cs{textfiguredash} and
+\cs{texthorizontalbar}, respectively.
+%
+\githubissue{404}
+
+
+\subsection{Poor man's \cs{textasteriskcentered}}
+
+The \cs{textasteriskcentered} symbol, used as part of the set of
+footnote symbols in \LaTeX{}, is assumed to be implemented by every
+font with the \texttt{TS1} encoding (when \pdfTeX{} is used) or with
+the \texttt{TU} encoding for the Unicode engines.  That assumption is
+unfortunately not correct for all fonts since, for example, the
+\texttt{stix2} fonts don't provide this glyph.  A result is that one
+gets missing glyph messages when using \cs{thanks}, etc.
+
+Therefore \cs{textasteriskcentered} now checks whether there is such a
+glyph and, if not, uses a normal \enquote{*}, but slightly enlarged
+and lowered.  This may not be perfect in all cases, but it is
+certainly better than no glyph showing up.
+%
+\githubissue{502}
+
+\subsection {The characters from \pkg{textcomp} are in the kernel}
+
+A couple of releases back, the functionality of the \pkg{textcomp}
+package was integrated into the \LaTeX{} kernel.  Thus it is no longer
+necessary to load this package in order to access glyphs such as
+\cs{textcopyright}, \cs{texteuro} or \cs{textyen}.
+ 
+ 
+At this time the opportunity was also taken to bring some order to the
+chaos surrounding the question: \enquote{which glyphs from the
+  \texttt{TS1} encoding are available in a given font?}.  This was
+done using an approach based on font families and collections, with
+the differing glyph coverage of the \enquote*{text symbols} being
+indicated by assigning to a font family or collection a ``sub-encoding
+number'' that indicates which glyphs from the \texttt{TS1} encoding are
+guaranteed to be available when using a font from that family or
+collection. This assignment ensures that \LaTeX{} always errs on the
+side of caution, possibly claiming that a glyph is not available even
+when it in fact is.
+
+\iffalse  %%FMi but drop that
+
+The documented code for this can be found now in the file 
+\file{lttextcomp.dtx} but we hope to publish a full explanation of 
+the approach very soon now. 
+
+\fi  %% FMi potential drop
+
+
+
+\subsubsection
+   [A note on the history of ``text symbols'']
+   {A note on the history of ``text symbols'' and
+     the  \texttt{TS1} encoding}
+
+
+The \enquote{text symbol encoding} (\texttt{TS1}) was originally
+designed at the Cork Conference as a companion to the \texttt{T1}
+encoding. In it various symbols that are not subject to hyphenation
+got assembled and the \pkg{textcomp} package was developed to make
+them accessible. Unfortunately the \TeX{} community was a bit too
+enthusiastic and included several symbols only available in a few
+\TeX{} fonts and some, such as the capital accents, not available at
+all but developed as part of the reference font implementation.
+
+In hindsight that was a very bad idea because it meant that other
+existing fonts (at the time) and later new fonts that got developed
+were unable to provide the full set of glyphs that made up the
+\texttt{TS1} encoding. For existing free PostScript fonts people 
+took the extra effort and produced virtual fonts that faked (some) of
+the missing glyphs. But this was and is a time-consuming effort so it
+was done for only a few basic fonts. But even then, only some fonts
+included all glyphs from \texttt{TS1} so the \pkg{textcomp} already
+back then contained a long list, dividing fonts into 5 categories
+according to which glyphs were implemented and which were missing.
+
+
+When we recently integrated the functionality of the \pkg{textcomp}
+into the \LaTeX{} kernel
+many new free fonts had appeared and
+unfortunately the chaos around the question \enquote{which glyphs of
+  the \texttt{TS1} encoding are implemented by which font} had
+increased with it. Not only did one find many new holes, it was next to
+impossible to order the set of fonts into a reasonable set of
+sub-encodings that are contained in each other in a single sequence.
+
+In the end we decided on nine or ten sub-encodings with a reasonable
+number of fonts in each so that all fonts implemented all glyphs of the
+sub-encoding they got mapped to. Thus when typesetting with a font one
+could be sure that a command like \cs{textcopyleft} would either
+typeset the requested character (if the glyph was part of the
+sub-encoding the font belonged to) or it would raise an error, saying
+that the glyph is unavailable in that font.  The mapping would ensure
+that \LaTeX{} always errs on the side of caution, because it might
+claim a glyph is unavailable even though in fact it is.\looseness-1
+
+For example, the old \texttt{pcr} (PostScript Courier) font (as well
+as most other older PS fonts) is mapped to sub-encoding 5 and
+therefore claims that \cs{textasciigrave} is unavailable even though
+in fact for Courier this is not true. If one uses such a font and this
+becomes an issue then there are a couple (suboptimal) possibilities.
+For one, one can alter the mapping of Courier and pretend that belongs
+to a fuller sub-encoding, e.g.
+\begin{verbatim}
+  \DeclareEncodingSubset{TS1}{pcr}{2}
+\end{verbatim}
+The downside is, that \LaTeX{} then believes other glyphs that are in fact
+unavailable are also there, so that it is important to check that the
+final document doesn't have some missing glyphs.
+
+An alternative is to pretend that \cs{textasciigrave} can always be
+taken from the \texttt{TS1} encoding (no questions asked):
+\begin{verbatim}
+  \DeclareTextSymbolDefault{\textasciigrave}{TS1}
+\end{verbatim}
+Again there is a danger that this is not true when it is used with a
+different font and would then generate a missing glyph.
+
+Finally, and possibly the best solution, if not impossible for other
+reasons, is to simply use a different font, for example, to use the
+\TeX{} Gyre Cursor font (a reimplementation of Courier with a
+much more complete glyph set).
+
+
+
+
+\section{New or improved commands}
+
+\subsection{Adjusting \env{itemize} labels with \cs{labelitemfont}}
+
+The command \cs{labelitemfont} was introduced already with the
+\LaTeX\ release 2020-02-02, but back then we forgot to describe it, so
+we do this now. Its purpose is to resolve some bad formatting issues
+with the \env{itemize} environment and also to make it easier to
+adjust the layout when necessary. What could happen in the past was
+that the \env{itemize} labels (e.g., the \textbullet{}) would
+sometimes react to surrounding font changes and could then suddenly
+change shape, for example to \textit{\textbullet}.
+
+This new command \cs{labelitemfont}, which defaults to \cs{normalfont}, 
+can be used to provide additional control in the typesetting of
+each label.  Thus by choosing
+different settings other effects can be achieved.  Here are two
+examples:
+\begin{verbatim}
+  \renewcommand\labelitemfont
+     {\normalfont\fontfamily{lmss}\selectfont}
+  \renewcommand\labelitemfont
+     {\rmfamily\normalshape}
+\end{verbatim}
+The first definition will take the symbols from the font Latin Modern
+Sans, so that you get
+%
+\def\myfont#1{{\let\labelitemfont\empty\fontfamily{lmss}\selectfont#1}}%
+%
+\myfont\labelitemi, \myfont\labelitemii, \myfont\labelitemiii\ and
+\!\!\myfont\labelitemiv\,; while the second variant freezes the font family
+and shape, but leaves the series as a variable quantity, so that an
+\env{itemize} in a bold context would show bolder symbols. Making
+\cs{labelitemfont} empty would give you back the buggy old behavior.
+%
+\githubissue{497}
+
+
+\subsection{Producing several marks for one footnote}
+
+It is sometimes necessary to reference the same footnote several
+times: i.e., to produce several footnote marks using the same number
+or symbol. This is now easily possible by placing a \cs{label} within
+the referenced \cs{footnote} and referencing this label by using the
+new command \cs{footref}.  This means that footnote marks can be
+generated to refer to arbitrary footnotes (including those in
+\texttt{minipage}s).
+
+This \cs{footref} command has previously been available, but only when
+using certain classes or the \pkg{footmisc} package.
+%
+\githubissue{482}
+
+
+\subsection{Allow \cs{nocite} in the preamble}
+
+A natural place for \verb=\nocite{*}= would be the preamble of the
+document, but for historical reasons \LaTeX{} issued an error message
+if it was placed there.  This command is now allowed in the preamble.
+%
+\githubissue{424}
+
+
+\subsection{Made \cs{\textbackslash} generally robust}
+
+In 2018 most \LaTeX{} user-level commands were made robust, including
+the \cs{\textbackslash} command.  However, \cs{\textbackslash} gets
+redefined in various environments and not all these cases were caught:
+such as, in particular, its use as the row delimiter in \env{tabular}
+structures.  This has been corrected so that \cs{\textbackslash}
+should now be robust in all circumstances.
+
+
+This change also fixed one anomaly present in the past:
+in a tabular preamble of the form
+\finalvspace*{-.3\baselineskip}
+\begin{quote}
+  \hspace*{-.15em}\verb={l=\texttt{\string>}\verb={raggedright}p{10cm}r}=    % stupid class
+\end{quote}
+\finalvspace*{-.3\baselineskip}
+a \cs{\textbackslash} in the second column would have the definition
+used within \cs{raggedright} and so it would not indicate the
+(premature) end of the \env{tabular}.  Thus, for example,%
+\finalvspace*{-.3\baselineskip}
+\begin{quote}
+   \verb=a & b1 \\ b2 & c \\=
+\end{quote}
+\finalvspace*{-.3\baselineskip}
+was interpreted as a single row of the \env{tabular} (as intended),
+whereas
+\finalvspace*{-.3\baselineskip}
+\begin{quote}
+   \verb=a &    \\ b2 & c \\=
+\end{quote}
+\finalvspace*{-.3\baselineskip}
+resulted in two rows!  This happened because the \cs{\textbackslash}
+directly following the \verb=&= got interpreted while it still had the
+\enquote{end the row} meaning and not yet the \enquote{start a new
+  line within the second column} meaning.
+
+With \cs{\textbackslash} now being robust, the special scanning mode
+initiated by the \verb=&= ends immediately when this command is seen:
+the second column is therefore then started, which results in the
+\cs{\textbackslash} being interpreted as being within that column and
+hence as having its expected, within-column, meaning.
+
+We have restored consistency here: now both of the above lines
+produce a single \env{tabular} row.
+%
+As before, you can 
+put \cs{raggedright}\cs{arraybackslash} in the \env{tabular}'s
+preamble for a column to ensure that \cs{\textbackslash} is always
+interpreted as a tabular row separator when used in that column. And
+you can use \cs{tabularnewline} to explicitly ask for a new table row,
+even when \cs{\textbackslash} has a different meaning within the
+current column.
+%
+\githubissue{548}
+
+
+
+
+\subsection{Allow extra space between name and address in \pkg{letter} class}
+
+The \cs{opening} command in the \pkg{letter} class expects the name
+and address to be separated by \verb=\\=, but it didn't allow the use
+of an optional argument to add some extra space after the name. The
+code has now been slightly altered to allow this.
+%
+\githubissue{427}
+
+
+
+\subsection{Additions to \cs{tracingall}}
+
+In July 2020 David Jones suggested an extension to \TeX{} engines,
+that added the possibility to set \cs{tracinglostchars}\texttt{=3} in
+order to generate an error message in case some character is missing
+from a font.  In previous years, a warning about a missing character
+was silently printed to the \texttt{.log} file\linebreak
+(if $\cs{tracinglostchars}>0$) and to the terminal\linebreak
+ (if ${}>1$).  This extension was added for \TL{} and \MiKTeX{} 
+(except in Knuth's \TeX, of course), 
+so that with $\cs{tracinglostchars}>2$ you now also get an
+error message for each missing glyph.
+
+Later, in January 2021, Petr Olšák suggested yet another extension:
+a new primitive
+\mbox{parameter}
+%
+\cs{tracingstacklevels} that, when both it and \cs{tracingmacros} are
+positive, will add to the \mbox{tracing} information for each 
+macro a visual indication (using dots) of
+its nesting level in the macro expansion stack.
+
+These changes have both now been added to \LaTeX's debugging macros
+\cs{tracingall} and \cs{tracingnone}, so that these two new extensions
+are activated/deactivated as appropriate, so long as the \TeX{} engine
+supports them.  An example document demonstrating these parameters is
+in the linked GitHub issue.
+%
+\githubissue{524}
+
+
+
+
+\section{Code improvements}
+
+\subsection{Execute \cs{par} at the end of \cs{marginpar}}
+
+Previously, \LaTeX{} ended a \cs{marginpar} without ever explicitly
+calling \cs{par}.  This command is now explicitly added because it is
+essential to the correct working of the paragraph hooks.
+
+Another case where this issue caused problems was the \pkg{lineno}
+package, where the last line was not numbered if the \cs{marginpar}
+ended without an explicit \cs{par}.
+%
+\githubissue{489}
+
+
+
+\subsection{Execute \cs{AtEndDocument} hook in vertical mode}
+
+Until now \verb=\end{document}= executed the code from the
+\cs{AtEndDocument} hook as its first action.  This meant that this
+hook was executed in horizontal mode if the user left no empty line
+after the last paragraph.  As a result, one could get a spurious space
+added when, for example, that code contained a \cs{write}
+statement. This was fixed and now \cs{enddocument} first issues a
+\cs{par} to ensure that it always goes into vertical mode.
+%
+\githubissue{385}
+
+
+\subsection{Color groups made permanent}
+
+The use of color in certain \LaTeX{} constructs, especially boxes,
+needs an extra layer of grouping to ensure that the color setting does
+not \emph{escape} and continue outside the box when it shouldn't.
+%
+To support this, the \LaTeX{} kernel defines a number of commands,
+e.g., \cs{color at begingroup} to be used in such places.
+
+
+Until now, these commands were initially set as no-ops and only the
+color packages redefined them to become real groups; this methodology
+complicates the coding as one has to account for a group being present
+or not (\mbox{depending} on what is loaded in the document).
+%
+The kernel therefore now permanently adds these \enquote{color groups}.
+%
+\githubissue{488}
+
+
+\subsection{Provide the raw option list to key/value option handlers}
+
+Before any further processing of the option list, the original
+(un-normalized, \enquote{raw} and unchanged) list of package or class
+options is now saved, as \cs{@raw at opt@...}; this list is not used by
+the standard option processing code but it is now available for use by
+extended class/package processing systems.  Note that, for
+compatibility reasons, the standard option processing code has not
+been changed.
+
+
+
+One
+aspect of this
+change does affect the standard \mbox{processing}: any tokens to the
+right of an \texttt{=}
+sign are \mbox{removed} 
+from consideration
+when constructing 
+the \enquote{\mbox{unused} option list}.
+For example, in 
+this release \texttt{clip=true} and
+\texttt{clip=false} both contribute \texttt{clip} to the list of
+options that have been used.
+%
+\githubissue{85}
+
+
+\subsection{New for \pkg{latexrelease}\,: \cs{NewModuleRelease}}
+
+To explain the need for this new feature, we shall consider the
+following example: in the 2020-10-01 release, \LaTeX's new hook
+management system was added to the kernel (see \cite{33:ltnews32})
+and, as with all changes to the kernel, it was added to
+\pkg{latexrelease}; this made it possible to roll back to a date where
+this module didn't yet exist, or to roll forward from an older
+\LaTeX{} release to get the hook management system (by loading the
+\pkg{latexrelease} package).
+%
+However, this method of rolling back from a later release to the
+2020-10-01 release didn't quite work because it would try to define
+all the commands from \pkg{lthooks} again; and this would of course
+result in the expected errors from commands defined with
+\cs{newcommand} or (as in \pkg{lthooks}) \cs{cs\_new:Npn}.
+
+To solve such issues, we now provide \cs{NewModuleRelease} so that
+completely new modules can be defined using the facilities of
+\pkg{latexrelease} in such a way that, when rolling back or forward,
+the system will know whether the code of the new module has to be read
+or completely ignored.  More details on this can be found in the
+\pkg{latexrelease} documentation (get this with
+\verb|texdoc latexrelease|).
+%
+\githubissue{479}
+
+
+\subsection{Small fix for rolling back prior to 2020-02-02}
+
+Whereas the \pkg{latexrelease} package can usually emulate an older
+\LaTeX{} kernel without much problem, rolling back to before the
+2020-02-02 release didn't work properly: this is because the
+management of the \cs{ExplSyntaxOn/Off} status for packages (after an
+\pkg{expl3}-based package is loaded) cannot be removed by the rollback
+without messing up the catcodes.  This has been fixed so that rollback
+is now more careful not to leave \cs{ExplSyntaxOn} after a package
+ends.
+%
+\githubissue{504}
+
+
+
+\section{Changes to packages in the \pkg{graphics} category}
+
+
+\subsection{Removed warning when loading graphics files}
+
+A previous release sometimes mistakenly caused a (false) warning
+message to appear when \mbox{using} a generic graphics rule to find
+and load a graphics file with an unknown \mbox{extension}.
+%%CCC removing hyphenation here makes this one line longer.
+This warning would incorrectly say that the file was not found,
+whereas the file would in fact be correctly loaded.  The warning now
+doesn't show up in that case.
+%
+\githubissue{516}
+
+
+\subsection{Fixed loading of \texttt{gzip}ped
+  PostScript files}
+
+A previous release mistakenly changed the file searching mechanism so
+that compressed PostScript graphics files would raise an error when
+being loaded with \cs{includegraphics}.  This has been fixed so that
+\texttt{gzip}ped graphics files now load correctly.
+%
+\githubissue{519}
+
+
+
+
+\section{Changes to packages in the \pkg{tools} category}
+
+\subsection{\pkg{layout}: Added language options}
+
+This package now recognizes \texttt{japanese} and \texttt{romanian} as
+language options.
+%
+\githubissue[s]{353 and 529}
+
+
+\subsection{\pkg{array} and \pkg{longtable}: Make \cs{\textbackslash} generally robust}
+
+The fix for this issue was also applied to these packages; see above.
+%
+\githubissue{548}
+
+
+\subsection{\pkg{longtable}: General bug fix update}
+
+This is a minor update to the \pkg{longtable} package that fixes several
+reported bugs: notably the possibility of incorrect page breaks when
+floats appear on the page where a \env{longtable} starts.  As this may
+affect page breaking in existing documents, a rollback to
+\pkg{longtable 4.13} (\file{longtable-2020-01-07.sty}) is supported.
+%
+\gnatsissue{tools}{2914 3396 3512}
+\githubissue{133 137 183 464 561}
+
+
+\subsection{\pkg{trace}: Additions to \cs{traceon}}
+
+The \cs{tracingstacklevels} and \cs{tracinglostchars} extensions to
+\cs{tracingall} (see above) were also added to \cs{traceon} in the
+\pkg{trace} package, so its users can also benefit from these new
+debugging possibilities.
+%
+\githubissue{524}
+
+
+\subsection{\pkg{bm}: Better support for commands with optional arguments}
+
+Some uses of optional arguments in \cs{bm} stopped being supported (in
+2004) when \cs{kernel at ifnextchar} was used internally by the format
+instead of \cs{@ifnextchar}. This update handles both versions of this
+command and restores the original \mbox{behavior}.
+
+In addition, package options for guiding the use of \enquote{poor
+  man's bold} in fallback situations were added.
+%
+\githubissue{554}
+
+
+
+\section{Changes to packages in the \pkg{amsmath} category}
+
+The fix for issue 548 was also applied in \pkg{amsmath}; see above. 
+%
+\githubissue{548}
+
+
+
+
+\medskip
+
+\begin{thebibliography}{9}
+
+\fontsize{9.3}{11.3}\selectfont
+
+\bibitem{33: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/}
+
+\bibitem{33:source2e}
+  \emph{\LaTeX{} documentation on the \LaTeX{} Project Website}.\\
+  \url{https://latex-project.org/help/documentation/}
+
+\bibitem{33:ltnews32} \LaTeX{} Project Team:
+  \emph{\LaTeXe{} news 32}.\\
+  \url{https://latex-project.org/news/latex2e-news/ltnews32.pdf}
+
+\end{thebibliography}
+
+
+
+\end{document}


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

Index: trunk/Master/texmf-dist/doc/latex/base/ltpara-code.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltpara-code.pdf	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltpara-code.pdf	2021-06-01 21:12:14 UTC (rev 59424)

Property changes on: trunk/Master/texmf-dist/doc/latex/base/ltpara-code.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/base/ltpara-code.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltpara-code.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/base/ltpara-code.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -0,0 +1,4 @@
+% this will typeset documentation + code
+
+\AtBeginDocument{\AlsoImplementation}
+\input{ltpara.dtx}


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

Index: trunk/Master/texmf-dist/doc/latex/base/ltpara-doc.pdf
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltpara-doc.pdf	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltpara-doc.pdf	2021-06-01 21:12:14 UTC (rev 59424)

Property changes on: trunk/Master/texmf-dist/doc/latex/base/ltpara-doc.pdf
___________________________________________________________________
Added: svn:mime-type
## -0,0 +1 ##
+application/pdf
\ No newline at end of property
Added: trunk/Master/texmf-dist/doc/latex/base/ltpara-doc.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltpara-doc.tex	                        (rev 0)
+++ trunk/Master/texmf-dist/doc/latex/base/ltpara-doc.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -0,0 +1,6 @@
+% this will typeset only documentation but not the code
+
+\AtBeginDocument{\OnlyDescription
+                 \let\tableofcontents\relax
+                 }
+\input{ltpara.dtx}


Property changes on: trunk/Master/texmf-dist/doc/latex/base/ltpara-doc.tex
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
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/ltx3info.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/ltx3info.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/ltx3info.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/ltx3info.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

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/manifest.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/manifest.txt	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/manifest.txt	2021-06-01 21:12:14 UTC (rev 59424)
@@ -135,6 +135,7 @@
 % -----------------
 %
 % ltexpl.dtx      --  Basic support
+% ltcmd.dtx       --  Document command definition
 % lthooks.dtx     --  Hook management
 % ltfilehook.dtx  --  Hook management for file loading
 % ltshipout.dtx   --  Hook management for \shipout
@@ -185,6 +186,7 @@
 % doc.dtx         --  Package for self documenting code.
 % docstrip.dtx    --  Module for removing comments.
 % ltxdoc.dtx      --  Class file for printing documentation.
+% doc-v3beta.sty  --  New version of doc, current for internal use only.
 %
 %
 % Installation scripts for the various parts:

Modified: trunk/Master/texmf-dist/doc/latex/base/manual.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/modguide.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/modguide.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/modguide.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -40,7 +40,7 @@
 
 \title{Modifying \LaTeX}
 
-\author{\copyright~Copyright 1995, \LaTeX3 Project Team.\\
+\author{\copyright~Copyright 1995, \LaTeX\ Project Team.\\
    All rights reserved.}
 
 \date{12 December 1995}

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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/source2e.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -248,8 +248,12 @@
 
  \DocInclude{ltdefns}  % Initial definitions.
 
+ \DocInclude{ltcmd}    % Document command creation (was xparse)
+
  \DocInclude{lthooks}  % Hook management (L3 module)
 
+ \DocInclude{ltcmdhooks}% Hook management for commands (L3 module)
+
  \DocInclude{ltalloc}  % Allocation of counters and others.
 
  \DocInclude{ltcntrl}  % Program control macros.
@@ -258,6 +262,8 @@
 
  \DocInclude{ltpar}    % Paragraphs.
 
+ \DocInclude{ltpara}   % Paragraph hooks (L3 module)
+
  \DocInclude{ltspace}  % Spacing, line and page breaking.
 
  \DocInclude{ltlogos}  % Logos.

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

Modified: trunk/Master/texmf-dist/doc/latex/base/texpert.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/texpert.txt	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/texpert.txt	2021-06-01 21:12:14 UTC (rev 59424)
@@ -207,4 +207,4 @@
 to install the new version before you can typeset these files.
 
 
---- Copyright 1995-2019 the LaTeX3 project.  All rights reserved ---
+--- Copyright (C) 1995-2019 the LaTeX Project.  All rights reserved ---

Modified: trunk/Master/texmf-dist/doc/latex/base/tlc2.err
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/tlc2.err	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/tlc2.err	2021-06-01 21:12:14 UTC (rev 59424)
@@ -35,9 +35,10 @@
 % Changes:
 %
 % v1.0a - changed name from errata.cls to ttcterrata.cls
+% v1.0b - added \arraybackslash
 
 \ProvidesClass{ttcterrata}
-  [2007/11/10 v1.0a Mini class for errata files; subject to change (FMi)]
+  [2021/04/22 v1.0b Mini class for errata files; subject to change (FMi)]
 
 \LoadClass{article}
 
@@ -164,7 +165,7 @@
   \multicolumn{4}{l}{\framebox[10cm][l]{\textbf{\normalsize\strut#1}}} \\}
 
 \newenvironment{erratalist}
-  {\begin{longtable}{r>{\raggedright}p{2cm}l>{\raggedright}p{10cm}l}}
+  {\begin{longtable}{r>{\raggedright\arraybackslash}p{2cm}l>{\raggedright\arraybackslash}p{10cm}l}}
   {\endgobble\end{longtable}}
 
 \newcommand\erratatitle[2]

Modified: trunk/Master/texmf-dist/doc/latex/base/tlc2.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.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/base/usrguide.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/usrguide.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/usrguide.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -34,7 +34,7 @@
 
 \title{\LaTeXe~for authors}
 
-\author{\copyright~Copyright 1995--2020, \LaTeX3 Project Team.\\
+\author{\copyright~Copyright 1995--2020, \LaTeX\ Project Team.\\
    All rights reserved.}
 
 \date{25 May 2020}
@@ -103,10 +103,10 @@
 |ltx3info.tex|.
 
 If you would like to support the project then you are welcome to send
-donations to the \LaTeX3 Project Fund; this has been set up to help
+donations to the \LaTeX\ Project Fund; this has been set up to help
 the research team by financing various expenses associated with this
 voluntary work of maintaining the current \LaTeX{} and developing
-\LaTeX3.
+\LaTeX\ further.
 
 The fund is administered by The \TeX{} Users Group and by various
 local user groups.  Information about making donations and joining

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

Modified: trunk/Master/texmf-dist/doc/latex/base/usrguide3.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/base/usrguide3.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/usrguide3.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 2020-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -32,11 +32,11 @@
 
 \usepackage[T1]{fontenc}  % needed for \textbackslash in tt
 
-\title{\LaTeX3 methods for authors}
-\author{\copyright~Copyright 2020, \LaTeX\ Project Team.\\
+\title{New \LaTeX\ methods for authors (starting 2020)}
+\author{\copyright~Copyright 2020-2021, \LaTeX\ Project Team.\\
    All rights reserved.}
 
-\date{Released 2020-12-02}
+\date{2021-04-12}
 
 \NewDocumentCommand\cs{m}{\texttt{\textbackslash\detokenize{#1}}}
 \NewDocumentCommand\marg{m}{\arg{#1}}
@@ -340,11 +340,11 @@
 
 \begin{decl}
   |\IfNoValueTF| \arg{arg} \arg{true code} \arg{false code} \\
-  |\IfNoValueT|  \arg{arg} \arg{true code} \arg{false code} \\
-  |\IfNoValueF|  \arg{arg} \arg{true code} \arg{false code}
+  |\IfNoValueT|  \arg{arg} \arg{true code} \\
+  |\IfNoValueF|  \arg{arg} \arg{false code}
 \end{decl}
 The \cs{IfNoValue(TF)} tests are used to check if \meta{argument} (|#1|,
-|#2|, \emph{etc.}) is the special |-NoValue-| marker For example
+|#2|, \emph{etc.}) is the special |-NoValue-| marker. For example
 \begin{verbatim}
   \NewDocumentCommand\foo{o m}
     {%
@@ -381,8 +381,8 @@
 
 \begin{decl}
   |\IfValueTF| \arg{arg} \arg{true code} \arg{false code} \\
-  |\IfValueT|  \arg{arg} \arg{true code} \arg{false code} \\
-  |\IfValueF|  \arg{arg} \arg{true code} \arg{false code}
+  |\IfValueT|  \arg{arg} \arg{true code} \\
+  |\IfValueF|  \arg{arg} \arg{false code}
 \end{decl}
 The reverse form of the \cs{IfNoValue(TF)} tests are also available
 as \cs{IfValue(TF)}. The context will determine which logical
@@ -398,8 +398,8 @@
 
 \begin{decl}
   |\IfBooleanTF| \arg{arg} \arg{true code} \arg{false code} \\
-  |\IfBooleanT|  \arg{arg} \arg{true code} \arg{false code} \\
-  |\IfBooleanF|  \arg{arg} \arg{true code} \arg{false code}
+  |\IfBooleanT|  \arg{arg} \arg{true code} \\
+  |\IfBooleanF|  \arg{arg} \arg{false code}
 \end{decl}
 Used to test if \meta{argument} (|#1|, |#2|, \emph{etc.}) is
 \cs{BooleanTrue} or \cs{BooleanFalse}. For example

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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/base/webcomp.err	2021-06-01 21:12:14 UTC (rev 59424)
@@ -12,7 +12,7 @@
 
 \begin{filecontents}{ttcterrata.cls}
 %%
-%% Copyright (C) 1997,2004,2005,2007 Frank Mittelbach
+%% Copyright (C) 1997-2021 Frank Mittelbach
 %% This class file is licenced under LPPL latest version;
 %% see https://www.latex-project.org/lppl
 %
@@ -28,9 +28,10 @@
 % Changes:
 %
 % v1.0a - changed name from errata.cls to ttcterrata.cls
+% v1.0b - added \arraybackslash
 
 \ProvidesClass{ttcterrata}
-  [2007/11/10 v1.0a Mini class for errata files; subject to change (FMi)]
+  [2021/04/22 v1.0b Mini class for errata files; subject to change (FMi)]
 
 \LoadClass{article}
 
@@ -157,7 +158,7 @@
   \multicolumn{4}{l}{\framebox[10cm][l]{\textbf{\normalsize\strut#1}}} \\}
 
 \newenvironment{erratalist}
-  {\begin{longtable}{r>{\raggedright}p{2cm}l>{\raggedright}p{10cm}l}}
+  {\begin{longtable}{r>{\raggedright\arraybackslash}p{2cm}l>{\raggedright\arraybackslash}p{10cm}l}}
   {\endgobble\end{longtable}}
 
 \newcommand\erratatitle[2]

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

Modified: trunk/Master/texmf-dist/doc/latex/graphics/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/graphics/README.md	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/graphics/README.md	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 The LaTeX `graphics` bundle
 ===========================
 
-Release 2020-10-01
+Release 2021-06-01
 
 Overview
 --------
@@ -61,4 +61,4 @@
 
 -----
 
-<p>Copyright (C) 1993-2020 The LaTeX Project <br />
+<p>Copyright (C) 1993-2021 The LaTeX Project <br />

Modified: trunk/Master/texmf-dist/doc/latex/graphics/changes.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/graphics/changes.txt	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/graphics/changes.txt	2021-06-01 21:12:14 UTC (rev 59424)
@@ -4,6 +4,39 @@
 are not part of the distribution.
 =======================================================================
 
+================================================================================
+All changes above are only part of the development branch for the next release.
+================================================================================
+
+#########################
+# 2021-16-01 Release
+#########################
+
+2021-03-04  Phelype Oleinik  <phelype.oleinik at latex-project.org>
+
+	* graphics.dtx: fix loading gzipped .(e)ps graphics files.
+
+2021-03-05  David Carlisle  <David.Carlisle at latex-project.org>
+
+	* grfguide.tex: Remove the example of calling zcat via the
+	backtick special in dvips which has not worked for many years
+	for security reasons.  dvips directly supports zip
+	uncompression, and does not allow arbitrary shell commands to
+	be executed via \special{`command..}
+
+2021-03-03  Phelype Oleinik  <phelype.oleinik at latex-project.org>
+
+	* graphics.dtx: Avoid warning when loading a file using a generic rule (gh/516).
+
+2020-12-05 Ulrike Fischer <Ulrike.Fischer at latex-project.org>
+
+	* graphics.dtx: fix missing default in quiet key.
+
+
+#########################
+# 2020-10-01 Release
+#########################
+
 2020-08-21  Phelype Oleinik  <phelype.oleinik at latex-project.org>
 
 	* graphics.dtx: add additional trial with known extensions if

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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/graphics/grfguide.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,5 +1,7 @@
-%% grfguide.tex Copyright (C) 1994 1995 1996 1998 1999 David Carlisle
-%%              Copyright (C) 2005-2020 David Carlisle, LaTeX3 Project
+%% grfguide.tex Copyright (C) 1994-1999 David Carlisle
+%%              Copyright (C) 2005-2021
+%% The LaTeX Project and any individual authors listed elsewhere
+%% in this file.
 %%
 %% This file is part of the Standard LaTeX `Graphics Bundle'.
 %% It may be distributed under the terms of the LaTeX Project Public
@@ -59,8 +61,8 @@
 
 \begin{document}
 \title{Packages in the `graphics' bundle}
-\author{D. P. Carlisle \and The \LaTeX3 Project}
-\date{2020-08-21}
+\author{D. P. Carlisle \and The \LaTeX\ Project}
+\date{2021-03-05}
 
 \maketitle
 
@@ -764,29 +766,13 @@
 would be treated as EPS files, and the graphic file would be read for
 a BoundingBox comment.
 
-\emph{command} is usually empty, but if non empty it is used in place
-of the filename in the |\special|. Within this argument, |#1| may be
-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
-file before inserting it into the PostScript output.
+\emph{command} is usually empty, but if non empty it may hold \TeX{} code
+to modify the name of the file as passed to the back end file inclusion
+commands. Within this argument, |#1| may be
+used to denote the original filename. Very early releases of the |dvips| code
+used this mechanism to support compressed EPS files, however for some years
+dvips has directly supported uncompression.
 
-Note that \LaTeX\ will find the graphics file by searching along
-TEXINPUTS (and possibly other places, as specified with
-|\graphicspath|) however it may be that the command you specify
-in this argument can not find such files unless they are in the
-current directory. On some systems it may be possible to modify
-the command so that it will find any files that \LaTeX\ can find.
-For example on newer web2c \TeX\ releases on unix, one may modify the
-above command so that the last argument is:\\
-|{`zcat `kpsewhich -n latex tex #1`}|\\
-which incantation causes the |kpsewhich| program to find the
-file, by searching along \LaTeX's path, and then pass the full path
-name to the |zcat| program so that it can uncompress the file.
-Any such uses are very system dependent, and would best be placed in
-a |graphics.cfg| file, thus keeping the document itself portable.
-
 \subsection{Global setting of keys}
 
 Most of the \package{keyval} keys used in the \package{graphicx} package

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/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/tools/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/latex/tools/README.md	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/tools/README.md	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 The LaTeX `tools` bundle
 ========================
 
-Release 2020-10-01
+Release 2021-06-01
 
 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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/tools/changes.txt	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,3 +1,4 @@
+
 =======================================================================
 This file lists changes to the LaTeX2e files in reverse chronological order.
 It is provided for convenience only.  It therefore makes no claims to
@@ -5,6 +6,85 @@
 are not part of the distribution.
 =======================================================================
 
+================================================================================
+All changes above are only part of the development branch for the next release.
+================================================================================
+
+#########################
+# 2021-06-01 Release
+#########################
+
+2021-05-07  David Carlisle  <David.Carlisle at latex-project.org>
+
+	* longtable.dtx: write lists of tables entry to the file with
+	extension \ext at table, not force .lot github/561
+
+2021-04-25  David Carlisle  <David.Carlisle at latex-project.org>
+
+	* bm.dtx: guard \kernel at ifnextchar (gh/554)
+	* bm.dtx: options to control poor man's bold and warnings (gh/71)
+
+2021-04-21  David Carlisle  <David.Carlisle at latex-project.org>
+
+	* longtable.dtx: make \\ robust (gh/548)
+
+2021-04-20  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* array.dtx (section{The line separator \\}):
+	Use \protected for \\ variant (gh/548)}
+
+2021-04-18  Phelype Oleinik  <phelype.oleinik at latex-project.org>
+
+	* trace.dtx:
+	Add support for \tracingstacklevels and \tracinglostchars=3.
+
+2021-04-18  David Carlisle  <David.Carlisle at latex-project.org>
+
+	* longtable.dtx: silence \vsplit with \vbadness in addition to \vfuzz
+	  https://tex.stackexchange.com/a/71121
+
+2021-03-28  David Carlisle  <David.Carlisle at latex-project.org>
+
+	* longtable.dtx: \reset at font in captions gh/133
+	
+	* longtable.dtx: Allow paragraphs in footnotes gh/364
+
+2021-03-10  Johannes Braams  <Johannes.Braams at latex-project.org>
+
+	* layout.dtx: (subsection{Options}):
+	Option romanian added (gh/529)
+
+2021-02-25  David Carlisle  <David.Carlisle at latex-project.org>
+
+	* longtable.dtx
+	(subsection{User Settable Parameters}):
+	Increase default chunksize from 20 to 200
+
+	(subsection{The \env{longtable} environment}):
+	Guard against shrink glue on current page tools/3396 and gh/183
+	Rearrange vertical space tests for tools/3512 (floats on same page)
+
+	(subsection{The {\ttfamily\bslash\bslash} and \cs{kill} Commands}):
+	allocated global box  (tools/2914)
+
+	(subsection{The Output Routine}):
+	Remove box from final page gh/3512
+
+2021-02-10  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
+
+	* array.dtx (section{The macros \texttt{\textbackslash @classz}):
+	Explicitly run \par at the end of pboxes in preparation for
+	paragraph hooks
+
+2020-07-25  Johannes Braams  <Johannes.Braams at latex-project.org>
+
+	* layout.dtx: (subsection{Options}):
+	Option japanese added (gh/353)
+
+#########################
+# 2020-10-01 Release
+#########################
+
 2020-08-11  Frank Mittelbach  <Frank.Mittelbach at latex-project.org>
 
 	* varioref.dtx: Updated suppor for Japanese (gh/352 and gh/369)

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)

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/manifest.txt
===================================================================
--- trunk/Master/texmf-dist/doc/latex/tools/manifest.txt	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/tools/manifest.txt	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright 1993-2016
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.

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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/doc/latex/tools/tools-overview.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,13 +1,13 @@
 \NeedsTeXFormat{LaTeX2e}
 \ProvidesFile{tools-overview.tex}[2015/03/31 v1.0 Tools overview]
 
-% Copyright (C) 2006-2020
+% Copyright (C) 2006-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % Copyright (c) 2006-2014 Heiko Oberdiek
-%           (c) 2015-2019 The LaTeX3 Project
+%           (c) 2015-2019 The LaTeX Project
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.
 % -------------------------------------------------------

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/source/latex/base/alltt.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/alltt.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/alltt.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -30,7 +30,7 @@
 %%
 %% File `alltt.dtx'.
 %% Copyright (C) 1987 by Leslie Lamport
-%% Copyright (C) 1994--1997 LaTeX3 project, Johannes Braams
+%% Copyright (C) 1994-2021 LaTeX Project, Johannes Braams
 %%                       all rights reserved.
 %%
 %<*dtx>
@@ -40,10 +40,11 @@
 %<package>\ProvidesPackage{alltt}
 %<driver>\ProvidesFile{alltt.drv}
 %\ProvidesFile{alltt.dtx}
-              [1997/06/16 v2.0g defines alltt environment]
+              [2021/01/29 v2.0g defines alltt environment]
 %
 %<*driver>
 \documentclass{ltxdoc}
+\usepackage{alltt}
 \begin{document}
 \providecommand{\Lenv}[1]{\textsf{#1}}
 \providecommand{\pkg}[1]{\texttt{#1}}
@@ -55,6 +56,8 @@
 %
 % \changes{v2.0g}{1997/06/16}{A few documentation fixes (PR 2520)}
 % \changes{v2.0d}{1995/04/02}{A few documentation fixes (PR 1517)}
+% \changes{v2.0g}{2021-01-29}{Added a warning about OT1 versus T1 font
+% encoding}
 %
 %  \GetFileInfo{alltt.dtx}
 %  \title{The \texttt{alltt} environment\thanks{This file
@@ -88,11 +91,19 @@
 %    extra blank line if you're not careful.
 %
 %   \item Insert a math formula.  Note that |$| just produces a dollar
-%   sign, so you'll have to type |\(...\)| or |\[...\]|.  Also, |^|
-%   and |_| just produce their characters; use |\sp| or |\sb| for
-%   super- and subscripts, as in |\(x\sp{2}\)|.
+%    sign, so you'll have to type |\(...\)| or |\[...\]|.  Also, |^|
+%    and |_| just produce their characters; use |\sp| or |\sb| for
+%    super- and subscripts, as in |\(x\sp{2}\)|.
 %   \end{itemize}
 %
+%    \textbf{NB} When you are using \textsf{OT1} encoded fonts you might
+%    be surprsied when you switch to italics, becuase those fonts have
+%    a different set of glyphs:
+%    \begin{alltt}
+%  The glyph at the position of the $ in a slanted font: \textsl{$}.
+%  The glyph at the position of the $ in an italic font: \textit{$}.
+%    \end{alltt}
+%
 %  \StopEventually{}
 %
 %  \section{The Implementation}
@@ -173,7 +184,7 @@
 %    control sequence |\do| between the characters. We use that to
 %    check whether a character has to be removed.
 %
-%    The macro |\g at remfrom@specials| takes one argument, the chracter
+%    The macro |\g at remfrom@specials| takes one argument, the character
 %    to be removed from the list.
 %    \begin{macrocode}
 \def\g at remfrom@specials#1{%

Modified: trunk/Master/texmf-dist/source/latex/base/alltt.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/alltt.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/alltt.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/classes.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/classes.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/classes.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -53,7 +53,7 @@
 %<*driver>
 \ProvidesFile{classes.drv}
 %</driver>
-              [2020/04/10 v1.4m
+              [2021/02/12 v1.4n
 %<article|report|book> Standard LaTeX document class]
 %<10pt|11pt|12pt>      Standard LaTeX file (size option)]
 %    \end{macrocode}
@@ -116,7 +116,7 @@
 \DoNotIndex{\viipt,\vipt,\vskip,\vspace}
 \DoNotIndex{\wd,\xiipt,\year,\z@}
 %    \end{macrocode}
-%    We do want an index, using linenumbers
+%    We do want an index, using line numbers
 %    \begin{macrocode}
 \EnableCrossrefs
 \CodelineIndex
@@ -199,7 +199,7 @@
 % \changes{v1.2o}{1994/05/24}{Changed file information}
 % \changes{v1.2p}{1994/05/27}{Moved identification and driver to the
 %    front of the file}
-% \changes{v1.2t}{1994/06/22}{Refrased a few sentences to prevent
+% \changes{v1.2t}{1994/06/22}{Rephrased a few sentences to prevent
 %    overfull hboxes}
 % \changes{v1.2v}{1994/12/01}{Made the oneside option work for the
 %    book class}
@@ -221,9 +221,9 @@
 %    file has version number \fileversion, last revised \filedate.}}
 %
 % \author{%
-% Copyright (C) 1992 by Leslie Lamport \and
-% Copyright (C) 1994-2020 by Frank Mittelbach \and Johannes Braams \and
-%                            \LaTeX3 Project Team
+% Copyright (C) 1992 by Leslie Lamport and
+% Copyright (C) 1994-2020 by Frank Mittelbach and Johannes Braams and
+%                            LaTeX Project Team
 % }
 % \date{\filedate}
 % \MaintainedByLaTeXTeam{latex}
@@ -423,7 +423,7 @@
 %<!article>\fi
 %    \end{macrocode}
 %
-%  \subsection{Twocolumn printing}
+%  \subsection{Two-column printing}
 %
 %    Two-column and one-column printing is again realized via a switch.
 %    \begin{macrocode}
@@ -788,7 +788,7 @@
 % \begin{macro}{\parindent}
 %    |\parskip| gives extra vertical space between paragraphs and
 %    |\parindent| is the width of the paragraph indentation. The value
-%    of |\parindent| depends on whether we are in two column mode.
+%    of |\parindent| depends on whether we are in two-column mode.
 % \changes{v1.0m}{1994/01/12}{\cs{parindent} should be different,
 %    depending on the pointsize}
 %    \begin{macrocode}
@@ -998,7 +998,7 @@
 %    Now we can set the |\textwidth|, depending on whether we will be
 %    setting one or two columns.
 %
-%    In two column mode each \emph{column} shouldn't be wider than
+%    In two-column mode each \emph{column} shouldn't be wider than
 %    |\@tempdimb| (which could happen on \textsc{a3} paper for
 %    instance).
 %    \begin{macrocode}
@@ -1010,7 +1010,7 @@
     \fi
 %    \end{macrocode}
 %
-%    In one column mode the text should not be wider than the minimum
+%    In one-column mode the text should not be wider than the minimum
 %    of the paperwidth (minus 2 inches for the margins) and the
 %    maximum length of a line as defined by the number of characters.
 %    \begin{macrocode}
@@ -1168,7 +1168,7 @@
   \fi
 %</!bk>
 %    \end{macrocode}
-%    And values for two column mode:
+%    And values for two-column mode:
 %    \begin{macrocode}
   \if at twocolumn
      \setlength\oddsidemargin  {30\p@}
@@ -1389,7 +1389,7 @@
 %
 % \begin{macro}{\c at dbltopnumber}
 %    The \Lcount{dbltopnumber} counter holds the maximum number of
-%    two column floats that can appear on the top of a two column text
+%    two-column floats that can appear on the top of a two-column text
 %    page.
 %    \begin{macrocode}
 \setcounter{dbltopnumber}{2}
@@ -1397,8 +1397,8 @@
 % \end{macro}
 %
 % \begin{macro}{\dbltopfraction}
-%    This indicates the maximum part of a two column text page that
-%    can be occupied by two column floats at the top.
+%    This indicates the maximum part of a two-column text page that
+%    can be occupied by two-column floats at the top.
 % \changes{v1.0h}{1993/12/18}{Replaced \cs{newcommand} with
 %    \cs{renewcommand}.  ASAJ.}
 %    \begin{macrocode}
@@ -1408,7 +1408,7 @@
 %
 % \begin{macro}{\dblfloatpagefraction}
 %    This indicates the minimum part of a page that has to be
-%    occupied by two column wide floating objects before a `float
+%    occupied by two-column wide floating objects before a `float
 %    page' is produced.
 % \changes{v1.0h}{1993/12/18}{Replaced \cs{newcommand} with
 %    \cs{renewcommand}.  ASAJ.}
@@ -1459,7 +1459,7 @@
 % \begin{macro}{\dblfloatsep}
 % \begin{macro}{\dbltextfloatsep}
 %    When floating objects that span the whole |\textwidth| are placed
-%    on a text page when we are in twocolumn mode the separation
+%    on a text page when we are in two-column mode the separation
 %    between the float and the text is controlled by |\dblfloatsep|
 %    and |\dbltextfloatsep|.
 %
@@ -1498,7 +1498,7 @@
 %    whitespace. Between adjacent floats the |\@fpsep| is inserted.
 %
 %    These parameters are used for the placement of floating objects
-%    in one column mode, or in single column floats in two column
+%    in one-column mode, or in single-column floats in two-column
 %    mode.
 %
 %    Note that at least one of the two parameters |\@fptop| and
@@ -1528,7 +1528,7 @@
 % \begin{macro}{\@dblfptop}
 % \begin{macro}{\@dblfpsep}
 % \begin{macro}{\@dblfpbot}
-%    Double column floats in two column mode are handled with similar
+%    Double-column floats in two-column mode are handled with similar
 %    parameters.
 %    \begin{macrocode}
 %<*10pt>
@@ -1809,7 +1809,7 @@
   \let \footnote \thanks
 %    \end{macrocode}
 %    We center the entire title vertically; the centering is set off a
-%    little by adding a |\vskip|. (In compatibility mode the pagenumber
+%    little by adding a |\vskip|. (In compatibility mode the page number
 %    is set to 0 by the titlepage environment to keep the behaviour
 %    of \LaTeX\ 2.09 style files.)
 % \changes{v1.0g}{1993/12/09}{Removed the setting of the page number,
@@ -1872,7 +1872,7 @@
 %    \end{macrocode}
 %    When the title is not on a page of its own, the layout of the
 %    title is a little different. We use symbols to mark the footnotes
-%    and we have to deal with two column documents.
+%    and we have to deal with two-column documents.
 %
 %    Therefore we first start a new group to keep changes local. Then
 %    we redefine |\thefootnote| to use |\fnsymbol|; and change
@@ -1893,7 +1893,7 @@
               \hb at xt@1.8em{%
                 \hss\@textsuperscript{\normalfont\@thefnmark}}##1}%
 %    \end{macrocode}
-%    If this is a twocolumn document we start a new page in twocolumn
+%    If this is a two-column document we start a new page in two-column
 %    mode, with the title set to the full width of the text. The
 %    actual printing of the title information is left to
 %    |\@maketitle|.
@@ -1908,7 +1908,7 @@
         \fi
       \else
 %    \end{macrocode}
-%    When this is not a twocolumn document we just start a new page,
+%    When this is not a two-column document we just start a new page,
 %    prevent floating objects from appearing on the top of this page
 %    and print the title information.
 %    \begin{macrocode}
@@ -2133,10 +2133,10 @@
 %    \Lcount{COUNTER} as an arabic numeral.
 %
 %    |\roman{|\Lcount{COUNTER}|}| prints the value of
-%    \Lcount{COUNTER} as a lowercase roman numberal.
+%    \Lcount{COUNTER} as a lowercase roman numeral.
 %
 %    |\Roman{|\Lcount{COUNTER}|}| prints the value of
-%    \Lcount{COUNTER} as an uppercase roman numberal.
+%    \Lcount{COUNTER} as an uppercase roman numeral.
 %
 %    |\alph{|\Lcount{COUNTER}|}| prints the value of \Lcount{COUNTER}
 %    as a lowercase letter: $1 =$~a, $2 =$~ b, etc.
@@ -2144,7 +2144,7 @@
 %    |\Alph{|\Lcount{COUNTER}|}| prints the value of \Lcount{COUNTER}
 %    as an uppercase letter: $1 =$~A, $2 =$~B, etc.
 %
-%    Actually to save space the internal counter repesentations
+%    Actually to save space the internal counter representations
 %    and the commands operating on those are used.
 %    \begin{macrocode}
 \renewcommand \thepart {\@Roman\c at part}
@@ -2281,7 +2281,7 @@
   \fi
   \thispagestyle{plain}%
 %    \end{macrocode}
-%    When we are making a two column document, this will be a one
+%    When we are making a two-column document, this will be a one
 %    column page. We use |@tempswa| to remember to switch back to two
 %    columns.
 %    \begin{macrocode}
@@ -2453,8 +2453,8 @@
                \fi
               \fi
 %    \end{macrocode}
-%    When this was a two column document we have to switch back to two
-%    column mode.
+%    When this was a two-column document we have to switch back to
+%    two-column mode.
 %    \begin{macrocode}
               \if at tempswa
                 \twocolumn
@@ -2522,8 +2522,8 @@
 %    \end{macrocode}
 %    Then we call upon |\@makechapterhead| to format the actual
 %    chapter title. We have to do this in a special way when we are in
-%    twocolumn mode in order to have the chapter title use the entire
-%    |\textwidth|. In one column mode we call |\@afterheading| which
+%    two-column mode in order to have the chapter title use the entire
+%    |\textwidth|. In one-column mode we call |\@afterheading| which
 %    takes care of suppressing the indentation.
 %    \begin{macrocode}
                     \if at twocolumn
@@ -2705,7 +2705,7 @@
 % \changes{v1.3q}{1995/12/20}{Temporary(?) fix: revert to setting
 %    \cs{leftmargin} at outer level}
 %
-% When we are in two column mode some of the margins are set somewhat
+% When we are in two-column mode some of the margins are set somewhat
 % smaller.
 %    \begin{macrocode}
 \if at twocolumn
@@ -2953,11 +2953,12 @@
 %    the labels of the various itemization levels: the symbols used are
 %    bullet, bold en-dash, centered asterisk and centred dot.
 %
+% \changes{v1.4n}{2021/06/11}{Drop incorrect space in \cs{labelitemiv} (gh/496)}
 %    \begin{macrocode}
 \newcommand\labelitemi  {\labelitemfont \textbullet}
 \newcommand\labelitemii {\labelitemfont \bfseries \textendash}
 \newcommand\labelitemiii{\labelitemfont \textasteriskcentered}
-\newcommand\labelitemiv{ \labelitemfont \textperiodcentered}
+\newcommand\labelitemiv {\labelitemfont \textperiodcentered}
 %    \end{macrocode}
 %
 % \begin{macro}{\labelitemfont}
@@ -2966,13 +2967,16 @@
 %    produced regardless of surrounding conditions.
 %
 % \changes{v1.4l}{2019/12/20}{Normalize label fonts}
-%    A possible alternative would be
+%    Possible alternatives would be, for example,
 %\begin{verbatim}
-%\renewcommand\labelitemfont{%
-%   \fontseries\seriesdefault
-%   \fontshape\shapedefault\selectfont}
+%  \renewcommand\labelitemfont
+%     {\normalfont\fontfamily{lmss}\selectfont}
+%  \renewcommand\labelitemfont
+%     {\rmfamily\normalshape}
 %\end{verbatim}
-%    which resets series and shape doesn't touch the family.
+%    the first would use symbols from Latin Modern Sans, the second
+%    would only allow changes in the font series so that an
+%    \texttt{itemize} in a bold context would produce bolder symbols.
 %    \begin{macrocode}
 \newcommand\labelitemfont{\normalfont}
 %    \end{macrocode}
@@ -3036,7 +3040,7 @@
      {\par\vfil\null\endtitlepage}
 %    \end{macrocode}
 %    When we are not making a separate titlepage --the default for the
-%    article document class-- we have to check if we are in twocolumn
+%    article document class-- we have to check if we are in two-column
 %    mode. In that case the abstract is as a |\section*|, otherwise
 %    the quotation environment is used to typeset the abstract.
 %    \begin{macrocode}
@@ -3125,13 +3129,16 @@
 %
 % \begin{environment}{titlepage}
 %  In the normal environments, the titlepage environment does nothing
-%  but start and end a page, and inhibit page numbers.  In the report
-%  style, it also resets the page number to one, and then sets it
-%  back to one at the end.  In compatibility mode, it sets the
-%  page number to zero. This is incorrect since it results in using
-%  the page parameters for a right-hand page but it is the way it was.
-%  In two-column style, it still makes a
-%  one-column page.
+%  but start and end a page, and inhibit page numbers. When \LaTeX\ is
+%  in two-column mode, the environmont temporarily switches to
+%  one-column mode.
+%  In the report class, it also resets the page number to one, and
+%  then, in two-column mode, sets it back to one at the end.
+%  For the book class the environment makes sure that the title page
+%  is on a recto page by issueing a \cs{cleardouplepage}-command.
+%  In compatibility mode, it sets the page number to zero. This is
+%  incorrect since it results in using the page parameters for a
+%  right-hand page but it is the way it was. 
 %
 % \changes{v1.0g}{1993/12/09}{Moved the setting of
 %    \cs{@restonecolfalse}}
@@ -3291,7 +3298,7 @@
 % \begin{macro}{\@minipagerestore}
 %    The macro |\@minipagerestore| is called upon entry to a minipage
 %    environment to set up things that are to be handled differently
-%    inside a minipage environment. In the current styles, it does
+%    inside a minipage environment. In the current classes, it does
 %    nothing.
 % \end{macro}
 %
@@ -3397,7 +3404,7 @@
 %    a figure is defined using the macros |\@float| and |\end at float|,
 %    which are defined in \file{latex.dtx}.
 %
-%    An environment that implements a single column floating object is
+%    An environment that implements a single-column floating object is
 %    started with |\@float{|\texttt{TYPE}|}[|\meta{placement}|]| of type
 %    \texttt{TYPE} with \meta{placement} as the placement specifier.
 %    The default value of \meta{PLACEMENT} is defined by |\fps at TYPE|.
@@ -3449,7 +3456,7 @@
 % \begin{environment}{figure}
 % \begin{environment}{figure*}
 %    And the definition of the actual environment. The form with the
-%    |*| is used for double column figures.
+%    |*| is used for double-column figures.
 %    \begin{macrocode}
 \newenvironment{figure}
                {\@float{figure}}
@@ -3506,7 +3513,7 @@
 % \begin{environment}{table}
 % \begin{environment}{table*}
 %    And the definition of the actual environment. The form with the
-%    |*| is used for double column tables.
+%    |*| is used for double-column tables.
 %    \begin{macrocode}
 \newenvironment{table}
                {\@float{table}}
@@ -3743,7 +3750,7 @@
 % \begin{macro}{\tableofcontents}
 %    This macro is used to request that \LaTeX{} produces a table of
 %    contents. In the report and book document classes the tables of
-%    contents, figures etc. are always set in single-column style.
+%    contents, figures etc. are always set in single-column mode.
 %
 % \changes{v1.0g}{1993/12/09}{Moved the setting of
 %    \cs{@restonecolfalse}}
@@ -3778,7 +3785,7 @@
            \MakeUppercase\contentsname}{\MakeUppercase\contentsname}}%
 %    \end{macrocode}
 %    The actual table of contents is made by calling
-%    |\@starttoc{toc}|. After that we restore twocolumn mode if
+%    |\@starttoc{toc}|. After that we restore two-column mode if
 %    necessary.
 %    \begin{macrocode}
     \@starttoc{toc}%
@@ -3823,13 +3830,13 @@
     \begingroup
 %    \end{macrocode}
 %    We set |\parindent| to 0pt and use |\rightskip| to leave
-%    enough room for the pagenumbers.\footnote{^^A
+%    enough room for the page numbers.\footnote{^^A
 %        We should really set \cs{rightskip} to \cs{@tocrmarg} instead
 %        of \cs{@pnumwidth} (no version of {\LaTeX} ever did this),
 %        otherwise the \cs{rightskip} is too small.
 %        Unfortunately this can't be changed in {\LaTeXe} as we don't
 %        want to create different versions of {\LaTeXe} which produce
-%        different typset output unless this is absolutely necessary;
+%        different typeset output unless this is absolutely necessary;
 %        instead we suspend it for \LaTeX3.}
 %    To prevent overfull box messages the |\parfillskip| is set to a
 %    negative value.
@@ -3838,7 +3845,7 @@
       \parfillskip -\@pnumwidth
 %    \end{macrocode}
 %    Now we can set the entry, in a large bold font. We make sure to
-%    leave vertical mode, set the part title and add the pagenumber,
+%    leave vertical mode, set the part title and add the page number,
 %    set flush right.
 %    \begin{macrocode}
       {\leavevmode
@@ -4238,9 +4245,9 @@
                 \columnsep 35\p@
                 \let\item\@idxitem}
 %    \end{macrocode}
-%    When the document continues after the index and it was a one
-%    column document we have to switch back to one column after the
-%    index.
+%    When the document continues after the index and it was a
+%    one-column document we have to switch back to one column after
+%    the index.
 %    \begin{macrocode}
                {\if at restonecol\onecolumn\else\clearpage\fi}
 %    \end{macrocode}
@@ -4293,7 +4300,7 @@
 %
 % \begin{macro}{\c at footnote}
 %    Footnotes are numbered within chapters in the report and book
-%    document styles.
+%    document classes.
 %    \begin{macrocode}
 %<!article>\@addtoreset{footnote}{chapter}
 %    \end{macrocode}
@@ -4433,10 +4440,10 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \subsection{Two column mode}
+% \subsection{Two-column mode}
 %
 % \begin{macro}{\columnsep}
-%    This gives the distance between two columns in two column mode.
+%    This gives the distance between two columns in two-column mode.
 %    \begin{macrocode}
 \setlength\columnsep{10\p@}
 %    \end{macrocode}
@@ -4443,8 +4450,8 @@
 % \end{macro}
 %
 % \begin{macro}{\columnseprule}
-%    This gives the width of the rule between two columns in two
-%    column mode. We have no visible rule.
+%    This gives the width of the rule between two columns in
+%    two-column mode. We have no visible rule.
 %    \begin{macrocode}
 \setlength\columnseprule{0\p@}
 %    \end{macrocode}
@@ -4454,7 +4461,7 @@
 %    We have \pstyle{plain} pages in the document classes article and
 %    report unless the user specified otherwise. In the `book'
 %    document class we use the page style \pstyle{headings} by
-%    default. We use arabic pagenumbers.
+%    default. We use arabic page numbers.
 %    \begin{macrocode}
 %<!book>\pagestyle{plain}
 %<book>\pagestyle{headings}

Modified: trunk/Master/texmf-dist/source/latex/base/classes.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/classes.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/classes.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/cmextra.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/cmextra.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/cmextra.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/cmfonts.fdd
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/cmfonts.fdd	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/cmfonts.fdd	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
 % Copyright 1993-2019
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/cmfonts.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/cmfonts.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/cmfonts.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/doc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/doc.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/doc.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -35,7 +35,7 @@
 %<+package|shortvrb>\NeedsTeXFormat{LaTeX2e}[1994/12/01]
 %<+package> \ProvidesPackage{doc}
 %<+shortvrb>\ProvidesPackage{shortvrb}
-%<+package|shortvrb>  [2020/06/15 v2.1m
+%<+package|shortvrb>  [2021/05/28 v2.1n
 %<+package|shortvrb>   Standard LaTeX documentation package (FMi)]
 %\catcode`\<=12
 %
@@ -47,7 +47,7 @@
 %
 %
 %% Package `doc' to use with LaTeX 2e
-%% Copyright (C) 1989-1999 Frank Mittelbach, all rights reserved.
+%% Copyright (C) 1989-2020 Frank Mittelbach, all rights reserved.
 %
 %
 % Version:     Date:     Changes:
@@ -751,7 +751,7 @@
 % in your package file.  Precede it by any bibliography commands
 % necessary for your citations.
 % Alternatively, it may be more convenient to put all such calls
-% amongst the arguments of the |\StopEventually| macro, in
+% amongt the arguments of the |\StopEventually| macro, in
 % which case a |\Finale| command should appear at the end of
 % your file.
 %
@@ -949,7 +949,7 @@
 % macro.}
 % \DescribeMacro\changes
 % To maintain a change history within the file, the |\changes|
-% command may be placed amongst the description part of the changed
+% command may be placed amongt the description part of the changed
 % code.  It takes three arguments, thus:
 % \begin{quote}
 % |\changes{|\meta{version}|}{|\meta{date}|}{|^^A
@@ -2117,6 +2117,7 @@
 % \begin{macro}{\verb 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.}
+% \changes{v2.1n}{2021/05/28}{Use same error message text as in format}
 %    \begin{macrocode}
 \let\verb at balance@group\@empty
 
@@ -2126,7 +2127,7 @@
   \obeylines%
   \gdef\verb at eol@error{\obeylines%
     \def^^M{\verb at egroup\@latex at error{%
-           Text for \noexpand\verb command ended by end of line}\@ehc}}%
+            \noexpand\verb ended by end of line}\@ehc}}%
 \endgroup
 %    \end{macrocode}
 % \end{macro}
@@ -2200,7 +2201,7 @@
 %
 % \begin{environment}{environment}
 % \changes{v1.8c}{1993/10/25}{Environment added}
-%    The ``environment'' envrionment will be implemented just like the
+%    The ``environment'' environment will be implemented just like the
 %    ``macro'' environment flagging any differences in the code by
 %    passing |\iffalse| or |\iftrue| to the |\m at cro@| environment
 %    doing the actual work.
@@ -3029,7 +3030,7 @@
 % \begin{macro}{\addto at hook}
 % The code for adding tokens (the second argument) to a token list
 % (the first argument) is taken from~\cite{art:verbatim}, but it needs
-% to be "\long" in case "\par" is amongst the tokens.
+% to be "\long" in case "\par" is amongt the tokens.
 %    \begin{macrocode}
 \long\def\addto at hook#1#2{#1\expandafter{\the#1#2}}
 %    \end{macrocode}
@@ -3149,7 +3150,7 @@
 % of an `index style file'; the character selected for this function
 % is |=|, and therefore this character too must be specially treated
 % when it is met in a \TeX\ command.  A suitable index style file is
-% provided amongst the supporting files for this style file in
+% provided amongt the supporting files for this style file in
 % \texttt{gind.ist} and is generated from this source by processing
 % with \texttt{docstrip} to extract the module \textbf{gind}.  A
 % similar style file \texttt{gglo.ist} is supplied for sorting the
@@ -4219,7 +4220,7 @@
 %
 % \begin{macro}{\meta at font@select}
 % \changes{v2.0k}{2000/05/26}{Macro added (pr/3170)}
-%    Maske font used inside |\meta| customizable.
+%    Make font used inside |\meta| customizable.
 %    \begin{macrocode}
 \def\meta at font@select{\itshape}
 %    \end{macrocode}
@@ -4431,7 +4432,7 @@
     \global\catcode`#1\csname cc\string#1\endcsname
 %    \end{macrocode}
 % \changes{v1.9e.2}{1994/02/07}{-js: Reset `cc`\protect\meta{c} in
-%                       in \cs{DeleteShortVerb}}
+%                       \cs{DeleteShortVerb}}
 % We must not forget to reset "\cc\"\meta{c}, otherwise the check in
 % "\MakeShortVerb" for a repeated definition will not work.
 %    \begin{macrocode}
@@ -4532,7 +4533,7 @@
 %
 % \begin{macro}{\init at checksum}
 % The checksum mechanism works by counting backslashes in the
-% macrocode.  This initialises the count (when called from
+% macrocode.  This initializes the count (when called from
 % "\StopEventually").
 % \changes{v1.5k}{1989/09/04}{Macro added to support checksum.}
 %    \begin{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/base/docstrip.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/docstrip.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/docstrip.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -30,8 +30,8 @@
 \catcode`\}=2
 \def\filename{docstrip.dtx}
 \def\fileversion{v2.6a}
-\def\filedate{2020-07-07}
-\def\docdate {2020-07-11}
+\def\filedate{2020-11-23}
+\def\docdate {2020-11-23}
 %%
 %
 %\iffalse
@@ -42,7 +42,7 @@
 %%                         Frank Mittelbach
 %% Copyright (C) 1995 Marcin Woli\'nski
 %% Copyright (C) 1996-1997 Mark Wooding, Marcin Woli\'nski
-%% Copyright (C) 1998-2020 LaTeX3 project and the above authors
+%% Copyright (C) 1998-2021 LaTeX Project and the above authors.
 %% All rights are reserved.
 %%
 %
@@ -77,7 +77,7 @@
 %                         less/more dirty---all uses of \cs{afterfi}}
 % \changes{2.3e}{1995/09/25}{Directories support}
 % \changes{2.3e}{1995/10/24}{added \cs{makepathname} to support
-%                         systems with bizzare pathnames}
+%                         systems with bizare pathnames}
 % \changes{2.3e}{1995/10/25}{batch files work by \cs{input}}
 % \changes{2.3e}{1996/10/02}{Introduced ``open lists''}
 % \changes{2.4a}{1996/06/06}{Add stream limits (MDW)}
@@ -122,7 +122,7 @@
 %
 % \changes{2.1b}{1993/02/23}{modified mailaddress of Johannes}
 % \changes{2.4i}{1998/01/18}{removed mail addresses as it is hopeless
-%                            to keep them uptodate}
+%                            to keep them up-to-date}
 % \author{%
 %   Frank Mittelbach
 %  \and
@@ -789,7 +789,7 @@
 %
 % \section{Internal functions and variables}
 %
-%    An important consideration for \LaTeX3 development is separating
+%    An important consideration for \LaTeX\ development is separating
 %    out public and internal functions. Functions and variables which
 %    are private to one module should not be used or modified by any
 %    other module. As \TeX{} does not have any formal namespacing
@@ -809,7 +809,7 @@
 % \end{verbatim}
 %
 %    To extract the code using \ds, the original `guard'
-%    mecahnism is extended by the introduction of the syntax
+%    mechanism is extended by the introduction of the syntax
 %    \texttt{\%<@@=\meta{module}>}. The \meta{module} name then
 %    replaces the |@@| when the code is extracted, so that
 % \begin{verbatim}
@@ -2305,7 +2305,7 @@
 %    delimited with |\endLine|) on all active output files i.e.
 %    those with off-counters equal to zero. It uses the
 %    search-and-replace macro \cs{replaceModuleInLine} to replace any
-%    occurences of \texttt{@@} with the current module name.
+%    occurrences of \texttt{@@} with the current module name.
 %    If statistics are included, the counter
 %    |\codeLinesPassed| is incremented by $1$.
 %    \begin{macrocode}
@@ -4310,7 +4310,7 @@
 %  \begin{macro}{\WriteToDir}
 %    Macro |\WriteToDir| is either empty or holds the prefix
 %    necessary to read a file from the current directory. Under UNIX
-%    this is |./| but a lot of other systems addopted this concept.
+%    this is |./| but a lot of other systems adopted this concept.
 %    This macro is a default value for |\destdir|.
 %
 %    The definition of this macro is now delayed until |\@setwritedir|

Modified: trunk/Master/texmf-dist/source/latex/base/docstrip.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/docstrip.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/docstrip.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -52,8 +52,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/ec.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ec.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ec.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/exscale.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/exscale.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/exscale.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/exscale.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/exscale.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/exscale.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/fix-cm.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/fix-cm.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/fix-cm.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -37,7 +37,7 @@
 %<driver>\ProvidesFile{fix-cm.drv}
 % \fi
 %         \ProvidesFile{fix-cm.dtx}
-          [2015/01/14 v1.1t fixes to LaTeX]
+          [2020/11/24 v1.1t fixes to LaTeX]
 %
 % \iffalse
 %<*driver>
@@ -446,7 +446,7 @@
        {<->sub * cmtt/m/sl}{}
 %    \end{macrocode}
 %
-% \paragraph{CM Typewiter (var.)}
+% \paragraph{CM Typewriter (var.)}
 %    \begin{macrocode}
 \DeclareFontFamily{T1}{cmvtt}{}
 \DeclareFontShape{T1}{cmvtt}{m}{n}{

Modified: trunk/Master/texmf-dist/source/latex/base/fix-cm.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/fix-cm.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/fix-cm.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/fontdef.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/fontdef.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/fontdef.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -39,13 +39,13 @@
 %<driver, >\ProvidesFile{fontdef.drv}
 % \fi
 %          \ProvidesFile{fontdef.dtx}
-%<-latexrelease>           [2020/08/01 v3.0i LaTeX Kernel
+%<-latexrelease>           [2021/01/15 v3.0i LaTeX Kernel
 % \iftrue  (\else
 %<text,   >(Text
 %<math,   >(Math
-%<+cfgtext>(Uncustomised text
-%<+cfgmath>(Uncustomised math
-%<+cfgprel>(Uncustomised preload
+%<+cfgtext>(Uncustomized text
+%<+cfgmath>(Uncustomized math
+%<+cfgprel>(Uncustomized preload
 % \fi
 %<-latexrelease>           font setup)]
 %
@@ -110,7 +110,7 @@
 % If you don't plan to use Computer Modern much or at all, it might
 % (!)  be a good idea to make your own \texttt{fonttext.cfg}. Look at
 % the comments below (docstrip module `text') to see what should
-% should go into such a file.
+% go into such a file.
 %
 % To change the math font setup use a copy of \texttt{fontmath.ltx}
 % under the name \texttt{fontmath.cfg} and change this copy. However,
@@ -227,7 +227,7 @@
 %    described in \texttt{ltoutenc.dtx}.
 %
 %    By convention, text  encoding specific declarations, including the
-%    declaration |\DeclareFontEncoding|, are kept in separate file of
+%    |\DeclareFontEncoding| declaration, are kept in separate file of
 %    the form \meta{enc}\texttt{enc.def}, e.g.~\texttt{ot1enc.def}. This
 %    allows other applications to make use of the declarations as
 %    well.

Modified: trunk/Master/texmf-dist/source/latex/base/format.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/format.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/format.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.
@@ -88,8 +88,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright 2015
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 2015-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.
@@ -123,8 +123,8 @@
 
 This is a generated file.
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.
@@ -166,11 +166,14 @@
 % we have the extensions as soon as possible.
           \from{ltexpl.dtx}{2ekernel}         % expl3-based extensions
           \from{ltdefns.dtx}{2ekernel}
+          \from{ltcmd.dtx}{2ekernel}          % L3 layer module (used to be xparse)
           \from{lthooks.dtx}{2ekernel}        % L3 layer module
+          \from{ltcmdhooks.dtx}{2ekernel}     % L3 layer module
           \from{ltalloc.dtx}{2ekernel}
           \from{ltcntrl.dtx}{2ekernel}
           \from{lterror.dtx}{2ekernel}
           \from{ltpar.dtx}{2ekernel}
+          \from{ltpara.dtx}{2ekernel}         % L3 layer module
           \from{ltspace.dtx}{2ekernel}
           \from{ltlogos.dtx}{2ekernel}
           \from{ltfiles.dtx}{2ekernel}
@@ -233,7 +236,6 @@
 
 % hook management support
 
-\generate{\file{everyshi-ltx.sty}{\from{ltshipout.dtx}{everyshi-ltx}}} % emulating everyshi
 \generate{\file{atbegshi-ltx.sty}{\from{ltshipout.dtx}{atbegshi-ltx}}} % emulating atbegshi
 \generate{\file{atveryend-ltx.sty}{\from{ltfilehook.dtx}{atveryend-ltx}}} % emulating atveryend
 
@@ -240,8 +242,6 @@
 \generate{\file{structuredlog.sty}{\from{ltfilehook.dtx}{structuredlog}}}
 
 
-
-
 % luatex support (TeX part)
 
 \generate{\file{ltluatex.tex}{\from{ltluatex.dtx}{tex,plain}}}

Modified: trunk/Master/texmf-dist/source/latex/base/graphpap.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/graphpap.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/graphpap.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/graphpap.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/graphpap.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/graphpap.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/ifthen.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ifthen.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ifthen.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -30,7 +30,7 @@
 %%
 %% File `ifthen.dtx'.
 %% Copyright (C) 1991 by Leslie Lamport
-%% Copyright (C) 1994-2001 LaTeX3 project, David Carlisle
+%% Copyright (C) 1994-2001 LaTeX project, David Carlisle
 %%                       all rights reserved.
 %%
 %
@@ -42,7 +42,7 @@
 %<driver>\ProvidesFile{ifthen.drv}
 % \fi
 %         \ProvidesFile{ifthen.dtx}
-          [2014/09/29 v1.1c Standard LaTeX ifthen package (DPC)]
+          [2020/11/24 v1.1c Standard LaTeX ifthen package (DPC)]
 %
 % \iffalse
 %<*driver>
@@ -368,7 +368,7 @@
 % \end{macro}
 %
 % \begin{macro}{\TE at endeval}
-% Finalise a term. (Expanded on the first pass).
+% Finalize a term. (Expanded on the first pass).
 %    \begin{macrocode}
 \def\TE at endeval{\relax
       \noexpand\TE at setvaltrue\noexpand

Modified: trunk/Master/texmf-dist/source/latex/base/ifthen.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ifthen.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ifthen.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/inputenc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/inputenc.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/inputenc.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -123,7 +123,7 @@
 %       THIS MAY CHANGE}
 % \changes{v0.95}{1997/12/20}{Updated documentation}
 % \changes{v0.97}{1998/03/05}{Spanish ords changed to text chars, pr/2579}
-% \changes{v1.1b}{2006/03/04}{Number of normalisations in the LICR
+% \changes{v1.1b}{2006/03/04}{Number of normalizations in the LICR
 %                             representation (pr/3849)}
 % \changes{v1.1c}{2006/11/18}{Added missing \cs{ProvidesFile} line for cp1257 (pr/3892)}
 %
@@ -283,7 +283,7 @@
 % with the |utf8| option.
 %
 % The |\DeclareUnicodeCharacter| takes UTF-8 code point as its first argument
-% (in form of a a hexadecimal number) and the definition that this maps to as
+% (in form of a hexadecimal number) and the definition that this maps to as
 % its second argument. For example, the code point |00E4| which is
 % ``LATIN SMALL LETTER A WITH DIAERESIS'' would be set up via:
 %\begin{verbatim}
@@ -410,7 +410,7 @@
 %<cp1252&!ansinew>  \ProvidesFile{cp1252.def}
 %<cp1250>  \ProvidesFile{cp1250.def}
 %<cp1257>  \ProvidesFile{cp1257.def}
-   [2020/08/01 v1.3d Input encoding file]
+   [2021/02/14 v1.3d Input encoding file]
 %<cp850>%%
 %<cp850>%% If you need a Euro symbol, try cp858 instead.
 %<cp850>%%
@@ -1053,7 +1053,7 @@
 %
 % The ISO Latin-3 encoding file defines the characters
 % in the ISO 8859-3 encoding.  It was contributed by
-% by J\"org Knappen (\texttt{joerg.knappen at uni-mainz.de}) and
+% J\"org Knappen (\texttt{joerg.knappen at uni-mainz.de}) and
 % adapted by Chris Rowley.
 %
 % It can be used for general purpose applications in

Modified: trunk/Master/texmf-dist/source/latex/base/inputenc.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/inputenc.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/inputenc.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/latex209.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/latex209.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/latex209.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -200,7 +200,7 @@
 %    \end{macrocode}
 % Describe the file.
 %    \begin{macrocode}
-\ProvidesFile{latex209.def}[2020/08/21 v0.55 Standard LaTeX file]
+\ProvidesFile{latex209.def}[2020/11/26 v0.55 Standard LaTeX file]
 %    \end{macrocode}
 % \changes{v0.24}{1994/05/14}{Removed date.}
 % \changes{v0.40}{1995/03/21}
@@ -712,7 +712,7 @@
 %
 % \changes{v0.18}{1994/03/11}{Added the catcode changes}
 %
-% By default, \LaTeXe{} makes the input charactes 0--8, 11, 14--31 and
+% By default, \LaTeXe{} makes the input characters 0--8, 11, 14--31 and
 % 128--255 illegal.  In compatibility mode, we restore their old
 % meanings.
 %    \begin{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/base/latex209.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/latex209.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/latex209.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/latexrelease.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/latexrelease.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/latexrelease.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -37,13 +37,13 @@
 %<fixltx2e>\ProvidesPackage{fixltx2e}
 %<fixltx2e>   [2016/12/29 v2.1a fixes to LaTeX (obsolete)]
 %<latexrelease>\ProvidesPackage{latexrelease}
-%<*!fixltx2e>
+%<*latexrelease>
 % \fi
 %         \ProvidesFile{latexrelease.dtx}
-          [2018/05/08 v1.0k LaTeX release emulation and tests
+          [2021/04/29 v1.0n LaTeX release emulation and tests
               (including releases up to \latexreleaseversion)]
 % \iffalse
-%</!fixltx2e>
+%</latexrelease>
 %<*driver>
  \documentclass{ltxdoc}
  \newcommand\Lopt[1]{\textsf{#1}}
@@ -51,6 +51,8 @@
  \providecommand{\file}[1]{\texttt{#1}}
  \providecommand{\MF}{\textsf{Metafont}}
  \providecommand{\danger}{\marginpar[\hfill\protect\Huge!!]{\protect\Huge!!\hfill}}
+ \DeclareRobustCommand\cs[2][]{\texttt{\char`\\\detokenize{#2}}}
+ \DeclareRobustCommand\pkg[1]{\textsf{#1}}
  \begin{document}
  \DocInput{latexrelease.dtx}
  \end{document}
@@ -69,7 +71,7 @@
 % \title{The \Lpack{latexrelease} package\thanks{This file
 %         has version number \fileversion, last
 %         revised \filedate.}}
-% \author{The \LaTeX3 Project}
+% \author{The \LaTeX{} Project}
 % \date{\filedate}
 % \MaintainedByLaTeXTeam{latex}
 %  \maketitle
@@ -129,7 +131,6 @@
 % package has no information will generate a warning. Dates
 % earlier than 2015 will work but will roll back to some point in 2015
 % when the method was introduced.
-% |\IncludeInRelease| command is defined.
 % The |\requestedLaTeXdate| is set to the normalized date argument
 % so that package rollback defaults to the specified date.
 %
@@ -137,9 +138,6 @@
 % |current| This is the default behaviour, it does not change the
 % effective date of the format but does ensure that the
 % |\IncludeInRelease| command is defined.
-% the |\requestedLaTeXdate| is reset to 0 so that package rollback
-% does not use the implicit date.
-% |\IncludeInRelease| command is defined.
 % The |\requestedLaTeXdate| macro is reset to 0 so that package rollback
 % does not use the implicit date.
 %
@@ -147,11 +145,16 @@
 % |latest| sets the effective date of the format to the release date
 % of this file, so in an older format applies all patches currently
 % available.
-% |\IncludeInRelease| command is defined.
 % The |\requestedLaTeXdate| macro is reset to 0 so that package rollback
 % does not use the implicit date.
 % \end{itemize}
 %
+% In all cases, when the package is loaded, the |\sourceLaTeXdate| is
+% defined to be the numerical representation of |\fmtversion| before the
+% rollback/forward actually happens, so it is possible to test from which
+% was the original \LaTeX{} version before \Lpack{latexrelease} was loaded.
+% This is particularly useful when some code in a package has to be
+% redefined differently if rolling backwards in time or forwards.
 %
 % \section{Release Specific Code}
 %
@@ -345,7 +348,7 @@
 %
 % Now if you make a further change to |\widget| in the future you
 % simply copy the current definition into the empty block and add a new
-% empty declaration with todays date and the current format date. This
+% empty declaration with today's date and the current format date. This
 % way your main code stays readable and the old versions accumulate at
 % the end of the package.\footnote{Of course there may be some cases
 % in which the old code has to be in a specific place within the
@@ -363,6 +366,99 @@
 % necessary as the new code only gets defined if that release is
 % chosen.
 %
+% \section{Declaring entire modules}
+%
+% Sometimes a large chunk of code is added as a module to another larger
+% code base.  As example of that in the 2020-10-01 release \LaTeX{} got
+% a new hook management system, \pkg{lthooks}, which was added in one go
+% and, as with all changes to the kernel, it was added to
+% \pkg{latexrelease}.  However rolling back from a future date to the
+% 2020-10-01 release didn't work because \pkg{latexrelease} would try to
+% define again all those commands, which would result in many
+% ``already defined'' errors and similar issues.
+%
+% To solve that problem, completely new modules can be defined in
+% \pkg{latexrelease} using the commands:
+% \begin{quote}
+%   \cs{NewModuleRelease}%^^A
+%     \verb|{|\meta{initial release date}%^^A
+%       \verb|}{|\meta{name}\verb|}{|\meta{message}\verb|}|\\
+%   \null\quad\meta{module code}\\
+%   \cs{IncludeInRelease}%^^A
+%     \verb|{0000/00/00}{|\meta{name}\verb|}{|\meta{message}\verb|}|\\
+%   \null\quad\meta{undefine module code}\\
+%   \cs{EndModuleRelease}
+% \end{quote}
+% With that setup, the module \meta{name} will be declared to exist only
+% in releases equal or later \meta{initial release date}.
+%
+% If \pkg{latexrelease} is rolling backwards or forwards between dates
+% after \meta{initial release date}, then all the \meta{module code} is
+% skipped, except when inside \meta{IncludeInRelease} guards, in which
+% case the code is applied or skipped as discussed above.
+%
+% If rolling forward from a date before the module's \meta{initial
+% release date} to a date after that, then all the \meta{module code} is
+% executed to define the module, and \cs{IncludeInRelease} guards are
+% executed accordingly, depending on the date declared and the target
+% date.
+%
+% If \pkg{latexrelease} is rolling back to a date before \meta{release
+% date}, then the code in the \cs{IncludeInRelease} guard dated
+% \verb|0000/00/00| is executed instead to undefine the module.  This
+% guard \emph{is not} ended by the usual \cs{EndIncludeInRelease}, but
+% instead by \cs{EndModuleRelease}.
+%
+% Finally, if rolling backwards or forwards between dates both before
+% \meta{initial release date}, the entire code between
+% \meta{NewModuleRelease} and \meta{EndModuleRelease} is entirely
+% skipped.
+%
+% \subsection{Example}
+%
+% Here is an example usage of the structure described above, as it would
+% be used in the \LaTeX{} kernel, taking \pkg{lthooks} as example:
+% \begin{verbatim}
+% %<*2ekernel|latexrelease>
+% \ExplSyntaxOn
+% %<latexrelease>\NewModuleRelease{2020/10/01}{lthooks}%
+% %<latexrelease>                 {The~hook~management~system}
+% \NewDocumentCommand \NewHook { m }
+%   { \hook_new:n {#1} }
+% %<latexrelease>\IncludeInRelease{2021/06/01}{\AddToHook}{Long~argument}
+% \NewDocumentCommand \AddToHook { m o +m }
+%   { \hook_gput_code:nnn {#1} {#2} {#3} }
+% %<latexrelease>\EndIncludeInRelease
+% %<latexrelease>
+% %<latexrelease>\IncludeInRelease{2020/10/01}{\AddToHook}{Long~argument}
+% %<latexrelease>\NewDocumentCommand \AddToHook { m o m }
+% %<latexrelease>  { \hook_gput_code:nnn {#1} {#2} {#3} }
+% %<latexrelease>\EndIncludeInRelease
+% %<latexrelease>
+% %<latexrelease>\IncludeInRelease{0000/00/00}{lthooks}{Undefine~lthooks}
+% %<latexrelease>\cs_undefine:N \NewHook
+% %<latexrelease>\cs_undefine:N \AddToHook
+% %<latexrelease>\EndModuleRelease
+% \ExplSyntaxOff
+% %</2ekernel|latexrelease>
+% \end{verbatim}
+%
+% In the example above, \cs{NewHook} is declared only once, and
+% unchanged in the next release (2021/06/01 in the example), so it has
+% no \cs{IncludeInRelease} guards, and will only be defined if needed.
+% \cs{AddToHook}, on the other hand, changed between the two releases
+% (made up for the example;  it didn't really happen)
+% and has an \cs{IncludeInRelease} block for the current release (off
+% \pkg{docstrip} guards, so it goes into the kernel too), and another
+% for the previous release (in \pkg{docstrip} guards so it goes only
+% into \pkg{latexrelease}).
+%
+% Note that in the example above, \cs{ExplSyntaxOn} and
+% \cs{ExplSyntaxOff} were added \emph{outside} the module code because,
+% as discussed above, sometimes the code outside \cs{IncludeInRelease}
+% guards may be skipped, but not the code inside them, and in that case
+% the catcodes would be wrong when defining the code.
+%
 % \section{fixltx2e}
 %
 % As noted above, prior to the 2015 \LaTeX\ release updates to the
@@ -386,17 +482,34 @@
 \NeedsTeXFormat{LaTeX2e}[1996/06/01]
 %    \end{macrocode}
 %
-% \section{Setup}
+% \subsection{Setup}
 %
-% \begin{macro}{\IncludeInRelease}
-% \begin{macro}{\EndIncludeInRelease}
+% \begin{macro}{\sourceLaTeXdate}
+%   \changes{v1.0l}{2021/01/23}{\cs{sourceLaTeXdate} added}
+%   \changes{v1.0m}{2021/03/18}{Define \cs{sourceLaTeXdate} conditionally}
+%   Store the original \LaTeX{} format version
+%   as a number in the format |YYYYMMDD|.  This macro has to
+%   be defined conditionally, so that it isn't changed in case
+%   \file{latexrelease.sty} is loaded twice (for tests), but it
+%   can't be defined in the kernel only, otherwise
+%   \file{latexrelease.sty} wouldn't work in older \LaTeX{} due
+%   to the missing macro.
 %    \begin{macrocode}
+\@ifundefined{sourceLaTeXdate}{%
+  \edef\sourceLaTeXdate{%
+    \expandafter\@parse at version\fmtversion//00\@nil}}{}%
 %    \end{macrocode}
 % \end{macro}
+%
+% \begin{macro}{\IncludeInRelease}
+% \begin{macro}{\EndIncludeInRelease}
+%   These are defined in \file{ltvers.dtx}.
 % \end{macro}
+% \end{macro}
 %
 % \changes{v1.0c}{2015/02/19}{Swap argument order}
-% \changes{v1.0k}{2018/05/08}{reset \cs{\requestedLaTeXdate} for current and latest options, gitub issue 43}
+% \changes{v1.0k}{2018/05/08}{reset \cs{\requestedLaTeXdate} for current
+%                             and latest options, github issue 43}
 %    \begin{macrocode}
 \DeclareOption*{%
   \def\@IncludeInRelease#1[#2]{\@IncludeInRele at se{#1}}%
@@ -483,17 +596,214 @@
 %    \end{macrocode}
 %
 %
-% \section{Individual  Changes}
+% \subsection{Ignoring \texttt{\string_new} errors when rolling back}
 %
-% The code for each change will be inserted at this point, extracted
-% from the kernel source files.
+% Enforce \cs{ExplSyntaxOn} and \cs{ExplSyntaxOff} to be \cs{relax} in
+% \pkg{latexrelease} if they are not yet defined.  They are later
+% restored to be undefined if needed.
+%    \begin{macrocode}
+\csname ExplSyntaxOn\endcsname
+\csname ExplSyntaxOff\endcsname
+%    \end{macrocode}
 %
+% \changes{v1.0m}{2021/03/18}
+%         {Make \texttt{\string_new} definitions harmless}
+%
+% Define a set of changes here, but we'll only use them later to make
+% sure they are applied after \pkg{expl3} is loaded.  If loading from a
+% rather old format, we don't have \cs{ExplSyntaxOn} yet.
 %    \begin{macrocode}
+\begingroup
+  \endlinechar=-1
+  \catcode95=11 % _
+  \catcode58=11 % :
+  \catcode126=10 % ~
+  \catcode32=09 % <space>
+  \xdef\latexrelease at postexpl{\unexpanded{%
+%<@@=latexrelease>
+%    \end{macrocode}
+%
+% First we'll define a \cs{declarecommand} that does \cs{renewcommand}
+% if the command being defined already exists, and \cs{newcommand}
+% otherwise.
+%    \begin{macrocode}
+\cs_gset_protected:Npn \@@_declare_command:w
+  { \@star at or@long \@@_declare_command:Nw }
+\cs_gset_protected:Npn \@@_declare_command:Nw #1
+  { \cs_if_exist:NTF #1 { \renew at command } { \new at command } #1 }
+%    \end{macrocode}
+%
+% Then define a version of \cs{e at alloc} that checks if the control
+% sequence being defined already exists, and if so, checks if its
+% meaning is the same as the one that would be defined with the call to
+% \cs{e at alloc}.  If both tests pass, nothing is defined to save a
+% register.  This version also takes care of setting
+% \cs{allocationnumber} to the value it would have after the register is
+% allocated.
+%    \begin{macrocode}
+\cs_gset_protected:Npn \@@_e at alloc:NnnnnN #1 #2 #3 #4 #5 #6
+  {
+    \cs_if_free:NTF #6
+      { \use:n }
+      {
+        \exp_after:wN \@@_e at alloc:N
+          \token_to_meaning:N #6 \scan_stop: {#2} #6
+      }
+        { \@@_e at alloc #1 {#2} {#3} {#4} {#5} #6 }
+  }
+%    \end{macrocode}
+% Walk through the meaning of the control sequence token by token,
+% looking for the register allocation number.
+%    \begin{macrocode}
+\cs_gset_protected:Npn \@@_e at alloc:N #1
+  {
+    \if_int_compare:w 0 < 0
+        \if_int_compare:w 10 < 9#1 ~ 1 \fi:
+        \if_charcode:w " #1 1 \fi: \exp_stop_f:
+      \tex_afterassignment:D \@@_e at alloc:w
+      \@tempcnta #1
+      \use_i:nnn
+    \fi:
+    \use:n
+      {
+        \if_meaning:w \scan_stop: #1
+          \exp_after:wN \use_iv:nnnn
+        \fi:
+        \@@_e at alloc:N
+      }
+  }
+%    \end{macrocode}
+% When found, check if it is the exact same register as it would be
+% allocated, and if it is, set \cs{allocationnumber} accordingly and
+% exit, otherwise undefine the register and allocate from scratch.
+%    \begin{macrocode}
+\cs_gset_protected:Npn \@@_e at alloc:w #1 \scan_stop: #2 #3
+  {
+    #2 \@@_tmp:w = \@tempcnta
+    \token_if_eq_meaning:NNTF #3 \@@_tmp:w
+      { \int_set_eq:NN \allocationnumber \@tempcnta  \use_none:n }
+      { \cs_set_eq:NN #3 \tex_undefined:D            \use:n      }
+  }
+%    \end{macrocode}
+%
+% Now create a token list to hold the list of changed commands, and
+% define a temporary macro that will loop through the command list,
+% store each in \cs{l_@@_restores_tl}, save a copy, and redefine each.
+%    \begin{macrocode}
+\tl_clear_new:N \l_@@_restores_tl
+\cs_gset:Npn \@@_tmp:w #1 #2
+  {
+    \quark_if_recursion_tail_stop_do:Nn #1
+      { \cs_undefine:N \@@_tmp:w }
+    \tl_put_right:Nn \l_@@_restores_tl {#1}
+    \cs_set_eq:cN { @@_ \cs_to_str:N #1 } #1
+    \cs_set_eq:NN #1 #2
+    \@@_tmp:w
+  }
+%    \end{macrocode}
+%
+% The redefinitions below are needed because:
+% \begin{description}
+%   \def\makelabel#1{\cs{#1}}
+%   \item[__kernel_chk_if_free_cs:N] This function is used ubiquitously
+%     in the \pkg{l3kernel} to check if a control sequence is definable,
+%     and give an error otherwise (similar to \cs{@ifdefinable}).
+%     Making it a no-op is enough for most cases (except when defining
+%     new registers);
+%   \item[e at alloc] In the case of new registers, we waste an allocation
+%     number if we do \cs[no-index]{new\meta{thing}} in a register
+%     that's already allocated, so the redefinition of \cs{e at alloc}
+%     checks if the new register is really necessary.  This code does
+%     not clear the register, which might cause problems in the future,
+%     if a register is allocated but not properly cleared before using;
+%   \item[__kernel_msg_error:nnx] This command is used to error on
+%     already defined scan marks.  Just making the error do nothing is
+%     enough, as no action is taken in that case;
+%   \item[msg_new:nnnn] Used to define new messages.  Making it
+%     \texttt{\string_gset} is enough.  Other msg commands like
+%     \cs{msg_new:nnn} and \cs[no-index]{__kernel_msg_new:nnn(n)} are
+%     defined in terms of \cs{msg_new:nnnn}, so there is no need to
+%     change the other ones;
+%   \item[NewDocumentCommand] Used to define user-level commands in the
+%     kernel.  Making it equal to \cs{DeclareDocumentCommand} solves the
+%     problem;
+%   \item[newcommand] Same as above.
+% \end{description}
+% And here we go:
+%    \begin{macrocode}
+\@@_tmp:w
+  \__kernel_chk_if_free_cs:N \use_none:n
+  \e at alloc \@@_e at alloc:NnnnnN
+  \__kernel_msg_error:nnx \use_none:nnn
+  \msg_new:nnnn \msg_gset:nnnn
+  \NewDocumentCommand \DeclareDocumentCommand
+  \newcommand \@@_declare_command:w
+%    \end{macrocode}
+%    Temp addition \ldots
+%    \begin{macrocode}
+  \__kernel_msg_error:nnn  \use_none:nnn  % needed while redirect for kernel msgs doesn't work
+  \q_recursion_tail \q_recursion_tail
+  \q_recursion_stop
+%    \end{macrocode}
+%
+% Finally, redirect the error thrown by \cs{NewHook} to nowhere so it
+% can be safely reused (the hook isn't redeclared if it already exists).
+%    \begin{macrocode}
+\msg_redirect_name:nnn { hooks } { exists } { none }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+  }}%
+\endgroup
 %</latexrelease>
 %    \end{macrocode}
 %
-% \section{fixltx2e}
+% \subsection{Undoing the temp modifications}
 %
+% If \cs{ExplSyntaxOn} exists (defined and not equal \cs{relax}), then
+% use the \pkg{expl3} restore code, otherwise restore \cs{ExplSyntaxOn}
+% and \cs{ExplSyntaxOff} to be undefined.
+%    \begin{macrocode}
+%<*latexrelease-finish>
+\@ifundefined{ExplSyntaxOn}%
+  {\let\ExplSyntaxOn\@undefined
+   \let\ExplSyntaxOff\@undefined
+   \@gobble}%
+  {\ExplSyntaxOn
+   \@firstofone}%
+  {%
+%    \end{macrocode}
+%
+% Now just loop through the list of redefined commands and restore their
+% previous meanings.
+%    \begin{macrocode}
+\tl_map_inline:Nn \l_@@_restores_tl
+  {
+    \cs_set_eq:Nc #1 { @@_ \cs_to_str:N #1 }
+    \cs_undefine:c { @@_ \cs_to_str:N #1 }
+  }
+\tl_clear:N \l_@@_restores_tl
+%    \end{macrocode}
+%
+% And restore the hook error message.
+%    \begin{macrocode}
+\msg_redirect_name:nnn { hooks } { exists } { }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<@@=>
+  \ExplSyntaxOff}%
+%</latexrelease-finish>
+%    \end{macrocode}
+%
+% \subsection{Individual Changes}
+%
+% The code for each change will be inserted at this point, extracted
+% from the kernel source files.
+%
+%
+% \subsection{fixltx2e}
+%
 % Generate a stub \Lpack{fixltx2e} package:
 %    \begin{macrocode}
 %<*fixltx2e>

Modified: trunk/Master/texmf-dist/source/latex/base/latexrelease.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/latexrelease.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/latexrelease.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.
@@ -93,13 +93,16 @@
   \from{ltluatex.dtx}    {latexrelease}% empty 
   \from{ltexpl.dtx}      {latexrelease}% empty 
   \from{ltdefns.dtx}     {latexrelease}%
-  \from{lthooks.dtx}     {latexrelease}% empty  % L3 layer module
+  \from{ltcmd.dtx}       {latexrelease}%
+  \from{lthooks.dtx}     {latexrelease}% L3 layer module
+  \from{ltcmdhooks.dtx}  {latexrelease}% L3 layer module
   \from{ltalloc.dtx}     {latexrelease}% empty
   \from{ltcntrl.dtx}     {latexrelease}% empty
   \from{lterror.dtx}     {latexrelease}% empty
   \from{ltpar.dtx}       {latexrelease}% empty
+  \from{ltpara.dtx}      {latexrelease}% empty
   \from{ltspace.dtx}     {latexrelease}%
-  \from{ltlogos.dtx}     {latexrelease}% empty
+  \from{ltlogos.dtx}     {latexrelease}% L3 layer module
   \from{ltfiles.dtx}     {latexrelease}%
   \from{ltoutenc.dtx}    {latexrelease}%
   \from{ltcounts.dtx}    {latexrelease}%
@@ -132,6 +135,7 @@
   \from{ltoutput.dtx}    {latexrelease}%
   \from{ltfsscmp.dtx}    {latexrelease}% only in latexrelease!
   \from{ltfinal.dtx}     {latexrelease}%
+  \from{latexrelease.dtx}{latexrelease-finish}%
 }
 
 

Modified: trunk/Master/texmf-dist/source/latex/base/latexsym.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/latexsym.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/latexsym.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/latexsym.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/latexsym.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/latexsym.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.
@@ -87,8 +87,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/letter.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/letter.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/letter.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -45,7 +45,7 @@
 %<*driver>
        \ProvidesFile{letter.drv}
 %</driver>
-              [2020/03/11 v1.3b
+              [2021/03/05 v1.3c
 %<+letter>               Standard LaTeX document class]
 %    \end{macrocode}
 %
@@ -165,7 +165,7 @@
 % \changes{v1.3a}{2020/03/07}{merged changes to classes.dtx into letter.dtx}
 %
 % \iffalse
-% Copyright (C) 1994 LaTeX3 project, Frank Mittelbach
+% Copyright (C) 1994 LaTeX Project, Frank Mittelbach
 % and Rainer Sch\"opf, all rights reserved.
 % \fi
 %
@@ -1019,7 +1019,29 @@
       \@date \end{tabular}\par}%
   \fi
   \vspace{2\parskip}%
-  {\raggedright \toname \\ \toaddress \par}%
+%    \end{macrocode}
+%    If the address field used \verb=\\[...]= then we have
+%    \cs{toaddress} starting with the bracket argument as the split
+%    was done simply at \verb=\\=. So we add \cs{expandafter} here so
+%    that is will be used and not typeset. A better fix would be to do
+%    a proper parsing but \ldots
+%
+%    Other classes based on \texttt{letter.cls} could benefit from the same fix, e.g.,
+%    \texttt{akletter.cls},
+%    \texttt{bletter.cls},
+%    \texttt{letter.cls},
+%    \texttt{chletter.cls},
+%    \texttt{extletter.cls},\\
+%    \texttt{frletter.cls},
+%    \texttt{hletter.cls},
+%    \texttt{scrlttr2.cls} (change rejected),
+%    \texttt{lettre.cls},
+%    \texttt{beletter.cls},\\
+%    \texttt{brief.cls} and perhaps others.
+%
+% \changes{v1.3c}{2020/12/28}{Add \cs{expandafter} (gh/427)}
+%    \begin{macrocode}
+  {\raggedright \toname \expandafter\\\toaddress \par}%
   \vspace{2\parskip}%
   #1\par\nobreak}
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/base/letter.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/letter.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/letter.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/ltalloc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltalloc.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltalloc.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/ltbibl.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltbibl.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltbibl.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -32,7 +32,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltbibl.dtx}
-             [2018/11/09 v1.1r LaTeX Kernel (Bibliography)]
+             [2020/12/10 v1.1s LaTeX Kernel (Bibliography)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltbibl.dtx}
@@ -104,7 +104,7 @@
 % but puts nothing in the text.
 %
 % |\nocite{*}| is special: it tells \BibTeX{} to put the whole of a
-% collection of references into the bibiography.
+% collection of references into the bibliography.
 %
 % \StopEventually{}
 %
@@ -253,7 +253,7 @@
 %    year citations it becomes more than questionable.
 %
 %    So Chris added yet another hook here, as suggested by, at least,
-%    Donald Arsenau.  Note that this one is inside the first argument
+%    Donald Arseneau.  Note that this one is inside the first argument
 %    of the |\@cite| hook.
 %    This decouples the top-level typesetting of the citation from
 %    the details of the other business conducted here.  All this really
@@ -327,6 +327,10 @@
 % \changes{v1.1g}{1995/05/08}{Use \cs{@firstofone}}
 % \changes{v1.1k}{1995/10/20}{Removed refundefined flag}
 %    \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>                 {\nocite}{Allow nocite in preamble}%
 \def\nocite#1{\@bsphack
 %    \end{macrocode}
 %    With the implementation designed already in \LaTeX\,2.09 the
@@ -335,10 +339,15 @@
 %    that point. As a result the ``reference'' will appear on the
 %    terminal and nothing else will happen.
 %
-%    This would be easy to fix, but then a document using the fix will
+%    [This would be easy to fix, but then a document using the fix will
 %    silently fail on an older release of \LaTeX{}, missing all
 %    citations done with |\nocite|. Thus we do only generate an error
-%    message and leave the fix for a \LaTeXe{} successor.
+%    message and leave the fix for a \LaTeXe{} successor.]
+%  
+%    Given that we are now a quarter century into using \LaTeXe{}
+%    there is no good reason any more do limit ourself to 2.09
+%    conciderations. So we now simply delay the \cs{nocide} if it is
+%    issued in the preamble.
 %
 % \changes{v1.1o}{2003/05/18}{Check if we are after \cs{document}}
 % \changes{v1.1p}{2004/01/04}{Changed error message}
@@ -354,18 +363,48 @@
           \@latex at warning{Citation `\@citeb' undefined}}{}}%
   \else
 %    \end{macrocode}
-%    But before |\begin{document}| we raise an error message:
+%    But before |\begin{document}| we raised an error message in the
+%    past but as of 2021/05 not any longer.
 %    \begin{macrocode}
-    \@latex at error{Cannot be used in preamble}\@eha
+%    \@latex at error{Cannot be used in preamble}\@eha
 %    \end{macrocode}
-%    Without the compatibility problems we could fix the problem as follows:
+%    Instead we delay the declaration to the start of the document.
+%    We have to use a late hook for this, so that it comes after the
+%    \texttt{.aux} file is open for writing and after
+%    \cs{@preamblecmds} was executed to change the above
+%    test. Therefore \cs{AtBeginDocument} would still be too early.
+% \changes{v1.1s}{2020/12/10}{Delay any \cs{nocite} in the preamble
+%    instead of raising an error}
 %    \begin{macrocode}
-    % \AtBeginDocument{\nocite{#1}}
+    \AddToHook{begindocument/end}[kernel]{\nocite{#1}}%
   \fi
   \@esphack}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
 %    \end{macrocode}
+%
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\nocite}{Allow nocite in preamble}%
+%<latexrelease>
+%<latexrelease>\def\nocite#1{\@bsphack
+%<latexrelease>  \ifx\@onlypreamble\document
+%<latexrelease>    \@for\@citeb:=#1\do{%
+%<latexrelease>      \edef\@citeb{\expandafter\@firstofone\@citeb}%
+%<latexrelease>      \if at filesw\immediate\write\@auxout{\string\citation{\@citeb}}\fi
+%<latexrelease>      \@ifundefined{b@\@citeb}{\G at refundefinedtrue
+%<latexrelease>          \@latex at warning{Citation `\@citeb' undefined}}{}}%
+%<latexrelease>  \else
+%<latexrelease>    \@latex at error{Cannot be used in preamble}\@eha
+%<latexrelease>  \fi
+%<latexrelease>  \@esphack}
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+%    \end{macrocode}
+%
 %    Since |\nocite{*}| should not produce a warning about undefined
-%    citation keys (seee PR 557), we need to set the control sequence
+%    citation keys (see PR 557), we need to set the control sequence
 %    `|\b@*|' to something other than |\relax|. As a result |\cite{*}|
 %    will not warn either (but that never worked with \BibTeX{} in the
 %    first place).

Modified: trunk/Master/texmf-dist/source/latex/base/ltboxes.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltboxes.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltboxes.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -33,7 +33,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltboxes.dtx}
-             [2020/09/27 v1.4a LaTeX Kernel (Box Commands)]
+             [2021/02/10 v1.4b LaTeX Kernel (Box Commands)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltboxes.dtx}
@@ -222,7 +222,7 @@
 % \changes{v1.0j}{1994/10/18}
 %         {stuff from ltpatch done}
 % \changes{v1.0p}{1994/11/09}
-%         {more colour changes\ldots}
+%         {more color changes\ldots}
 % \changes{v1.0q}{1994/11/17}
 %         {\cs{@tempa} to \cs{reserved at a}}
 % \changes{v1.0t}{1995/05/07}{Use \cs{hb at xt@}}
@@ -422,7 +422,7 @@
 %         {macro added}
 % \changes{v0.1a}{1993/12/03}
 %         {color support}
-% This macro is initially a no-op, but the colour package will redefine
+% This macro is initially a no-op, but the color package will redefine
 % it to insert a |\special|.
 %    \begin{macrocode}
 \let\set at color\relax
@@ -431,39 +431,67 @@
 %
 % \begin{macro}{\color at begingroup}
 % \changes{v1.0b}{1994/03/14}
-%         {macro added for colour support}
+%         {macro added for color support}
 % \begin{macro}{\color at endgroup}
 % \changes{v1.0b}{1994/03/14}
-%         {macro added for colour support}
+%         {macro added for color support}
 % \begin{macro}{\color at setgroup}
 % \changes{v1.0f}{1994/05/11}
-%         {macro added for colour support}
+%         {macro added for color support}
 % \begin{macro}{\normalcolor}
 % \changes{v1.0g}{1994/05/12}
-%         {macro added for colour support}
+%         {macro added for color support}
 % \begin{macro}{\color at hbox}
 % \changes{v1.0n}{1994/11/05}
-%         {macro added for colour support}
+%         {macro added for color support}
 % \begin{macro}{\color at vbox}
 % \changes{v1.0r}{1994/11/18}
-%         {macro added for colour support}
+%         {macro added for color support}
 % \begin{macro}{\color at endbox}
 % \changes{v1.0n}{1994/11/05}
-%         {macro added for colour support}
-% These macros are initially a no-op, but the colour package will
+%         {macro added for color support}
+% \changes{v1.4b}{2021/02/04}
+%         {Always add the color groups (gh/488)}
+% In the past these macros were initially no-ops, and the \pkg{color}
+% package redefined
 % redefine them to be |\begingroup|, |\endgroup|,
 % |\begingroup\set at color|,\\ |\hbox\bgroup\color at begingroup|,
 % |\color at endgroup\egroup|.
-% and \meta{set to main document colour} respectively.
+% and \meta{set to main document color} respectively.
+%
+% Nowadays we always set the group already in the kernel as this makes the
+% coding simpler.
 %    \begin{macrocode}
-\let\color at begingroup\relax
-\let\color at endgroup\relax
-\let\color at setgroup\relax
-\let\normalcolor\relax
-\let\color at hbox\relax
-\let\color at vbox\relax
-\let\color at endbox\relax
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>                 {\color at begingroup}{color group settings}%
+\let\color at begingroup\begingroup
+\def\color at endgroup{\endgraf\endgroup}
+\def\color at setgroup{\color at begingroup}        % changed further in color package
+\let\normalcolor\relax                        % remains untouched; only changed in a color package
+\def\color at hbox{\hbox\bgroup\color at begingroup}
+\def\color at vbox{\vbox\bgroup\color at begingroup}
+\def\color at endbox{\color at endgroup\egroup}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
 %    \end{macrocode}
+%
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\color at begingroup}{color group settings}%
+%<latexrelease>
+%<latexrelease>\let\color at begingroup\relax
+%<latexrelease>\let\color at endgroup\relax
+%<latexrelease>\let\color at setgroup\relax
+%<latexrelease>\let\normalcolor\relax
+%<latexrelease>\let\color at hbox\relax
+%<latexrelease>\let\color at vbox\relax
+%<latexrelease>\let\color at endbox\relax
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+%    \end{macrocode}
 % \end{macro}
 % \end{macro}
 % \end{macro}
@@ -539,7 +567,7 @@
 % \changes{v1.0b}{1994/03/14}
 %         {Use \cs{color at setgroup}}
 % \changes{v1.0d}{1994/04/15}
-%         {Added missing procent character.}
+%         {Added missing percent character.}
 % \changes{v1.0v}{1995/07/20}
 %         {Use \cs{sbox}}
 %    \begin{macrocode}
@@ -888,7 +916,7 @@
 %
 % The rational for allowing two normally global flags to be set
 % locally here was stated originally by
-% Donald Arsenau and extended by Chris Rowley.
+% Donald Arseneau and extended by Chris Rowley.
 % It is because these flags are only set globally to
 % true by section commands, and these should never appear within
 % boxes or, indeed, in any group; and they are only ever
@@ -1016,7 +1044,7 @@
 %
 % \begin{macro}{\@iiiminipage}
 % \changes{v1.0e}{1994/04/21}
-%     {Extra \cs{bgroup} for colour}
+%     {Extra \cs{bgroup} for color}
 % \changes{v1.0f}{1994/05/11}
 %         {Use new \cs{color at setgroup} concept.}
 % Internal form of |minipage|.
@@ -1054,11 +1082,11 @@
 %     {(RmS) replaced \cs{vskip}-\cs{lastskip} by \cs{unskip}
 %       (proposed by FMi)}
 % \changes{v1.0e}{1994/04/21}
-%     {Extra \cs{egroup} for colour}
+%     {Extra \cs{egroup} for color}
 % \changes{v1.0f}{1994/05/11}
 %         {Use new \cs{color at setgroup} concept.}
 % \changes{v1.0n}{1994/11/05}
-%     {Colour resetting for footnotes moved to here: as for main
+%     {Color resetting for footnotes moved to here: as for main
 %     page.}
 %    \begin{macrocode}
 \def\endminipage{%
@@ -1093,9 +1121,9 @@
 % Final |\strut| added 27 Mar 89, on suggestion by Don Hosek
 % \changes{LaTeX2.09}{1991/09/29}{(RmS) added \cs{reset at font}}
 % \changes{LaTeX2.09}{1992/11/26}{(RmS) added protection for \cs{edef}}
-% \changes{v0.1a}{1994/03/07}{Extra group for colour}
+% \changes{v0.1a}{1994/03/07}{Extra group for color}
 % \changes{v1.0e}{1994/04/21}
-%     {Extra \cs{endgraf} for colour}
+%     {Extra \cs{endgraf} for color}
 % \changes{v1.0f}{1994/05/11}
 %         {Use new \cs{color at setgroup} concept.}
 % \changes{v1.0f}{1994/05/11}
@@ -1103,11 +1131,17 @@
 % \changes{v1.0m}{1994/11/04}
 %         {Added \cs{protected at edef}. ASAJ.}
 % \changes{v1.0n}{1994/11/05}
-%     {Colour resetting for footnotes moved to endminipage: as for main
+%     {Color resetting for footnotes moved to endminipage: as for main
 %     page.}
 % \changes{v1.0o}{1994/11/05}
-%     {Colour groups restored here.}
+%     {Color groups restored here.}
+% \changes{v1.4b}{2021/02/10}
+%         {Explicitly run \cs{par} in support for paragraph tagging}
 %    \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>                 {\@mpfootnotetext}{footnotetext tagging}%
 \long\def\@mpfootnotetext#1{%
   \global\setbox\@mpfootins\vbox{%
     \unvbox\@mpfootins
@@ -1119,8 +1153,32 @@
     \color at begingroup
       \@makefntext{%
         \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
+    \par
     \color at endgroup}}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
 %    \end{macrocode}
+%
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\@mpfootnotetext}{footnotetext tagging}%
+%<latexrelease>
+%<latexrelease>\long\def\@mpfootnotetext#1{%
+%<latexrelease>  \global\setbox\@mpfootins\vbox{%
+%<latexrelease>    \unvbox\@mpfootins
+%<latexrelease>    \reset at font\footnotesize
+%<latexrelease>    \hsize\columnwidth
+%<latexrelease>    \@parboxrestore
+%<latexrelease>    \protected at edef\@currentlabel
+%<latexrelease>         {\csname p at mpfootnote\endcsname\@thefnmark}%
+%<latexrelease>    \color at begingroup
+%<latexrelease>      \@makefntext{%
+%<latexrelease>        \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
+%<latexrelease>    \color at endgroup}}
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+%    \end{macrocode}
 % \end{macro}
 %
 %    \begin{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/base/ltclass.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltclass.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltclass.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -33,7 +33,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltclass.dtx}
-             [2020/12/17 v1.3v LaTeX Kernel (Class & Package Interface)]
+             [2021/05/18 v1.4b LaTeX Kernel (Class & Package Interface)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltclass.dtx}
@@ -427,7 +427,7 @@
 % \changes{v0.2h}{1993/11/28}
 %         {Primitive filenames now terminated by space not \cs{relax}.}
 % \changes{v0.2h}{1993/11/28}
-%         {Directory syntax checing moved to dircheck.dtx}
+%         {Directory syntax checking moved to dircheck.dtx}
 % \changes{v0.2h}{1993/11/28}
 %         {Assorted commands now in the kernel removed.}
 % \changes{v0.2i}{1993/12/03}
@@ -486,7 +486,7 @@
 %  \begin{macro}{\@declaredoptions}
 %    This list is automatically built by |\DeclareOption|.
 %    It is the list of options (separated by commas) declared in
-%    the class or package file and it defines the order in which the
+%    the class or package file and it defines the order in which
 %    the corresponding |\ds@|\meta{option} commands are executed.
 %    All local \meta{option}s which are not declared will be processed
 %    in the order defined by the optional argument of |\documentclass|
@@ -505,6 +505,14 @@
 %    \end{macrocode}
 %  \end{macro}
 %
+%  \begin{macro}{\@raw at classoptionslist}
+%    List of options of the main class (unprocessed).
+% \changes{v1.4b}{2021/05/18}{Initialise to \cs{relax} to match \cs{@classoptionslist}}
+%    \begin{macrocode}
+\let\@raw at classoptionslist\relax
+%    \end{macrocode}
+%  \end{macro}
+%
 %  \begin{macro}{\@unusedoptionlist}
 % \changes{v1.0u}{1996/07/26}{made only preamble}
 %    List of options of the main class that haven't been declared or
@@ -640,8 +648,21 @@
 %<latexrelease>    \@expl at push@filename at aux@@}
 %<latexrelease>\EndIncludeInRelease
 %<latexrelease>
+%    \end{macrocode}
+%
+% When we roll back from a release that has \pkg{expl3} preloaded, the
+% definitions of \cs{@pushfilename} and \cs{@popfilename} can't be
+% completely rolled back otherwise \pkg{expl3}-based packages won't
+% have the automatic \cs{ExplSyntaxOff} at the end.  Here and below for
+% \cs{@popfilename}, we don't roll back all the way through if coming
+% from \LaTeX${}>2020-02-02$.
+% \changes{v1.4a}{2021/03/27}
+%         {Do not completely roll back if \pkg{expl3} is loaded.}
+%    \begin{macrocode}
 %<latexrelease>\IncludeInRelease{0000/00/00}{\@pushfilename}%
 %<latexrelease>  {Add \@expl at push@filename@@ and \@expl at push@filename at aux@@}%
+%<latexrelease>\ifnum\sourceLaTeXdate<20200202\relax
+%<latexrelease>  \GenericInfo{}{Defining 00-00-00\string\@pushfilename.}
 %<latexrelease>\def\@pushfilename{%
 %<latexrelease>  \xdef\@currnamestack{%
 %<latexrelease>    {\@currname}%
@@ -648,6 +669,17 @@
 %<latexrelease>    {\@currext}%
 %<latexrelease>    {\the\catcode`\@}%
 %<latexrelease>    \@currnamestack}}
+%<latexrelease>\else
+%<latexrelease>  \GenericInfo{}{Defining 2020-02-02\string\@pushfilename.}
+%<latexrelease>\def\@pushfilename{%
+%<latexrelease>  \@expl at push@filename@@
+%<latexrelease>  \xdef\@currnamestack{%
+%<latexrelease>    {\@currname}%
+%<latexrelease>    {\@currext}%
+%<latexrelease>    {\the\catcode`\@}%
+%<latexrelease>    \@currnamestack}%
+%<latexrelease>    \@expl at push@filename at aux@@}
+%<latexrelease>\fi
 %<latexrelease>\EndIncludeInRelease
 \@onlypreamble\@pushfilename
 %    \end{macrocode}
@@ -676,9 +708,21 @@
 %<latexrelease>  \@expl at pop@filename@@}
 %<latexrelease>\EndIncludeInRelease
 %<latexrelease>
+%    \end{macrocode}
+%
+% \changes{v1.4a}{2021/03/27}
+%         {Do not completely roll back if \pkg{expl3} is loaded.}
+%    \begin{macrocode}
 %<latexrelease>\IncludeInRelease{0000/00/00}{\@popfilename}%
 %<latexrelease>  {Add \@expl at push@filename@@ and \@expl at push@filename at aux@@}%
+%<latexrelease>\ifnum\sourceLaTeXdate<20200202\relax
+%<latexrelease>  \GenericInfo{}{Defining 00-00-00\string\@popfilename.}
 %<latexrelease>\def\@popfilename{\expandafter\@p at pfilename\@currnamestack\@nil}
+%<latexrelease>\else
+%<latexrelease>  \GenericInfo{}{Defining 2020-02-02\string\@popfilename.}
+%<latexrelease>\def\@popfilename{\expandafter\@p at pfilename\@currnamestack\@nil
+%<latexrelease>  \@expl at pop@filename@@}
+%<latexrelease>\fi
 %<latexrelease>\EndIncludeInRelease
 \@onlypreamble\@popfilename
 %    \end{macrocode}
@@ -712,6 +756,7 @@
 %   Path to the current file if explicitly given.  The auxiliary is
 %   needed here to insert a \cs{@empty} to prevent the loss of braces.
 %   \changes{v1.3u}{2020/11/20}{Macro added}
+%   \changes{v1.3w}{2021/01/21}{Add empty entry for latexrelease}
 %    \begin{macrocode}
 %</2ekernel>
 %<*2ekernel|latexrelease>
@@ -719,6 +764,7 @@
 %<latexrelease>\IncludeInRelease{2020/10/01}{\@kernel at currpathstack}%
 %<latexrelease>  {Add \@kernel at currpathstack}%
 \gdef\@kernel at currpathstack{}
+%<latexrelease>\g at addto@macro\@kernel at currpathstack{{}}
 \def\@p at pfilepath#1{%
   \gdef\@currpath{#1}\@p at pfilepath@aux\@empty}
 \def\@p at pfilepath@aux#1\@nil{%
@@ -1026,12 +1072,12 @@
 %    be cautious when handling the identification string in case it
 %    contains UTF-8 characters.
 % \changes{v1.3e}{2019/11/29}{Protect package info text (gh/52)}
-% \changes{v1.3r}{2020/10/01}{Allow for package subsitution}
+% \changes{v1.3r}{2020/10/01}{Allow for package substitution}
 %    \begin{macrocode}
 %</2ekernel>
 %<*2ekernel|latexrelease>
 %<latexrelease>\IncludeInRelease{2020/10/01}%
-%<latexrelease>                 {\@pr at videpackage}{Allow for package subsitution}%
+%<latexrelease>                 {\@pr at videpackage}{Allow for package substitution}%
 \def\@pr at videpackage[#1]{%
   \expandafter\protected at xdef                %     <-- protected...
      \csname ver@\@currname.\@currext\endcsname{#1}% Loaded package
@@ -1164,13 +1210,14 @@
 %
 % \begin{macro}{\PassOptionsToPackage}
 % \begin{macro}{\PassOptionsToClass}
-% If the package has been loaded, we check that it was first loaded with
-% the options.  Otherwise we add the option list to that of the package.
+%   If the package has been loaded, we check that it was first loaded with
+%   the options.  Otherwise we add the option list to that of the package.
 % \changes{v1.3t}{2020/10/18}{Drop path from \cs{input at path} (gh/414).}
+% \changes{v1.3x}{2021/02/18}{save raw option lists (gh/85)}
 %    \begin{macrocode}
 %</2ekernel>
-%<latexrelease>\IncludeInRelease{2020/10/01}{\@pass at ptions}
-%<latexrelease>  {Add file replacement in \@pass at ptions}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>                 {\@pass at ptions}{Raw option lists}%
 %<*2ekernel|latexrelease>
 \def\@pass at ptions#1#2#3{%
   \@expl@@@filehook at set@curr at file@@nNN
@@ -1187,12 +1234,41 @@
 %    \begin{macrocode}
   \expandafter\let
     \csname opt@#3.#1\expandafter\endcsname
-    \csname opt@\reserved at a\endcsname}
+    \csname opt@\reserved at a\endcsname
+%    \end{macrocode}
+% Extend raw option list
+%    \begin{macrocode}
+    \@ifundefined{@raw at opt@#3.#1}%
+      {\expandafter\gdef\csname @raw at opt@#3.#1\endcsname{#2}}%
+      {\expandafter\g at addto@macro\csname @raw at opt@#3.#1\endcsname{,#2}}%
+}
 %</2ekernel|latexrelease>
 %<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
 %
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{2020/10/01}{\@pass at ptions}
+%<latexrelease>  {Add file replacement in \@pass at ptions}%
+%<latexrelease>
+%<latexrelease>\def\@pass at ptions#1#2#3{%
+%<latexrelease>  \@expl@@@filehook at set@curr at file@@nNN
+%<latexrelease>    {\@expl@@@filehook at resolve@file at subst@@w #3.#1\@nil}%
+%<latexrelease>      \reserved at a\reserved at b
+%<latexrelease>  \@expl@@@filehook at clear@replacement at flag@@
+%<latexrelease>  \expandafter\xdef\csname opt@\reserved at a\endcsname{%
+%<latexrelease>    \@ifundefined{opt@\reserved at a}\@empty
+%<latexrelease>      {\csname opt@\reserved at a\endcsname,}%
+%<latexrelease>    \zap at space#2 \@empty}%
+%<latexrelease>  \expandafter\let
+%<latexrelease>    \csname opt@#3.#1\expandafter\endcsname
+%<latexrelease>    \csname opt@\reserved at a\endcsname}
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 %<latexrelease>\IncludeInRelease{0000/00/00}{\@pass at ptions}
 %<latexrelease>  {\@pass at ptions}%
+%<latexrelease>
 %<latexrelease>\def\@pass at ptions#1#2#3{%
 %<latexrelease>  \expandafter\xdef\csname opt@#3.#1\endcsname{%
 %<latexrelease>    \@ifundefined{opt@#3.#1}\@empty
@@ -1200,6 +1276,9 @@
 %<latexrelease>    \zap at space#2 \@empty}}
 %<latexrelease>\EndIncludeInRelease
 %<*2ekernel>
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \@onlypreamble\@pass at ptions
 %    \end{macrocode}
 %
@@ -1241,18 +1320,49 @@
 % \end{macro}
 %
 % \begin{macro}{\OptionNotUsed}
+% \changes{v1.3x}{2021/02/18}{filter out =value from unused option list (gh/85)}
+% \begin{macro}{\@remove at eq@value}
+% \changes{v1.3x}{2021/02/18}{macro added (gh/85)}
 % If we are in a class file, add |\CurrentOption| to the list of
 % unused options. Otherwise, in a package file do nothing.
 %    \begin{macrocode}
+%</2ekernel>
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>                 {\OptionNotUsed}{filter unused option list}%
+%<*2ekernel|latexrelease>
+\def\@remove at eq@value#1=#2\@nil{#1}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \def\OptionNotUsed{%
   \ifx\@currext\@clsextension
     \xdef\@unusedoptionlist{%
       \ifx\@unusedoptionlist\@empty\else\@unusedoptionlist,\fi
-      \CurrentOption}%
+      \expandafter\@remove at eq@value\CurrentOption=\@nil}%
   \fi}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\OptionNotUsed}{filter unused option list}%
+%<latexrelease>\let\@remove at eq@value\@undefined
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<latexrelease>\def\OptionNotUsed{%
+%<latexrelease>  \ifx\@currext\@clsextension
+%<latexrelease>    \xdef\@unusedoptionlist{%
+%<latexrelease>      \ifx\@unusedoptionlist\@empty\else\@unusedoptionlist,\fi
+%<latexrelease>      \CurrentOption}%
+%<latexrelease>  \fi}
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \@onlypreamble\OptionNotUsed
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\default at ds}
 % The default option code.
@@ -1279,7 +1389,7 @@
 % \changes{v0.2a}{1993/11/14}
 %         {Stop adding the global option list inside class files.}
 % \changes{v0.2a}{1993/11/14}
-%         {Optimise `empty option' code.}
+%         {Optimize `empty option' code.}
 % \changes{v0.2b}{1993/11/15}
 %         {Star form added.}
 % \changes{v0.2c}{1993/11/17}
@@ -1312,19 +1422,50 @@
 %
 % \changes{v0.2y}{1994/02/07}
 %         {Add extra ,s so `two' is not matched with `twocolumn'}
+% \changes{v1.3z}{2021/03/05}{modify so braces to not give errors (gh/513)}
 %    \begin{macrocode}
+%</2ekernel>
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>                 {\@xprocess at ptions}{safer @xprocess at ptions}%
+%<*2ekernel|latexrelease>
 \def\@xprocess at ptions{%
   \ifx\@currext\@clsextension\else
+   \ifx\@classoptionslist\relax\else
     \@for\CurrentOption:=\@classoptionslist\do{%
       \ifx\CurrentOption\@empty\else
-        \@expandtwoargs\in@{,\CurrentOption,}{,\@declaredoptions,}%
-        \ifin@
+        \@ifundefined{ds@\CurrentOption}{}{%
           \@use at ption
           \expandafter\let\csname ds@\CurrentOption\endcsname\@empty
-        \fi
+        }%
       \fi}%
+    \fi
   \fi
   \@process at pti@ns}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\@xprocess at ptions}{safer @xprocess at ptions}%
+%<latexrelease>\let\@remove at eq@value\@undefined
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<latexrelease>\def\@xprocess at ptions{%
+%<latexrelease>  \ifx\@currext\@clsextension\else
+%<latexrelease>    \@for\CurrentOption:=\@classoptionslist\do{%
+%<latexrelease>      \ifx\CurrentOption\@empty\else
+%<latexrelease>        \@expandtwoargs\in@{,\CurrentOption,}{,\@declaredoptions,}%
+%<latexrelease>        \ifin@
+%<latexrelease>          \@use at ption
+%<latexrelease>          \expandafter\let\csname ds@\CurrentOption\endcsname\@empty
+%<latexrelease>        \fi
+%<latexrelease>      \fi}%
+%<latexrelease>  \fi
+%<latexrelease>  \@process at pti@ns}
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \@onlypreamble\@xprocess at ptions
 %    \end{macrocode}
 %
@@ -1403,11 +1544,30 @@
 %         {Name changed from \cs{@executeoption}}
 % \changes{v1.0e}{1994/05/17}
 %         {Execute option after removing from list, not before}
+% \changes{v1.3x}{2021/02/18}{filter out =value from unused option list (gh/85)}
 %    \begin{macrocode}
+%</2ekernel>
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>                 {\@use at ption}{filter unused option list}%
+%<*2ekernel|latexrelease>
 \def\@use at ption{%
-  \@expandtwoargs\@removeelement\CurrentOption
+  \@expandtwoargs\@removeelement
+     {\expandafter\@remove at eq@value\CurrentOption=\@nil}%
   \@unusedoptionlist\@unusedoptionlist
   \csname ds@\CurrentOption\endcsname}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\@use at ption}{filter unused option list}%
+%<latexrelease>\def\@use at ption{%
+%<latexrelease>  \@expandtwoargs\@removeelement\CurrentOption
+%<latexrelease>  \@unusedoptionlist\@unusedoptionlist
+%<latexrelease>  \csname ds@\CurrentOption\endcsname}
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \@onlypreamble\@use at ption
 %    \end{macrocode}
 % \end{macro}
@@ -1460,7 +1620,7 @@
 % the internal command, |\@fileswithoptions|.
 % \begin{macro}{\documentclass}
 % \changes{v1.0q}{1995/06/19}
-%         {Dont redefine \cs{usepackage} in compat mode for /1634}
+%         {Don't redefine \cs{usepackage} in compat mode for /1634}
 % The main new-style class declaration.
 %    \begin{macrocode}
 \def\documentclass{%
@@ -1721,9 +1881,10 @@
 %         {Prevent loss of brackets PR/3965}
 % \changes{v2.1b}{2016/11/09}
 %         {Improve \cs{ifx} tests PR/4497}
+% \changes{v1.3x}{2021/02/18}{save raw class option list (gh/85)}
 %    \begin{macrocode}
 %</2ekernel>
-%<latexrelease>\IncludeInRelease{2017/01/01}%
+%<latexrelease>\IncludeInRelease{2020/10/01}%
 %<latexrelease>        {\@fileswith at pti@ns}{ifx tests in \@fileswith at pti@ns}%
 %<*2ekernel|latexrelease>
 \def\@fileswith at pti@ns#1[#2]#3[#4]{%
@@ -1730,6 +1891,13 @@
   \ifx#1\@clsextension
     \ifx\@classoptionslist\relax
       \xdef\@classoptionslist{\zap at space#2 \@empty}%
+%    \end{macrocode}
+% Save raw class list.
+%    \begin{macrocode}
+      \gdef\@raw at classoptionslist{#2}%
+%    \end{macrocode}
+%
+%    \begin{macrocode}
       \def\reserved at a{%
         \@onefilewithoptions#3[{#2}][{#4}]#1%
         \@documentclasshook}%
@@ -1750,8 +1918,8 @@
 %    \begin{macrocode}
       \ifx\@nnil##1\relax\else
 %    \end{macrocode}
-%  If |\ifx\@nnil##1\n at nil| is true then |#1| is (presumably) empty
-% (Older code used |\relax| which is slighly easier to get into |#1|
+%  If |\ifx\@nnil##1\@nnil| is true then |#1| is (presumably) empty
+% (Older code used |\relax| which is slightly easier to get into |#1|
 % by mistake, which would spoil this test.)
 %    \begin{macrocode}
         \ifx\@nnil##1\@nnil\else
@@ -1768,6 +1936,33 @@
   \fi
   \reserved at a}
 %</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{2017/01/01}%
+%<latexrelease>        {\@fileswith at pti@ns}{ifx tests in \@fileswith at pti@ns}%
+%<latexrelease>\def\@fileswith at pti@ns#1[#2]#3[#4]{%
+%<latexrelease>  \ifx#1\@clsextension
+%<latexrelease>    \ifx\@classoptionslist\relax
+%<latexrelease>      \xdef\@classoptionslist{\zap at space#2 \@empty}%
+%<latexrelease>      \def\reserved at a{%
+%<latexrelease>        \@onefilewithoptions#3[{#2}][{#4}]#1%
+%<latexrelease>        \@documentclasshook}%
+%<latexrelease>    \else
+%<latexrelease>      \def\reserved at a{%
+%<latexrelease>        \@onefilewithoptions#3[{#2}][{#4}]#1}%
+%<latexrelease>    \fi
+%<latexrelease>  \else
+%<latexrelease>    \def\reserved at b##1,{%
+%<latexrelease>      \ifx\@nnil##1\relax\else
+%<latexrelease>        \ifx\@nnil##1\@nnil\else
+%<latexrelease>         \noexpand\@onefilewithoptions##1[{#2}][{#4}]%
+%<latexrelease>         \noexpand\@pkgextension
+%<latexrelease>        \fi
+%<latexrelease>        \expandafter\reserved at b
+%<latexrelease>      \fi}%
+%<latexrelease>      \edef\reserved at a{\zap at space#3 \@empty}%
+%<latexrelease>      \edef\reserved at a{\expandafter\reserved at b\reserved at a,\@nnil,}%
+%<latexrelease>  \fi
+%<latexrelease>  \reserved at a}
 %    \end{macrocode}
 %
 %    \begin{macrocode}
@@ -1834,7 +2029,7 @@
 %   \usepackage{some/local/path/array}
 %   \usepackage{array}
 % \end{verbatim}
-%    won't load \file{array.sty} twice.  It is remotely possible that
+%    won't load |array.sty| twice.  It is remotely possible that
 %    those are two different files, but as a matter of principles, we
 %    will consider that the base file name uniquely identifies a
 %    package, regardless of where it lives.  This assumption already
@@ -2087,7 +2282,7 @@
 %    loaded.}
 %
 %    This has changed in 2020. We now use a separate macro per package
-%    to avoid interferences in case of nested packages.  The whole
+%    to avoid interference in case of nested packages.  The whole
 %    code for handling this issue (GitHub 22) was provided by Hironobu
 %    Yamashita, thanks for that.
 % \changes{v1.3k}{2020/04/07}{Use different method to ignore
@@ -2424,7 +2619,7 @@
 % \changes{v0.2r}{1993/12/19}{Different message when ignoring a file}
 % \changes{v0.3g}{1994/04/11}
 %         {Add star form,
-%          dont write \cs{endinput} at the end of the file.}
+%          don't write \cs{endinput} at the end of the file.}
 % \changes{v1.0c}{1994/05/11}
 %         {Add checks for form feed and tab}
 % \changes{v1.0m}{1995/04/21}
@@ -2549,15 +2744,15 @@
 %    this only works for input files ending in \texttt{.tex}. If a
 %    different extension is used there is no way to see that we are
 %    overwriting ourselves!
+% \changes{v1.3y}{2021/03/03}
+%         {Fix overwrite check for files with UTF-8 (gh/415)}
 %    \begin{macrocode}
-      \edef\reserved at a{#1}%
-      \edef\reserved at a{\detokenize\expandafter{\reserved at a}}%
       \edef\reserved at b{\detokenize\expandafter{\jobname}}%
-      \ifx\reserved at a\reserved at b%
+      \ifx\@curr at file\reserved at b%
         \@fileswtrue%
       \else%
         \edef\reserved at b{\reserved at b\detokenize{.tex}}%
-        \ifx\reserved at a\reserved at b
+        \ifx\@curr at file\reserved at b
           \@fileswtrue%
         \fi%
       \fi%
@@ -2640,7 +2835,8 @@
 % Text before the |\end|, write it with a warning.
 %    \begin{macrocode}
           \@latex at warning{Writing text `##1' before %
-             \string\end{\@currenvir}\MessageBreak as last line of \@curr at file}%
+            \string\end{\@currenvir}\MessageBreak
+            as last line of \@curr at file}%
         \immediate\write\reserved at c{##1}%
       \fi%
       \ifx\relax##2\relax%
@@ -2675,7 +2871,8 @@
 %</2ekernel|latexrelease>
 %<latexrelease>\EndIncludeInRelease
 %<latexrelease>\IncludeInRelease{2019/10/01}%
-%<latexrelease>                 {\filec at ntents}{Spaces in file names + optional arg}%
+%<latexrelease>    {\filec at ntents}{Spaces in file names + optional arg}%
+%<latexrelease>
 %<latexrelease>\def\filecontents{\@tempswatrue\@fileswtrue
 %<latexrelease>  \@ifnextchar[\filec at ntents@opt\filec at ntents
 %<latexrelease>}
@@ -2805,7 +3002,7 @@
 %<latexrelease>\endgroup%
 %<latexrelease>\EndIncludeInRelease
 %<latexrelease>\IncludeInRelease{0000/00/00}%
-%<latexrelease>                 {\filec at ntents}{Spaces in file names + optional arg}%
+%<latexrelease>    {\filec at ntents}{Spaces in file names + optional arg}%
 %<latexrelease>
 %<latexrelease>\let\filec at ntents@opt        \@undefined
 %<latexrelease>\let\filec at ntents@force      \@undefined
@@ -2976,7 +3173,7 @@
 %    YYYYMMDD (if there was one, otherwise the value of
 %    |\requestedLaTeXdate|) and |\pkgcls at targetlabel| will be
 %    empty. If there was a request for a named version then
-%    |\pkgcls at targetlabel| holds the verion name and
+%    |\pkgcls at targetlabel| holds the version name and
 %    |\pkgcls at targetdate| is set to \texttt{1}.
 %
 %    |\pkgcls at targetdate=0| is used to indicate that there was no
@@ -3063,7 +3260,7 @@
   \pkgcls at parse@date at arg{#3}%
 %    \end{macrocode}
 %    When determining the correct release to load we keep track of
-%    candiates in |\pkgcls at candidate| and initially we don't have any:
+%    candidates in |\pkgcls at candidate| and initially we don't have any:
 %    \begin{macrocode}
   \let\pkgcls at candidate\@empty
 %    \end{macrocode}
@@ -3103,7 +3300,7 @@
 %
 %   But if it starts with an equal sign followed by a date string or
 %   followed by a version name then this means that we should roll
-%   back to the state of the package at tht date or to the version
+%   back to the state of the package at that date or to the version
 %   with the requested name.
 %
 %   If there was no optional argument or the optional argument
@@ -3381,7 +3578,7 @@
 %
 %  \begin{macro}{\pkgcls at show@selection}
 %    This command records what selection was made. As that is needed
-%    in two places (and it is rather lengthly) it was placed in a
+%    in two places (and it is rather lengthy) it was placed in a
 %    separate command. The first argument is the name of the external
 %    file that is being loaded and is only needed for debugging.  The
 %    second argument is the date that corresponds to this file and it
@@ -3484,7 +3681,7 @@
                                   \pkgcls at releasedate
         \fi
 %    \end{macrocode}
-%    Otherwise the curent file is the right release, so we record that
+%    Otherwise the current file is the right release, so we record that
 %    in the transcript and then carry on.
 %    \begin{macrocode}
       \else

Added: trunk/Master/texmf-dist/source/latex/base/ltcmd.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltcmd.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/base/ltcmd.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -0,0 +1,4034 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 1999 Frank Mittelbach, Chris Rowley, David Carlisle
+% Copyright (C) 2004-2008 Frank Mittelbach, The LaTeX3 Project
+% Copyright (C) 2009-2021
+% The LaTeX Project and any individual authors listed elsewhere
+% in this file.
+%
+% This file is part of the LaTeX base system.
+% -------------------------------------------
+%
+% It may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3c
+% of this license or (at your option) any later version.
+% The latest version of this license is in
+%    https://www.latex-project.org/lppl.txt
+% and version 1.3c or later is part of all distributions of LaTeX
+% version 2008 or later.
+%
+% This file has the LPPL maintenance status "maintained".
+%
+% The list of all files belonging to the LaTeX base distribution is
+% given in the file `manifest.txt'. See also `legal.txt' for additional
+% information.
+%
+% The list of derived (unpacked) files belonging to the distribution
+% and covered by LPPL is defined by the unpacking scripts (with
+% extension .ins) which are part of the distribution.
+%
+% \fi
+%
+% \iffalse
+%
+%%% From File: ltcmd.dtx
+%
+%    \begin{macrocode}
+\def\ltcmdversion{v1.0e}
+\def\ltcmddate{2021-05-24}
+%    \end{macrocode}
+%
+%<*driver>
+% \fi
+\ProvidesFile{ltcmd.dtx}
+  [\ltcmddate\space \ltcmdversion\space
+   LaTeX Kernel (Document commands)]
+% \iffalse
+\documentclass{l3doc}
+\GetFileInfo{ltcmd.dtx}
+\title{\filename}
+\date{\filedate}
+\author{Frank Mittelbach, Chris Rowley, David Carlisle, \LaTeX{} Project Team}
+\begin{document}
+  \maketitle
+  \DocInput{ltcmd.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \section{Creating document commands}
+%
+% \changes{v1.0a}{2020/11/20}{Initial version derived from \texttt{xparse.dtx}}
+%
+% Document commands should be created using the tools provided by this module:
+% \cs{NewDocumentCommand}, etc.\@, in almost all cases. This allows clean
+% separation of document-level syntax from code-level interfaces. Users have
+% a need to create new document commands, and as such a significant amount of
+% documentation for \pkg{ltcmd} is provided as part of \texttt{usrguide3}. Here,
+% additional material aimed at programmers is provided
+%
+% \StopEventually{}
+%
+%    \begin{macrocode}
+%<@@=cmd>
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<*2ekernel>
+\message{document commands,}
+%</2ekernel>
+%    \end{macrocode}
+%
+% \changes{v1.0b}{2021/03/18}{Use \cs{NewModuleRelease}.}
+% \changes{v1.0e}{2021/05/24}{Use \cs{msg_...} instead of \cs{__kernel_msg...}}
+%
+%
+% \pkg{ltcmd} code contains an |^^@| character, which usually has
+% catcode~15, so \cs{IncludeInRelease} will break when this code is
+% being skipped, so we'll save the catcode of |^^@| to restore later:
+%    \begin{macrocode}
+%<*2ekernel|latexrelease>
+%<latexrelease>\edef\@latexrelease at catcode@null{\the\catcode`\^^@ }
+%<latexrelease>\catcode`\^^@=12
+\ExplSyntaxOn
+%<latexrelease>\NewModuleRelease{2020/10/01}{ltcmd}
+%<latexrelease>                 {Document~command~parser}%
+%    \end{macrocode}
+%
+% \subsection{Variables and constants}
+%
+% \begin{variable}{\l_@@_arg_spec_tl}
+%   Holds the argument specification after normalization of shorthands.
+%    \begin{macrocode}
+\tl_new:N \l_@@_arg_spec_tl
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_args_tl}
+%   Token list variable for grabbed arguments.
+%    \begin{macrocode}
+\tl_new:N \l_@@_args_tl
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_args_i_tl, \l_@@_args_ii_tl}
+%   Hold the modified arguments when dealing with default values or
+%   processors.
+%    \begin{macrocode}
+\tl_new:N \l_@@_args_i_tl
+\tl_new:N \l_@@_args_ii_tl
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_current_arg_int}
+%   The number of the current argument being set up: this is used to
+%   make sure there are at most 9 arguments, then for creating the
+%   expandable auxiliary functions and knowing how many arguments the
+%   code function should take.
+%    \begin{macrocode}
+\int_new:N \l_@@_current_arg_int
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_defaults_bool, \l_@@_defaults_tl}
+%   The boolean indicates whether there are any argument with default
+%   value other than |-NoValue-|; the token list holds the code to
+%   determine these default values in terms of other arguments.
+%    \begin{macrocode}
+\bool_new:N \l_@@_defaults_bool
+\tl_new:N \l_@@_defaults_tl
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_environment_bool}
+%   Generating environments uses the same mechanism as generating functions.
+%   However, full processing of arguments is always needed for environments,
+%   and so the function-generating code needs to know this.
+%   This variable is also used at run time to give correct error messages.
+%    \begin{macrocode}
+\bool_new:N \l_@@_environment_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_environment_str}
+%   Name of the environment, used at definition time and at run time.
+%    \begin{macrocode}
+\str_new:N \l_@@_environment_str
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_expandable_bool}
+%   Used to indicate if an expandable command is begin generated, as this
+%   affects both the acceptable argument types and how they are implemented.
+%    \begin{macrocode}
+\bool_new:N \l_@@_expandable_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_expandable_aux_name_tl}
+%   Used to create pretty-printing names for the auxiliaries: although the
+%   immediate definition does not vary, the full expansion does and so it
+%   does not count as a constant.
+%    \begin{macrocode}
+\tl_new:N \l_@@_expandable_aux_name_tl
+\tl_set:Nn \l_@@_expandable_aux_name_tl
+  {
+    \l_@@_function_tl \c_space_tl
+    ( arg~ \int_use:N \l_@@_current_arg_int )
+  }
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\g_@@_grabber_int}
+%   Used (in exceptional cases) to get unique names for grabbers used by
+%   expandable commands.
+%    \begin{macrocode}
+\int_new:N \g_@@_grabber_int
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_fn_tl}
+%   For passing the pre-formed name of the auxiliary to be used as the
+%   parsing function.
+%    \begin{macrocode}
+\tl_new:N \l_@@_fn_tl
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_fn_code_tl}
+%   For passing the pre-formed name of the auxiliary that contains the
+%   actual code.
+%    \begin{macrocode}
+\tl_new:N \l_@@_fn_code_tl
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_function_tl}
+%   Holds the control sequence name of the function currently being
+%   defined: used to avoid passing this as an argument and to avoid repeated
+%   use of \cs{cs_to_str:N}.
+%    \begin{macrocode}
+\tl_new:N \l_@@_function_tl
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_grab_expandably_bool}
+%   When defining a non-expandable command, indicates whether the
+%   arguments can all safely be grabbed by expandable grabbers.  This is
+%   to support abuses of \pkg{xparse} that use protected functions
+%   inside csname constructions.
+%    \begin{macrocode}
+\bool_new:N \l_@@_grab_expandably_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_obey_spaces_bool}
+%   For trailing optionals.
+%    \begin{macrocode}
+\bool_new:N \l_@@_obey_spaces_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_last_delimiters_tl}
+%   Holds the delimiters (first tokens) of all optional arguments since
+%   the previous mandatory argument, to warn about cases where it would
+%   be impossible to omit optional arguments completely because the
+%   following mandatory argument has the same delimiter as one of the
+%   optional arguments.
+%    \begin{macrocode}
+\tl_new:N \l_@@_last_delimiters_tl
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_long_bool}
+%   Used to indicate that an argument is long, on a per-argument basis.
+%    \begin{macrocode}
+\bool_new:N \l_@@_long_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_m_args_int}
+%   The number of \texttt{m} arguments: if this is the same as the total
+%   number of arguments, then a short-cut can be taken in the creation of
+%   the grabber code.
+%    \begin{macrocode}
+\int_new:N \l_@@_m_args_int
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_prefixed_bool}
+%   When preparing the signature of non-expandable commands, indicates
+%   that the current argument is affected by a processor or by |+|
+%   (namely is long).
+%    \begin{macrocode}
+\bool_new:N \l_@@_prefixed_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_process_all_tl, \l_@@_process_one_tl, \l_@@_process_some_bool}
+%   When preparing the signature, the processors that will be applied to
+%   a given argument are collected in \cs{l_@@_process_one_tl}, while
+%   \cs{l_@@_process_all_tl} contains processors for all arguments.  The
+%   boolean indicates whether there are any processors (to bypass the
+%   whole endeavour otherwise).
+%    \begin{macrocode}
+\tl_new:N \l_@@_process_all_tl
+\tl_new:N \l_@@_process_one_tl
+\bool_new:N \l_@@_process_some_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_saved_args_tl}
+%   Stores \cs{l_@@_args_tl} to deal with space-trimming of
+%   \texttt{b}-type arguments.
+%    \begin{macrocode}
+\tl_new:N \l_@@_saved_args_tl
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_signature_tl}
+%   Used when constructing the signature (code for argument grabbing) to
+%   hold what will become the implementation of the main function.
+%   When arguments are grabbed (at point of use of the command/environment),
+%   it also stores the code for grabbing the remaining arguments.
+%    \begin{macrocode}
+\tl_new:N \l_@@_signature_tl
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}
+%   {\l_@@_some_obey_spaces_bool, \l_@@_some_long_bool, \l_@@_some_short_bool}
+%   These flags are set while normalizing the argument specification.
+%   The \texttt{obey_spaces} one is used to detect when |!| is used on
+%   an argument that is not a trailing optional argument.
+%   The other two are used to check whether all short arguments appear
+%   before long arguments: this is needed to grab arguments expandably.
+%   As soon as the first long argument is seen (other than
+%   \texttt{t}-type, whose long status is ignored) the
+%   \texttt{some_long} flag is set.  The \texttt{some_short} flag is
+%   used for expandable commands, to know whether to define a short
+%   auxiliary too.
+%    \begin{macrocode}
+\bool_new:N \l_@@_some_obey_spaces_bool
+\bool_new:N \l_@@_some_long_bool
+\bool_new:N \l_@@_some_short_bool
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_tmp_prop, \l_@@_tmpa_tl, \l_@@_tmpb_tl}
+% \begin{macro}{\@@_tmp:w}
+%   Scratch space.
+%    \begin{macrocode}
+\prop_new:N \l_@@_tmp_prop
+\tl_new:N \l_@@_tmpa_tl
+\tl_new:N \l_@@_tmpb_tl
+\cs_new_eq:NN \@@_tmp:w ?
+%    \end{macrocode}
+% \end{macro}
+% \end{variable}
+%
+%   With \pkg{xparse}, information about commands being (re)defined was
+%   switched off by default, unless the |log-declarations| package
+%   option was used, so here we'll switch that off as well.
+%    \begin{macrocode}
+\msg_redirect_module:nnn { cmd } { info } { none }
+%    \end{macrocode}
+%
+%   Also add \pkg{cmd} to the \pkg{LaTeX} messages.
+%    \begin{macrocode}
+\prop_gput:Nnn \g_msg_module_type_prop { cmd } { LaTeX }
+%    \end{macrocode}
+%
+% \subsection{Declaring commands and environments}
+%
+% \begin{macro}{\@@_declare_cmd:Nnn, \@@_declare_expandable_cmd:Nnn}
+% \begin{macro}{\@@_declare_cmd_aux:Nnn}
+% \begin{macro}
+%   {\@@_declare_cmd_internal:Nnnn, \@@_declare_cmd_internal:cnxn}
+%   The main functions for creating commands set the appropriate flag then
+%   use the same internal code to do the definition.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_declare_cmd:Nnn
+  {
+    \bool_set_false:N \l_@@_expandable_bool
+    \@@_declare_cmd_aux:Nnn
+  }
+\cs_new_protected:Npn \@@_declare_expandable_cmd:Nnn
+  {
+    \bool_set_true:N \l_@@_expandable_bool
+    \@@_declare_cmd_aux:Nnn
+  }
+%    \end{macrocode}
+%  The first stage is to log information, both for the user in the log and
+%  for programmatic use in a property list of all declared commands.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_declare_cmd_aux:Nnn #1#2#3
+  {
+    \cs_if_exist:NTF #1
+      {
+        \msg_info:nnxx { cmd } { redefine-command }
+          { \token_to_str:N #1 } { \tl_to_str:n {#2} }
+      }
+      {
+        \bool_lazy_or:nnT
+          { \cs_if_exist_p:c { \cs_to_str:N #1 ~ code } }
+          { \cs_if_exist_p:c { \cs_to_str:N #1 ~ defaults } }
+          {
+            \msg_warning:nnx { cmd } { unsupported-let }
+              { \token_to_str:N #1 }
+          }
+        \msg_info:nnxx { cmd } { define-command }
+          { \token_to_str:N #1 } { \tl_to_str:n {#2} }
+      }
+    \bool_set_false:N \l_@@_environment_bool
+    \@@_declare_cmd_internal:Nnnn #1 {#2} {#3} { }
+  }
+%    \end{macrocode}
+%   At definition time, the variable \cs{l_@@_fn_tl} is only used for error messages.
+%   The real business of defining a document command starts with setting up
+%   the appropriate name, then normalizing the argument specification to get rid of
+%   shorthands.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_declare_cmd_internal:Nnnn #1#2#3#4
+  {
+    \tl_set:Nx \l_@@_function_tl { \cs_to_str:N #1 }
+    \tl_set:Nx \l_@@_fn_tl
+      { \exp_not:c { \l_@@_function_tl \c_space_tl } }
+    \@@_normalize_arg_spec:n {#2}
+    \exp_args:No \@@_prepare_signature:n \l_@@_arg_spec_tl
+    \@@_declare_cmd_code:Nnn #1 {#2} {#3}
+    #4
+    \@@_break_point:n {#2}
+  }
+\cs_generate_variant:Nn \@@_declare_cmd_internal:Nnnn { cnx }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_break_point:n}
+%   A marker used to escape from creating a definition if necessary.
+%    \begin{macrocode}
+\cs_new_eq:NN \@@_break_point:n \use_none:n
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_declare_cmd_code:Nnn}
+% \begin{macro}
+%   {\@@_declare_cmd_code_aux:Nnn, \@@_declare_cmd_code_expandable:Nnn}
+%   The appropriate auxiliary is called.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_declare_cmd_code:Nnn
+  {
+    \bool_if:NTF \l_@@_grab_expandably_bool
+      { \@@_declare_cmd_code_expandable:Nnn }
+      { \@@_declare_cmd_code_aux:Nnn }
+   }
+%    \end{macrocode}
+%   Standard functions call \cs{@@_start:nNNnnn}, which receives the
+%   argument specification, an auxiliary used for
+%   grabbing arguments, an auxiliary containing the code, and then the
+%   signature, default arguments, and processors.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_declare_cmd_code_aux:Nnn #1#2#3
+  {
+    \cs_generate_from_arg_count:cNnn
+      { \l_@@_function_tl \c_space_tl code }
+      \cs_set_protected:Npn \l_@@_current_arg_int {#3}
+    \cs_set_protected_nopar:Npx #1
+      {
+        \bool_if:NTF \l_@@_environment_bool
+          {
+            \@@_start_env:nnnnn { \exp_not:n {#2} }
+              { \l_@@_environment_str }
+          }
+          {
+            \@@_start:nNNnnn { \exp_not:n {#2} }
+              \exp_not:c { \l_@@_function_tl \c_space_tl }
+              \exp_not:c { \l_@@_function_tl \c_space_tl code }
+          }
+          { \exp_not:o \l_@@_signature_tl }
+          {
+            \bool_if:NT \l_@@_defaults_bool
+              { \exp_not:o \l_@@_defaults_tl }
+          }
+          {
+            \bool_if:NT \l_@@_process_some_bool
+              { \exp_not:o \l_@@_process_all_tl }
+          }
+      }
+  }
+%    \end{macrocode}
+%   Expandable functions and functions whose arguments can be grabbed
+%   expandably call \cs{@@_start_expandable:nNNNNn}, which receives the
+%   argument specification, four auxiliaries (two for grabbing arguments, one for
+%   the code, and one for default arguments), and finally the signature.
+%   Non-expandable functions that take this branch should nevertheless
+%   be protected, as well as their \texttt{code} function.  They will
+%   only be expanded in contexts such as constructing a csname.
+%   The two grabbers (named after the function with one or two spaces)
+%   are needed when there are both short and long arguments; otherwise
+%   the same grabber is included twice in the definition.  If all
+%   arguments are long or all are short the (only) grabber is defined
+%   correspondingly to be long/short.  Otherwise two grabbers are
+%   defined, one long, one short.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_declare_cmd_code_expandable:Nnn #1#2#3
+  {
+    \exp_args:Ncc \cs_generate_from_arg_count:NNnn
+      { \l_@@_function_tl \c_space_tl code }
+      { cs_set \bool_if:NF \l_@@_expandable_bool { _protected } :Npn }
+      \l_@@_current_arg_int {#3}
+    \bool_if:NT \l_@@_defaults_bool
+      {
+        \use:x
+          {
+            \cs_generate_from_arg_count:cNnn
+              { \l_@@_function_tl \c_space_tl defaults }
+              \cs_set:Npn \l_@@_current_arg_int
+              { \exp_not:o \l_@@_defaults_tl }
+          }
+      }
+    \bool_if:NTF \l_@@_expandable_bool
+      { \cs_set_nopar:Npx } { \cs_set_protected_nopar:Npx } #1
+      {
+        \exp_not:N \@@_start_expandable:nNNNNn
+          { \exp_not:n {#2} }
+          \exp_not:c { \l_@@_function_tl \c_space_tl }
+          \exp_not:c
+            {
+              \l_@@_function_tl \c_space_tl
+              \bool_if:NT \l_@@_some_short_bool
+                { \bool_if:NT \l_@@_some_long_bool { \c_space_tl } }
+            }
+          \exp_not:c { \l_@@_function_tl \c_space_tl code }
+          \bool_if:NTF \l_@@_defaults_bool
+            { \exp_not:c { \l_@@_function_tl \c_space_tl defaults } }
+            { ? }
+          { \exp_not:o \l_@@_signature_tl }
+      }
+    \bool_if:NTF \l_@@_some_long_bool
+      {
+        \bool_if:NT \l_@@_some_short_bool
+          {
+            \cs_set_nopar:cpx { \l_@@_function_tl \c_space_tl \c_space_tl }
+              ##1##2 { ##1 {##2} }
+          }
+        \cs_set:cpx
+      }
+      { \cs_set_nopar:cpx }
+          { \l_@@_function_tl \c_space_tl } ##1##2 { ##1 {##2} }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_declare_env:nnnn}
+% \begin{macro}{\@@_declare_env_internal:nnnn}
+%   The lead-off to creating an environment is much the same as that for
+%   creating a command: issue the appropriate message, store the argument
+%   specification then hand off to an internal function.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_declare_env:nnnn #1#2
+  {
+    \str_set:Nx \l_@@_environment_str {#1}
+    \str_set:Nx \l_@@_environment_str
+      { \tl_trim_spaces:o { \l_@@_environment_str } }
+    \cs_if_exist:cTF { \l_@@_environment_str }
+      {
+        \msg_info:nnxx { cmd } { redefine-environment }
+          { \l_@@_environment_str } { \tl_to_str:n {#2} }
+      }
+      {
+        \msg_info:nnxx { cmd } { define-environment }
+          { \l_@@_environment_str } { \tl_to_str:n {#2} }
+      }
+    \bool_set_false:N \l_@@_expandable_bool
+    \bool_set_true:N \l_@@_environment_bool
+    \exp_args:NV \@@_declare_env_internal:nnnn
+      \l_@@_environment_str {#2}
+  }
+%    \end{macrocode}
+%   Creating a document environment requires a few more steps than creating
+%   a single command. In order to pass the arguments of the command to the
+%   end of the function, it is necessary to store the grabbed arguments.
+%   To do that, the function used at the end of the environment has to be
+%   redefined to contain the appropriate information. To minimize the amount
+%   of expansion at point of use, the code here is expanded now as well as
+%   when used.
+%   The last argument of \cs{@@_declare_cmd_internal:Nnnn} is only run
+%   if the definition succeeded.  In package mode this ensures that the
+%   original definition of the environment is not changed if the
+%   definition fails for any reason.  This also avoids an error when
+%   defining the \verb*|end aux | function when the user asks for more
+%   than $9$ arguments.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_declare_env_internal:nnnn #1#2#3#4
+  {
+    \@@_declare_cmd_internal:cnxn { environment~ #1 } {#2}
+      {
+        \cs_set_nopar:Npx \exp_not:c { environment~ #1 ~end~aux }
+          {
+            \exp_not:N \exp_not:N \exp_not:c { environment~ #1~end~aux~ }
+            \exp_not:n { \exp_not:o \l_@@_args_tl }
+          }
+        \exp_not:n {#3}
+      }
+      {
+        \cs_set_nopar:cpx { environment~ #1 ~end }
+          { \exp_not:c { environment~ #1 ~end~aux } }
+        \cs_generate_from_arg_count:cNnn
+          { environment~ #1 ~end~aux~ } \cs_set:Npn
+          \l_@@_current_arg_int {#4}
+        \cs_set_eq:cc {#1}       { environment~ #1 }
+        \cs_set_eq:cc { end #1 } { environment~ #1 ~end }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Structure of \pkg{xparse} commands}
+%
+% \begin{macro}{\@@_start_env:nnnnn, \@@_start:nNNnnn}
+%   For error messages that occur during run-time when getting arguments
+%   of environments it is necessary to keep track of the environment
+%   name.  We begin non-expandable commands with a token equal to
+%   \cs{scan_stop:}, whose name gives a reasonable error message if the
+%   command is used inside a csname and protects against
+%   \texttt{f}-expansion.  This is useless for environments since
+%   \cs{begin} is already not expandable.  Both the command and
+%   environment codes start with \cs{group_align_safe_begin:}, then
+%   \cs{@@_run_code:} (used by both) does \cs{group_align_safe_end:}, so
+%   that delimited arguments may be grabbed in alignments if they
+%   contain and alignment tab token (see latex3/latex3/issues/839).
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_start_env:nnnnn #1#2
+  {
+    \conditionally at traceoff
+    \group_align_safe_begin:
+    \str_set:Nn \l_@@_environment_str {#2}
+    \bool_set_true:N \l_@@_environment_bool
+    \@@_start_aux:ccnnnn
+      { environment~ \l_@@_environment_str \c_space_tl }
+      { environment~ \l_@@_environment_str \c_space_tl code }
+      {#1}
+  }
+\cs_new_protected:Npx \@@_start:nNNnnn #1#2#3
+  {
+    \exp_not:c { xparse~function~is~not~expandable }
+    \exp_not:N \conditionally at traceoff
+    \exp_not:N \group_align_safe_begin:
+    \exp_not:n { \bool_set_false:N \l_@@_environment_bool }
+    \exp_not:N \@@_start_aux:NNnnnn
+    #2 #3 {#1}
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_start_aux:NNnnnn, \@@_start_aux:ccnnnn}
+%   This sets up a few variables to minimize the boilerplate code
+%   included in all \pkg{xparse}-defined commands.  It then runs the
+%   grabbers~|#4|.  Again, the argument specification |#1| is only for
+%   diagnostics.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_start_aux:NNnnnn #1#2#3#4#5#6
+  {
+    \tl_clear:N \l_@@_args_tl
+    \tl_set:Nn \l_@@_fn_tl {#1}
+    \tl_set:Nn \l_@@_fn_code_tl {#2}
+    \tl_set:Nn \l_@@_defaults_tl {#5}
+    \tl_set:Nn \l_@@_process_all_tl {#6}
+    #4 \@@_run_code:
+  }
+\cs_generate_variant:Nn \@@_start_aux:NNnnnn { cc }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_run_code:}
+%   After arguments are grabbed, this function is responsible for
+%   inserting default values, running processors, and finally doing
+%   \cs{group_align_safe_end:} as promised, and running the code.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_run_code:
+  {
+    \tl_if_empty:NF \l_@@_defaults_tl { \@@_defaults: }
+    \tl_if_empty:NF \l_@@_process_all_tl { \@@_args_process: }
+    \group_align_safe_end:
+    \conditionally at traceon
+    \exp_after:wN \l_@@_fn_code_tl \l_@@_args_tl
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_defaults:}
+% \begin{macro}{\@@_defaults_def:, \@@_defaults_def:nn, \@@_defaults_def:nnn}
+% \begin{macro}{\@@_defaults_aux:,  \@@_defaults_error:w}
+%   First construct \cs{@@_tmp:w} (see below) that will receive
+%   the arguments found so far and determine default values for any
+%   missing argument.  Then call it repeatedly until the set of
+%   arguments stabilizes.  Since that could lead to an infinite loop we
+%   only call it up to nine times, the maximal number needed for
+%   stabilization if there is a chain of arguments that depend on each
+%   other.  If that fails to stabilize raise an error.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_defaults:
+  {
+    \@@_defaults_def:
+    \tl_set_eq:NN \l_@@_args_i_tl \l_@@_args_tl
+    \@@_defaults_aux: \@@_defaults_aux: \@@_defaults_aux:
+    \@@_defaults_aux: \@@_defaults_aux: \@@_defaults_aux:
+    \@@_defaults_aux: \@@_defaults_aux: \@@_defaults_aux:
+    \@@_defaults_error:w
+    \q_recursion_stop
+    \tl_set_eq:NN \l_@@_args_tl \l_@@_args_i_tl
+  }
+\cs_new_protected:Npn \@@_defaults_aux:
+  {
+    \tl_set:Nx \l_@@_args_ii_tl
+      { \exp_after:wN \@@_tmp:w \l_@@_args_i_tl }
+    \tl_if_eq:NNT \l_@@_args_ii_tl \l_@@_args_i_tl
+      { \use_none_delimit_by_q_recursion_stop:w }
+    \tl_set_eq:NN \l_@@_args_i_tl \l_@@_args_ii_tl
+  }
+\cs_new_protected:Npn \@@_defaults_error:w \q_recursion_stop
+  {
+    \msg_error:nnx { cmd } { loop-in-defaults }
+      { \@@_environment_or_command: }
+  }
+%    \end{macrocode}
+%   To construct \cs{@@_tmp:w}, first go through the arguments
+%   found and the corresponding defaults, building a token list with
+%   |{#|\meta{arg number}|}| for arguments found in the input (whose
+%   default will not be used) and otherwise
+%   |{|\cs{exp_not:n}\Arg{default}|}| for arguments whose default will
+%   be used.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_defaults_def:
+  {
+    \tl_clear:N \l_@@_tmpa_tl
+    \int_zero:N \l_@@_current_arg_int
+    \@@_tl_mapthread_function:NNN \l_@@_args_tl \l_@@_defaults_tl
+      \@@_defaults_def:nn
+    \cs_generate_from_arg_count:NNVo \@@_tmp:w \cs_set:Npn
+      \l_@@_current_arg_int \l_@@_tmpa_tl
+  }
+\cs_generate_variant:Nn \cs_generate_from_arg_count:NNnn { NNVo }
+\cs_new_protected:Npn \@@_defaults_def:nn
+  {
+    \int_incr:N \l_@@_current_arg_int
+    \exp_args:NV \@@_defaults_def:nnn \l_@@_current_arg_int
+  }
+\cs_new_protected:Npn \@@_defaults_def:nnn #1#2#3
+  {
+    \tl_put_right:Nx \l_@@_tmpa_tl
+      {
+        {
+          \exp_not:N \exp_not:n
+            {
+              \tl_if_novalue:nTF {#2}
+                { \exp_not:o {#3} }
+                { \exp_not:n { ## #1 } }
+            }
+        }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_args_process:}
+% \begin{macro}{\@@_args_process_loop:nn, \@@_args_process_aux:n}
+%   Loop through arguments (stored in \cs{l_@@_args_tl}) and the
+%   corresponding processors (in \cs{l_@@_process_all_tl})
+%   simultaneously, apply all processors for each argument and store the
+%   result back into \cs{l_@@_args_tl}.  To allow processors to depend
+%   on other arguments, for every processor define a temporary auxiliary
+%   that receives all arguments \cs{l_@@_args_tl}.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_args_process:
+  {
+    \tl_clear:N \l_@@_args_ii_tl
+    \@@_tl_mapthread_function:NNN
+      \l_@@_args_tl
+      \l_@@_process_all_tl
+      \@@_args_process_loop:nn
+    \tl_set_eq:NN \l_@@_args_tl \l_@@_args_ii_tl
+  }
+\cs_new_protected:Npn \@@_args_process_loop:nn #1#2
+  {
+    \tl_set:Nn \ProcessedArgument {#1}
+    \tl_if_novalue:nF {#1}
+      { \tl_map_function:nN {#2} \@@_args_process_aux:n }
+    \tl_put_right:No \l_@@_args_ii_tl
+      { \exp_after:wN { \ProcessedArgument } }
+  }
+\cs_new_protected:Npn \@@_args_process_aux:n #1
+  {
+    \cs_generate_from_arg_count:NNnn \@@_tmp:w \cs_set:Npn
+      { \tl_count:N \l_@@_args_tl } {#1}
+    \exp_args:NNNo \exp_after:wN \@@_tmp:w \l_@@_args_tl
+      { \ProcessedArgument }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_start_expandable:nNNNNn}
+%   This is called for all expandable commands.  |#6| is the signature,
+%   responsible for grabbing arguments.  |#5| is used to determine
+%   default values (or is |?| if there are none).  |#4| is the code to run.
+%   |#2|~and~|#3| are functions (named after the command) that grab a single
+%   argument in the input stream (|#3|~is~short).  The argument specification |#1| is
+%   only used by diagnostic functions.  Same as for the non-expandable
+%   version, this starts with \cs{group_align_safe_begin:}, which
+%   expands to nothing, so may be safely used in an expandable context.
+%    \begin{macrocode}
+\cs_new:Npn \@@_start_expandable:nNNNNn #1#2#3#4#5#6
+  {
+    \group_align_safe_begin:
+    #6 \@@_end_expandable:NNw #5 #4 \q_@@ #2#3
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_end_expandable:NNw}
+% \begin{macro}[EXP]{\@@_end_expandable_aux:w}
+% \begin{macro}[EXP]{\@@_end_expandable_aux:nNNNN}
+% \begin{macro}[EXP]{\@@_end_expandable_defaults:nnnNNn}
+% \begin{macro}[EXP]{\@@_end_expandable_defaults:nnw}
+% \begin{macro}[EXP]{\@@_end_expandable_defaults:nw}
+%   Followed by a function |#1| to determine default values (or |?| if
+%   there are no defaults), the code
+%   |#2|, arguments that have been grabbed, then \cs{q_@@} and two generic
+%   grabbers.  The idea to find default values is similar to the
+%   non-expandable case but we cannot define an auxiliary function, so
+%   at every step in the loop we need to go through all arguments
+%   searching for which ones started out as |-NoValue-| and replacing
+%   these by the newly computed values.  In fact we need to keep track
+%   of three versions of all arguments: the original version, the
+%   previous version with default values, and the currently built
+%   version (first argument of \cs{@@_end_expandable_defaults:nnnNNn}).
+%    \begin{macrocode}
+\cs_new:Npn \@@_end_expandable:NNw #1#2
+  { \@@_end_expandable_aux:w #1#2 \prg_do_nothing: }
+\cs_new:Npn \@@_end_expandable_aux:w #1#2#3 \q_@@
+  { \exp_args:No \@@_end_expandable_aux:nNNNN {#3} #1 #2 }
+\cs_new:Npn \@@_end_expandable_aux:nNNNN #1#2#3#4#5
+  {
+    \token_if_eq_charcode:NNT ? #2 { \exp_after:wN \use_iv:nnnn }
+    \@@_end_expandable_defaults:nnnNNn {#1} { } {#1} #2#3
+      { } { } { } { } { } { } { } { } { } { }
+      {
+        \msg_expandable_error:nnf { cmd } { loop-in-defaults }
+          { \exp_args:Nf \tl_trim_spaces:n { \token_to_str:N #4 } }
+        \use_iv:nnnn
+      }
+    \q_stop
+  }
+\cs_new:Npn \@@_end_expandable_defaults:nnnNNn #1#2#3#4#5#6
+  {
+    #6
+    \str_if_eq:nnTF {#1} {#2}
+      { \use_i_delimit_by_q_stop:nw { \group_align_safe_end: #5 #1 } }
+      {
+        \exp_args:No \@@_tl_mapthread_function:nnN
+          { #4 #1 } {#3}
+          \@@_end_expandable_defaults:nnw
+        \@@_end_expandable_defaults:nnnNNn { } {#1} {#3} #4 #5
+      }
+  }
+\cs_new:Npn \@@_end_expandable_defaults:nnw #1#2
+  {
+    \tl_if_novalue:nTF {#2}
+      { \exp_args:No \@@_end_expandable_defaults:nw {#1} }
+      { \@@_end_expandable_defaults:nw {#2} }
+  }
+\cs_new:Npn \@@_end_expandable_defaults:nw
+    #1#2 \@@_end_expandable_defaults:nnnNNn #3
+  { #2 \@@_end_expandable_defaults:nnnNNn { #3 {#1} } }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Normalizing the argument specifications}
+%
+% The goal here is to expand aliases and check that the argument
+% specification is valid before the main parsing run.  If it is not
+% valid the entire set up is abandoned to avoid any strange internal
+% errors.  A function is provided for each argument type that will grab
+% any extra data items and call the loop function after performing the
+% following checks and tasks.
+% \begin{itemize}
+%   \item Check that each argument has the correct number of data items
+%     associated with it, and that where a single character is required,
+%     one has actually been supplied.
+%   \item Check that processors and the markers~|+| and~|!| are followed
+%     by an argument for which they make sense, and are not redundant.
+%   \item Check the absence of forbidden types for expandable commands,
+%     namely \texttt{G}/\texttt{v} always, and \texttt{l}/\texttt{u}
+%     after optional arguments (\pkg{xparse} may have inserted braces
+%     due to a failed search for an optional argument).
+%   \item Check that no optional argument is followed by a mandatory
+%     argument with the same delimiter, as otherwise the optional
+%     argument could never be omitted.
+%   \item Keep track in \cs{l_@@_some_long_bool} and
+%     \cs{l_@@_some_short_bool} of whether the command has some
+%     long/short arguments.
+%   \item Keep track in \cs{l_@@_grab_expandably_bool} of whether all
+%     arguments are \texttt{m}/\texttt{l}/\texttt{u} type and short
+%     arguments appear before long ones, in which case they can be
+%     grabbed expandably just as safely as they could be grabbed
+%     nonexpandably.  Regardless of that, arguments of expandable
+%     commands will be grabbed expandably and arguments of environments
+%     will not (because the list of arguments built by non-expandable
+%     grabbing is used to pass them to the end-environment code).
+% \end{itemize}
+% Further checks happen at the end of the loop:
+% \begin{itemize}
+% \item that there are at most $9$ arguments;
+% \item that an expandable command does not end with an optional
+%   argument (this case is detected by using the fact that
+%   \cs{l_@@_last_delimiters_tl} is cleared by every mandatory argument
+%   and filled by every optional argument).
+% \end{itemize}
+%
+% \begin{macro}{\@@_normalize_arg_spec:n}
+% \begin{macro}{\@@_normalize_arg_spec_loop:n}
+%   Loop through the argument specification, calling an auxiliary
+%   specific to each argument type.  If any argument is unknown stop the
+%   definition.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_normalize_arg_spec:n #1
+  {
+    \int_zero:N \l_@@_current_arg_int
+    \tl_clear:N \l_@@_last_delimiters_tl
+    \tl_clear:N \l_@@_arg_spec_tl
+    \bool_set_true:N \l_@@_grab_expandably_bool
+    \bool_set_false:N \l_@@_obey_spaces_bool
+    \bool_set_false:N \l_@@_long_bool
+    \bool_set_false:N \l_@@_some_obey_spaces_bool
+    \bool_set_false:N \l_@@_some_long_bool
+    \bool_set_false:N \l_@@_some_short_bool
+    \@@_normalize_arg_spec_loop:n #1
+      \q_recursion_tail \q_recursion_tail \q_recursion_tail \q_recursion_stop
+    \int_compare:nNnT \l_@@_current_arg_int > 9
+      {
+        \msg_error:nnxx { cmd } { too-many-arguments }
+          { \@@_environment_or_command: } { \tl_to_str:n {#1} }
+        \@@_bad_def:wn
+      }
+    \bool_if:NT \l_@@_expandable_bool
+      {
+        \tl_if_empty:NF \l_@@_last_delimiters_tl
+          {
+            \msg_error:nnxx { cmd } { expandable-ending-optional }
+              { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} }
+            \@@_bad_def:wn
+          }
+      }
+    \bool_if:NT \l_@@_expandable_bool
+      { \bool_set_true:N \l_@@_grab_expandably_bool }
+    \bool_if:NT \l_@@_environment_bool
+      { \bool_set_false:N \l_@@_grab_expandably_bool }
+  }
+\cs_new_protected:Npn \@@_normalize_arg_spec_loop:n #1
+  {
+    \quark_if_recursion_tail_stop:n {#1}
+    \int_incr:N \l_@@_current_arg_int
+    \cs_if_exist_use:cF { @@_normalize_type_ \tl_to_str:n {#1} :w }
+      {
+        \bool_lazy_any:nTF
+          {
+            { \str_if_eq_p:nn {#1} { G } }
+            { \str_if_eq_p:nn {#1} { g } }
+            { \str_if_eq_p:nn {#1} { l } }
+            { \str_if_eq_p:nn {#1} { u } }
+          }
+          {
+            \msg_error:nnxx { cmd } { xparse-argument-type }
+              { \@@_environment_or_command: } { \tl_to_str:n {#1} }
+          }
+          {
+            \msg_error:nnxx { cmd } { unknown-argument-type }
+              { \@@_environment_or_command: } { \tl_to_str:n {#1} }
+          }
+        \@@_bad_def:wn
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+%   {
+%     \@@_normalize_type_d:w,
+%     \@@_normalize_type_e:w,
+%     \@@_normalize_type_o:w,
+%     \@@_normalize_type_O:w,
+%     \@@_normalize_type_r:w,
+%     \@@_normalize_type_s:w,
+%   }
+%   These argument types are aliases of more general ones, for example
+%   with the default argument |-NoValue-|.  To easily insert that marker
+%   expanded in the definitions we call \cs{@@_tmp:w} with the argument
+%   |-NoValue-|.  For argument types that need additional data, check
+%   that the data is present (not \cs{q_recursion_tail}) before
+%   proceeding.
+%    \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1
+  {
+    \cs_new_protected:Npn \@@_normalize_type_d:w ##1##2
+      {
+        \quark_if_recursion_tail_stop_do:nn {##2} { \@@_bad_arg_spec:wn }
+        \@@_normalize_type_D:w {##1} {##2} {#1}
+      }
+    \cs_new_protected:Npn \@@_normalize_type_e:w ##1
+      {
+        \quark_if_recursion_tail_stop_do:nn {##1} { \@@_bad_arg_spec:wn }
+        \@@_normalize_type_E:w {##1} { }
+      }
+    \cs_new_protected:Npn \@@_normalize_type_o:w
+      { \@@_normalize_type_D:w [ ] {#1} }
+    \cs_new_protected:Npn \@@_normalize_type_O:w
+      { \@@_normalize_type_D:w [ ] }
+    \cs_new_protected:Npn \@@_normalize_type_r:w ##1##2
+      {
+        \quark_if_recursion_tail_stop_do:nn {##2} { \@@_bad_arg_spec:wn }
+        \@@_normalize_type_R:w {##1} {##2} {#1}
+      }
+    \cs_new_protected:Npn \@@_normalize_type_s:w
+      { \@@_normalize_type_t:w * }
+  }
+\exp_args:No \@@_tmp:w { \c_novalue_tl }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {
+%     \@@_normalize_type_>:w,
+%     \@@_normalize_type_+:w,
+%     \@@_normalize_type_!:w,
+%   }
+%   Check that these prefixes have arguments, namely that the next token
+%   is not \cs{q_recursion_tail}, and remember to leave it after the
+%   looping macro.  Processors are forbidden in expandable commands.
+%   If all is good, store the prefix in the cleaned up
+%   \cs{l_@@_arg_spec_tl}, and decrement the argument number as prefixes
+%   do not correspond to arguments.
+%    \begin{macrocode}
+\cs_new_protected:cpn { @@_normalize_type_>:w } #1#2
+  {
+    \quark_if_recursion_tail_stop_do:nn {#2} { \@@_bad_arg_spec:wn }
+    \bool_if:NT \l_@@_expandable_bool
+      {
+        \msg_error:nnxx { cmd } { processor-in-expandable }
+          { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} }
+        \@@_bad_def:wn
+      }
+    \tl_put_right:Nx \l_@@_arg_spec_tl { > { \tl_trim_spaces:n {#1} } }
+    \int_decr:N \l_@@_current_arg_int
+    \bool_set_false:N \l_@@_grab_expandably_bool
+    \@@_normalize_arg_spec_loop:n {#2}
+  }
+\cs_new_protected:cpn { @@_normalize_type_+:w } #1
+  {
+    \quark_if_recursion_tail_stop_do:nn {#1} { \@@_bad_arg_spec:wn }
+    \bool_if:NT \l_@@_long_bool
+      {
+        \msg_error:nnxx { cmd } { two-markers }
+          { \@@_environment_or_command: } { + }
+        \@@_bad_def:wn
+      }
+    \bool_set_true:N \l_@@_long_bool
+    \int_decr:N \l_@@_current_arg_int
+    \@@_normalize_arg_spec_loop:n {#1}
+  }
+\cs_new_protected:cpn { @@_normalize_type_!:w } #1
+  {
+    \quark_if_recursion_tail_stop_do:nn {#1} { \@@_bad_arg_spec:wn }
+    \bool_if:NT \l_@@_obey_spaces_bool
+      {
+        \msg_error:nnxx { cmd } { two-markers }
+          { \@@_environment_or_command: } { ! }
+        \@@_bad_def:wn
+      }
+    \bool_set_true:N \l_@@_obey_spaces_bool
+    \bool_set_true:N \l_@@_some_obey_spaces_bool
+    \int_decr:N \l_@@_current_arg_int
+    \@@_normalize_arg_spec_loop:n {#1}
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {
+%     \@@_normalize_type_D:w,
+%     \@@_normalize_type_E:w,
+%     \@@_normalize_type_t:w,
+%   }
+% \begin{macro}{\@@_normalize_E_unique_check:w}
+%   Optional argument types.  Check that all required data is present
+%   (and consists of single characters if applicable) and check for
+%   forbidden types for expandable commands.  For \texttt{E}-type
+%   require that there is at least one embellishment, that each one is a
+%   single character, and that there aren't more optional arguments than
+%   embellishments; also remember that each embellishment counts as one
+%   argument for \cs{l_@@_current_arg_int}.  Then in each case
+%   store the data in \cs{l_@@_arg_spec_tl}, and
+%   for later checks store in \cs{l_@@_last_delimiters_tl} the tokens
+%   whose presence determines whether there is an optional argument (for
+%   braces store |{}|, seen later as an empty delimiter).
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_normalize_type_D:w #1#2#3
+  {
+    \quark_if_recursion_tail_stop_do:nn {#3} { \@@_bad_arg_spec:wn }
+    \@@_single_token_check:n {#1} \@@_allowed_token_check:N #1
+    \@@_single_token_check:n {#2}
+    \@@_add_arg_spec:n { D #1 #2 {#3} }
+    \tl_put_right:Nn \l_@@_last_delimiters_tl {#1}
+    \bool_set_false:N \l_@@_grab_expandably_bool
+    \@@_normalize_arg_spec_loop:n
+  }
+\cs_new_protected:Npn \@@_normalize_type_E:w #1#2
+  {
+    \quark_if_recursion_tail_stop_do:nn {#2} { \@@_bad_arg_spec:wn }
+    \tl_if_blank:nT {#1} { \@@_bad_arg_spec:wn }
+    \tl_map_function:nN {#1} \@@_single_token_check:n
+    \tl_map_function:nN {#1} \@@_allowed_token_check:N
+    \@@_normalize_E_unique_check:w #1 \q_nil \q_stop
+    \int_compare:nNnT { \tl_count:n {#2} } > { \tl_count:n {#1} }
+      { \@@_bad_arg_spec:wn }
+    \@@_add_arg_spec:n { E {#1} {#2} }
+    \tl_put_right:Nn \l_@@_last_delimiters_tl {#1}
+    \bool_set_false:N \l_@@_grab_expandably_bool
+    \int_add:Nn \l_@@_current_arg_int { \tl_count:n {#1} - 1 }
+    \@@_normalize_arg_spec_loop:n
+  }
+\cs_new_protected:Npn \@@_normalize_E_unique_check:w #1#2 \q_stop
+  {
+    \quark_if_nil:NF #1
+      {
+        \tl_if_in:nnT {#2} {#1} { \@@_bad_arg_spec:wn }
+        \@@_normalize_E_unique_check:w #2 \q_stop
+      }
+  }
+\cs_new_protected:Npn \@@_normalize_type_t:w #1
+  {
+    \quark_if_recursion_tail_stop_do:Nn #1 { \@@_bad_arg_spec:wn }
+    \@@_single_token_check:n {#1} \@@_allowed_token_check:N #1
+    \tl_put_right:Nx \l_@@_arg_spec_tl
+      {
+        \bool_if:NT \l_@@_obey_spaces_bool { ! }
+        t \exp_not:n {#1}
+      }
+    \tl_put_right:Nn \l_@@_last_delimiters_tl {#1}
+    \bool_set_false:N \l_@@_grab_expandably_bool
+    \bool_set_false:N \l_@@_obey_spaces_bool
+    \bool_set_false:N \l_@@_long_bool
+    \@@_normalize_arg_spec_loop:n
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+%   {
+%     \@@_normalize_type_m:w,
+%     \@@_normalize_type_R:w,
+%     \@@_normalize_type_v:w
+%   }
+%   Mandatory arguments.  First check the required data is present,
+%   consists of single characters where applicable, and that the argument
+%   type is allowed for expandable commands if applicable.  For the
+%   \texttt{m} and \texttt{R} argument types check that they do not
+%   follow some optional argument with that delimiter as otherwise the
+%   optional argument could not be omitted.  Then save data in
+%   \cs{l_@@_arg_spec_tl}, count the mandatory argument, and empty the
+%   list of last delimiters.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_normalize_type_m:w
+  {
+    \@@_delimiter_check:nnn { } { m } { \iow_char:N \{ }
+    \@@_add_arg_spec_mandatory:n { m }
+    \@@_normalize_arg_spec_loop:n
+  }
+\cs_new_protected:Npn \@@_normalize_type_R:w #1#2#3
+  {
+    \quark_if_recursion_tail_stop_do:nn {#3} { \@@_bad_arg_spec:wn }
+    \@@_single_token_check:n {#1} \@@_allowed_token_check:N #1
+    \@@_single_token_check:n {#2}
+    \@@_delimiter_check:nnn {#1} { R/r } { \tl_to_str:n {#1} }
+    \bool_set_false:N \l_@@_grab_expandably_bool
+    \@@_add_arg_spec_mandatory:n { R #1 #2 {#3} }
+    \@@_normalize_arg_spec_loop:n
+  }
+\cs_new_protected:Npn \@@_normalize_type_v:w
+  {
+    \@@_normalize_check_gv:N v
+    \@@_add_arg_spec_mandatory:n { v }
+    \@@_normalize_arg_spec_loop:n
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_normalize_type_b:w}
+%   This argument type is not allowed for commands.  This is only
+%   allowed at the end of the argument specification, hence we check
+%   that |#1| is the end.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_normalize_type_b:w #1
+  {
+    \bool_if:NF \l_@@_environment_bool
+      {
+        \msg_error:nnxx { cmd } { invalid-command-arg }
+          { \@@_environment_or_command: } { b }
+        \@@_bad_def:wn
+      }
+    \tl_clear:N \l_@@_last_delimiters_tl
+    \@@_add_arg_spec:n { b }
+    \quark_if_recursion_tail_stop:n {#1}
+    \msg_error:nnxx { cmd } { arg-after-body }
+      { \@@_environment_or_command: }
+      { \tl_to_str:n {#1} }
+    \@@_bad_def:wn
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_single_token_check:n}
+%   Checks that the argument is a single (non-space) token (possibly
+%   surrounded by spaces), and aborts the definition otherwise.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_single_token_check:n #1
+  {
+    \tl_trim_spaces_apply:nN {#1} \tl_if_single_token:nF
+      {
+        \msg_error:nnxx { cmd } { not-single-token }
+          { \@@_environment_or_command: } { \tl_to_str:n {#1} }
+        \@@_bad_def:wn
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_allowed_token_check:N}
+%   Some tokens are now allowed as delimiters for some argument types,
+%   notably implicit begin/end-group tokens (|\bgroup|/|\egroup|).
+%   The major problem with these tokens is that for |\peek_...| functions,
+%   a literal~|{|$_1$. is virtually indistinguishable from a |\bgroup| or
+%   other token which was |\let| to a~|{|$_1$, and the same goes
+%   for~|}|$_2$.  All other tokens can be easily distingushed from their
+%   implicit counterparts by grabbing them and looking at the string
+%   length (see \cs{@@_token_if_cs:NTF}), but for begin/end group tokens
+%   that is not possible without the risk of mistakenly grabbing the
+%   entire brace group (potentially leading to a~\texttt{!~Runaway argument}
+%   error) or trying to grab a |}|$_2$, leading to
+%   an~\verb|! Argument of \dots has an extra }| error.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_allowed_token_check:N #1
+  {
+    \token_if_eq_meaning:NNTF #1 \c_group_begin_token
+        { \use:n }
+        {
+          \token_if_eq_meaning:NNTF #1 \c_group_end_token
+            { \use:n }
+            { \use_none:n }
+        }
+      {
+        \msg_error:nnxxx { cmd } { forbidden-implicit-group-token }
+          { \@@_environment_or_command: } { \tl_to_str:n {#1} }
+          {
+            \token_if_eq_meaning:NNTF #1 \c_group_begin_token
+              { begin } { end }
+          }
+        \@@_bad_def:wn
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_normalize_check_gv:N, \@@_normalize_check_lu:N}
+%   Called for arguments that are always forbidden, or forbidden after
+%   an optional argument, for expandable commands.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_normalize_check_gv:N #1
+  {
+    \bool_if:NT \l_@@_expandable_bool
+      {
+        \msg_error:nnxx { cmd } { invalid-expandable-argument-type }
+          { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} }
+        \@@_bad_def:wn
+      }
+    \bool_set_false:N \l_@@_grab_expandably_bool
+  }
+\cs_new_protected:Npn \@@_normalize_check_lu:N #1
+  {
+    \bool_if:NT \l_@@_expandable_bool
+      {
+        \tl_if_empty:NF \l_@@_last_delimiters_tl
+          {
+            \msg_error:nnxx { cmd } { invalid-after-optional-expandably }
+              { \iow_char:N \\ \l_@@_function_tl } { \tl_to_str:n {#1} }
+            \@@_bad_def:wn
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_delimiter_check:nnn}
+%   Called for \texttt{m} and \texttt{R} arguments.  Checks that the
+%   leading token does not coincide with the token denoting the presence
+%   of a previous optional argument.  Instead of dealing with braces for
+%   the \texttt{m}-type we use an empty delimiter to denote that case.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_delimiter_check:nnn #1#2#3
+  {
+    \tl_map_inline:Nn \l_@@_last_delimiters_tl
+      {
+        \tl_if_eq:nnT {##1} {#1}
+          {
+            \msg_warning:nnxx { cmd } { optional-mandatory }
+              {#2} {#3}
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_bad_arg_spec:wn, \@@_bad_def:wn}
+%   If the argument specification is wrong, this provides an escape from
+%   the entire definition process.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_bad_arg_spec:wn #1 \@@_break_point:n #2
+  {
+    \msg_error:nnxx { cmd } { bad-arg-spec }
+      { \@@_environment_or_command: } { \tl_to_str:n {#2} }
+  }
+\cs_new_protected:Npn \@@_bad_def:wn #1 \@@_break_point:n #2 { }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_arg_spec:n, \@@_add_arg_spec_mandatory:n}
+%   When adding an argument to the argument specification, set the
+%   \texttt{some_long} or \texttt{some_short} booleans as appropriate
+%   and clear the booleans keeping track of |+| and |!| markers.
+%   Before that, test for a short argument following some long
+%   arguments: this is forbidden for expandable commands and prevents
+%   grabbing arguments expandably.
+%
+%   For mandatory arguments do some more work, in particular complain if
+%   they were preceeded by~|!|.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_arg_spec:n #1
+  {
+    \bool_lazy_and:nnT
+      { ! \l_@@_long_bool }
+      { \l_@@_some_long_bool }
+      {
+        \bool_if:NT \l_@@_expandable_bool
+          {
+            \msg_error:nnx { cmd } { inconsistent-long }
+              { \iow_char:N \\ \l_@@_function_tl }
+            \@@_bad_def:wn
+          }
+        \bool_set_false:N \l_@@_grab_expandably_bool
+      }
+    \bool_if:NTF \l_@@_long_bool
+      { \bool_set_true:N \l_@@_some_long_bool }
+      { \bool_set_true:N \l_@@_some_short_bool }
+    \tl_put_right:Nx \l_@@_arg_spec_tl
+      {
+        \bool_if:NT \l_@@_long_bool { + }
+        \bool_if:NT \l_@@_obey_spaces_bool { ! }
+        \exp_not:n {#1}
+      }
+    \bool_set_false:N \l_@@_long_bool
+    \bool_set_false:N \l_@@_obey_spaces_bool
+  }
+\cs_new_protected:Npn \@@_add_arg_spec_mandatory:n #1
+  {
+    \bool_if:NT \l_@@_some_obey_spaces_bool
+      {
+        \msg_error:nnxx { cmd } { non-trailing-obey-spaces }
+          { \@@_environment_or_command: } { \tl_to_str:n {#1} }
+        \@@_bad_def:wn
+      }
+    \tl_clear:N \l_@@_last_delimiters_tl
+    \@@_add_arg_spec:n {#1}
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Preparing the signature: general mechanism}
+%
+% \begin{macro}{\@@_prepare_signature:n}
+% \begin{macro}{\@@_prepare_signature:N}
+% \begin{macro}{\@@_prepare_signature_bypass:N}
+%   Actually creating the signature uses the same loop approach as
+%   normalizing the signature. There are first a number of variables which need
+%   to be set to track what is going on. Many of these variables are unused
+%   when defining expandable commands.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_prepare_signature:n #1
+  {
+    \int_zero:N \l_@@_current_arg_int
+    \bool_set_false:N \l_@@_long_bool
+    \bool_set_false:N \l_@@_obey_spaces_bool
+    \int_zero:N \l_@@_m_args_int
+    \bool_set_false:N \l_@@_defaults_bool
+    \tl_clear:N \l_@@_defaults_tl
+    \tl_clear:N \l_@@_process_all_tl
+    \tl_clear:N \l_@@_process_one_tl
+    \bool_set_false:N \l_@@_process_some_bool
+    \tl_clear:N \l_@@_signature_tl
+    \@@_prepare_signature:N #1 \q_recursion_tail \q_recursion_stop
+    \bool_if:NF \l_@@_expandable_bool { \@@_flush_m_args: }
+  }
+%    \end{macrocode}
+%  The main looping function does not take an argument, but carries out the
+%  reset on the processor boolean. This is split off from the rest of the
+%  process so that when actually setting up processors the flag-reset can
+%  be bypassed.
+%
+%  For each known argument type there is an appropriate function to actually
+%  do the addition to the signature. These are separate for expandable and
+%  standard functions, as the approaches are different.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_prepare_signature:N
+  {
+    \bool_set_false:N \l_@@_prefixed_bool
+    \@@_prepare_signature_bypass:N
+  }
+\cs_new_protected:Npn \@@_prepare_signature_bypass:N #1
+  {
+    \quark_if_recursion_tail_stop:N #1
+    \use:c
+      {
+         @@_add
+         \bool_if:NT \l_@@_grab_expandably_bool { _expandable }
+         _type_  \token_to_str:N #1 :w
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Setting up a standard signature}
+%
+% Each argument-adding function appends to the signature a grabber (and
+% for some types, the delimiters or default value), except the one for
+% \texttt{m} arguments.  These are collected and added to the signature
+% all at once by \cs{@@_flush_m_args:}, called for every other argument
+% type.  All of the functions then call the loop function
+% \cs{@@_prepare_signature:N}.  Default values of arguments are
+% collected by \cs{@@_add_default:n} rather than being stored with the
+% argument; this function and \cs{@@_add_default:} are also responsible
+% for keeping track of \cs{l_@@_current_arg_int}.
+%
+% \begin{macro}{\@@_add_type_+:w}
+%   Making the next argument long means setting the flag. The \texttt{m}
+%   arguments are recorded here as
+%   this has to be done for every case where there is then a long argument.
+%    \begin{macrocode}
+\cs_new_protected:cpn { @@_add_type_+:w }
+  {
+    \@@_flush_m_args:
+    \bool_set_true:N \l_@@_long_bool
+    \bool_set_true:N \l_@@_prefixed_bool
+    \@@_prepare_signature_bypass:N
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_type_!:w}
+%   Much the same for controlling trailing optional arguments.
+%    \begin{macrocode}
+\cs_new_protected:cpn { @@_add_type_!:w }
+  {
+    \@@_flush_m_args:
+    \bool_set_true:N \l_@@_obey_spaces_bool
+    \bool_set_true:N \l_@@_prefixed_bool
+    \@@_prepare_signature_bypass:N
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_type_>:w}
+%   When a processor is found, the processor code is stored.  It will be
+%   used by \cs{@@_args_process:} once arguments are all found. Here too
+%   the loop calls \cs{@@_prepare_signature_bypass:N} rather than
+%   \cs{@@_prepare_signature:N} so that the flag is not reset.
+%    \begin{macrocode}
+\cs_new_protected:cpn { @@_add_type_>:w } #1
+  {
+    \@@_flush_m_args:
+    \bool_set_true:N \l_@@_prefixed_bool
+    \bool_set_true:N \l_@@_process_some_bool
+    \tl_put_left:Nn \l_@@_process_one_tl { {#1} }
+    \@@_prepare_signature_bypass:N
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_type_b:w}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_type_b:w
+  {
+    \@@_flush_m_args:
+    \@@_add_default:
+    \@@_add_grabber:N b
+    \@@_prepare_signature:N
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_type_D:w}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_type_D:w #1#2#3
+  {
+    \@@_flush_m_args:
+    \@@_add_default:n {#3}
+    \@@_add_grabber:N D
+    \tl_put_right:Nn \l_@@_signature_tl { #1 #2 }
+    \@@_prepare_signature:N
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_type_E:w}
+%   The \texttt{E}-type argument needs a special handling of default
+%   values.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_type_E:w #1#2
+  {
+    \@@_flush_m_args:
+    \@@_add_default_E:nn {#1} {#2}
+    \@@_add_grabber:N E
+    \tl_put_right:Nn \l_@@_signature_tl { {#1} }
+    \@@_prepare_signature:N
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_type_m:w}
+%   The \texttt{m} type is special as short arguments which are not
+%   post-processed are simply counted at this stage. Thus there is a check
+%   to see if either of these cases apply. If so, a one-argument grabber
+%   is added to the signature. On the other hand, if a standard short
+%   argument is required it is simply counted at this stage, to be
+%   added later using \cs{@@_flush_m_args:}.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_type_m:w
+  {
+    \@@_add_default:
+    \bool_if:NTF \l_@@_prefixed_bool
+      { \@@_add_grabber:N m }
+      { \int_incr:N \l_@@_m_args_int }
+    \@@_prepare_signature:N
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_type_R:w}
+%   The \texttt{R}-type argument is very similar to the \texttt{D}-type.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_type_R:w #1#2#3
+  {
+    \@@_flush_m_args:
+    \@@_add_default:n {#3}
+    \@@_add_grabber:N R
+    \tl_put_right:Nn \l_@@_signature_tl { #1 #2 }
+    \@@_prepare_signature:N
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_type_t:w}
+%   Setting up a \texttt{t} argument means collecting one token for the test,
+%   and adding it along with the grabber to the signature.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_type_t:w #1
+  {
+    \@@_flush_m_args:
+    \@@_add_default:
+    \@@_add_grabber:N t
+    \tl_put_right:Nn \l_@@_signature_tl {#1}
+    \@@_prepare_signature:N
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_type_v:w}
+%   At this stage, the \texttt{v} argument is identical to \texttt{l}
+%   except that since the grabber may fail to read a verbatim argument
+%   we need a default value.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_type_v:w
+  {
+    \@@_flush_m_args:
+    \exp_args:No \@@_add_default:n \c_novalue_tl
+    \@@_add_grabber:N v
+    \@@_prepare_signature:N
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_flush_m_args:}
+%   As \texttt{m} arguments are simply counted, there is a need to add
+%   them to the token register in a block. As this function can only
+%   be called if something other than \texttt{m} turns up, the flag can
+%   be switched here.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_flush_m_args:
+  {
+    \int_compare:nNnT \l_@@_m_args_int > 0
+      {
+        \tl_put_right:Nx \l_@@_signature_tl
+          { \exp_not:c { @@_grab_m_ \int_use:N \l_@@_m_args_int :w } }
+        \tl_put_right:Nx \l_@@_process_all_tl
+          { \prg_replicate:nn { \l_@@_m_args_int } { { } } }
+      }
+    \int_zero:N \l_@@_m_args_int
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_grabber:N}
+%   To keep the various checks needed in one place, adding the grabber
+%   to the signature is done here.  The only questions are whether the
+%   grabber should be long or not, and whether to obey spaces.  The
+%   \cs{l_@@_obey_spaces_bool} boolean can only be \texttt{true} for
+%   trailing optional arguments.  In that case spaces will not be
+%   ignored when looking for that optional argument.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_grabber:N #1
+  {
+    \tl_put_right:Nx \l_@@_signature_tl
+      {
+        \exp_not:c
+          {
+            @@_grab_ #1
+            \bool_if:NT \l_@@_long_bool { _long }
+            \bool_if:NT \l_@@_obey_spaces_bool { _obey_spaces }
+            :w
+          }
+      }
+    \bool_set_false:N \l_@@_long_bool
+    \bool_set_false:N \l_@@_obey_spaces_bool
+    \tl_put_right:Nx \l_@@_process_all_tl
+      { { \exp_not:o \l_@@_process_one_tl } }
+    \tl_clear:N \l_@@_process_one_tl
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_default:n, \@@_add_default:, \@@_add_default_E:nn}
+%   Store the default value of an argument, or rather code that gives
+%   that default value (it may involve other arguments).  This is
+%   \cs{c_novalue_tl} for arguments with no actual default or with
+%   default |-NoValue-|; and (in a brace group) \cs{prg_do_nothing:}
+%   followed by a default value for others.  For \texttt{E}-type
+%   arguments, pad the defaults |#2| with some \cs{c_novalue_tl}
+%   until there are as many as embellishments~|#1|.  These functions are
+%   also used when defining expandable commands.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_default:n #1
+  {
+    \tl_if_novalue:nTF {#1}
+      { \@@_add_default: }
+      {
+        \int_incr:N \l_@@_current_arg_int
+        \bool_set_true:N \l_@@_defaults_bool
+        \tl_put_right:Nn \l_@@_defaults_tl { { \prg_do_nothing: #1 } }
+      }
+  }
+\cs_new_protected:Npn \@@_add_default:
+  {
+    \int_incr:N \l_@@_current_arg_int
+    \tl_put_right:Nn \l_@@_defaults_tl { \c_novalue_tl }
+  }
+\cs_new_protected:Npn \@@_add_default_E:nn #1#2
+  {
+    \tl_map_function:nN {#2} \@@_add_default:n
+    \prg_replicate:nn
+      { \tl_count:n {#1} - \tl_count:n {#2} }
+      { \@@_add_default: }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Setting up expandable types}
+%
+% The approach here is not dissimilar to that for standard types, but fewer types
+% are supported. There is
+% also a need to define the per-function auxiliaries: this is done here, while
+% the general grabbers are dealt with later.
+%
+% \begin{macro}{\@@_add_expandable_type_+:w}
+%   We have already checked that short arguments are before long
+%   arguments, so \cs{l_@@_long_bool} only changes from \texttt{false}
+%   to \texttt{true} once (and there is no need to reset it after each
+%   argument).  Also knock back the argument count because |+| is not an
+%   argument.  Continue the loop.
+%    \begin{macrocode}
+\cs_new_protected:cpn { @@_add_expandable_type_+:w }
+  {
+    \bool_set_true:N \l_@@_long_bool
+    \@@_prepare_signature:N
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_expandable_type_D:w}
+% \begin{macro}{\@@_add_expandable_type_D_aux:NNNn}
+% \begin{macro}{\@@_add_expandable_type_D_aux:NNN}
+% \begin{macro}{\@@_add_expandable_type_D_aux:NN}
+%   The set up for \texttt{D}-type arguments involves constructing a
+%   rather complex auxiliary which is used
+%   repeatedly when grabbing. There is an auxiliary here so that the
+%   \texttt{R}-type can share code readily: |#1| is |D| or~|R|.
+%   The |_aux:NN| auxiliary is needed if the two delimiting tokens are
+%   identical: in contrast to the non-expandable route, the grabber here
+%   has to act differently for this case.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_expandable_type_D:w
+  { \@@_add_expandable_type_D_aux:NNNn D }
+\cs_new_protected:Npn \@@_add_expandable_type_D_aux:NNNn #1#2#3#4
+  {
+    \@@_add_default:n {#4}
+    \tl_if_eq:nnTF {#2} {#3}
+      { \@@_add_expandable_type_D_aux:NN #1 #2 }
+      { \@@_add_expandable_type_D_aux:NNN #1 #2 #3 }
+    \@@_prepare_signature:N
+  }
+\cs_new_protected:Npn \@@_add_expandable_type_D_aux:NNN #1#2#3
+  {
+    \bool_if:NTF \l_@@_long_bool
+      { \cs_set:cpx }
+      { \cs_set_nopar:cpx }
+      { \l_@@_expandable_aux_name_tl } ##1 ##2 #2 ##3 \q_@@ ##4 #3
+      { ##1 {##2} {##3} {##4} }
+    \@@_add_expandable_grabber:nn {#1}
+      {
+        \exp_not:c  { \l_@@_expandable_aux_name_tl }
+        \exp_not:n { #2 #3 }
+      }
+  }
+\cs_new_protected:Npn \@@_add_expandable_type_D_aux:NN #1#2
+  {
+    \bool_if:NTF \l_@@_long_bool
+      { \cs_set:cpx }
+      { \cs_set_nopar:cpx }
+      { \l_@@_expandable_aux_name_tl } ##1 #2 ##2 #2
+      { ##1 {##2} }
+    \@@_add_expandable_grabber:nn { #1_alt }
+      {
+        \exp_not:c  { \l_@@_expandable_aux_name_tl }
+        \exp_not:n {#2}
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_expandable_type_E:w}
+% \begin{macro}{\@@_add_expandable_type_E_aux:n}
+%   For each embellishment, use \cs{@@_get_grabber:NN} to obtain an
+%   auxiliary delimited by that token and store a pair constituted of
+%   the auxiliary and the token in \cs{l_@@_tmpb_tl}, before appending
+%   the whole set of these pairs to the signature, and an equal number
+%   of |-NoValue-| markers (regardless of the default values of
+%   arguments).  Set the current argument appropriately.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_expandable_type_E:w #1#2
+  {
+    \@@_add_default_E:nn {#1} {#2}
+    \tl_clear:N \l_@@_tmpb_tl
+    \tl_map_function:nN {#1} \@@_add_expandable_type_E_aux:n
+    \@@_add_expandable_grabber:nn
+      { E \bool_if:NT \l_@@_long_bool { _long } }
+      {
+        { \exp_not:o \l_@@_tmpb_tl }
+        {
+          \prg_replicate:nn { \tl_count:n {#1} }
+            { { \c_novalue_tl } }
+        }
+      }
+    \@@_prepare_signature:N
+  }
+\cs_new_protected:Npn \@@_add_expandable_type_E_aux:n #1
+  {
+    \@@_get_grabber:NN #1 \l_@@_tmpa_tl
+    \tl_put_right:Nx \l_@@_tmpb_tl
+      { \exp_not:o \l_@@_tmpa_tl \exp_not:N #1 }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_expandable_type_m:w}
+%   Unlike the standard case, when working expandably each argument is always
+%   grabbed separately.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_expandable_type_m:w
+  {
+    \@@_add_default:
+    \@@_add_expandable_grabber:nn
+      { m \bool_if:NT \l_@@_long_bool { _long } } { }
+    \@@_prepare_signature:N
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_expandable_type_R:w}
+%   The \texttt{R}-type is very similar to the \texttt{D}-type
+%   argument, and so the same internals are used.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_expandable_type_R:w
+  { \@@_add_expandable_type_D_aux:NNNn R }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_expandable_type_t:w}
+%   An auxiliary delimited by |#1| is built now.  It will be used to
+%   test for the presence of that token.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_expandable_type_t:w #1
+  {
+    \@@_add_default:
+    \@@_get_grabber:NN #1 \l_@@_tmpa_tl
+    \@@_add_expandable_grabber:nn { t }
+      {
+        \exp_not:o \l_@@_tmpa_tl
+        \exp_not:N #1
+      }
+    \@@_prepare_signature:N
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_expandable_grabber:nn}
+%   This is called for all arguments to place the right grabber in the
+%   signature.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_expandable_grabber:nn #1#2
+  {
+    \tl_put_right:Nx \l_@@_signature_tl
+      { \exp_not:c { @@_expandable_grab_ #1 :w } #2 }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_get_grabber:NN}
+% \begin{macro}{\@@_get_grabber_auxi:NN}
+% \begin{macro}{\@@_get_grabber_auxii:NN}
+%   Given a token |#1|, defines an expandable function delimited by that
+%   token and stores it in the token list~|#2|.  The function is named
+%   after the token, unless that function name is already taken by some
+%   other grabber (this can happen in the rare case where delimiters
+%   with different category codes are used in the same document): in
+%   that case use a global counter to get a unique name.  Since the
+%   grabbers are not named after \pkg{xparse} commands they should not
+%   be used to get material from the input stream.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_get_grabber:NN #1#2
+  {
+    \cs_set:Npn \@@_tmp:w ##1 #1 {##1}
+    \exp_args:Nc \@@_get_grabber_auxi:NN
+      { @@_grabber_ \token_to_str:N #1 :w } #2
+  }
+\cs_new_protected:Npn \@@_get_grabber_auxi:NN #1#2
+  {
+    \cs_if_eq:NNTF \@@_tmp:w #1
+      { \tl_set:Nn #2 {#1} }
+      {
+        \cs_if_exist:NTF #1
+          {
+            \int_gincr:N \g_@@_grabber_int
+            \exp_args:Nc \@@_get_grabber_auxi:NN
+              {
+                @@_grabber_
+                - \int_use:N \g_@@_grabber_int :w
+              }
+              #2
+          }
+          { \@@_get_grabber_auxii:NN #1 #2 }
+      }
+  }
+\cs_new_protected:Npn \@@_get_grabber_auxii:NN #1#2
+  {
+    \cs_set_eq:NN #1 \@@_tmp:w
+    \tl_set:Nn #2 {#1}
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Grabbing arguments}
+%
+% All of the grabbers follow the same basic pattern. The initial
+% function stores in \cs{l_@@_signature_tl} the code to grab further
+% arguments, defines (the function in) \cs{l_@@_fn_tl} that will grab
+% the argument, and calls it.
+%
+% Defining \cs{l_@@_fn_tl} means determining whether to use
+% \cs{cs_set:Npn} or \cs{cs_set_nopar:Npn}, and for optional arguments
+% whether to skip spaces. Once the argument is found, \cs{l_@@_fn_tl}
+% calls \cs{@@_add_arg:n}, responsible for calling processors and
+% grabbing further arguments.
+%
+% \begin{macro}
+%   {
+%     \@@_grab_b:w,
+%     \@@_grab_b_long:w,
+%     \@@_grab_b_obey_spaces:w,
+%     \@@_grab_b_long_obey_spaces:w,
+%     \@@_grab_b_aux:NNw,
+%     \@@_grab_b_end:Nw
+%   }
+%   This uses the well-tested code of \texttt{D}-type arguments,
+%   skipping the peeking step because the \texttt{b}-type argument is
+%   always present, and adding a cleanup stage at the end by hijacking
+%   the signature.  The clean-up consists of properly
+%   dealing with \cs{l_@@_args_tl} and also putting back the \cs{end}
+%   that served as an end-delimiter: this \cs{end} receives the
+%   environment name as its argument and is run normally.  The
+%   \texttt{D}-type code stores the argument found (body of the
+%   environment) as a brace group in \cs{l_@@_args_tl} and depending on
+%   the presence of a prefix~|!| we trim spaces or not before adding
+%   this braced argument into the saved \cs{l_@@_args_tl}.
+%   The strange \verb*|\begin | control sequence is there for display
+%     purposes only: it has to look like |\begin| in the terminal but
+%       not to delimited arguments.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_b:w
+  { \@@_grab_b_aux:NNw \cs_set_protected_nopar:Npn \tl_trim_spaces:n }
+\cs_new_protected:Npn \@@_grab_b_long:w
+  { \@@_grab_b_aux:NNw \cs_set_protected:Npn \tl_trim_spaces:n }
+\cs_new_protected:Npn \@@_grab_b_obey_spaces:w
+  { \@@_grab_b_aux:NNw \cs_set_protected_nopar:Npn \exp_not:n }
+\cs_new_protected:Npn \@@_grab_b_long_obey_spaces:w
+  { \@@_grab_b_aux:NNw \cs_set_protected:Npn \exp_not:n }
+\cs_new_protected:Npn \@@_grab_b_aux:NNw #1#2#3 \@@_run_code:
+  {
+    \@@_grab_D_aux:NNnN \begin \end {#3} #1
+    \tl_put_left:Nn \l_@@_signature_tl { \@@_grab_b_end:Nw #2 }
+    \tl_set_eq:NN \l_@@_saved_args_tl \l_@@_args_tl
+    \tl_clear:N \l_@@_args_tl
+    \exp_args:Nc \l_@@_fn_tl { begin ~ }
+  }
+\cs_new_protected:Npn \@@_grab_b_end:Nw #1#2 \@@_run_code:
+  {
+    \tl_set:Nx \l_@@_args_tl
+      {
+        \exp_not:V \l_@@_saved_args_tl
+        { \exp_after:wN #1 \l_@@_args_tl }
+      }
+    #2
+    \@@_run_code:
+    \end
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_grab_D:w}
+% \begin{macro}{\@@_grab_D_long:w}
+% \begin{macro}{\@@_grab_D_obey_spaces:w}
+% \begin{macro}{\@@_grab_D_long_obey_spaces:w}
+%   The generic delimited argument grabber. The auxiliary function does
+%   a peek test before calling \cs{@@_grab_D_call:Nw}, so that the
+%   optional nature of the argument works as expected.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_D:w #1#2#3 \@@_run_code:
+  {
+    \@@_grab_D_aux:NNnNN #1 #2 {#3} \cs_set_protected_nopar:Npn
+      \@@_peek_nonspace_remove:NTF
+  }
+\cs_new_protected:Npn \@@_grab_D_long:w #1#2#3 \@@_run_code:
+  {
+    \@@_grab_D_aux:NNnNN #1 #2 {#3} \cs_set_protected:Npn
+      \@@_peek_nonspace_remove:NTF
+  }
+\cs_new_protected:Npn \@@_grab_D_obey_spaces:w #1#2#3 \@@_run_code:
+  {
+    \@@_grab_D_aux:NNnNN #1 #2 {#3} \cs_set_protected_nopar:Npn
+      \@@_peek_meaning_remove:NTF
+  }
+\cs_new_protected:Npn \@@_grab_D_long_obey_spaces:w #1#2#3 \@@_run_code:
+  {
+    \@@_grab_D_aux:NNnNN #1 #2 {#3} \cs_set_protected:Npn
+      \@@_peek_meaning_remove:NTF
+  }
+%    \end{macrocode}
+% \begin{macro}{\@@_grab_D_aux:NNnNN}
+% \begin{macro}{\@@_grab_D_aux:NNnN}
+%   This is a bit complicated. The idea is that, in order to check for
+%   nested optional argument tokens (\texttt{[[...]]} and so on) the
+%   argument needs to be grabbed without removing any braces at all. If
+%   this is not done, then cases like |[{[}]| fail. So after testing for
+%   an optional argument, it is collected piece-wise. Inserting a quark
+%   prevents loss of braces, and there is then a test to see if there are
+%   nested delimiters to handle.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_D_aux:NNnNN #1#2#3#4#5
+  {
+    \@@_grab_D_aux:NNnN #1#2 {#3} #4
+    #5 #1
+      { \@@_grab_D_call:Nw #1 }
+      { \@@_add_arg:o \c_novalue_tl }
+  }
+%    \end{macrocode}
+%   Inside the \enquote{standard} grabber, there is a test to see if the
+%   grabbed argument is entirely enclosed by braces. There are a couple of
+%   extra factors to allow for: the argument might be entirely empty, and
+%   spaces at the start and end of the input must be retained around a brace
+%   group. Also notice that a \emph{blank} argument might still contain
+%   spaces.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_D_aux:NNnN #1#2#3#4
+  {
+    \tl_set:Nn \l_@@_signature_tl {#3}
+    \exp_after:wN #4 \l_@@_fn_tl ##1 #2
+      {
+        \tl_if_in:nnTF {##1} {#1}
+          { \@@_grab_D_nested:NNnN #1 #2 {##1} #4 }
+          {
+            \tl_if_blank:oTF { \use_none:n ##1 }
+              { \@@_add_arg:o { \use_none:n ##1 } }
+              {
+                \str_if_eq:eeTF
+                  { \exp_not:o { \use_none:n ##1 } }
+                  { { \exp_not:o { \use_ii:nnn ##1 \q_nil } } }
+                  { \@@_add_arg:o { \use_ii:nn ##1 } }
+                  { \@@_add_arg:o { \use_none:n ##1 } }
+              }
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\@@_grab_D_nested:NNnN}
+% \begin{macro}{\@@_grab_D_nested:w}
+% \begin{macro}{\l_@@_nesting_a_tl}
+% \begin{macro}{\l_@@_nesting_b_tl}
+% \begin{macro}{\q_@@}
+%   Catching nested optional arguments means more work. The aim here is
+%   to collect up each pair of optional tokens without \TeX{} helping out,
+%   and without counting anything. The code above will already have
+%   removed the leading opening token and a closing token, but the
+%   wrong one. The aim is then to work through the material grabbed
+%   so far and divide it up on each opening token, grabbing a closing
+%   token to match (thus working in pairs). Once there are no opening
+%   tokens, then there is a second check to see if there are any
+%   opening tokens in the second part of the argument (for things
+%   like |[][]|). Once everything has been found, the entire collected
+%   material is added to the output as a single argument. The only tricky part
+%   here is ensuring that any grabbing function that might run away is named
+%   after the function currently being parsed and not after \pkg{xparse}. That
+%   leads to some rather complex nesting! There is also a need to prevent the
+%   loss of any braces, hence the insertion and removal of quarks along the
+%   way.
+%    \begin{macrocode}
+\tl_new:N \l_@@_nesting_a_tl
+\tl_new:N \l_@@_nesting_b_tl
+\quark_new:N \q_@@
+\cs_new_protected:Npn \@@_grab_D_nested:NNnN #1#2#3#4
+  {
+    \tl_clear:N \l_@@_nesting_a_tl
+    \tl_clear:N \l_@@_nesting_b_tl
+    \exp_after:wN #4 \l_@@_fn_tl ##1 #1 ##2 \q_@@ ##3 #2
+      {
+        \tl_put_right:No \l_@@_nesting_a_tl { \use_none:n ##1 #1 }
+        \tl_put_right:No \l_@@_nesting_b_tl { \use_i:nn #2 ##3 }
+        \tl_if_in:nnTF {##2} {#1}
+          {
+            \l_@@_fn_tl
+              \q_nil ##2 \q_@@ \ERROR
+          }
+          {
+            \tl_put_right:Nx \l_@@_nesting_a_tl
+              { \@@_grab_D_nested:w \q_nil ##2 \q_stop }
+            \tl_if_in:NnTF \l_@@_nesting_b_tl {#1}
+              {
+                \tl_set_eq:NN \l_@@_tmpa_tl \l_@@_nesting_b_tl
+                \tl_clear:N \l_@@_nesting_b_tl
+                \exp_after:wN \l_@@_fn_tl \exp_after:wN
+                  \q_nil \l_@@_tmpa_tl \q_nil \q_@@ \ERROR
+              }
+              {
+                \tl_put_right:No \l_@@_nesting_a_tl
+                  \l_@@_nesting_b_tl
+                \@@_add_arg:V \l_@@_nesting_a_tl
+              }
+          }
+      }
+    \l_@@_fn_tl #3 \q_nil \q_@@ \ERROR
+  }
+\cs_new:Npn \@@_grab_D_nested:w #1 \q_nil \q_stop
+  { \exp_not:o { \use_none:n #1 } }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\@@_grab_D_call:Nw}
+%   For \texttt{D} and \texttt{R}-type arguments, to avoid losing any
+%   braces, a token needs to be inserted before the argument to be grabbed.
+%   If the argument runs away because the closing token is missing then this
+%   inserted token shows up in the terminal. Ideally, |#1| would therefore be
+%   used directly, but that is no good as it will mess up the rest of the
+%   grabber. Instead, a copy of |#1| with an altered category code is used,
+%   as this will look right in the terminal but will not mess up the grabber.
+%   The only issue then is that the category code of |#1| is unknown. So there
+%   is a quick test to ensure that the inserted token can never be matched by
+%   the grabber. (This assumes that the open and close delimiters are not the
+%   same character with different category codes, but that really should not
+%   happen in any sensible document-level syntax.)
+%   An exception is when |#1| is a control sequence token, in which case the
+%   character-token treatment is no good because if hit with \cs{token_to_str:N}
+%   it would add sputios tokens to the argument. In this case a different
+%   branch is taken. The token inserted is then the same \meta{csname} as |#1|,
+%   but with a space appended, so that the grabber don't see it as another
+%   of the same delimiter.
+%    \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_grab_D_call:Nw #1
+  {
+    \token_if_eq_catcode:NNTF + #1
+      {
+        \exp_after:wN \exp_after:wN \exp_after:wN
+          \l_@@_fn_tl \char_generate:nn { `#1 } { 11 }
+      }
+      {
+        \@@_token_if_cs:NTF #1
+          {
+            \exp_after:wN \l_@@_fn_tl
+            \cs:w \cs_to_str:N #1 ~ \cs_end:
+          }
+          {
+            \exp_after:wN \l_@@_fn_tl
+            \token_to_str:N #1
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}
+%   {
+%     \@@_grab_E:w, \@@_grab_E_long:w,
+%     \@@_grab_E_obey_spaces:w, \@@_grab_E_long_obey_spaces:w
+%   }
+% \begin{macro}{\@@_grab_E:nnNN}
+% \begin{macro}{\@@_grab_E_loop:NnN}
+% \begin{macro}{\@@_grab_E_finalise:}
+%   Everything here needs to point to a loop.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_E:w #1#2 \@@_run_code:
+  {
+    \@@_grab_E:nnNN {#1} {#2}
+      \cs_set_protected_nopar:Npn
+      \@@_peek_nonspace_remove:NTF
+  }
+\cs_new_protected:Npn \@@_grab_E_long:w #1#2 \@@_run_code:
+  {
+    \@@_grab_E:nnNN {#1} {#2}
+      \cs_set_protected:Npn
+      \@@_peek_nonspace_remove:NTF
+  }
+\cs_new_protected:Npn \@@_grab_E_obey_spaces:w #1#2 \@@_run_code:
+  {
+    \@@_grab_E:nnNN {#1} {#2}
+      \cs_set_protected_nopar:Npn
+      \@@_peek_meaning_remove:NTF
+  }
+\cs_new_protected:Npn \@@_grab_E_long_obey_spaces:w #1#2 \@@_run_code:
+  {
+    \@@_grab_E:nnNN {#1} {#2}
+      \cs_set_protected:Npn
+      \@@_peek_meaning_remove:NTF
+  }
+%    \end{macrocode}
+%   A loop is needed here to allow a random ordering of keys. These are
+%   searched for one at a time, with any not found needing to be tracked:
+%   they can appear later. The grabbed values are held in a property list
+%   which is then turned into an ordered list to be passed back to the user.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_E:nnNN #1#2#3#4
+  {
+    \exp_after:wN #3 \l_@@_fn_tl ##1##2##3
+      {
+        \prop_put:Nnn \l_@@_tmp_prop {##1} {##3}
+        \@@_grab_E_loop:NnN #4 { } ##2 \q_recursion_stop
+      }
+    \prop_clear:N \l_@@_tmp_prop
+    \tl_set:Nn \l_@@_signature_tl {#2}
+    \cs_set_protected:Npn \@@_grab_E_finalise:
+      {
+        \tl_map_inline:nn {#1}
+          {
+            \prop_get:NnNF \l_@@_tmp_prop {####1} \l_@@_tmpb_tl
+              { \tl_set_eq:NN \l_@@_tmpb_tl \c_novalue_tl }
+            \tl_put_right:Nx \l_@@_args_tl
+              { { \exp_not:V \l_@@_tmpb_tl } }
+          }
+        \l_@@_signature_tl \@@_run_code:
+      }
+    \@@_grab_E_loop:NnN #4 { } #1 \q_recursion_tail \q_recursion_stop
+  }
+\cs_new_protected:Npn \@@_grab_E_loop:NnN #1#2#3#4 \q_recursion_stop
+  {
+    \cs_if_eq:NNTF #3 \q_recursion_tail
+      { \@@_grab_E_finalise: }
+      {
+        #1 #3
+          { \l_@@_fn_tl #3 {#2#4} }
+          { \@@_grab_E_loop:NnN #1 {#2#3} #4 \q_recursion_stop }
+      }
+  }
+\cs_new_protected:Npn \@@_grab_E_finalise: { }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_grab_m:w}
+% \begin{macro}{\@@_grab_m_long:w}
+%   Collecting a single mandatory argument is quite easy.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_m:w #1 \@@_run_code:
+  {
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN \cs_set_protected_nopar:Npn \l_@@_fn_tl ##1
+      { \@@_add_arg:n {##1} }
+    \l_@@_fn_tl
+  }
+\cs_new_protected:Npn \@@_grab_m_long:w #1 \@@_run_code:
+  {
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN \cs_set_protected:Npn \l_@@_fn_tl ##1
+      { \@@_add_arg:n {##1} }
+    \l_@@_fn_tl
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_grab_m_1:w}
+% \begin{macro}{\@@_grab_m_2:w}
+% \begin{macro}{\@@_grab_m_3:w}
+% \begin{macro}{\@@_grab_m_4:w}
+% \begin{macro}{\@@_grab_m_5:w}
+% \begin{macro}{\@@_grab_m_6:w}
+% \begin{macro}{\@@_grab_m_7:w}
+% \begin{macro}{\@@_grab_m_8:w}
+% \begin{macro}{\@@_grab_m_9:w}
+% \begin{macro}{\@@_grab_m_aux:Nnnnnnnnn}
+%   Grabbing 1--8 mandatory arguments is done by giving 8--1 known
+%   arguments to a 9-argument function that stores them in
+%   \cs{l_@@_args_tl}.  For simplicity, grabbing 9 mandatory arguments
+%   is done by grabbing 5 then 4 arguments.
+%    \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_grab_m_aux:Nnnnnnnnn #1#2#3#4#5#6#7#8#9
+  {
+    \tl_put_right:No \l_@@_args_tl
+      { #1 {#2} {#3} {#4} {#5} {#6} {#7} {#8} {#9} }
+    \l_@@_signature_tl \@@_run_code:
+  }
+\cs_new_protected:cpn { @@_grab_m_1:w } #1 \@@_run_code:
+  {
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn
+    \l_@@_fn_tl \use_none:nnnnnnn { } { } { } { } { } { } { }
+  }
+\cs_new_protected:cpn { @@_grab_m_2:w } #1 \@@_run_code:
+  {
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn
+    \l_@@_fn_tl \use_none:nnnnnn { } { } { } { } { } { }
+  }
+\cs_new_protected:cpn { @@_grab_m_3:w } #1 \@@_run_code:
+  {
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn
+    \l_@@_fn_tl \use_none:nnnnn { } { } { } { } { }
+  }
+\cs_new_protected:cpn { @@_grab_m_4:w } #1 \@@_run_code:
+  {
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn
+    \l_@@_fn_tl \use_none:nnnn { } { } { } { }
+  }
+\cs_new_protected:cpn { @@_grab_m_5:w } #1 \@@_run_code:
+  {
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn
+    \l_@@_fn_tl \use_none:nnn { } { } { }
+  }
+\cs_new_protected:cpn { @@_grab_m_6:w } #1 \@@_run_code:
+  {
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn
+    \l_@@_fn_tl \use_none:nn { } { }
+  }
+\cs_new_protected:cpn { @@_grab_m_7:w } #1 \@@_run_code:
+  {
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn
+    \l_@@_fn_tl \use_none:n { }
+  }
+\cs_new_protected:cpn { @@_grab_m_8:w } #1 \@@_run_code:
+  {
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l_@@_fn_tl \@@_grab_m_aux:Nnnnnnnnn
+    \l_@@_fn_tl \prg_do_nothing:
+  }
+\cs_new_protected:cpx { @@_grab_m_9:w }
+  {
+    \exp_not:c { @@_grab_m_5:w }
+    \exp_not:c { @@_grab_m_4:w }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_grab_R:w, \@@_grab_R_long:w}
+% \begin{macro}{\@@_grab_R_aux:NNnN}
+%  The grabber for \texttt{R}-type arguments is basically the same as
+%  that for \texttt{D}-type ones, but always skips spaces (as it is mandatory)
+%  and has a hard-coded error message.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_R:w #1#2#3 \@@_run_code:
+  { \@@_grab_R_aux:NNnN #1 #2 {#3} \cs_set_protected_nopar:Npn }
+\cs_new_protected:Npn \@@_grab_R_long:w #1#2#3 \@@_run_code:
+  { \@@_grab_R_aux:NNnN #1 #2 {#3} \cs_set_protected:Npn }
+\cs_new_protected:Npn \@@_grab_R_aux:NNnN #1#2#3#4
+  {
+    \@@_grab_D_aux:NNnN #1 #2 {#3} #4
+    \@@_peek_nonspace_remove:NTF #1
+      { \@@_grab_D_call:Nw #1 }
+      {
+        \msg_error:nnxx { cmd } { missing-required }
+          { \@@_environment_or_command: }
+          { \token_to_str:N #1 }
+        \@@_add_arg:o \c_novalue_tl
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_grab_t:w}
+% \begin{macro}{\@@_grab_t_obey_spaces:w}
+% \begin{macro}{\@@_grab_t_aux:NNw}
+%   Dealing with a token is quite easy. Check the match, remove the
+%   token if needed and add a flag to the output.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_t:w
+  { \@@_grab_t_aux:NNw \@@_peek_nonspace_remove:NTF }
+\cs_new_protected:Npn \@@_grab_t_obey_spaces:w
+  { \@@_grab_t_aux:NNw \@@_peek_meaning_remove:NTF }
+\cs_new_protected:Npn \@@_grab_t_aux:NNw #1#2#3 \@@_run_code:
+  {
+    \tl_set:Nn \l_@@_signature_tl {#3}
+    \exp_after:wN \cs_set_protected:Npn \l_@@_fn_tl
+      {
+        #1 #2
+          { \@@_add_arg:n { \BooleanTrue } }
+          { \@@_add_arg:n { \BooleanFalse } }
+      }
+    \l_@@_fn_tl
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_v_arg_tl}
+%    \begin{macrocode}
+\tl_new:N \l_@@_v_arg_tl
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_grab_v:w}
+% \begin{macro}{\@@_grab_v_long:w}
+% \begin{macro}{\@@_grab_v_aux:w}
+% \begin{macro}{\@@_grab_v_group_end:}
+%   The opening delimiter is the first non-space token, and is never
+%   read verbatim.  This is required by consistency with the case where
+%   the preceding argument was optional and absent: then \TeX{} has
+%   already read and tokenized that token when looking for the optional
+%   argument.  The first thing is thus to check is that this delimiter
+%   is a character, and to distinguish the case of a left brace (in that
+%   case, \cs{group_align_safe_end:} is needed to compensate for the
+%   begin-group character that was just seen).  Then set verbatim
+%   catcodes with \cs{@@_grab_v_aux_catcodes:}.
+%
+%   The group keep catcode changes local, and
+%   \cs{group_align_safe_begin/end:} allow to use a character
+%   with category code~$4$ (normally |&|) as the delimiter (all commands
+%   do \cs{group_align_safe_begin/end:}, so there's no need to do that
+%   again here).
+%   It is ended by \cs{@@_grab_v_group_end:}, which smuggles
+%   the collected argument out of the group.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_v:w
+  {
+    \bool_set_false:N \l_@@_long_bool
+    \@@_grab_v_aux:w
+  }
+\cs_new_protected:Npn \@@_grab_v_long:w
+  {
+    \bool_set_true:N \l_@@_long_bool
+    \@@_grab_v_aux:w
+  }
+\cs_new_protected:Npn \@@_grab_v_aux:w #1 \@@_run_code:
+  {
+    \tl_set:Nn \l_@@_signature_tl {#1}
+    \group_begin:
+      \tex_escapechar:D = 92 \scan_stop:
+      \tl_clear:N \l_@@_v_arg_tl
+      \peek_remove_spaces:n
+        {
+          \peek_meaning_remove:NTF \c_group_begin_token
+            {
+              \group_align_safe_end:
+              \@@_grab_v_bgroup:
+            }
+            {
+              \peek_N_type:TF
+                { \@@_grab_v_aux_test:N }
+                { \@@_grab_v_aux_abort:n { } }
+            }
+        }
+  }
+\cs_new_protected:Npn \@@_grab_v_group_end:
+  {
+        \exp_args:NNNo
+      \group_end:
+    \tl_set:Nn \l_@@_v_arg_tl { \l_@@_v_arg_tl }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_grab_v_aux_test:N}
+% \begin{macro}
+%   {
+%     \@@_grab_v_aux_loop:N,
+%     \@@_grab_v_aux_loop:NN,
+%     \@@_grab_v_aux_loop_end:
+%   }
+%   Check that the opening delimiter is a character, setup category codes,
+%   then start reading tokens one by one, keeping the delimiter as an argument.
+%   If the verbatim was not nested, we will be grabbing one character
+%   at each step. Unfortunately, it can happen that what follows the
+%   verbatim argument is already tokenized. Thus, we check at each step
+%   that the next token is indeed a \enquote{nice}
+%   character, \emph{i.e.}, is not a character with
+%   category code $1$ (begin-group), $2$ (end-group)
+%   or $6$ (macro parameter), nor the space character,
+%   with category code~$10$ and character code~$32$,
+%   nor a control sequence.
+%   The partially built argument is stored in \cs{l_@@_v_arg_tl}.
+%   If we ever meet a token which we cannot grab (non-N-type),
+%   or which is not a character according to
+%   \cs{@@_grab_v_token_if_char:NTF}, then we bail out with
+%   \cs{@@_grab_v_aux_abort:n}. Otherwise, we stop at the first
+%   character matching the delimiter.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_v_aux_test:N #1
+  {
+    \@@_grab_v_token_if_char:NTF #1
+      {
+        \@@_grab_v_aux_put:N #1
+        \@@_grab_v_aux_catcodes:
+        \@@_grab_v_aux_loop:N #1
+      }
+      { \@@_grab_v_aux_abort:n {#1} #1 }
+  }
+\cs_new_protected:Npn \@@_grab_v_aux_loop:N #1
+  {
+    \peek_N_type:TF
+      { \@@_grab_v_aux_loop:NN #1 }
+      { \@@_grab_v_aux_abort:n { } }
+  }
+\cs_new_protected:Npn \@@_grab_v_aux_loop:NN #1#2
+  {
+    \@@_grab_v_token_if_char:NTF #2
+      {
+        \token_if_eq_charcode:NNTF #1 #2
+          { \@@_grab_v_aux_loop_end: }
+          {
+            \@@_grab_v_aux_put:N #2
+            \@@_grab_v_aux_loop:N #1
+          }
+      }
+      { \@@_grab_v_aux_abort:n {#2} #2 }
+  }
+\cs_new_protected:Npn \@@_grab_v_aux_loop_end:
+  {
+    \@@_grab_v_group_end:
+    \@@_add_arg:x { \tl_tail:N \l_@@_v_arg_tl }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_v_nesting_int}
+%    \begin{macrocode}
+\int_new:N \l_@@_v_nesting_int
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_grab_v_bgroup:}
+% \begin{macro}{\@@_grab_v_bgroup_loop:}
+% \begin{macro}{\@@_grab_v_bgroup_loop:N}
+%   If the opening delimiter is a left brace, we keep track of
+%   how many left and right braces were encountered so far in
+%   \cs{l_@@_v_nesting_int} (the methods used for optional
+%   arguments cannot apply here), and stop as soon as it reaches~$0$.
+%
+%   Some care was needed when removing the opening delimiter, which
+%   has already been assigned category code~$1$: using
+%   \cs{peek_meaning_remove:NTF} in the \cs{@@_grab_v_aux:w}
+%   function would break within alignments. Instead, we first
+%   convert that token to a string, and remove the result as a
+%   normal undelimited argument.
+%    \begin{macrocode}
+\cs_new_protected:Npx \@@_grab_v_bgroup:
+  {
+    \exp_not:N \@@_grab_v_aux_catcodes:
+    \exp_not:n { \int_set:Nn \l_@@_v_nesting_int { 1 } }
+    \exp_not:N \@@_grab_v_aux_put:N \iow_char:N \{
+    \exp_not:N \@@_grab_v_bgroup_loop:
+  }
+\cs_new_protected:Npn \@@_grab_v_bgroup_loop:
+  {
+    \peek_N_type:TF
+      { \@@_grab_v_bgroup_loop:N }
+      { \@@_grab_v_aux_abort:n { } }
+  }
+\cs_new_protected:Npn \@@_grab_v_bgroup_loop:N #1
+  {
+    \@@_grab_v_token_if_char:NTF #1
+      {
+        \token_if_eq_charcode:NNTF \c_group_end_token #1
+          {
+            \int_decr:N \l_@@_v_nesting_int
+            \int_compare:nNnTF \l_@@_v_nesting_int > 0
+              {
+                \@@_grab_v_aux_put:N #1
+                \@@_grab_v_bgroup_loop:
+              }
+              { \@@_grab_v_aux_loop_end: }
+          }
+          {
+            \token_if_eq_charcode:NNT \c_group_begin_token #1
+              { \int_incr:N \l_@@_v_nesting_int }
+            \@@_grab_v_aux_put:N #1
+            \@@_grab_v_bgroup_loop:
+          }
+      }
+      { \@@_grab_v_aux_abort:n {#1} #1 }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_grab_v_aux_catcodes:}
+% \begin{macro}{\@@_grab_v_aux_abort:n}
+%   The approach for short verbatim arguments is to make the end-line
+%   character a macro parameter character: this is forbidden by the
+%   rest of the code. Then the error branch can check what caused the
+%   bail out and give the appropriate error message.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_v_aux_catcodes:
+  {
+    \cs_set_eq:NN \do \char_set_catcode_other:N
+    \dospecials
+    \tex_endlinechar:D = `\^^M \scan_stop:
+    \bool_if:NTF \l_@@_long_bool
+      { \char_set_catcode_other:n { \tex_endlinechar:D } }
+      { \char_set_catcode_parameter:n { \tex_endlinechar:D } }
+  }
+\cs_new_protected:Npn \@@_grab_v_aux_abort:n #1
+  {
+    \@@_grab_v_group_end:
+    \exp_after:wN \exp_after:wN \exp_after:wN
+      \peek_meaning_remove:NTF \char_generate:nn { \tex_endlinechar:D } { 6 }
+      {
+        \msg_error:nnxxx { cmd } { verbatim-newline }
+          { \@@_environment_or_command: }
+          { \tl_to_str:N \l_@@_v_arg_tl }
+          { \tl_to_str:n {#1} }
+        \@@_add_arg:o \c_novalue_tl
+      }
+      {
+        \msg_error:nnxxx { cmd } { verbatim-tokenized }
+          { \@@_environment_or_command: }
+          { \tl_to_str:N \l_@@_v_arg_tl }
+          { \tl_to_str:n {#1} }
+        \@@_add_arg:o \c_novalue_tl
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_grab_v_aux_put:N}
+%   Storing one token in the collected argument. Most tokens are
+%   converted to category code $12$, with the exception of active
+%   characters, and spaces (not sure what should be done for those).
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_v_aux_put:N #1
+  {
+    \tl_put_right:Nx \l_@@_v_arg_tl
+      {
+        \token_if_active:NTF #1
+          { \exp_not:N #1 } { \token_to_str:N #1 }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_grab_v_token_if_char:NTF}
+%   This function assumes that the escape character is printable.
+%   Then the string representation of control sequences is at least
+%   two characters, and \cs{str_tail:n} only removes the escape
+%   character. Macro parameter characters are doubled by
+%   \cs{tl_to_str:n}, and will also yield a non-empty result,
+%   hence are not considered as characters.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_v_token_if_char:NTF #1
+  { \str_if_eq:eeTF { } { \str_tail:n {#1} } }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_arg:n, \@@_add_arg:V, \@@_add_arg:o, \@@_add_arg:x}
+%   When an argument is found it is stored, then further arguments are
+%   grabbed by calling \cs{l_@@_signature_tl}.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_add_arg:n #1
+  {
+    \tl_put_right:Nn \l_@@_args_tl { {#1} }
+    \l_@@_signature_tl \@@_run_code:
+  }
+\cs_generate_variant:Nn \@@_add_arg:n { V , o , x }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Grabbing arguments expandably}
+%
+% \begin{macro}[EXP]{\@@_expandable_grab_D:w}
+% \begin{macro}[EXP]{\@@_expandable_grab_D:NNNwNNn}
+% \begin{macro}[EXP]{\@@_expandable_grab_D:NNNwNNnnn}
+% \begin{macro}[EXP]{\@@_expandable_grab_D:Nw}
+% \begin{macro}[EXP]{\@@_expandable_grab_D:nnNNNwNN}
+%   The first step is to grab the first token or group. The generic grabbers
+%   \cs{\meta{function}}\verb*| | and \cs{\meta{function}}\verb*| | are just after \cs{q_@@}, we go and find
+%   them (and use the long one).
+%    \begin{macrocode}
+\cs_new:Npn \@@_expandable_grab_D:w #1 \q_@@ #2#3
+  { #2 { \@@_expandable_grab_D:NNNwNNn #1 \q_@@ #2 #3 } }
+%    \end{macrocode}
+%   We then wish to test whether |#7|, which we just grabbed, is exactly |#2|.
+%   A preliminary test is whether their string representations coincide, then
+%   expand the only grabber function we have, |#1|, once: the two strings below
+%   are equal if and only if |#7| matches |#2| exactly.\footnote{It is obvious
+%   that if \texttt{\#7} matches \texttt{\#2} then the strings are equal. We
+%   must check the converse. The right-hand-side of \cs{str_if_eq:onTF} does
+%   not end with \texttt{\#3}, implying that the grabber function took
+%   everything as its arguments. The first brace group can only be empty if
+%   \texttt{\#7} starts with \texttt{\#2}, otherwise the brace group preceding
+%   \texttt{\#7} would not vanish. The third brace group is empty, thus the
+%   \cs{q_@@} that was used by our grabber \texttt{\#1} must be the one
+%   that we inserted (not some token in \texttt{\#7}), hence the second brace
+%   group contains the end of \texttt{\#7} followed by \texttt{\#2}. Since this
+%   is \texttt{\#2} on the right-hand-side, and no brace can be lost there,
+%   \texttt{\#7} must contain nothing else than its leading \texttt{\#2}.}
+%   The preliminary test is needed as |#7| could validly contain
+%   \tn{par} (because a later mandatory argument could be long) and our
+%   grabber may be short.  If
+%   |#7| does not match |#2|, then the optional argument is missing, we use the
+%   default |-NoValue-|, and put back the argument |#7| in the input stream.
+%
+%   If it does match, then interesting things need to be done. We will grab the
+%   argument piece by piece, with the following pattern:
+%   \begin{quote}
+%     \meta{grabber} \Arg{tokens} \\
+%     ~~\cs{q_nil} \Arg{piece 1} \meta{piece 2} \cs{ERROR} \cs{q_@@}\\
+%     ~~\cs{q_nil} \meta{input stream}
+%   \end{quote}
+%   The \meta{grabber} will find an opening delimiter in \meta{piece 2}, take
+%   the \cs{q_@@} as a second delimiter, and find more material delimited
+%   by the closing delimiter in the \meta{input stream}. We then move the part
+%   before the opening delimiter from \meta{piece 2} to \meta{piece 1}, and the
+%   material taken from the \meta{input stream} to the \meta{piece 2}. Thus,
+%   the argument moves gradually from the \meta{input stream} to the
+%   \meta{piece 2}, then to the \meta{piece 1} when we have made sure to find
+%   all opening and closing delimiters. This two-step process ensures that
+%   nesting works: the number of opening delimiters minus closing delimiters in
+%   \meta{piece 1} is always equal to the number of closing delimiters in
+%   \meta{piece 2}. We stop grabbing arguments once the \meta{piece 2} contains
+%   no opening delimiter any more, hence the balance is reached, and the final
+%   argument is \meta{piece 1} \meta{piece 2}.
+%   The indirection via \cs{@@_tmp:w} allows to insert |-NoValue-| expanded.
+%    \begin{macrocode}
+\cs_set_protected:Npn \@@_tmp:w #1
+  {
+    \cs_new:Npn \@@_expandable_grab_D:NNNwNNn ##1##2##3##4 \q_@@ ##5##6##7
+      {
+        \str_if_eq:nnTF {##2} {##7}
+          {
+            \str_if_eq:onTF
+              { ##1 { } { } ##7 ##2 \q_@@ ##3 }
+              { { } {##2} { } }
+          }
+          { \use_ii:nn }
+          {
+            ##1
+              { \@@_expandable_grab_D:NNNwNNnnn ##1##2##3##4 \q_@@ ##5##6 }
+              \q_nil { } ##2 \ERROR \q_@@ \ERROR
+          }
+          { ##4 {#1} \q_@@ ##5 ##6 {##7} }
+      }
+  }
+\exp_args:No \@@_tmp:w { \c_novalue_tl }
+%    \end{macrocode}
+%   At this stage, |#7| is \cs{q_nil} \Arg{piece 1} \meta{more for piece 1},
+%   and we want to concatenate all that, removing \cs{q_nil}, and keeping the
+%   opening delimiter |#2|. Simply use \cs{use_ii:nn}. Also, |#8| is
+%   \meta{remainder of piece 2} \cs{ERROR}, and |#9| is \cs{ERROR} \meta{more
+%   for piece 2}. We concatenate those, replacing the two \cs{ERROR} by the
+%   closing delimiter |#3|.
+%    \begin{macrocode}
+\cs_new:Npn \@@_expandable_grab_D:NNNwNNnnn #1#2#3#4 \q_@@ #5#6#7#8#9
+  {
+    \exp_args:Nof \@@_expandable_grab_D:nnNNNwNN
+      { \use_ii:nn #7 #2 }
+      { \@@_expandable_grab_D:Nw #3 \exp_stop_f: #8 #9 }
+    #1#2#3 #4 \q_@@ #5 #6
+  }
+\cs_new:Npn \@@_expandable_grab_D:Nw #1#2 \ERROR \ERROR { #2 #1 }
+%    \end{macrocode}
+%   Armed with our two new \meta{pieces}, we are ready to loop. However, we
+%   must first see if \meta{piece 2} (here |#2|) contains any opening
+%   delimiter |#4|. Again, we expand |#3|, this time removing its whole output
+%   with \cs{use_none:nnn}. The test is similar to \cs{tl_if_in:nnTF}. The
+%   token list is empty if and only if |#2| does not contain the opening
+%   delimiter. In that case, we are done, and put the argument (from which we
+%   remove a spurious pair of delimiters coming from how we started the loop).
+%   Otherwise, we go back to looping with
+%   \cs{@@_expandable_grab_D:NNNwNNnnn}. The code to deal with brace stripping
+%   is much the same as for the non-expandable case.
+%    \begin{macrocode}
+\cs_new:Npn \@@_expandable_grab_D:nnNNNwNN #1#2#3#4#5#6 \q_@@ #7#8
+  {
+    \exp_args:No \tl_if_empty:oTF
+      { #3 { \use_none:nnn } #2 \q_@@ #5 #4 \q_@@ #5 }
+      {
+        \tl_if_blank:oTF { \use_none:nn #1#2 }
+          { \@@_put_arg_expandable:ow { \use_none:nn #1#2 } }
+          {
+            \str_if_eq:eeTF
+              { \exp_not:o { \use_none:nn #1#2 } }
+              { { \exp_not:o { \use_iii:nnnn #1#2 \q_nil } } }
+              { \@@_put_arg_expandable:ow { \use_iii:nnn #1#2 } }
+              { \@@_put_arg_expandable:ow { \use_none:nn #1#2 } }
+          }
+            #6 \q_@@ #7 #8
+      }
+      {
+        #3
+          { \@@_expandable_grab_D:NNNwNNnnn #3#4#5#6 \q_@@ #7 #8 }
+          \q_nil {#1} #2 \ERROR \q_@@ \ERROR
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_expandable_grab_D_alt:w}
+% \begin{macro}[EXP]{\@@_expandable_grab_D_alt:NNwNNn}
+% \begin{macro}[EXP]{\@@_expandable_grab_D_alt:Nwn}
+%   When the delimiters are identical, nesting is not possible and a simplified
+%   approach is used. The test concept here is the same as for the case where
+%   the delimiters are different but there cannot be any nesting.
+%    \begin{macrocode}
+\cs_new:Npn \@@_expandable_grab_D_alt:w #1 \q_@@ #2#3
+  { #2 { \@@_expandable_grab_D_alt:NNwNNn #1 \q_@@ #2 #3 } }
+\cs_set_protected:Npn \@@_tmp:w #1
+  {
+    \cs_new:Npn \@@_expandable_grab_D_alt:NNwNNn ##1##2##3 \q_@@ ##4##5##6
+      {
+        \str_if_eq:nnTF {##6} {##2}
+          {
+            \str_if_eq:onTF
+              { ##1 { } ##6 ##2 ##2 }
+              { { } ##2 }
+          }
+          { \use_ii:nn }
+          {
+            ##1
+              { \@@_expandable_grab_D_alt:NNwn ##4 ##5 ##3 \q_@@ }
+              ##6 \ERROR
+          }
+          { ##3 {#1} \q_@@ ##4 ##5 {##6} }
+      }
+  }
+\exp_args:No \@@_tmp:w { \c_novalue_tl }
+\cs_new:Npn \@@_expandable_grab_D_alt:NNwn #1#2#3 \q_@@ #4
+  {
+    \tl_if_blank:oTF { \use_none:n #4 }
+      { \@@_put_arg_expandable:ow { \use_none:n #4 } }
+      {
+        \str_if_eq:eeTF
+          { \exp_not:o { \use_none:n #4 } }
+          { { \exp_not:o { \use_ii:nnn #4 \q_nil } } }
+          { \@@_put_arg_expandable:ow { \use_ii:nn #4 } }
+          { \@@_put_arg_expandable:ow { \use_none:n #4 } }
+      }
+        #3 \q_@@ #1 #2
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_expandable_grab_E:w, \@@_expandable_grab_E_long:w}
+% \begin{macro}[EXP]{\@@_expandable_grab_E_aux:w}
+% \begin{macro}[EXP]{\@@_expandable_grab_E_test:nnw}
+% \begin{macro}[EXP]{\@@_expandable_grab_E_loop:nnnNNw}
+% \begin{macro}[EXP]{\@@_expandable_grab_E_find:w}
+% \begin{macro}[EXP]{\@@_expandable_grab_E_find:nnw}
+% \begin{macro}[EXP]{\@@_expandable_grab_E_end:nnw}
+%   We keep track of long/short by placing the appropriate grabber as
+%   the third token after \cs{q_@@}; it is eventually removed by the
+%   \texttt{end:nnw} auxiliary.  The \texttt{aux:w} auxiliary will be
+%   called repeatedly with two arguments: the set
+%   of pairs \meta{parser} \meta{token}, and the set of arguments found
+%   so far (initially all |{-NoValue-}|).  At each step, grab what
+%   follows in the input stream then call the \texttt{loop:nnnNNw}
+%   auxiliary to compare it with each possible embellishment in turn.
+%   This auxiliary's |#1| is what was found in the input, |#2| collects
+%   \meta{parser} \meta{token} pairs that did not match, |#3| collects
+%   the corresponding arguments found previously, |#4| and |#5| is the
+%   current pair, |#6| is the remaining pairs, |#7| is empty or two
+%   \cs{q_nil}, and |#8| is the current argument.  If none of the pairs
+%   matched (determined by \cs{quark_if_nil:NTF}) then call the
+%   \texttt{end} auxiliary to stop looking for embellishments,
+%   remembering to put what was grabbed in the input back where it
+%   belongs, and storing the arguments found just before \cs{q_@@}.  If
+%   the current argument |#8| is not |-NoValue-| or if the input |#1|
+%   does not match |#5| (see \texttt{t}-type arguments below for a
+%   similar \cs{str_if_eq:onTF} test) then carry on the loop.
+%   Otherwise, we found a new embellishment: grab the corresponding
+%   argument in the input using the \texttt{find:w} auxiliary.  To avoid
+%   losing braces around that auxiliary's argument we include a
+%   space, which will be eliminated in the next loop through
+%   embellishments.
+%    \begin{macrocode}
+\cs_new:Npn \@@_expandable_grab_E:w #1 \q_@@ #2#3
+  { \@@_expandable_grab_E_aux:w #1 \q_@@ #2 #3 #3 }
+\cs_new:Npn \@@_expandable_grab_E_long:w #1 \q_@@ #2#3
+  { \@@_expandable_grab_E_aux:w #1 \q_@@ #2 #3 #2 }
+\cs_new:Npn \@@_expandable_grab_E_aux:w #1 \q_@@ #2#3#4
+  { #2 { \@@_expandable_grab_E_test:nnw #1 \q_@@ #2 #3 #4 } }
+\cs_new:Npn \@@_expandable_grab_E_test:nnw #1#2#3 \q_@@ #4#5#6#7
+  {
+    \@@_expandable_grab_E_loop:nnnNNw {#7} { } { }
+      #1 \q_nil \q_nil \q_nil \q_mark #2 \q_nil
+    #3 \q_@@ #4 #5 #6
+  }
+\cs_new:Npn \@@_expandable_grab_E_loop:nnnNNw
+    #1#2#3#4#5#6 \q_nil #7 \q_mark #8
+  {
+    \quark_if_nil:NTF #4
+      { \@@_expandable_grab_E_end:nnw {#1} {#3} }
+      {
+        \tl_if_novalue:nTF {#8}
+          { \str_if_eq:onTF { #4 { } #1 #5 } {#5} }
+          { \use_ii:nn }
+            { \@@_expandable_grab_E_find:w { #2 #4 #5 #6 } {#3} ~ }
+            {
+              \@@_expandable_grab_E_loop:nnnNNw
+                {#1} { #2 #4 #5 } { #3 {#8} }
+                #6 \q_nil #7 \q_mark
+            }
+      }
+  }
+\cs_new:Npn \@@_expandable_grab_E_find:w #1 \q_@@ #2#3#4
+  { #4 { \@@_expandable_grab_E_find:nnw #1 \q_@@ #2 #3 #4 } }
+\cs_new:Npn \@@_expandable_grab_E_find:nnw #1#2#3 \q_nil #4 \q_@@ #5#6#7#8
+  { \@@_expandable_grab_E_aux:w {#1} { #2 {#8} #3 } #4 \q_@@ #5 #6 #7 }
+\cs_new:Npn \@@_expandable_grab_E_end:nnw #1#2#3 \q_@@ #4#5#6
+  { #3 #2 \q_@@ #4 #5 {#1} }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_expandable_grab_m:w, \@@_expandable_grab_m_long:w}
+% \begin{macro}[EXP]{\@@_expandable_grab_m_aux:wNn}
+%   The mandatory case is easy: find the auxiliary after the \cs{q_@@},
+%   and use it directly to grab the argument, then correctly position
+%   the argument before \cs{q_@@}.
+%    \begin{macrocode}
+\cs_new:Npn \@@_expandable_grab_m:w #1 \q_@@ #2#3
+  { #3 { \@@_expandable_grab_m_aux:wNn #1 \q_@@ #2 #3 } }
+\cs_new:Npn \@@_expandable_grab_m_long:w #1 \q_@@ #2#3
+  { #2 { \@@_expandable_grab_m_aux:wNn #1 \q_@@ #2 #3 } }
+\cs_new:Npn \@@_expandable_grab_m_aux:wNn #1 \q_@@ #2#3#4
+  { #1 {#4} \q_@@ #2 #3 }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_expandable_grab_R:w}
+% \begin{macro}[EXP]{\@@_expandable_grab_R_aux:NNNwNNn}
+%   Much the same as for the \texttt{D}-type argument, with only the lead-off
+%   function varying.
+%    \begin{macrocode}
+\cs_new:Npn \@@_expandable_grab_R:w #1 \q_@@ #2#3
+  { #2 { \@@_expandable_grab_R_aux:NNNwNNn #1 \q_@@ #2#3 } }
+\cs_set_protected:Npn \@@_tmp:w #1
+  {
+    \cs_new:Npn \@@_expandable_grab_R_aux:NNNwNNn ##1##2##3##4 \q_@@ ##5##6##7
+      {
+        \str_if_eq:nnTF {##7} {##2}
+          {
+            \str_if_eq:onTF
+              { ##1 { } { } ##7 ##2 \q_@@ ##3 }
+              { { } {##2} { } }
+          }
+          { \use_ii:nn }
+          {
+            ##1
+              { \@@_expandable_grab_D:NNNwNNnnn ##1##2##3##4 \q_@@ ##5##6 }
+              \q_nil { } ##2 \ERROR \q_@@ \ERROR
+          }
+          {
+            \msg_expandable_error:nnff { cmd } { missing-required }
+              { \exp_args:Nf \tl_trim_spaces:n { \token_to_str:N ##5 } }
+              { \tl_to_str:n {##2} }
+            ##4 {#1} \q_@@ ##5 ##6 {##7}
+          }
+      }
+  }
+\exp_args:No \@@_tmp:w { \c_novalue_tl }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_expandable_grab_R_alt:w}
+% \begin{macro}[EXP]{\@@_expandable_grab_R_alt_aux:NNwNNn}
+%   When the delimiters are identical, nesting is not possible and a simplified
+%   approach is used. The test concept here is the same as for the case where
+%   the delimiters are different.
+%    \begin{macrocode}
+\cs_new:Npn \@@_expandable_grab_R_alt:w #1 \q_@@ #2#3
+  { #2 { \@@_expandable_grab_R_alt_aux:NNwNNn #1 \q_@@ #2#3 } }
+\cs_set_protected:Npn \@@_tmp:w #1
+  {
+    \cs_new:Npn \@@_expandable_grab_R_alt_aux:NNwNNn ##1##2##3 \q_@@ ##4##5##6
+      {
+        \str_if_eq:nnTF {##6} {##2}
+          {
+            \str_if_eq:onTF
+              { ##1 { } ##6 ##2 ##2 }
+              { { } ##2 }
+          }
+          { \use_ii:nn }
+          {
+            ##1
+              { \@@_expandable_grab_D_alt:NNwn ##4 ##5 ##3 \q_@@ }
+              ##6 \ERROR
+          }
+          {
+            \msg_expandable_error:nnff { cmd } { missing-required }
+              { \exp_args:Nf \tl_trim_spaces:n { \token_to_str:N ##4 } }
+              { \tl_to_str:n {##2} }
+            ##3 {#1} \q_@@ ##4 ##5 {##6}
+          }
+      }
+  }
+\exp_args:No \@@_tmp:w { \c_novalue_tl }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\@@_expandable_grab_t:w}
+% \begin{macro}[EXP]{\@@_expandable_grab_t_aux:NNwn}
+%   As for a \texttt{D}-type argument, here we compare the grabbed tokens using
+%   the only parser we have in order to work out if |#2| is exactly equal to
+%   the output of the grabber.
+%    \begin{macrocode}
+\cs_new:Npn \@@_expandable_grab_t:w #1 \q_@@ #2#3
+  { #2 { \@@_expandable_grab_t_aux:NNwn #1 \q_@@ #2 #3 } }
+\cs_new:Npn \@@_expandable_grab_t_aux:NNwn #1#2#3 \q_@@ #4#5#6
+  {
+    \str_if_eq:onTF { #1 { } #6 #2 } {#2}
+      { #3 { \BooleanTrue } \q_@@ #4 #5 }
+      { #3 { \BooleanFalse } \q_@@ #4 #5 {#6} }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+%   {\@@_put_arg_expandable:nw, \@@_put_arg_expandable:ow}
+%   A useful helper, to store arguments when they are ready.
+%    \begin{macrocode}
+\cs_new:Npn \@@_put_arg_expandable:nw #1#2 \q_@@ { #2 {#1} \q_@@ }
+\cs_generate_variant:Nn \@@_put_arg_expandable:nw { o }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Argument processors}
+%
+% \begin{macro}{\@@_bool_reverse:N}
+%   A simple reversal.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_bool_reverse:N #1
+  {
+    \bool_if:NTF #1
+      { \tl_set:Nn \ProcessedArgument { \c_false_bool } }
+      { \tl_set:Nn \ProcessedArgument { \c_true_bool } }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{variable}{\l_@@_split_list_seq, \l_@@_split_list_tl}
+% \begin{macro}{\@@_split_list:nn}
+% \begin{macro}{\@@_split_list_multi:nn, \@@_split_list_multi:nV}
+% \begin{macro}{\@@_split_list_single:Nn}
+%   Splitting can take place either at a single token or at a longer
+%   identifier. To deal with single active tokens, a two-part procedure is
+%   needed.
+%    \begin{macrocode}
+\seq_new:N \l_@@_split_list_seq
+\tl_new:N \l_@@_split_list_tl
+\cs_new_protected:Npn \@@_split_list:nn #1#2
+  {
+    \tl_if_single:nTF {#1}
+      {
+        \token_if_cs:NTF #1
+          { \@@_split_list_multi:nn {#1} {#2} }
+          { \@@_split_list_single:Nn #1 {#2} }
+      }
+      { \@@_split_list_multi:nn {#1} {#2} }
+  }
+\cs_new_protected:Npn \@@_split_list_multi:nn #1#2
+  {
+    \seq_set_split:Nnn \l_@@_split_list_seq {#1} {#2}
+    \tl_clear:N \ProcessedArgument
+    \seq_map_inline:Nn \l_@@_split_list_seq
+      { \tl_put_right:Nn \ProcessedArgument { {##1} } }
+  }
+\cs_generate_variant:Nn \@@_split_list_multi:nn { nV }
+\group_begin:
+\char_set_catcode_active:N \^^@
+\cs_new_protected:Npn \@@_split_list_single:Nn #1#2
+  {
+    \tl_set:Nn \l_@@_split_list_tl {#2}
+    \group_begin:
+    \char_set_lccode:nn { `\^^@ } { `#1 }
+    \tex_lowercase:D
+      {
+        \group_end:
+        \tl_replace_all:Nnn \l_@@_split_list_tl { ^^@ }
+      }   {#1}
+     \@@_split_list_multi:nV {#1} \l_@@_split_list_tl
+   }
+\group_end:
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{variable}
+%
+% \begin{macro}{\@@_split_argument:nnn}
+% \begin{macro}{\@@_split_argument_aux:nnnn}
+% \begin{macro}[EXP]{\@@_split_argument_aux:n}
+% \begin{macro}[rEXP]{\@@_split_argument_aux:wn}
+%   Splitting to a known number of items is a special version of splitting
+%   a list, in which the limit is hard-coded and where there will always be
+%   exactly the correct number of output items. An auxiliary function is
+%   used to save on working out the token list length several times.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_split_argument:nnn #1#2#3
+  {
+    \@@_split_list:nn {#2} {#3}
+    \exp_args:Nf \@@_split_argument_aux:nnnn
+      { \tl_count:N \ProcessedArgument }
+      {#1} {#2} {#3}
+  }
+\cs_new_protected:Npn \@@_split_argument_aux:nnnn #1#2#3#4
+  {
+    \int_compare:nNnF {#1} = { #2 + 1 }
+      {
+        \int_compare:nNnTF {#1} > { #2 + 1 }
+          {
+            \tl_set:Nx \ProcessedArgument
+              {
+                \exp_last_unbraced:NnNo
+                  \@@_split_argument_aux:n
+                  { #2 + 1 }
+                  \use_none_delimit_by_q_stop:w
+                  \ProcessedArgument
+                  \q_stop
+              }
+            \msg_error:nnxxx { cmd } { split-excess-tokens }
+              { \tl_to_str:n {#3} } { \int_eval:n { #2 + 1 } }
+              { \tl_to_str:n {#4} }
+          }
+          {
+            \tl_put_right:Nx \ProcessedArgument
+              {
+                \prg_replicate:nn { #2 + 1 - (#1) }
+                  { { \exp_not:V \c_novalue_tl } }
+              }
+          }
+      }
+  }
+%    \end{macrocode}
+%   Auxiliaries to leave exactly the correct number of arguments in
+%   \cs{ProcessedArgument}.
+%    \begin{macrocode}
+\cs_new:Npn \@@_split_argument_aux:n #1
+  { \prg_replicate:nn {#1} { \@@_split_argument_aux:wn } }
+\cs_new:Npn \@@_split_argument_aux:wn #1 \use_none_delimit_by_q_stop:w #2
+  {
+    \exp_not:n { {#2} }
+    #1
+    \use_none_delimit_by_q_stop:w
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_trim_spaces:n}
+%   This one is almost trivial.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_trim_spaces:n #1
+  { \tl_set:Nx \ProcessedArgument { \tl_trim_spaces:n {#1} } }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Access to the argument specification}
+%
+% \begin{macro}{\@@_get_arg_spec_error:N, \@@_get_arg_spec_error:n}
+% \begin{macro}{\@@_get_arg_spec_error_aux:n}
+%   Provide an informative error when trying to get the argument
+%   specification of a non-\pkg{xparse} command or environment.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_get_arg_spec_error:N #1
+  {
+    \bool_set_false:N \l_@@_environment_bool
+    \tl_set:Nn \l_@@_fn_tl {#1}
+    \@@_get_arg_spec_error_aux:n { \cs_if_exist:NTF #1 }
+  }
+\cs_new_protected:Npn \@@_get_arg_spec_error:n #1
+  {
+    \bool_set_true:N \l_@@_environment_bool
+    \str_set:Nx \l_@@_environment_str {#1}
+    \@@_get_arg_spec_error_aux:n
+      { \cs_if_exist:cTF { \l_@@_environment_str } }
+  }
+\cs_new_protected:Npn \@@_get_arg_spec_error_aux:n #1
+  {
+    #1
+      {
+        \msg_error:nnx { cmd } { non-xparse }
+          { \@@_environment_or_command: }
+      }
+      {
+        \msg_error:nnx { cmd } { unknown }
+          { \@@_environment_or_command: }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_get_arg_spec:NTF}
+%   If the command is not an \pkg{xparse} command, complain.  If it is,
+%   its second \enquote{item} is the argument specification.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_get_arg_spec:NTF #1#2#3
+  {
+    \__kernel_cmd_if_xparse:NTF #1
+      {
+        \tl_set:Nx \ArgumentSpecification { \tl_item:Nn #1 { 2 } }
+        #2
+      }
+      {#3}
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% Rolling forward from 2020-10-01 is tricky because the entire |ltcmd|
+% module is new, but the user-level commands have the same name, so only
+% these will clash.  To work around that, in |latexrelease| mode we will
+% (temporarily) disable \cs{__kernel_chk_if_free_cs:N} for this final
+% part of the code, then restore at the end.
+%    \begin{macrocode}
+%<latexrelease>\cs_new_eq:NN \@@_chk_if_free_cs:N \__kernel_chk_if_free_cs:N
+%<latexrelease>\cs_gset_eq:NN \__kernel_chk_if_free_cs:N \use_none:n
+%    \end{macrocode}
+%
+% \begin{variable}{\ArgumentSpecification}
+%    \begin{macrocode}
+\tl_new:N \ArgumentSpecification
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_get_arg_spec:N}
+% \begin{macro}{\@@_get_arg_spec:n}
+%   Recovering the argument specification is now trivial.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_get_arg_spec:N #1
+  {
+    \@@_get_arg_spec:NTF #1 { }
+      { \@@_get_arg_spec_error:N #1 }
+  }
+\cs_new_protected:Npn \@@_get_arg_spec:n #1
+  {
+    \exp_args:Nc \@@_get_arg_spec:NTF
+      { environment~ \tl_to_str:n {#1} }
+      { }
+      { \@@_get_arg_spec_error:n {#1} }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_show_arg_spec:N}
+% \begin{macro}{\@@_show_arg_spec:n}
+%   Showing the argument specification simply means finding it and then
+%   calling the \cs{tl_show:N} function.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_show_arg_spec:N #1
+  {
+    \@@_get_arg_spec:NTF #1
+      { \tl_show:N \ArgumentSpecification }
+      { \@@_get_arg_spec_error:N #1 }
+  }
+\cs_new_protected:Npn \@@_show_arg_spec:n #1
+  {
+    \exp_args:Nc \@@_get_arg_spec:NTF
+      { environment~ \tl_to_str:n {#1} }
+      { \tl_show:N \ArgumentSpecification }
+      { \@@_get_arg_spec_error:n {#1} }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Utilities}
+%
+% \begin{macro}{\@@_check_definable:nNT, \@@_check_definable_aux:nN}
+%   Check that a token list is appropriate as a first argument of
+%   \cs{NewDocumentCommand} and similar functions and otherwise
+%   produce an error.  First trim whitespace to allow for spaces around
+%   the actual command to be defined.  If the result has multiple
+%   tokens, it is not a valid argument.  The single token is a control
+%   sequence exactly if its string representation has more than one
+%   character (using \cs{token_to_str:N} rather than \cs{tl_to_str:n}
+%   to avoid problems with macro parameter characters, and setting
+%   \cs{tex_escapechar:D} to prevent it from being non-printable).
+%   Finally, check for an active character: this is done by lowercasing
+%   the token to fix its character code (arbitrarily to that of~|?|)
+%   and comparing the result to an active~|?|.  Both control sequences
+%   and active characters are valid arguments, and non-active character
+%   tokens are not.  In all cases, the group opened to keep assignments
+%   local must be closed.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_check_definable:nNT #1
+  { \tl_trim_spaces_apply:nN {#1} \@@_check_definable_aux:nN }
+\group_begin:
+  \char_set_catcode_active:n { `? }
+  \cs_new_protected:Npn \@@_check_definable_aux:nN #1#2
+    {
+      \group_begin:
+      \tl_if_single_token:nTF {#1}
+        {
+          \int_set:Nn \tex_escapechar:D { 92 }
+          \exp_args:Nx \tl_if_empty:nTF
+            { \exp_args:No \str_tail:n { \token_to_str:N #1 } }
+            {
+              \exp_args:Nx \char_set_lccode:nn
+                { ` \str_head:n {#1} } { `? }
+              \tex_lowercase:D { \tl_if_eq:nnTF {#1} } { ? }
+                { \group_end: \use_iii:nnn }
+                { \group_end: \use_i:nnn }
+            }
+            { \group_end: \use_iii:nnn }
+        }
+        { \group_end: \use_ii:nnn }
+      {
+        \msg_error:nnxx { cmd } { not-definable }
+          { \tl_to_str:n {#1} } { \token_to_str:N #2 }
+      }
+      {
+        \msg_error:nnxx { cmd } { not-one-token }
+          { \tl_to_str:n {#1} } { \token_to_str:N #2 }
+      }
+    }
+\group_end:
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_token_if_cs:NTF}
+%   Based on the definition of \cs{@@_check_definable_aux:nN} above, but
+%   only checks for an actual control sequence (\emph{i.e.},
+%   \cs[no-index]{\meta{anything}}). \cs{tex_escapechar:D} is
+%   temporarily changed to a known value and then it checks if
+%   |\string#1| contains more than one character: if it does, it's a
+%   control sequence.  This test differs from \cs{token_if_cs:NTF} for
+%   example in \verb|\token_if_cs:NTF \c_group_begin_token {T}{F}|,
+%   where \cs{token_if_cs:NTF} returns false.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_token_if_cs:NTF #1
+  {
+    \group_begin:
+      \int_set:Nn \tex_escapechar:D { 92 }
+      \exp_args:Nx \tl_if_empty:nTF
+          { \exp_args:No \str_tail:n { \token_to_str:N #1 } }
+        { \group_end: \use_ii:nn }
+        { \group_end: \use_i:nn }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_tl_mapthread_function:NNN, \@@_tl_mapthread_function:nnN}
+% \begin{macro}{\@@_tl_mapthread_loop:w}
+%   Analogue of \cs{seq_mapthread_function:NNN} for token lists.
+%    \begin{macrocode}
+\cs_new:Npn \@@_tl_mapthread_function:NNN #1#2#3
+  {
+    \exp_after:wN \exp_after:wN
+    \exp_after:wN \@@_tl_mapthread_loop:w
+    \exp_after:wN \exp_after:wN
+    \exp_after:wN #3
+    \exp_after:wN #1
+    \exp_after:wN \q_recursion_tail
+    \exp_after:wN \q_mark
+    #2
+    \q_recursion_tail
+    \q_recursion_stop
+  }
+\cs_new:Npn \@@_tl_mapthread_function:nnN #1#2#3
+  {
+    \@@_tl_mapthread_loop:w #3
+      #1 \q_recursion_tail \q_mark
+      #2 \q_recursion_tail \q_recursion_stop
+  }
+\cs_new:Npn \@@_tl_mapthread_loop:w #1#2#3 \q_mark #4
+  {
+    \quark_if_recursion_tail_stop:n {#2}
+    \quark_if_recursion_tail_stop:n {#4}
+    #1 {#2} {#4}
+    \@@_tl_mapthread_loop:w #1#3 \q_mark
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\__kernel_cmd_if_xparse:NTF}
+% \changes{v1.0d}{2021/04/19}{Renamed \cs{__cmd_cmd_if_xparse:NTF} to
+%      \cs{__kernel_cmd_if_xparse:NTF} for cross-module usage}
+% \begin{macro}{\@@_cmd_if_xparse_aux:N}
+%
+%    To determine whether the command is an \pkg{xparse} command check
+%    that its |arg_spec| is empty (this also excludes non-macros) and
+%    that its |replacement_spec| starts with either
+%    \cs{@@_start:nNNnnn} (non-expandable command) or
+%    \cs{@@_start_expandable:nNNNNn} (expandable command) or
+%    \cs{@@_start_env:nnnnn} (environment).
+%
+%    This conditional is needed in several kernel modules and is
+%    therefore has a kernel-internal name.
+%    \begin{macrocode}
+\cs_new_protected:Npn \__kernel_cmd_if_xparse:NTF #1
+  {
+    \exp_args:Nf \str_case_e:nnTF
+      {
+        \exp_args:Nf \tl_if_empty:nT { \cs_argument_spec:N #1 }
+          {
+            \exp_last_unbraced:Nf \@@_cmd_if_xparse_aux:w
+              { \cs_replacement_spec:N #1 } ~ \q_stop
+          }
+      }
+      {
+        { \token_to_str:N \@@_start:nNNnnn } { }
+        { \token_to_str:N \@@_start_expandable:nNNNNn } { }
+        { \token_to_str:N \@@_start_env:nnnnn } { }
+      }
+  }
+\cs_new:Npn \@@_cmd_if_xparse_aux:w #1 ~ #2 \q_stop {#1}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_peek_nonspace:NTF, \@@_peek_nonspace_remove:NTF, \@@_peek_nonspace_aux:nNNTF}
+%   Collect spaces in a loop, and put the collected spaces back in the
+%   false branch of a call to \cs{peek_meaning:NTF} or
+%   \cs{peek_meaning_remove:NTF}.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_nonspace:NTF
+  { \@@_peek_nonspace_aux:nNNTF { } \@@_peek_meaning:NTF }
+\cs_new_protected:Npn \@@_peek_nonspace_remove:NTF
+  { \@@_peek_nonspace_aux:nNNTF { } \@@_peek_meaning_remove:NTF }
+\cs_new_protected:Npn \@@_peek_nonspace_aux:nNNTF #1#2#3#4#5
+  {
+    \peek_meaning_remove:NTF \c_space_token
+      { \@@_peek_nonspace_aux:nNNTF { #1 ~ } #2 #3 {#4} {#5} }
+      { #2 #3 { #4 } { #5 #1 } }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_peek_meaning:NTF, \@@_peek_meaning_remove:NTF}
+% \begin{macro}{\@@_peek_cs_check_equal:NNN, \@@_peek_meaning_aux:NNTF, \@@_peek_true_remove:NNw}
+%   Peek ahead for a token with a given meaning.  In case the search
+%   token is a control sequence, also check that the \meta{csname} is
+%   the same as the control sequence peeked at.  This extra verification
+%   is necessary when the command is delimited by control sequence tokens
+%   (as opposed to character tokens), and we want the the exact same
+%   control sequence to match.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_peek_meaning:NTF
+  { \@@_peek_meaning_aux:NNTF \c_false_bool }
+\cs_new_protected:Npn \@@_peek_meaning_remove:NTF
+  { \@@_peek_meaning_aux:NNTF \c_true_bool }
+\cs_new_protected:Npn \@@_peek_meaning_aux:NNTF #1#2#3#4
+  {
+    \tl_set:Nn \l_@@_tmpa_tl {#3}
+    \tl_set:Nn \l_@@_tmpb_tl {#4}
+    \peek_meaning:NTF #2
+      {
+        \token_if_eq_meaning:NNTF #2 \c_group_begin_token
+          { \@@_peek_true_remove:Nw #1 }
+          {
+            \@@_token_if_cs:NTF #2
+              { \@@_peek_cs_check_equal:NNN #1 #2 }
+              { \@@_peek_true_remove:Nw #1 }
+          }
+      }
+      { \l_@@_tmpb_tl }
+  }
+\cs_new_protected:Npn \@@_peek_cs_check_equal:NNN #1#2#3
+  {
+    \str_if_eq:nnTF {#2} {#3}
+      { \@@_peek_true_remove:Nw #1 }
+      { \l_@@_tmpb_tl }
+    #3
+  }
+\cs_new_protected:Npn \@@_peek_true_remove:Nw #1
+  {
+    \bool_if:NTF #1
+      {
+        \tex_afterassignment:D \l_@@_tmpa_tl
+        \cs_set_eq:NN \@@_tmp:w
+      }
+      { \l_@@_tmpa_tl }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Messages}
+%
+% \begin{variable}{\c_@@_ignore_def_tl}
+%    \begin{macrocode}
+\tl_const:Nn \c_@@_ignore_def_tl
+  { \\ \\ LaTeX~will~ignore~this~entire~definition. }
+%    \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_environment_or_command:}
+%   Two texts used in several messages.
+%    \begin{macrocode}
+\cs_new:Npn \@@_environment_or_command:
+  {
+    \bool_if:NTF \l_@@_environment_bool
+      { environment ~ ' \l_@@_environment_str ' }
+      {
+        command ~ '
+        \exp_args:Nf \tl_trim_spaces:n
+          { \exp_after:wN \token_to_str:N \l_@@_fn_tl }
+        '
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% Some messages intended as errors when defining commands/environments.
+%    \begin{macrocode}
+\msg_new:nnnn { cmd } { arg-after-body }
+  { In~the~definition~of~#1,~b~(body)~argument~must~be~last. }
+  {
+    The~'body'~argument~type~is~followed~by~'#2'~in~the~argument~
+    specification~of~the~#1.~This~is~not~allowed.
+    \c_@@_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { bad-arg-spec }
+  { Bad~argument~specification~'#2'~for~#1. }
+  {
+    The~argument~specification~provided~was~not~valid:~
+    one~or~more~mandatory~pieces~of~information~were~missing.
+    \c_@@_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { command-already-defined }
+  { Command~'#1'~already~defined! }
+  {
+    You~have~used~#2~
+    with~a~command~that~already~has~a~definition. \\ \\
+    The~existing~definition~of~'#1'~will~not~be~altered.
+  }
+\msg_new:nnnn { cmd } { command-not-yet-defined }
+  { Command ~'#1'~not~yet~defined! }
+  {
+    You~have~used~#2~
+    with~a~command~that~was~never~defined.
+    \c_@@_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { environment-already-defined }
+  { Environment~'#1'~already~defined! }
+  {
+    You~have~used~\NewDocumentEnvironment
+    with~an~environment~that~already~has~a~definition. \\ \\
+    The~existing~definition~of~'#1'~will~not~be~altered.
+  }
+\msg_new:nnnn { cmd } { environment-not-yet-defined }
+  { Environment~'#1'~not~yet~defined! }
+  {
+    You~have~used~\RenewDocumentEnvironment
+    with~an~environment~that~was~never~defined.
+    \c_@@_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { expandable-ending-optional }
+  {
+    Argument~specification~'#2'~for~expandable~command~'#1'~
+    ends~with~optional~argument.
+  }
+  {
+    Expandable~commands~must~have~a~final~mandatory~argument~
+    (or~no~arguments~at~all).~You~cannot~have~a~terminal~optional~
+    argument~with~expandable~commands.
+  }
+\msg_new:nnnn { cmd } { inconsistent-long }
+  { Inconsistent~long~arguments~for~expandable~command~'#1'. }
+  {
+    The~arguments~for~an~expandable~command~must~not~involve~short~
+    arguments~after~long~arguments.~You~have~tried~to~mix~the~two~types.
+  }
+\msg_new:nnnn { cmd } { invalid-command-arg }
+  { Argument~type~'#2'~not~available~for~#1. }
+  {
+    The~letter~'#2'~can~only~be~used~in~environment~argument~
+    specifications,~not~for~commands.
+    \\ \\
+    LaTeX~will~ignore~this~entire~definition.
+  }
+\msg_new:nnnn { cmd } { invalid-expandable-argument-type }
+  { Argument~type~'#2'~not~available~for~expandable~command~'#1'. }
+  {
+    The~letter~'#2'~specifies~an~argument~type~which~cannot~be~used~
+    in~an~expandable~command.
+    \c_@@_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { invalid-after-optional-expandably }
+  {
+    Argument~type~'#2'~not~available~after~optional~argument~
+    for~expandable~command~'#1'.
+  }
+  {
+    The~letter~'#2'~specifies~an~argument~type~which~cannot~be~used~
+    in~an~expandable~command~after~an~optional~argument.
+    \c_@@_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { non-trailing-obey-spaces }
+  { Prefix~'!'~used~before~mandatory~argument~'#2'~of~#1. }
+  {
+    The~prefix~'!'~can~only~apply~to~trailing~optional~arguments.
+    \c_@@_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { not-definable }
+  { First~argument~of~'#2'~must~be~a~command. }
+  {
+    The~first~argument~of~'#2'~should~be~the~document~command~that~will~
+    be~defined.~The~provided~argument~'#1'~is~a~character.~Perhaps~a~
+    backslash~is~missing?
+    \c_@@_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { not-one-token }
+  { First~argument~of~'#2'~must~be~a~command. }
+  {
+    The~first~argument~of~'#2'~should~be~the~document~command~that~will~
+    be~defined.~The~provided~argument~'#1'~contains~more~than~one~
+    token.~Perhaps~a~backslash~is~missing?
+    \c_@@_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { not-single-token }
+  {
+    Argument~delimiter~'#2'~for~the~#1~should~be~
+    a~single~non-space~token.
+  }
+  {
+    The~argument~specification~provided~was~not~valid:~in~a~place~
+    where~a~single~token~is~required,~LaTeX~found~'#2'.
+    \c_@@_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { forbidden-implicit-group-token }
+  { Argument~delimiter~'#2'~for~the~#1~is~not~allowed. }
+  {
+    The~argument~specification~provided~was~not~valid:~the~implicit~
+    #3-group~token~'#2'~is~not~allowed~as~an~argument~delimiter.
+    \c_@@_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { processor-in-expandable }
+  { Argument~processor~'>{#2}'~cannot~be~used~for~the~expandable~command~'#1'. }
+  {
+    The~argument~specification~for~#1~contains~a~processor~function:~
+    this~is~only~supported~for~standard~robust~commands.
+    \c_@@_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { too-many-arguments }
+  { Too~many~arguments~in~argument~specification~'#2'~of~#1. }
+  {
+    The~argument~specification~provided~has~more~than~9~arguments.~
+    This~cannot~be~implemented.
+    \c_@@_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { two-markers }
+  { Two~'#2'~apply~to~the~same~argument~in~argument~specification~of~#1. }
+  {
+    The~argument~specification~provided~has~two~markers~'#2'~applying~
+    to~the~same~argument;~these~are~redundant.
+  }
+\msg_new:nnnn { cmd } { unknown-argument-type }
+  { Unknown~argument~type~'#2'~for~the~#1. }
+  {
+    The~letter~'#2'~does~not~specify~a~known~argument~type.
+    \c_@@_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { xparse-argument-type }
+  { Deprecated~argument~type~'#2'~for~the~#1~requires~xparse. }
+  {
+    The~letter~'#2'~specifies~a~known~argument~type~that~requires~
+    the~xparse~package.
+    \c_@@_ignore_def_tl
+  }
+%    \end{macrocode}
+%
+% Errors when using commands/environments.  The \texttt{if-boolean}
+% message is always used in expandable errors.  The
+% \texttt{loop-in-defaults} and \texttt{missing-required} messages can
+% be expandable or not expandable.
+%    \begin{macrocode}
+\msg_new:nnn { cmd } { if-boolean }
+  { Invalid~use~\iow_char:N\\IfBooleanTF~{#1} }
+\msg_new:nnnn { cmd } { loop-in-defaults }
+  { Defaults~of~#1~have~circular~dependency. }
+  {
+    The~default~values~of~two~or~more~arguments~of~the~#1~
+    depend~on~each~other~in~a~way~that~cannot~be~resolved.
+  }
+\msg_new:nnnn { cmd } { missing-required }
+  { Missing~required~argument~for~#1. }
+  {
+    The~current~#1~expects~an~argument~starting~with~'#2'.~
+    LaTeX~did~not~find~it,~and~will~insert~a~default~value~to~be~processed.
+  }
+\msg_new:nnnn { cmd } { non-xparse }
+  { \str_uppercase:n #1~not~defined~using~xparse. }
+  {
+    You~have~asked~for~the~argument~specification~for~the~#1,~
+    but~this~was~not~defined~using~xparse.
+  }
+\msg_new:nnnn { cmd } { split-excess-tokens }
+  { Too~many~'#1'~tokens~when~trying~to~split~argument. }
+  {
+    LaTeX~was~asked~to~split~the~input~'#3'~
+    at~each~occurrence~of~the~token~'#1',~up~to~a~maximum~of~#2~parts.~
+    There~were~too~many~'#1'~tokens.
+  }
+\msg_new:nnnn { cmd } { unknown }
+  { Unknown~document~#1. }
+  {
+    You~have~asked~for~the~argument~specification~for~the~#1,~
+    but~it~is~not~defined.
+  }
+\msg_new:nnnn { cmd } { verbatim-newline }
+  { Verbatim~argument~of~#1~ended~by~end~of~line. }
+  {
+    The~verbatim~argument~of~the~#1~cannot~contain~more~than~one~line,~
+    but~the~end~
+    of~the~current~line~has~been~reached.~You~may~have~forgotten~the~
+    closing~delimiter.
+    \\ \\
+    LaTeX~will~ignore~'#2'.
+  }
+\msg_new:nnnn { cmd } { verbatim-tokenized }
+  { The~verbatim~#1~cannot~be~used~inside~an~argument. }
+  {
+    The~#1~takes~a~verbatim~argument.~
+    It~may~not~appear~within~the~argument~of~another~function.~
+    It~received~an~illegal~token \tl_if_empty:nF {#3} { ~'#3' } .
+    \\ \\
+    LaTeX~will~ignore~'#2'.
+  }
+%    \end{macrocode}
+%
+% Intended more for information.
+%    \begin{macrocode}
+\msg_new:nnn { cmd } { define-command }
+  {
+    Defining~command~#1~
+    with~sig.~'#2'~\msg_line_context:.
+  }
+\msg_new:nnn { cmd } { define-environment }
+  {
+    Defining~environment~'#1'~
+    with~sig.~'#2'~\msg_line_context:.
+  }
+\msg_new:nnn { cmd } { redefine-command }
+  {
+    Redefining~command~#1~
+    with~sig.~'#2'~\msg_line_context:.
+  }
+\msg_new:nnn { cmd } { redefine-environment }
+  {
+    Redefining~environment~'#1'~
+    with~sig.~'#2'~\msg_line_context:.
+  }
+\msg_new:nnn { cmd } { optional-mandatory }
+  {
+    Since~the~mandatory~argument~'#1'~has~the~same~delimiter~'#2'~
+    as~a~previous~optional~argument,~it~will~not~be~possible~to~
+    omit~all~optional~arguments~when~calling~this~command.
+  }
+\msg_new:nnn { cmd } { unsupported-let }
+  {
+    The~command~'#1'~was~undefined~but~not~the~associated~commands~
+    '#1~code'~and/or~'#1~defaults'.~Maybe~you~tried~using~
+    \iow_char:N\\let.~This~may~lead~to~an~infinite~loop.
+  }
+%    \end{macrocode}
+%
+% \subsection{User functions}
+%
+% The user functions are more or less just the internal functions
+% renamed.
+%
+% \begin{macro}{\BooleanFalse}
+% \begin{macro}{\BooleanTrue}
+%   Design-space names for the Boolean values.
+%    \begin{macrocode}
+\cs_new_eq:NN \BooleanFalse \c_false_bool
+\cs_new_eq:NN \BooleanTrue  \c_true_bool
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\NewDocumentCommand}
+% \begin{macro}{\RenewDocumentCommand}
+% \begin{macro}{\ProvideDocumentCommand}
+% \begin{macro}{\DeclareDocumentCommand}
+%   The user macros are pretty simple wrappers around the internal ones.
+%   There is however a check that the first argument is a single token,
+%   possibly surrounded by spaces (hence the strange \cs{use:nnn}), and
+%   is definable.
+%    \begin{macrocode}
+\cs_new_protected:Npn \NewDocumentCommand #1#2#3
+  {
+    \@@_check_definable:nNT {#1} \NewDocumentCommand
+      {
+        \cs_if_exist:NTF #1
+          {
+            \msg_error:nnxx { cmd } { command-already-defined }
+              { \use:nnn \token_to_str:N #1 { } }
+              { \token_to_str:N \NewDocumentCommand }
+          }
+          { \@@_declare_cmd:Nnn #1 {#2} {#3} }
+      }
+  }
+\cs_new_protected:Npn \RenewDocumentCommand #1#2#3
+  {
+    \@@_check_definable:nNT {#1} \RenewDocumentCommand
+      {
+        \cs_if_exist:NTF #1
+          { \@@_declare_cmd:Nnn #1 {#2} {#3} }
+          {
+            \msg_error:nnxx { cmd } { command-not-yet-defined }
+              { \use:nnn \token_to_str:N #1 { } }
+              { \token_to_str:N \RenewDocumentCommand }
+          }
+      }
+  }
+\cs_new_protected:Npn \ProvideDocumentCommand #1#2#3
+  {
+    \@@_check_definable:nNT {#1} \ProvideDocumentCommand
+      { \cs_if_exist:NF #1 { \@@_declare_cmd:Nnn #1 {#2} {#3} } }
+ }
+\cs_new_protected:Npn \DeclareDocumentCommand #1#2#3
+  {
+    \@@_check_definable:nNT {#1} \DeclareDocumentCommand
+      { \@@_declare_cmd:Nnn #1 {#2} {#3} }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\NewDocumentEnvironment}
+% \begin{macro}{\RenewDocumentEnvironment}
+% \begin{macro}{\ProvideDocumentEnvironment}
+% \begin{macro}{\DeclareDocumentEnvironment}
+%   Very similar for environments.
+%    \begin{macrocode}
+\cs_new_protected:Npn \NewDocumentEnvironment #1#2#3#4
+  {
+    \cs_if_exist:cTF {#1}
+      { \msg_error:nnx { cmd } { environment-already-defined } {#1} }
+      { \@@_declare_env:nnnn {#1} {#2} {#3} {#4} }
+  }
+\cs_new_protected:Npn \RenewDocumentEnvironment #1#2#3#4
+  {
+    \cs_if_exist:cTF {#1}
+      { \@@_declare_env:nnnn {#1} {#2} {#3} {#4} }
+      { \msg_error:nnx { cmd } { environment-not-yet-defined } {#1} }
+  }
+\cs_new_protected:Npn \ProvideDocumentEnvironment #1#2#3#4
+  { \cs_if_exist:cF {#1} { \@@_declare_env:nnnn {#1} {#2} {#3} {#4} } }
+\cs_new_protected:Npn \DeclareDocumentEnvironment #1#2#3#4
+  { \@@_declare_env:nnnn {#1} {#2} {#3} {#4} }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\NewExpandableDocumentCommand}
+% \begin{macro}{\RenewExpandableDocumentCommand}
+% \begin{macro}{\ProvideExpandableDocumentCommand}
+% \begin{macro}{\DeclareExpandableDocumentCommand}
+%   The expandable versions are essentially the same as the basic
+%   functions.  The strange \cs{use:nnn} is there in case |#1| is
+%   surrounded with spaces, as can happen with usual document catcodes
+%   in \cs{RenewExpandableDocumentCommand} |{| |\!| |}| \ldots{}
+%    \begin{macrocode}
+\cs_new_protected:Npn \NewExpandableDocumentCommand #1#2#3
+  {
+    \@@_check_definable:nNT {#1} \NewExpandableDocumentCommand
+      {
+        \cs_if_exist:NTF #1
+          {
+            \msg_error:nnxx { cmd } { command-already-defined }
+              { \use:nnn \token_to_str:N #1 { } }
+              { \token_to_str:N \NewExpandableDocumentCommand }
+          }
+          { \@@_declare_expandable_cmd:Nnn #1 {#2} {#3} }
+      }
+  }
+\cs_new_protected:Npn \RenewExpandableDocumentCommand #1#2#3
+  {
+    \@@_check_definable:nNT {#1} \RenewExpandableDocumentCommand
+      {
+        \cs_if_exist:NTF #1
+          { \@@_declare_expandable_cmd:Nnn #1 {#2} {#3} }
+          {
+            \msg_error:nnxx { cmd } { command-not-yet-defined }
+              { \use:nnn \token_to_str:N #1 { } }
+              { \token_to_str:N \RenewExpandableDocumentCommand }
+          }
+      }
+  }
+\cs_new_protected:Npn \ProvideExpandableDocumentCommand #1#2#3
+  {
+    \@@_check_definable:nNT {#1} \ProvideExpandableDocumentCommand
+      {
+        \cs_if_exist:NF #1
+          { \@@_declare_expandable_cmd:Nnn #1 {#2} {#3} }
+      }
+ }
+\cs_new_protected:Npn \DeclareExpandableDocumentCommand #1#2#3
+  {
+    \@@_check_definable:nNT {#1} \DeclareExpandableDocumentCommand
+      { \@@_declare_expandable_cmd:Nnn #1 {#2} {#3} }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\IfBooleanT, \IfBooleanF, \IfBooleanTF}
+%   The logical \meta{true} and \meta{false} statements are just the
+%   normal \cs{c_true_bool} and \cs{c_false_bool} so \cs{bool_if:NTF} is
+%   almost enough.  However, this code-level function blows up badly
+%   when passed invalid input.  We want \cs{IfBooleanTF} to accept a
+%   single (non-space) token equal to \cs{c_true_bool} or
+%   \cs{c_false_bool}, possibly surrounded by spaces.  If the input is
+%   blank or multiple items, jump to the error and pick the false
+%   branch.  If the input, ignoring spaces (we do this by omitting
+%   braces in the \cs{tl_if_single_token:nF} test), is not a single
+%   token then jump to the error as well.  It is then safe to compare
+%   the token to the two booleans, picking the appropriate branch.  If
+%   neither matches, we jump to the error as well.
+%    \begin{macrocode}
+\cs_new:Npn \IfBooleanTF #1
+  {
+    \tl_if_single:nF {#1}
+      { \prg_break:n { \use:n } }
+    \tl_if_single_token:nF #1
+      { \prg_break:n { \use:n } }
+    \token_if_eq_meaning:NNT #1 \c_true_bool
+      { \prg_break:n { \use_ii:nnn } }
+    \token_if_eq_meaning:NNT #1 \c_false_bool
+      { \prg_break:n { \use_iii:nnn } }
+    \prg_break:n { \use:n }
+    \prg_break_point:
+    {
+      \msg_expandable_error:nnn { cmd } { if-boolean } {#1}
+      \use_ii:nn
+    }
+  }
+\cs_new:Npn \IfBooleanT #1#2 { \IfBooleanTF {#1} {#2} { } }
+\cs_new:Npn \IfBooleanF #1 { \IfBooleanTF {#1} { } }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\IfNoValueT, \IfNoValueF, \IfNoValueTF}
+%   Simple re-naming.
+%    \begin{macrocode}
+\cs_new_eq:NN \IfNoValueF  \tl_if_novalue:nF
+\cs_new_eq:NN \IfNoValueT  \tl_if_novalue:nT
+\cs_new_eq:NN \IfNoValueTF \tl_if_novalue:nTF
+%    \end{macrocode}
+% \end{macro}
+% \begin{macro}{\IfValueT, \IfValueF, \IfValueTF}
+%   Inverted logic.
+%    \begin{macrocode}
+\cs_new:Npn \IfValueF { \tl_if_novalue:nT }
+\cs_new:Npn \IfValueT { \tl_if_novalue:nF }
+\cs_new:Npn \IfValueTF #1#2#3 { \tl_if_novalue:nTF {#1} {#3} {#2} }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ProcessedArgument}
+%   Processed arguments are returned using this name, which is reserved
+%   here although the definition will change.
+%    \begin{macrocode}
+\tl_new:N \ProcessedArgument
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ReverseBoolean, \SplitArgument, \SplitList, \TrimSpaces}
+%   Simple copies.
+%    \begin{macrocode}
+\cs_new_eq:NN \ReverseBoolean \@@_bool_reverse:N
+\cs_new_eq:NN \SplitArgument  \@@_split_argument:nnn
+\cs_new_eq:NN \SplitList      \@@_split_list:nn
+\cs_new_eq:NN \TrimSpaces     \@@_trim_spaces:n
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\ProcessList}
+%   To support \cs{SplitList}.
+%    \begin{macrocode}
+\cs_new_eq:NN \ProcessList \tl_map_function:nN
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\GetDocumentCommandArgSpec}
+% \begin{macro}{\GetDocumentEnvironmentArgSpec}
+% \begin{macro}{\ShowDocumentCommandArgSpec}
+% \begin{macro}{\ShowDocumentEnvironmentArgSpec}
+%   More simple mappings, with a check that the argument is a single
+%   control sequence or active character.
+%    \begin{macrocode}
+\cs_new_protected:Npn \GetDocumentCommandArgSpec #1
+  {
+    \@@_check_definable:nNT {#1} \GetDocumentCommandArgSpec
+      { \@@_get_arg_spec:N #1 }
+  }
+\cs_new_eq:NN \GetDocumentEnvironmentArgSpec \@@_get_arg_spec:n
+\cs_new_protected:Npn \ShowDocumentCommandArgSpec #1
+  {
+    \@@_check_definable:nNT {#1} \ShowDocumentCommandArgSpec
+      { \@@_show_arg_spec:N #1 }
+  }
+\cs_new_eq:NN \ShowDocumentEnvironmentArgSpec \@@_show_arg_spec:n
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% Finally as promised, restore \cs{__kernel_chk_if_free_cs:N}:
+%    \begin{macrocode}
+%<latexrelease>\cs_gset_eq:NN \__kernel_chk_if_free_cs:N \@@_chk_if_free_cs:N
+%<latexrelease>\cs_undefine:N \@@_chk_if_free_cs:N
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<latexrelease>
+%<latexrelease>\IncludeInRelease{0000/00/00}{ltcmd}%
+%<latexrelease>                 {Document~command~parser}%
+%<latexrelease>
+%<latexrelease>\EndModuleRelease
+\ExplSyntaxOff
+%<latexrelease>\@ifundefined{ExplSyntaxOff}{}{\latexrelease at postexpl}
+%<latexrelease>\catcode`\^^@=\@latexrelease at catcode@null\relax
+%</2ekernel|latexrelease>
+%    \end{macrocode}
+%
+% We need to stop DocStrip treating |@@| in a special way at this point.
+%    \begin{macrocode}
+%<@@=>
+%    \end{macrocode}
+%
+% \Finale


Property changes on: trunk/Master/texmf-dist/source/latex/base/ltcmd.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Added: trunk/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -0,0 +1,1094 @@
+% \iffalse meta-comment
+%
+%% File: ltcmdhooks.dtx (C) Copyright 2020-2021
+%%       Frank Mittelbach, Phelype Oleinik, LaTeX Team
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version.  The latest version
+% of this license is in the file
+%
+%    https://www.latex-project.org/lppl.txt
+%
+%
+%%% From File: ltcmdhooks.dtx
+%
+\def\ltcmdhooksversion{v1.0b}
+\def\ltcmdhooksdate{2021/05/26}
+%
+%
+%
+%<*driver>
+\documentclass{l3doc}
+%\usepackage{ltcmdhooks}
+\makeatletter
+\providecommand\footref[1]{%
+  \begingroup
+    \unrestored at protected@xdef\@thefnmark{\ref{#1}}%
+  \endgroup
+  \@footnotemark}
+\makeatother
+\EnableCrossrefs
+\CodelineIndex
+\begin{document}
+  \DocInput{ltcmdhooks.dtx}
+\end{document}
+%</driver>
+%
+% \fi
+%
+%
+% \providecommand\hook[1]{\texttt{#1}}
+% \providecommand\fmi[1]{\marginpar{\footnotesize FMi: #1}}
+% \providecommand\pho[1]{\marginpar{\footnotesize PhO: #1}}
+% \providecommand\phoinline[1]{\begin{quote}\itshape\footnotesize PhO: #1\end{quote}}
+%
+% \title{The \texttt{ltcmdhooks} module\thanks{This file has version
+%    \ltcmdhooksversion\ dated \ltcmdhooksdate, \copyright\ \LaTeX\
+%    Project.}}
+% \author{Frank Mittelbach \and Phelype Oleinik}
+%
+% \maketitle
+%
+%
+% \tableofcontents
+%
+%
+% \section{Introduction}
+%
+%    This file implements generic hooks for (arbitrary) commands.
+%    In theory every command \tn[no-index]{\meta{name}} offers now two
+%    associated hooks to which code can be added using \tn{AddToHook}
+%    or \tn{AddToHookNext}.\footnote{In practice this is not supported
+%    for all types of commands, see section~\ref{sec:look-ahead} for
+%    the restrictions that apply and what happens if one tries to use
+%    this with commands for which this is not supported.}  These are
+%    \begin{description}
+%    \item[\hook{cmd/\meta{name}/before}]
+%
+%       This hook is executed at the very start of the command
+%       execution after its arguments (if any) are parsed.  The hook
+%       \meta{code} is wrapped in the command inside a call to
+%       \cs{UseHook}|{cmd/|\meta{name}|/before}|, so the arguments
+%       passed to the command are \emph{not} available in the hook
+%       \meta{code}.
+%
+%    \item[\hook{cmd/\meta{name}/after}]
+%
+%       This hook is similar to \hook{cmd/\meta{name}/before}, but it is
+%       executed at the very end of the command body.  This hook is
+%       implemented as a reversed hook.
+%    \end{description}
+%
+%    The hooks are not physically present before
+%    \verb=\begin{document}= (i.e., using a command in the preamble
+%    will never execute them) and if nobody has declared any code for
+%    them, then they are not added to the command code ever.  For
+%    example, if we have the following definition
+%\begin{verbatim}
+%    \newcommand\foo[2]{Code #1 for #2!}
+%\end{verbatim}
+%    then executing \verb=\foo{A}{B}= will simply run
+%    \verb*=Code A for B!=
+%    as it was always the case. However, if somebody, somewhere (e.g.,
+%    in a package) adds
+%\begin{verbatim}
+%    \AddToHook{cmd/foo/before}{<before code>}
+%\end{verbatim}
+%    then, after |\begin{document}| the definition of \cs[no-index]{foo} will be:
+%\begin{verbatim}
+%    \renewcommand\foo[2]{\UseHook{cmd/foo/before}Code #1 for #2!}
+%\end{verbatim}
+%    and similarly \verb=\AddToHook{cmd/foo/after}{<after code>}=
+%    alters the definition to
+%\begin{verbatim}
+%    \renewcommand\foo[2]{Code #1 for #2!\UseHook{cmd/foo/after}}
+%\end{verbatim}
+%
+%    In other words, the mechanism is similar to what \pkg{etoolbox}
+%    offers with \tn{pretocmd} and \tn{apptocmd} with the important
+%    differences 
+%    \begin{itemize}
+%    \item
+%
+%      that code can be prepended or appended (i.e., added to the
+%      hooks) even if the command itself is not defined, because the
+%      defining package has not yet been loaded
+%
+%    \item
+%
+%      and that by using the hook management interface it is now
+%      possible to define how the code chunks added in these places
+%      are ordered, if different packages want to add code at these
+%      points.
+%
+%    \end{itemize}
+%
+%
+%
+%
+% \section{Restrictions and Operational details}
+% \label{sec:restrictions}
+%
+% Adding arbitrary material to commands is tricky because most of the
+% time we do not know what the macro expects as arguments when expanding
+% and \TeX{} doesn't have a reliable way to see that, so some guesswork
+% has to be employed.
+%
+% \subsection{Patching}
+%
+% The code here tries to find out if a command was defined with
+% \tn{newcommand} or \tn{DeclareRobustCommand} or
+% \tn{NewDocumentCommand}, and if so it \emph{assumes} that the argument
+% specification of the command is as expected (which is not fail-proof,
+% if someone redefines the internals of these commands in devious ways,
+% but is a reasonable assumption).
+%
+% If the command is one of the defined types, the code here does a
+% sandboxed expansion of the command such that it can be redefined again
+% exactly as before, but with the hook code added.
+%
+% If however the command is not a known type (it was defined with
+% \tn{def}, for example), then the code uses an approach similar to
+% \pkg{etoolbox}'s \tn{patchcmd} to retokenize the command with the hook
+% code in place.  This procedure, however, is more likely to fail if the
+% catcode settings are not the same as the ones at the time of command's
+% definition, so not always adding a hook to a command will work.
+%
+% \subsubsection{Timing}
+%
+% When \cs{AddToHook} (or its \pkg{expl3} equivalent) is called with
+% a generic |cmd| hook, say, \hook{cmd/foo/before}, for the first time
+% (that is, no code was added to that same hook before), in the preamble
+% of a document, it will store a patch instruction for that command
+% until |\begin{document}|, and only then all the commands which had
+% hooks added will be patched in one go.  That means that no command in
+% the preamble will have hooks patched into them.
+%
+% At |\begin{document}| all the delayed patches will be executed, and
+% if the command doesn't exist the code is still added to the hook,
+% but it will not be executed.  After |\begin{document}|, when
+% \cs{AddToHook} is called with a generic |cmd| hook the first time,
+% the command will be immediately patched to include the hook, and if
+% it doesn't exist or if it can't be patched for any reason, an error
+% is thrown; if \cs{AddToHook} was already used in the preamble no new
+% patching is attempted.
+%
+% This has the consequence that a command defined or redefined after
+% |\begin{document}| only uses generic |cmd| hook code if
+% \cs{AddToHook} is called for the first time after the definition is
+% made, or if the command explicitly uses the generic hook in its
+% definition by declaring it with \cs{NewHookPair} adding \cs{UseHook} as
+% part of the code.\footnote{We might change this behavior in the main
+% document slightly after gaining some usage experience.}
+%
+%
+% \subsection{Commands that look ahead}
+% \label{sec:look-ahead}
+%
+% Some commands are defined in different ``steps'' and they look ahead
+% in the input stream to find more arguments.  If you try to add some
+% code to the \hook{cmd/\meta{name}/after} hook of such command, it will
+% not work, and it is not possible to detect that programmatically, so
+% the user has to know (or find out) which commands can or cannot have
+% hooks attached to them.
+%
+% One good example is the \tn{section} command.  You can add something
+% to the \hook{cmd/section/before} hook, but if you try to add something
+% to the \hook{cmd/section/after} hook, \tn{section} will no longer
+% work.  That happens because the \tn{section} macro takes no argument,
+% but instead calls a few internal \LaTeX{} macros to look for the
+% optional and mandatory arguments.  By adding code to the
+% \hook{cmd/section/after} hook, you get in the way of that scanning.
+%
+%
+%
+% \section{Package Author Interface}
+%
+% The \hook{cmd} hooks are, by default, available for all commands
+% that can be patched to add the hooks.  For some commands, however,
+% the very beginning or the very end of the code is not the best place
+% to put the hooks, for example, if the command looks ahead for
+% arguments (see section~\ref{sec:look-ahead}).
+%
+% If you are a package author and you want to add the hooks to your
+% own commands in the proper position you can define the command and
+% manually add the \cs{UseHook} calls inside the command in the proper
+% positions, and manually define the hooks with \cs{NewHook} or
+% \cs{NewReversedHook}.  When the hooks are explicitly defined,
+% patching is not attempted so you can make sure your command works
+% properly.  For example, an (admittedly not really useful) command
+% that typesets its contents in a framed box with width optionally
+% given in parentheses:
+% \begin{verbatim}
+%    \newcommand\fancybox{\@ifnextchar({\@fancybox}{\@fancybox(5cm)}}
+%    \def\@fancybox(#1)#2{\fbox{\parbox{#1}{#2}}}
+% \end{verbatim}
+% If you try that definition, then add some code after it with
+% \begin{verbatim}
+%    \AddToHook{cmd/fancybox/after}{<code>}
+% \end{verbatim}
+% and then use the \cs[no-index]{fancybox} command you will see that it
+% will be completely broken, because the hook will get executed in the
+% middle of parsing for optional \texttt{(...)} argument.
+%
+% If, on the other hand, you want to add hooks to your command you can
+% do something like:
+% \begin{verbatim}
+%   \newcommand\fancybox{\@ifnextchar({\@fancybox}{\@fancybox(5cm)}}
+%   \def\@fancybox(#1)#2{\fbox{%
+%                        \UseHook{cmd/fancybox/before}%
+%                        \parbox{#1}{#2}%
+%                        \UseHook{cmd/fancybox/after}}}
+%   \NewHook{cmd/fancybox/before}
+%   \NewReversedHook{cmd/fancybox/after}
+% \end{verbatim}
+% then the hooks will be executed where they should and no patching
+% will be attempted.  It is important that the hooks are declared with
+% \cs{NewHook} or \cs{NewReversedHook}, otherwise the command hook
+% code will try to patch the command.  Note also that the call to
+% |\UseHook{cmd/fancybox/before}| does not need to be in the
+% definition of \cs[no-index]{fancybox}, but anywhere it makes sense
+% to insert it (in this case in the internal
+% \cs[no-index]{@fancybox}).
+%
+% Alternatively, if for whatever reason your command does not support
+% the generic hooks provided here, you can disable a hook with
+% \cs{DisableHook}\footnote{Please use \cs{DisableHook} if at all, only
+% on hooks that you \enquote{own}, i.e., for commands that your
+% package or class defines and not second guess
+% whether or not hooks of other packages should get disabled!}, so
+% that when someone tries to add code to it they will get an error.
+% Or if you don't want the error, you can simply declare the hook with
+% \cs{NewHook} and never use it.
+%
+%
+% The above approach is useful for really complex commands where for
+% one or the other reason the hooks can't be placed at the very
+% beginning and end of the command body and some hand-crafting is
+% needed. However, in the example above the real (and in fact only)
+% issue is the cascading argument parsing in the style developed long
+% ago in \LaTeX~2.09. Thus, a much simpler solution for this case is
+% to replace it with the modern \cs{NewDocumentCommand} syntax and
+% define the command as follows:
+% \begin{verbatim}
+%  \DeclareDocumentCommand\fancybox{D(){5cm}m}{\fbox{\parbox{#1}{#2}}}
+% \end{verbatim}
+% If you do that then both hooks automatically work and are patched
+% into the right places.
+%
+% \StopEventually{\setlength\IndexMin{200pt}  \PrintIndex  }
+%
+%
+%
+% \section{The Implementation}
+%
+% \subsection{Execution plan}
+%
+% To add |before| and |after| hooks to a command we will need to peek
+% into the definition of a command, which is always a tricky thing to
+% do.  Some cases are easy because we know how the command was defined,
+% so we can assume how its \meta{parameter text} looks like (for example
+% a command defined with \tn{newcommand} may have an optional argument
+% followed by a run of mandatory arguments), so we can just expand that
+% command and make it grab |#1|, |#2|, etc.\@ as arguments and
+% define it all back with the hooks added.
+%
+% Life's usually not that easy, so with some commands we can't do that
+% (a |#1| might as well be |#|$_{12}$|1|$_{12}$ instead of the expected
+% |#|$_{6}$|1|$_{12}$, for example) so we need to resort to ``patching''
+% the command: read its \tn{meaning}, and tokenize it again with
+% \tn{scantokens} and hope for the best.
+%
+% So the overall plan is:
+% \begin{enumerate}
+%   \item
+%     Check if a command is of a known type (that is, defined with
+%     \tn{newcommand}\footnote{It's not always possible to reliably
+%     detect this case because a command defined with no optional
+%     argument is indistinguishable from a \tn{def}ed command.},
+%     \cs[no-index]{DeclareRobustCommand}, or
+%     \cs[no-index]{New(Expandable)DocumentCommand}), and if is, take
+%     appropriate action.
+%   \item
+%     If the command is not a known type, we'll check if the command can
+%     be patched.  Two things will prevent a command from being
+%     patched:  if it was defined in a nonstandard catcode setting, or
+%     if it is an internal expl3 command with |__|\meta{module} in its
+%     name, in which case we refuse to patch.
+%   \item
+%     If the command was defined in nonstandard catcode settings, we
+%     will try a few standard ones to try our best to carry out the
+%     pathing.  If this doesn't help either, the code will give up and
+%     throw an error.
+% \end{enumerate}
+%
+%
+%    \begin{macrocode}
+%<@@=hook>
+%    \end{macrocode}
+%
+% \changes{v1.0b}{2021/05/24}{Use \cs{msg_...} instead of \cs{__kernel_msg...}}
+%
+%    \begin{macrocode}
+%<*2ekernel|latexrelease>
+\ExplSyntaxOn
+%<latexrelease>\NewModuleRelease{2021/06/01}{ltcmdhooks}
+%<latexrelease>                 {The~hook~management~system~for~commands}
+%    \end{macrocode}
+%
+% \subsection{Variables}
+%
+% \begin{macro}[int]{\g_hook_patch_action_list_tl}
+%    Pairs of |\if<cmd>..\patch<cmd>| to be used with
+%    \tn{robust at command@act} when looking for a known patching
+%    rule. This token list is exposed because we see some future
+%    applications (with very specialized packages, such as
+%    \pkg{etoolbox} that may want to extend the pairs processed. It is
+%    not meant for general use which is why it is not documented in
+%    the interface documentation above.
+%    \begin{macrocode}
+\tl_new:N \g_hook_patch_action_list_tl
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_@@_patch_num_args_int}
+%   The number of arguments in a macro being patched.
+%    \begin{macrocode}
+\int_new:N \l_@@_patch_num_args_int
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_@@_patch_prefixes_tl}
+% \begin{macro}{\l_@@_patch_param_text_tl}
+% \begin{macro}{\l_@@_patch_replacement_tl}
+%   The prefixes and parameters of the definition for the macro being
+%   patched.
+%    \begin{macrocode}
+\tl_new:N \l_@@_patch_prefixes_tl
+\tl_new:N \l_@@_patch_param_text_tl
+\tl_new:N \l_@@_patch_replacement_tl
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\g_@@_delayed_patches_prop}
+%   A list containing the patches delayed to |\begin{document}|, so that
+%   patching is not attempted twice.
+%    \begin{macrocode}
+\prop_new:N \g_@@_delayed_patches_prop
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_patch_debug:x}
+%   A helper for patching debug info.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_patch_debug:x #1
+  { \@@_debug:n { \iow_term:x { [lthooks]~#1 } } }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Variants}
+%
+% \begin{macro}[int]{\tl_rescan:nV}
+%   \pkg{expl3} function variants used throughout the code.
+%    \begin{macrocode}
+\cs_generate_variant:Nn \tl_rescan:nn { nV }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Patching or delaying}
+%
+% \begin{macro}{\@@_try_put_cmd_hook:n,\@@_try_put_cmd_hook:w}
+%   Before |\begin{document}| all patching is delayed.
+%   This function is called from within \cs{AddToHook}, when code is
+%   added to a generic |cmd| hook is newly declared.  It checks whether
+%   the patch position is valid, then proceeds to trying to patch or
+%   delaying to |\begin{document}| if in the preamble.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_try_put_cmd_hook:n #1
+  { \@@_try_put_cmd_hook:w #1 / / / \s_@@_mark {#1} }
+\cs_new_protected:Npn \@@_try_put_cmd_hook:w
+    #1 / #2 / #3 / #4 \s_@@_mark #5
+  {
+    \@@_debug:n { \iow_term:n { ->~Adding~cmd~hook~to~'#2'~(#3): } }
+    \str_case:nnTF {#3}
+        { { before } { } { after } { } }
+      { \exp_args:Nc \@@_patch_cmd_or_delay:Nnn {#2} {#2} {#3} }
+      { \msg_error:nnnn { hooks } { wrong-cmd-hook } {#2} {#3} }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_patch_cmd_or_delay:Nnn}
+% \begin{macro}{\@@_cmd_begindocument_code:}
+%   In the preamble, \cs{@@_patch_cmd_or_delay:Nnn} just adds the patch
+%   instruction to a property list to be executed later.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_patch_cmd_or_delay:Nnn #1 #2 #3
+  {
+    \@@_debug:n { \iow_term:n { ->~Add~generic~cmd~hook~for~#2~(#3). } }
+    \@@_debug:n
+      { \iow_term:n { !~In~the~preamble:~delaying. } }
+    \prop_gput:Nnn \g_@@_delayed_patches_prop { #2 / #3 }
+      { \@@_cmd_try_patch:nn {#2} {#3} }
+  }
+%    \end{macrocode}
+%
+%   The delayed patches are added to a property list to prevent
+%   duplication, and the code stored in the property list for each
+%   key is executed.  The function \cs{@@_patch_cmd_or_delay:Nnn} is
+%   also redefined to be \cs{@@_patch_command:Nnn} so that no further
+%   delaying is attempted.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_cmd_begindocument_code:
+  {
+    \cs_gset_eq:NN \@@_patch_cmd_or_delay:Nnn \@@_patch_command:Nnn
+    \prop_map_function:NN \g_@@_delayed_patches_prop { \use_ii:nn }
+    \prop_gclear:N \g_@@_delayed_patches_prop
+    \cs_undefine:N \@@_cmd_begindocument_code:
+  }
+\g at addto@macro \@kernel at after@begindocument
+  { \@@_cmd_begindocument_code: }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_cmd_try_patch:nn}
+%   At |\begin{document}| tries patching the command if the hook
+%   was not manually created in the meantime.  If the document does not
+%   exist, no error is raised here as it may hook into a package that
+%   wasn't loaded.  Hooks added to commands in the document body still
+%   raise an error if the command is not defined.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_cmd_try_patch:nn #1 #2
+  {
+    \@@_debug:n
+      { \iow_term:x { ->~\string\begin{document}~try~cmd / #1 / #2. } }
+    \@@_if_declared:nTF { cmd / #1 / #2 }
+      {
+        \@@_debug:n
+          { \iow_term:n { .->~Giving~up:~hook~already~created. } }
+      }
+      {
+        \cs_if_exist:cT {#1}
+          { \exp_args:Nc \@@_patch_command:Nnn {#1} {#1} {#2} }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+% \subsection{Patching commands}
+%
+% \begin{macro}{\@@_patch_command:Nnn}
+% \begin{macro}{\@@_patch_check:NNnn}
+% \begin{macro}[TF]{\@@_if_public_command:N}
+% \begin{macro}{\@@_if_public_command:w}
+%   \cs{@@_patch_command:Nnn} will do some sanity checks on the
+%   argument to detect if it is possible to add hooks to the command,
+%   and raises an error otherwise.  If the command can contain hooks,
+%   then it uses \tn{robust at command@act} to find out what type is the
+%   command, and patch it accordingly.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_patch_command:Nnn #1 #2 #3
+  {
+    \@@_patch_debug:x { analyzing~'\token_to_str:N #1' }
+    \@@_patch_debug:x { \token_to_str:N #1 = \token_to_meaning:N #1 }
+    \@@_patch_check:NNnn \cs_if_exist:NTF #1 { undef }
+      {
+        \@@_patch_debug:x { ++~control~sequence~is~defined }
+        \@@_patch_check:NNnn \token_if_macro:NTF #1 { macro }
+          {
+            \@@_patch_debug:x { ++~control~sequence~is~a~macro }
+            \@@_patch_check:NNnn \@@_if_public_command:NTF #1 { expl3 }
+              {
+                \@@_patch_debug:x { ++~macro~is~not~private }
+                \robust at command@act
+                  \g_hook_patch_action_list_tl #1
+                  \@@_retokenize_patch:Nnn { #1 {#2} {#3} }
+              }
+          }
+      }
+  }
+%    \end{macrocode}
+%
+%   And here's the auxiliary used above:
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_patch_check:NNnn #1 #2 #3 #4
+  {
+    #1 #2 {#4}
+      {
+        \msg_error:nnxx { hooks } { cant-patch }
+          { \token_to_str:N #2 } {#3}
+      }
+  }
+%    \end{macrocode}
+%   and a conditional \cs{@@_if_public_command:N} to check if a command
+%   has |__| in its name (no other checking is performed).  Primitives
+%   with |:D| in their name could be included here, but they are already
+%   discarded in the \cs{token_if_macro:NTF} test above.
+%    \begin{macrocode}
+\use:x
+  {
+    \prg_new_protected_conditional:Npnn
+        \exp_not:N \@@_if_public_command:N ##1 { TF }
+      {
+        \exp_not:N \exp_last_unbraced:Nf
+          \exp_not:N \@@_if_public_command:w
+            { \exp_not:N \cs_to_str:N ##1 }
+          \tl_to_str:n { _ _ } \s_@@_mark
+      }
+  }
+\exp_last_unbraced:NNNNo
+\cs_new_protected:Npn \@@_if_public_command:w
+    #1 \tl_to_str:n { _ _ } #2 \s_@@_mark
+  {
+    \tl_if_empty:nTF {#2}
+      { \prg_return_true: }
+      { \prg_return_false: }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+%
+% \subsubsection{Patching by expansion and redefinition}
+%
+% \begin{macro}[int]{\g_hook_patch_action_list_tl}
+%    This is the list of known command types and the function that
+%    patches the command hooks into them.  The conditionals are taken
+%    from \tn{ShowCommand}, \tn{NewCommandCopy} and
+%    \cs{__kernel_cmd_if_xparse:NTF} defined in \texttt{ltcmd}.
+%    \begin{macrocode}
+\tl_gset:Nn \g_hook_patch_action_list_tl
+  {
+    { \@if at DeclareRobustCommand \@@_patch_DeclareRobustCommand:Nnn }
+    { \@if at newcommand \@@_patch_newcommand:Nnn }
+    { \__kernel_cmd_if_xparse:NTF \@@_cmd_patch_xparse:Nnn }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+% \begin{macro}{\@@_patch_DeclareRobustCommand:Nnn}
+%   At this point we know that the commands can be patched by expanding
+%   then redefining.  These are the cases of commands defined with
+%   \tn{newcommand} with an optional argument or with
+%   \tn{DeclareRobustCommand}.
+%
+%   With \cs{@@_patch_DeclareRobustCommand:Nnn} we check if the command
+%   has an optional argument (with a test counter-intuitively called
+%   \tn{@if at newcommand}).  If so, we forward the action to
+%   \cs{@@_patch_newcommand:Nnn}, otherwise call the patching engine
+%   \cs{@@_patch_expand_redefine:NNnn} with a \cs{c_false_bool} to
+%   indicate that there is no optional argument.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_patch_DeclareRobustCommand:Nnn #1
+  {
+    \exp_args:Nc \@if at newcommand { \cs_to_str:N #1 ~ }
+      { \exp_args:Nc \@@_patch_newcommand:Nnn }
+      { \exp_args:NNc \@@_patch_expand_redefine:NNnn \c_false_bool }
+        { \cs_to_str:N #1 ~ }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\@@_patch_newcommand:Nnn}
+%   If the command was defined with \tn{newcommand} and an optional
+%   argument, call the patching engine with a \cs{c_true_bool} to flag
+%   the presence of an optional argument, and with
+%   \cs[no-index]{\string\command} to patch the actual code for
+%   \cs[no-index]{command}.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_patch_newcommand:Nnn #1
+  {
+    \exp_args:NNc \@@_patch_expand_redefine:NNnn \c_true_bool
+      { \c_backslash_str \cs_to_str:N #1 }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%  \begin{macro}{\@@_cmd_patch_xparse:Nnn}
+%    And for commands defined by the \pkg{xparse} commands use this
+%    for patching:
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_cmd_patch_xparse:Nnn #1
+  {
+    \exp_args:NNc \@@_patch_expand_redefine:NNnn \c_false_bool
+      { \cs_to_str:N #1 ~ code }
+  }
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%
+%
+% \begin{macro}{\@@_patch_expand_redefine:NNnn}
+% \begin{macro}[EXP]{\@@_make_prefixes:w}
+%   Now the real action begins.  Here we have in |#1| a boolean
+%   indicating if the command has a |[|\ldots|]|-delimited argument, in
+%   |#2| the command control sequence, in |#3| the name of the command
+%   (note that |#1|${}\ne{}$|\csname#2\endcsname| at this point!), and
+%   in |#4| the hook position, either |before| or |after|.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_patch_expand_redefine:NNnn #1 #2 #3 #4
+  {
+    \@@_patch_debug:x { ++~command~can~be~patched~without~rescanning }
+%    \end{macrocode}
+%   We'll start by counting the number of arguments in the command by
+%   counting the number of characters in the \cs{cs_argument_spec:N} of
+%   the macro, divided by two, and subtracting one if the command has an
+%   optional argument (that is, an extra |[]| in its
+%   \meta{parameter text}).
+%    \begin{macrocode}
+    \int_set:Nn \l_@@_patch_num_args_int
+      {
+        \exp_args:Nf \str_count:n { \cs_argument_spec:N #2 } / 2
+        \bool_if:NT #1 { -1 }
+      }
+%    \end{macrocode}
+%   Now build two token lists:
+%   \begin{description}
+%     \item[\cs{l_@@_patch_param_text_tl}] will contain the
+%       \meta{parameter text} to be used when redefining the macro.  It
+%       should be identical to the \meta{parameter text} used when
+%       originally defining that macro.
+%     \item[\cs{l_@@_patch_replacement_tl}] will contain braced pairs of
+%       |#|$_{12}$\meta{num} to feed to the macro when expanded.  This
+%       token list as well as the previous will have the first item
+%       surrounded by |[|\ldots|]| in the case of an optional argument.
+%   \end{description}
+%    \begin{macrocode}
+    \int_compare:nNnTF { \l_@@_patch_num_args_int } > { \c_zero_int }
+      {
+        \tl_set:Nx \l_@@_patch_param_text_tl
+          { \bool_if:NTF #1 { [####1] } {  ####1  } }
+        \tl_set:Nx \l_@@_patch_replacement_tl
+          { \bool_if:NTF #1 { [####1] } { {####1} } }
+        \int_step_inline:nnn { 2 } { \l_@@_patch_num_args_int }
+          {
+            \tl_put_right:Nn \l_@@_patch_param_text_tl    { ## ####1 }
+            \tl_put_right:Nn \l_@@_patch_replacement_tl { { ## ####1 } }
+          }
+      }
+      {
+        \tl_clear:N \l_@@_patch_param_text_tl
+        \tl_clear:N \l_@@_patch_replacement_tl
+      }
+%    \end{macrocode}
+%   Finally, before redefining, we need to also get the prefixes used
+%   when defining the command.  Here we ensure that the \tn{escapechar}
+%   is printable, otherwise a macro defined with prefixes
+%   |\protected \long| will have it \tn{meaning} printed as
+%   |protectedlong|, making life unnecessarily complicated.  Here the
+%   \tn{escapechar} is changed to |/|, then we loop between pairs of
+%   |/|\ldots|/| extracting the prefixes.
+%    \begin{macrocode}
+    \group_begin:
+      \int_set:Nn \tex_escapechar:D { `\/ }
+      \use:x
+        {
+    \group_end:
+    \tl_set:Nx \exp_not:N \l_@@_patch_prefixes_tl
+      { \exp_not:N \@@_make_prefixes:w \cs_prefix_spec:N #2 / / }
+        }
+%    \end{macrocode}
+%   Now that all the needed tools are ready, without further ado we'll
+%   redefine the command |#2|.  The definition uses the prefixes
+%   gathered in \cs{l_@@_patch_prefixes_tl}, a primitive \cs{tex_def:D}
+%   to avoid adding extra prefixes, and the \meta{parameter text} from
+%   \cs{l_@@_patch_param_text_tl}.
+%
+%   Then finally, in the body of the definition, we insert
+%   \hook{cmd/\#3/before} if |#4| is |before|, the code of the
+%   command expanded once grabbing the parameters in
+%   \cs{l_@@_patch_replacement_tl}, and \hook{cmd/\#3/after} if |#4| is
+%   |after|.
+%    \begin{macrocode}
+    \use:x
+      {
+        \l_@@_patch_prefixes_tl \tex_def:D
+            \exp_not:N #2 \exp_not:V \l_@@_patch_param_text_tl
+          {
+            \str_if_eq:nnT {#4} { before }
+              { \exp_not:N \UseHook { cmd / #3 / #4 } }
+            \exp_args:No \exp_not:o
+              { \exp_after:wN #2 \l_@@_patch_replacement_tl }
+            \str_if_eq:nnT {#4} { after }
+              { \exp_not:N \UseHook { cmd / #3 / #4 } }
+          }
+      }
+  }
+%    \end{macrocode}
+%
+%   Here's the auxiliary that makes the prefix control sequences for the
+%   redefinition.  Each item has to be \cs{tl_trim_spaces:n}'d because
+%   the last item (and not any other) has a trailing space.
+%    \begin{macrocode}
+\cs_new:Npn \@@_make_prefixes:w / #1 /
+  {
+    \tl_if_empty:nF {#1}
+      {
+        \exp_not:c { tex_ \tl_trim_spaces:n {#1} :D }
+        \@@_make_prefixes:w /
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+% \subsubsection{Patching by retokenization}
+%
+% At this point we've drained the possibilities of patching a command by
+% expansion-and-redefinition, so we have to resort to patching by
+% retokenizing the command.  Patching by retokenization is done by
+% getting the \tn{meaning} of the command, doing the necessary
+% manipulations on the generated string, and the retokenizing that again
+% by using \tn{scantokens}.
+%
+% Patching by retokenization is definitely a riskier business, because
+% it relies that the tokens printed by \tn{meaning} produce the exact
+% same tokens as the ones in the original definition.  That is, the
+% catcode régime must be exactly(ish) the same, and there is no way of
+% telling except by trial and error.
+%
+% \begin{macro}{\@@_retokenize_patch:Nnn}
+%   This is the macro that will control the whole process.  First we'll
+%   try out one final, rather trivial case, of a command with no
+%   arguments;  that is, a token list.  This case can be patched with
+%   the expand-and-redefine routine but it has to be the very last case
+%   tested for, because most (all?) robust commands start with a
+%   top-level macro with no arguments, so testing this first would
+%   short-circuit \tn{robust 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{@@_patch_expand_redefine:NNnn}.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_retokenize_patch:Nnn #1 #2 #3
+  {
+    \@@_patch_debug:x { ..~command~can~only~be~patched~by~rescanning }
+    \str_if_eq:eeTF { \cs_argument_spec:N #1 } { }
+      { \@@_patch_expand_redefine:NNnn \c_false_bool #1 {#2} {#3} }
+      {
+%    \end{macrocode}
+%
+%   Otherwise, we start the actual patching by retokenization job.  The
+%   code calls \cs{@@_try_patch_with_catcodes:Nnnnw} with a different
+%   catcode setting:
+%   \begin{itemize}
+%     \item The current catcode setting;
+%     \item Switching the catcode of |@|;
+%     \item Switching the \pkg{expl3} syntax on or off;
+%     \item Both of the above.
+%   \end{itemize}
+%
+%   If patching succeeds, \cs{@@_try_patch_with_catcodes:Nnnnw} has the
+%   side-effect of patching the macro |#1| (which may be an internal
+%   from the command whose name is~|#2|).
+%    \begin{macrocode}
+        \tl_set:Nx \l_@@_tmpa_tl
+          {
+            \int_compare:nNnTF { \char_value_catcode:n {`\@ } } = { 12 }
+              { \exp_not:N \makeatletter } { \exp_not:N \makeatother }
+          }
+        \tl_set:Nx \l_@@_tmpb_tl
+          {
+            \bool_if:NTF \l__kernel_expl_bool
+              { \ExplSyntaxOff } { \ExplSyntaxOn }
+          }
+        \use:x
+          {
+            \exp_not:N \@@_try_patch_with_catcodes:Nnnnw
+                \exp_not:n { #1 {#2} {#3} }
+              { \prg_do_nothing: }
+              { \exp_not:V \l_@@_tmpa_tl } % @
+              { \exp_not:V \l_@@_tmpb_tl } % _:
+              {
+                \exp_not:V \l_@@_tmpa_tl   % @
+                \exp_not:V \l_@@_tmpb_tl   % _:
+              }
+          }
+              \q_recursion_tail \q_recursion_stop
+%    \end{macrocode}
+%
+%   If no catcode setting succeeds, give up and raise an error.  The
+%   command isn't changed in any way in that case.
+%    \begin{macrocode}
+          {
+            \msg_error:nnxx { hooks } { cant-patch }
+              { \c_backslash_str #2 } { retok }
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\@@_try_patch_with_catcodes:Nnnnw}
+%   This function is a simple wrapper around
+%   \cs{@@_cmd_if_scanable:NnTF} and \cs{@@_patch_retokenize:Nnnn} if
+%   the former returns \meta{true}, plus some debug messages.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_try_patch_with_catcodes:Nnnnw #1 #2 #3 #4
+  {
+    \quark_if_recursion_tail_stop_do:nn {#4} { \use:n }
+    \@@_patch_debug:x { ++~trying~to~patch~by~retokenization }
+    \@@_cmd_if_scanable:NnTF {#1} {#4}
+      {
+        \@@_patch_debug:x { ++~macro~can~be~retokenized~cleanly }
+        \@@_patch_debug:x { ==~retokenizing~macro~now }
+        \@@_patch_retokenize:Nnnn #1 {#2} {#3} {#4}
+        \use_i_delimit_by_q_recursion_stop:nw \use_none:n
+      }
+      {
+        \@@_patch_debug:x { --~macro~cannot~be~retokenized~cleanly }
+        \@@_try_patch_with_catcodes:Nnnnw #1 {#2} {#3}
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+% \begin{macro}[int]{\kerneltmpDoNotUse}
+%   This is an oddity required to be safe (as safe as reasonably
+%   possible) when patching the command.  The entirety of
+%   \begin{quote}
+%     \meta{prefixes} \tn{def} \meta{cs} \meta{parameter text}
+%       |{|\meta{replacement text}|}|
+%   \end{quote}
+%   will go through \tn{scantokens}.  The \meta{parameter text} and
+%   \meta{replacement text} are what we are trying to retokenize, so not
+%   much worry there.  The other items, however, should ``just work'',
+%   so some care is needed to not use too fancy catcode settings.
+%   Therefore we can't use an \pkg{expl3}-named macro for \meta{cs}, nor
+%   the \pkg{expl3} versions of \tn{def} or the \meta{prefixes}.
+%   That is why the definitions that will eventually go into
+%   \tn{scantokens} will use the oddly (but hopefully clearly)-named
+%   \cs{kerneltmpDoNotUse}:
+%    \begin{macrocode}
+\cs_new_eq:NN \kerneltmpDoNotUse !
+%    \end{macrocode}
+%   \phoinline{Maybe this can be avoided by running the \meta{parameter text}
+%     and the \meta{replacement text} separately through \tn{scantokens}
+%     and then putting everything together at the end.}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\@@_patch_required_catcodes:}
+%   Here are the catcode settings that are \emph{mandatory} when
+%   retokenizing commands.  These are the minimum necessary settings to
+%   perform the definitions:  they identify control sequences, which
+%   must be escaped with |\|$_0$, delimit the definition with |{|$_1$
+%   and |}|$_2$, and mark parameters with |#|$_6$.  Everything else may
+%   be changed, but not these.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_patch_required_catcodes:
+  {
+    \char_set_catcode_escape:N \\
+    \char_set_catcode_group_begin:N \{
+    \char_set_catcode_group_end:N \}
+    \char_set_catcode_parameter:N \#
+    % \int_set:Nn \tex_endlinechar:D { -1 }
+    % \int_set:Nn \tex_newlinechar:D { -1 }
+  }
+%    \end{macrocode}
+%   \phoinline{\pkg{etoolbox} sets the \tn{endlinechar} and \tn{newlinechar}
+%     when patching, but as far as I tested these didn't make much of
+%     a difference, so I left them out for now.  Maybe
+%     \tn{newlinechar}|=-1| avoids a space token being added after the
+%     definition.}
+%   \phoinline{If the patching is split by \meta{parameter text} and
+%     \meta{replacement text}, then only \# will have to stay in that
+%     list.}
+%   \phoinline{Actually now that we patch
+%     \texttt{\cs{UseHook}\{cmd/foo/before\}}, all the tokens there need
+%     to have the right catcodes, so this list now includes all
+%     lowercase letters, U and H, the slash, and whatever characters in
+%     the command name\ldots sigh\ldots}
+% \end{macro}
+%
+%
+%
+%
+% \begin{macro}[TF]{\@@_cmd_if_scanable:Nn}
+%   Here we'll do a quick test if the command being patched can in fact
+%   be retokenized with the specific catcode setting without changing
+%   in meaning.  The test is straightforward:
+%   \begin{enumerate}
+%     \item apply \tn{meaning} to the command;
+%     \item split the \meta{prefixes}, \meta{parameter text} and
+%       \meta{replacement text} and arrange them as
+%       \begin{quote}
+%         \meta{prefixes}\tn{def}\cs{kerneltmpDoNotUse}%^^A
+%           \meta{parameter text}|{|\meta{replacement text}|}|
+%       \end{quote}
+%     \item rescan that with the given catcode settings, and do
+%       the definition; then finally
+%     \item compare \cs{kerneltmpDoNotUse} with the original command.
+%   \end{enumerate}
+%   If both are \tn{ifx}-equal, the command can be safely patched.
+%    \begin{macrocode}
+\prg_new_protected_conditional:Npnn \@@_cmd_if_scanable:Nn #1 #2 { TF }
+  {
+    \cs_set_eq:NN \kerneltmpDoNotUse \scan_stop:
+    \cs_set_eq:NN \@@_tmp:w \scan_stop:
+    \use:x
+      {
+        \cs_set:Npn \@@_tmp:w
+            ####1 \tl_to_str:n { macro: } ####2 -> ####3 \s_@@_mark
+          { ####1 \def \kerneltmpDoNotUse ####2   {####3} }
+        \tl_set:Nx \exp_not:N \l_@@_tmpa_tl
+          { \exp_not:N \@@_tmp:w \token_to_meaning:N #1 \s_@@_mark }
+      }
+    \tl_rescan:nV { #2 \@@_patch_required_catcodes: } \l_@@_tmpa_tl
+    \token_if_eq_meaning:NNTF #1 \kerneltmpDoNotUse
+      { \prg_return_true: }
+      { \prg_return_false: }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\@@_patch_retokenize:Nnnn}
+%   Then, if \cs{@@_cmd_if_scanable:NnTF} returned true, we can go on
+%   and patch the command.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_patch_retokenize:Nnnn #1 #2 #3 #4
+  {
+%    \end{macrocode}
+%   Start off by making some things \tn{relax} to avoid lots of
+%   \tn{noexpand} below.
+%    \begin{macrocode}
+    \cs_set_eq:NN \kerneltmpDoNotUse \scan_stop:
+    \cs_set_eq:NN \@@_tmp:w \scan_stop:
+    \use:x
+      {
+%    \end{macrocode}
+%   Now we'll define \cs{@@_tmp:w} such that it splits the \tn{meaning}
+%   of the macro (|#1|) into its three parts:
+%   \begin{enumerate}
+%     \def\makelabel#1{\texttt{\#\#\#\##1}}
+%     \item \meta{prefixes}
+%     \item \meta{parameter text}
+%     \item \meta{replacement text}
+%   \end{enumerate}
+%   and arrange that a complete definition, then place the |before|
+%   or |after| hooks around the \meta{replacement text}:
+%   accordingly.
+%    \begin{macrocode}
+        \cs_set:Npn \@@_tmp:w
+            ####1 \tl_to_str:n { macro: } ####2 -> ####3 \s_@@_mark
+          {
+            ####1 \def \kerneltmpDoNotUse ####2
+              {
+                \str_if_eq:nnT {#3} { before }
+                  { \token_to_str:N \UseHook { cmd / #2 / #3 } }
+                ####3
+                \str_if_eq:nnT {#3} { after }
+                  { \token_to_str:N \UseHook { cmd / #2 / #3 } }
+              }
+          }
+%    \end{macrocode}
+%   Now we just have to get the \tn{meaning} of the command being
+%   patched and pass it through the meat grinder above.
+%    \begin{macrocode}
+        \tl_set:Nx \exp_not:N \l_@@_tmpa_tl
+          { \exp_not:N \@@_tmp:w \token_to_meaning:N #1 \s_@@_mark }
+      }
+%    \end{macrocode}
+%   Now rescan with the given catcode settings (overridden by the
+%   \cs{@@_patch_required_catcodes:}), and implicitly (by using the
+%   rescanned token list) carry out the definition from above.
+%    \begin{macrocode}
+    \tl_rescan:nV { #4 \@@_patch_required_catcodes: } \l_@@_tmpa_tl
+%    \end{macrocode}
+%   And to close, copy the newly-defined command into the old name and
+%   the patching is finally completed:
+%    \begin{macrocode}
+    \cs_set_eq:NN #1 \kerneltmpDoNotUse
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \subsection{Messages}
+%
+%    \begin{macrocode}
+\msg_new:nnnn { hooks } { wrong-cmd-hook }
+  {
+    Generic~hook~`cmd/#1/#2'~is~invalid.
+%    The~hook~should~be~`cmd/#1/before'~or~`cmd/#1/after'.
+  }
+  {
+    You~tried~to~add~a~generic~hook~to~command~\iow_char:N \\#1,~but~`#2'~
+    is~an~invalid~component.~Only~`before'~or~`after'~are~allowed.
+  }
+\msg_new:nnnn { hooks } { cant-patch }
+  {
+    Generic~hooks~cannot~be~added~to~'#1'.
+  }
+  {
+    You~tried~to~add~a~hook~to~'#1',~but~LaTeX~was~unable~to~
+    patch~the~command~because~it~\@@_unpatchable_cases:n {#2}.
+  }
+\cs_new:Npn \@@_unpatchable_cases:n #1
+  {
+    \str_case:nn {#1}
+      {
+        { undef } { doesn't~exist }
+        { macro } { is~not~a~macro }
+        { expl3 } { is~a~private~expl3~macro }
+        { retok } { can't~be~retokenized~cleanly }
+      }
+  }
+%    \end{macrocode}
+%
+%
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{0000/00/00}{ltcmdhooks}%
+%<latexrelease>                 {The~hook~management~system~for~commands}
+%<latexrelease>
+%    \end{macrocode}
+%    The command \cs{@@_cmd_begindocument_code:} is used in an
+%    internal hook, so we need to make sure it has a harmless
+%    definition after rollback as that will not remove it from the
+%    kernel hook.
+%    \begin{macrocode}
+%<latexrelease>\cs_set_eq:NN \@@_cmd_begindocument_code: \prg_do_nothing:
+%<latexrelease>
+%<latexrelease>\EndModuleRelease
+\ExplSyntaxOff
+%</2ekernel|latexrelease>
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<@@=>
+%    \end{macrocode}
+%
+% \Finale
+%


Property changes on: trunk/Master/texmf-dist/source/latex/base/ltcmdhooks.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/source/latex/base/ltcntrl.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltcntrl.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltcntrl.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -32,7 +32,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltcntrl.dtx}
-             [2014/04/21 v1.0h LaTeX Kernel (program control)]
+             [2020/12/04 v1.0h LaTeX Kernel (program control)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltcntrl.dtx}
@@ -241,7 +241,7 @@
 %
 % \begin{macro}{\@for}
 % \changes{v1.0d}{1995/04/24}
-%      {Dont expand second argument with \cs{edef}: /1317 (DPC)}
+%      {Don't expand second argument with \cs{edef}: /1317 (DPC)}
 %    \begin{macrocode}
 \long\def\@for#1:=#2\do#3{%
   \expandafter\def\expandafter\@fortmp\expandafter{#2}%

Modified: trunk/Master/texmf-dist/source/latex/base/ltcounts.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltcounts.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltcounts.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -33,7 +33,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltcounts.dtx}
-             [2018/04/22 v1.1l LaTeX Kernel (Counters)]
+             [2020/12/04 v1.1l LaTeX Kernel (Counters)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltcounts.dtx}
@@ -630,7 +630,7 @@
 %    always selects the correct branch in an |\ifmmode| switch with
 %    the usual disadvantage of ruining kerning. For the application we
 %    use it for here that shouldn't matter. The alternative would be
-%    to mimic |\IeC| from \textsf{inputenc} but then it wil have the
+%    to mimic |\IeC| from \textsf{inputenc} but then it will have the
 %    disadvantage of choosing the wrong branch if appearing at the
 %    beginning of an alignment cell. However, users of e\TeX\ will be
 %    pleasantly surprised to get the best of both worlds and no bad

Modified: trunk/Master/texmf-dist/source/latex/base/ltdefns.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltdefns.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltdefns.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -32,7 +32,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltdefns.dtx}
-             [2020/11/25 v1.5o LaTeX Kernel (definition commands)]
+             [2021/05/27 v1.5p LaTeX Kernel (definition commands)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltdefns.dtx}
@@ -103,7 +103,7 @@
 %    \end{macrocode}
 %
 %
-% \subsection{Initex initialisations}
+% \subsection{Initex initializations}
 %
 % \task{???}{This section needs extension}
 %
@@ -858,7 +858,7 @@
 %    |\CheckCommand| takes the same arguments as |\newcommand|. If
 %    the command already exists, with the same definition, then
 %    nothing happens, otherwise a warning is issued. Useful for
-%    checking the current state befor a macro package starts
+%    checking the current state before a macro package starts
 %    redefining things.  Currently two macros are considered to have
 %    the same definition if they are the same except for different
 %    default arguments.  That is, if the old definition was:
@@ -1217,11 +1217,12 @@
 %    top-level definition to have the right kind of structure, but
 %    this is somewhat problematical as we then have to distinguish
 %    between \cs{long} macros and others and also take into account
-%    that sometimes the top-level is deliberately dones manually (like
+%    that sometimes the top-level is deliberately done manually (like
 %    with \cs{begin}).
 %
 %    The macro firstly checks if the control sequence in question exists
 %    at all.
+% \changes{v1.5p}{2021/05/26}{Normalize error message in \cs{MakeRobust}}
 %    \begin{macrocode}
 %</2ekernel>
 %<latexrelease>\IncludeInRelease{2020/10/01}{\MakeRobust}{\MakeRobust}%
@@ -1230,7 +1231,7 @@
   \count@=\escapechar
   \escapechar=`\\
   \@ifundefined{\expandafter\@gobble\string#1}{%
-    \@latex at error{The control sequence `\string#1' is undefined!%
+    \@latex at error{Command `\string#1' is undefined!%
       \MessageBreak There is nothing here to make robust}%
     \@eha
   }%
@@ -1259,7 +1260,7 @@
         \noexpand\protect\expandafter\noexpand
         \csname\expandafter\@gobble\string#1\space\endcsname}%
     }%
-    {\@latex at info{The control sequence `\string#1' is already robust}}%
+    {\@latex at info{Command `\string#1' is already robust}}%
   }%
   \escapechar=\count@
 }%
@@ -1363,12 +1364,12 @@
 % \end{macro}
 %
 %  \begin{macro}{\kernel at make@fragile}
-%    The opposite of |\MakeRobust| execpt that it doesn't do many
+%    The opposite of |\MakeRobust| except that it doesn't do many
 %    checks as it is internal to the kernel. Why does one want such a
 %    thing?
 %    Only for compatibility reasons if \texttt{latexrelease} requests
 %    a rollback of the kernel. For this reason we pretend that this
-%    command existed in all earler versions of \LaTeX{} i.e., we are
+%    command existed in all earlier versions of \LaTeX{} i.e., we are
 %    not rolling it back since we need it precisely then. But we have
 %    to get it into the \texttt{latexrelease} file so that a roll
 %    forward is possible too.
@@ -1452,7 +1453,7 @@
 %   robust commands.  This code will then be used to test if a command is
 %   robust, considered the different types of robustness, and then either copy
 %   that definition, if \cs{DeclareCommandCopy} (or similar) is used, or show
-%   the definition of the command, if \cs{ShowCommmand} is used.
+%   the definition of the command, if \cs{ShowCommand} is used.
 %
 % \begin{macro}{\robust at command@act}
 % \changes{v1.5k}{2020/08/19}{Made \cs{robust at command@act}
@@ -1471,7 +1472,7 @@
 %     \ldots
 %   \end{quote}
 %   \cs{robust at command@act} will iterate over the \meta{action-list}, evaluating
-%   each \meta{if-type-$n$}\meta{robust-cmd}|{|\meta{true}|}{|\meta{false}|}|.
+%   each \meta{if-type-$n$} \meta{robust-cmd} |{|\meta{true}|}{|\meta{false}|}|.
 %   If the \meta{if-type-$n$} conditional returns \meta{true}, then
 %   \meta{act-type-$n$}\meta{act-arg} is executed, and the loop ends.  If the
 %   conditional returns \meta{false}, then \meta{if-type-$n+1$} is executed in
@@ -1711,7 +1712,7 @@
 % \begin{macro}{\@showcommandlisthook}
 %   The initial definition of \cs{@showcommandlisthook} contains the same tests
 %   as used for copying, but \cs{@show at ...} commands instead of \cs{@copy at ...}.
-%   Same as before, it is initialised to cope with \cs{DeclareRobustCommand} and
+%   Same as before, it is initialized to cope with \cs{DeclareRobustCommand} and
 %   \cs{newcommand} with optional arguments.
 %    \begin{macrocode}
 \def\@showcommandlisthook{%
@@ -2283,7 +2284,7 @@
 %
 % The primitive |\-| command adds a discretionary hyphen using the
 % current font's |\hyphenchar|. Monospace fonts are usually declared
-% with |\hyphenchar| set to $-1$ to suppress hyhenation.
+% with |\hyphenchar| set to $-1$ to suppress hyphenation.
 %
 % \LaTeX, from \LaTeX2.09 in 1986 defined |\-| by
 % \begin{verbatim}
@@ -2419,7 +2420,8 @@
 %
 %
 % \begin{macro}{\g at addto@macro}
-% Globally add to the end of a macro.
+%    Globally add to the end of a macro.
+%    This macro is used by the kernel to add to its internal hooks.
 % \changes{v0.2a}{1993/11/14}{Made global}
 % \changes{v0.2w}{1994/01/31}
 %     {Use toks register to avoid `hash' problems}

Modified: trunk/Master/texmf-dist/source/latex/base/ltdirchk.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltdirchk.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltdirchk.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -37,7 +37,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltdirchk.dtx}
-             [2020/08/21 v1.3a LaTeX Kernel (System Dependent Parts)]
+             [2021/01/15 v1.3a LaTeX Kernel (System Dependent Parts)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltdirchk.dtx}
@@ -63,7 +63,7 @@
 %         {Add unstripped module,
 %          so that dircheck.dtx may be used with initex}
 % \changes{v1.0a}{1994/03/08}
-%         {Reorganise driver module into `new style'}
+%         {Reorganize driver module into `new style'}
 % \changes{v1.0b}{1994/03/12}
 %         {Change name from dircheck.dtx}
 % \changes{v1.0b}{1994/03/12}
@@ -81,13 +81,13 @@
 % \changes{v1.0w}{1998/08/17}{(RmS) Documentation improvements.}
 %
 %
-% \section{\LaTeX\ System Dependent Initialisations}
+% \section{\LaTeX\ System Dependent Initializations}
 %
 % \changes{v0.2g}{1994/01/21}
-%         {Improve documentation, reorganise docstrip module}
+%         {Improve documentation, reorganize docstrip module}
 %
 % This file implements the semi-automatic determination of various
-% system dependent parts of the initialisation. The actual definitions
+% system dependent parts of the initialization. The actual definitions
 % may be placed in a file |texsys.cfg|. Thus for operating systems for
 % which the tests here do not result in acceptable settings, a `hand
 % written' |texsys.cfg| may be produced.
@@ -127,14 +127,16 @@
 % |\input at path| should expand to a list of such directories, each in a
 % |{}| group.
 %
+% \begin{sloppypar}
 % \DescribeMacro{\filename at parse}
 % After a call of the form: |\filename at parse{|\meta{filename}|}|, the
-% three macros |\filename at area|,|\filename at base|,|\filename at ext| should
+% three macros |\filename at area|, |\filename at base| and |\filename at ext| should
 % be defined to be the `area' (or directory), basename and
 % extension respectively. If there was no extension specified in
 % \meta{filename}, |\filename at ext| should be |\let| to |\relax| (so this
 % case may be tested with |\@ifundefined{filename at ext}| and, perhaps a
 % default extension substituted).
+% \end{sloppypar}
 %
 % Normally one would not need to define this macro in |texsys.cfg| as
 % the automatic tests can supply parsers that work with UNIX and VMS and
@@ -153,7 +155,7 @@
 %
 % \DescribeMacro{\@TeXversion}
 % \changes{v1.0f}{1994/05/23}{Document \cs{@TeXversion}}
-% |\@TeXversion| is now set automatically by the initialisation tests
+% |\@TeXversion| is now set automatically by the initialization tests
 % in this file. You should not need to set it in |texsys.cfg|, however
 % the following documentation is left for information. \LaTeX\ does
 % not set this variable exactly, the automatic tests set it to:\\
@@ -206,7 +208,7 @@
 %
 % \StopEventually{}
 %
-% \section{Initialisation}
+% \section{Initialization}
 % As this file is read at a very early stage, some definitions that
 % are normally considered to be part of the format must be made here.
 %
@@ -470,18 +472,20 @@
 % |{}| group.
 %
 %
+% \begin{sloppypar}
 % \DescribeMacro{\filename at parse}
 % After a call of the form: |\filename at parse{|\meta{filename}|}|, the
-% three macros |\filename at area|,|\filename at base|,|\filename at ext| should
+% three macros |\filename at area|, |\filename at base|, |\filename at ext| should
 % be defined to be the `area' (or directory), basename and
 % extension respectively. If there was no extension specified in
 % \meta{filename}, |\filename at ext| should be |\let| to |\relax| (so this
 % case may be tested with |\@ifundefined{filename at ext}| and, perhaps a
 % default extension substituted).
+% \end{sloppypar}
 %
 % Normally one would not need to define this macro in |texsys.cfg| as
 % the automatic tests can supply parsers that work with UNIX and VMS
-% syntax, as well as a basic parser that willcover many other cases.
+% syntax, as well as a basic parser that will cover many other cases.
 % However some operating systems may need a `hand produced' parser
 % in which case it should be defined in this file.
 %
@@ -794,7 +798,7 @@
 % to supply the correct information to the prompts. Now the interaction
 % is omitted. After the format is made the installer can attempt to run
 % the test document |ltxcheck.tex| through \LaTeXe. This will check,
-% amongst other things, whether |texsys.cfg| will need to be edited and
+% among other things, whether |texsys.cfg| will need to be edited and
 % the format remade.
 %
 % \begin{macro}{\input at path}

Modified: trunk/Master/texmf-dist/source/latex/base/lterror.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/lterror.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/lterror.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/ltexpl.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltexpl.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltexpl.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 2019-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 2019-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -33,7 +33,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltexpl.dtx}
-             [2020/12/18 v1.2h LaTeX Kernel (expl3-dependent code)]
+             [2021/04/20 v1.3c LaTeX Kernel (expl3-dependent code)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltexpl.dtx}
@@ -82,33 +82,60 @@
 %    \begin{macrocode}
 %<*2ekernel|latexrelease>
 %<latexrelease>\IncludeInRelease{2020/10/01}%
-%<latexrelease>  {kernel at enddocument hooks}{Define kernel enddocument Hooks}%
-\let\@kernel at after@enddocument\@empty
-\let\@kernel at after@enddocument at afterlastpage\@empty
+%<latexrelease>  {kernel at enddocument hooks}{Define several kernel hooks}
+%    \end{macrocode}
+%    We only initialize these kernel hooks if they are not already
+%    existing. Otherwise they would be set to \cs{@empty} on rollback
+%    which would be wrong because code that has been added to to them
+%    may still have to be executed in the rollback situation . Instead
+%    code that writes to them needs to handle the rollback as needed.
+%    It is likely that we have to change that approach in the future,
+%    but for now it should do.
+%    (It is enough to test only for the existence of one hook, as all
+%    got added at the same time.)
+% \changes{v1.3c}{2021/04/20}{Don't empty kernel hooks on rollback}
+%    \begin{macrocode}
+\ifx\@kernel at after@enddocument\@undefined
+  \let \@kernel at after@enddocument               \@empty
+  \let \@kernel at after@enddocument at afterlastpage \@empty
+%    \end{macrocode}
+%
+%  \begin{macro}{\@kernel at before@begindocument,\@kernel at after@begindocument}
+%    For the similar reasons we also define those that are used in
+%    \cs{document} because they too get material added to in early modules.
+%    \begin{macrocode}
+  \let \@kernel at before@begindocument \@empty
+  \let \@kernel at after@begindocument  \@empty
+\fi
 %<latexrelease>\EndIncludeInRelease
 %    \end{macrocode}
 %
 %    \begin{macrocode}
 %<latexrelease>\IncludeInRelease{0000/00/00}%
-%<latexrelease>  {kernel at enddocument hooks}{Define kernel enddocument Hooks}%
+%<latexrelease>  {kernel at enddocument hooks}{Define several kernel hooks}
 %<latexrelease>\let\@kernel at after@enddocument\@undefined
 %<latexrelease>\let\@kernel at after@enddocument at afterlastpage\@undefined
+%<latexrelease>\let\@kernel at before@begindocument\@undefined
+%<latexrelease>\let\@kernel at after@begindocument\@undefined
+%</2ekernel|latexrelease>
 %<latexrelease>\EndIncludeInRelease
-%</2ekernel|latexrelease>
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
 %
 % First define some blank commands, so that in case something goes wrong while
 % loading \textsf{expl3}, we won't get strange \texttt{Undefined control
 % sequence} errors.
+% \changes{v1.3a}{2021/01/24}{Define \pkg{expl3} hooks conditionally}
 %    \begin{macrocode}
 %<*2ekernel|latexrelease>
 %<latexrelease>\IncludeInRelease{2020/10/01}%
 %<latexrelease>            {\@expl at sys@load at backend@@}{Roll forward support}%
-\def\@expl at sys@load at backend@@{}
-\def\@expl at push@filename@@{}
-\def\@expl at push@filename at aux@@{}
-\def\@expl at pop@filename@@{}
+\def\reserved at a#1{\ifdefined#1\else\def#1{}\fi}
+\reserved at a\@expl at sys@load at backend@@
+\reserved at a\@expl at push@filename@@
+\reserved at a\@expl at push@filename at aux@@
+\reserved at a\@expl at pop@filename@@
 %<latexrelease>\EndIncludeInRelease
 %</2ekernel|latexrelease>
 %    \end{macrocode}
@@ -188,7 +215,9 @@
 % In \texttt{2ekernel} mode, an error is fatal and building the format
 % is aborted. Use \verb=\batchmode \read -1 to \tokenlist=, which errors
 % with
-% \verb=! Emergency stop. (cannot \read from terminal in nonstop modes)=
+%\begin{verbatim}
+%   ! Emergency stop. (cannot \read from terminal in nonstop modes)
+%\end{verbatim}
 % and aborts the \TeX{} run.  In \texttt{latexrelease} mode, raise an
 % error and do nothing.  Both ways, the error message shows the minimum
 % \textsf{expl3} engine requirements.
@@ -214,7 +243,7 @@
 %</2ekernel>
 %    \end{macrocode}
 %    We do not support a roll forward across 2019. You need to start
-%    with 2019 if you want to get to 2020 or beyond. 
+%    with 2019 if you want to get to 2020 or beyond.
 % \changes{v1.2g}{2020/11/24}{Support for roll forward (gh/434)}
 %    \begin{macrocode}
 %<*latexrelease>
@@ -225,21 +254,18 @@
            --- I'm giving up!\MessageBreak\MessageBreak
            Note that manually loading the expl3 package\MessageBreak
            from your distribution is not enough}%
-        \@@end  % die
+        \batchmode \read -1 to \reserved at a
 %</latexrelease>
       }%
-      {%
-        \input expl3.ltx
-        \ifdefined\NewDocumentCommand
-        \else
-          \IfFileExists{xparse.ltx}
-            {\input xparse.ltx }
-            {}%
-         \fi
-      }%
+      {\input expl3.ltx }%
   }
 %<latexrelease>\EndIncludeInRelease
 %<latexrelease>
+%    \end{macrocode}
+% To support roll-forward for the case where \textsf{xparse} is fully
+% integrated into the kernel, we do not need to repeat the complex test
+% above as we can simply look for the marker command.
+%    \begin{macrocode}
 %<latexrelease>\IncludeInRelease{2020/02/02}%
 %<latexrelease>                 {expl3}{Pre-load expl3}%
 %<latexrelease>\IfFileExists{expl3.ltx}
@@ -262,39 +288,12 @@
 %<latexrelease>\EndIncludeInRelease
 %    \end{macrocode}
 %
+% \changes{v1.3a}{2021/01/21}
+%                {Move \pkg{xparse} rollback code to \texttt{ltcmd.dtx}}
 %
-%    Starting with 2020-10 the kernel contains most of the
-%    \texttt{xparse} interfaces loaded above. These interfaces are
-%    later used to define various user command. However, if somebody
-%    with an earlier installation tries to roll forward (using a
-%    \texttt{latexrelease} package from a newer release) this will not
-%    work as the earlier kernel doesn't contain commands such as
-%    \cs{NewDocumentCommand}.
-%
-%    We therefore add code into \texttt{latexrelease.sty} to load the
-%    \texttt{xparse} package of the current installation instead. this
-%    may not work if the installation is really old, but roll forward
-%    can't do miracles.
-%
-%    If the kernel is 2020-10 or later \cs{NewDocumentCommand} is
-%    already known (whether or not you roll forward or back) so
-%    nothing happens, but if you start from am earlier kernel the
-%    \texttt{xparse} package gets loaded by \texttt{latexrelease}.
-% \changes{v1.2g}{2020/11/24}{Load xparse in latexrelease if needed (gh/434)}
-%    \begin{macrocode}
-%<latexrelease>\IncludeInRelease{2020/10/01}%
-%<latexrelease>                 {\NewDocumentCommand}{Emergency loading xparse}%
-%<latexrelease>
-%<latexrelease>\ifdefined\NewDocumentCommand \else
-%<latexrelease>  \RequirePackage{xparse}
-%<latexrelease>\fi
-%<latexrelease>
-%<latexrelease>\EndIncludeInRelease
-%    \end{macrocode}
-%
 %    \subsection{Using expl3 code}
 %
-%    In order to ease the implemantation of some new features in
+%    In order to ease the implementation of some new features in
 %    \LaTeXe\ we may (temporarily) use some coding based on the
 %    \pkg{expl3}-code.
 %    Such macros will eventually vanish and may be changed

Modified: trunk/Master/texmf-dist/source/latex/base/ltfilehook.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfilehook.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltfilehook.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
-%%
-%% File: ltfilehook.dtx (C) Copyright 2020 Frank Mittelbach,
-%%                                         Phelype Oleinik & LaTeX Team
 %
+% Copyright (C) 2020-2021
+%     Frank Mittelbach, Phelype Oleinik & LaTeX Team
+%
 % This file is part of the LaTeX base system.
 % -------------------------------------------
 %
@@ -31,8 +31,8 @@
 %%% From File: ltfilehook.dtx
 %
 %    \begin{macrocode}
-\providecommand\ltfilehookversion{v1.0e}
-\providecommand\ltfilehookdate{2021/01/07}
+\providecommand\ltfilehookversion{v1.0k}
+\providecommand\ltfilehookdate{2021/05/25}
 %    \end{macrocode}
 %
 %<*driver>
@@ -55,6 +55,10 @@
   }
 \ExplSyntaxOff
 
+\providecommand\InternalDetectionOff{}
+\providecommand\InternalDetectionOn{}
+
+
 \usepackage{structuredlog}  % for demonstration
 
 \EnableCrossrefs
@@ -75,7 +79,7 @@
 %    \ltfilehookversion\ dated \ltfilehookdate, \copyright\ \LaTeX\
 %    Project.}}
 %
-% \author{Frank Mittelbach}
+% \author{Frank Mittelbach, Phelype Oleinik, \LaTeX{} Project Team}
 %
 % \maketitle
 %
@@ -339,9 +343,12 @@
 %
 % \subsection{High-level interfaces for \LaTeX{}}
 %
-%    We do not provide any high-level \LaTeX{} commands (like
-%    \pkg{filehook} or \pkg{scrlfile} do) but think that for package
-%    writers the commands from for hook management are sufficient.
+%    We do not provide any additional wrappers around the hooks (like
+%    \pkg{filehook} or \pkg{scrlfile} do) because we believe that for
+%    package writers the high-level commands from the hook management,
+%    e.g., \cs{AddToHook}, etc.\
+%    are sufficient and in fact easier to work with, given that the hooks
+%    have consistent naming conventions.
 %
 %
 %
@@ -371,7 +378,7 @@
 %      \em
 %      Please do not misuse this functionality and replace a file with
 %      another unless if really needed and only if the new version is
-%      implementating the same functionality as the original one!
+%      implementing the same functionality as the original one!
 %    \end{quote}
 %  \end{function}
 %
@@ -447,6 +454,7 @@
 %
 %
 % \section{The Implementation}
+%
 %    \begin{macrocode}
 %<*2ekernel>
 %    \end{macrocode}
@@ -455,7 +463,9 @@
 %<@@=filehook>
 %    \end{macrocode}
 %
+% \changes{v1.0k}{2021/05/24}{Use \cs{msg_...} instead of \cs{__kernel_msg...}}
 %
+%
 % \subsection{Document and package-level commands}
 %
 %
@@ -517,7 +527,7 @@
 %   }
 %   A utility macro to trigger \pkg{expl3}'s file-parsing and lookup,
 %   and return a normalized representation of the file name.  If the
-%   queried file doesn't exist, no normalisation takes place.
+%   queried file doesn't exist, no normalization takes place.
 %   The output of \cs{@@_file_parse_full_name:nN} is passed on to the
 %   |#2|---a 3-argument macro that takes the \meta{path}, \meta{base},
 %   and \meta{ext} parts of the file name.
@@ -578,9 +588,13 @@
 %   places don't use \cs{InputIfFileExists} directly (\cs{include}) or
 %   need \cs{CurrentFile} earlier (\cs{@onefilewithoptions}), so these
 %   are manually used elsewhere as well.
+%   \changes{v1.0h}{2021/03/18}
+%           {Define \cs{g_@@_input_file_seq} to avoid losing data when
+%            rolling back.}
 %    \begin{macrocode}
 \tl_new:N \l_@@_internal_tl
-\seq_new:N \g_@@_input_file_seq
+\seq_if_exist:NF \g_@@_input_file_seq
+  { \seq_new:N \g_@@_input_file_seq }
 \cs_new_protected:Npn \@@_file_push:
   {
     \seq_gpush:Nx \g_@@_input_file_seq
@@ -594,7 +608,7 @@
     \seq_gpop:NNTF \g_@@_input_file_seq \l_@@_internal_tl
       { \exp_after:wN \@@_file_pop_assign:nnnn \l_@@_internal_tl }
       {
-        \msg_error:nnn { hooks } { should-not-happen }
+        \msg_error:nnn { kernel } { should-not-happen }
           { Tried~to~pop~from~an~empty~file~name~stack. }
       }
   }
@@ -619,6 +633,7 @@
 %    When rolling forward the following expl3 functions may not be defined.
 %    If we roll back the code does nothing.
 % \changes{v1.0d}{2020/11/24}{Support for roll forward (gh/434)}
+% \InternalDetectionOff
 %    \begin{macrocode}
 %<latexrelease>\IncludeInRelease{2020/10/01}%
 %<latexrelease>                 {\file_parse_full_name_apply:nN}{Roll forward help}%
@@ -640,7 +655,8 @@
 %<latexrelease>  {
 %<latexrelease>    \tl_if_empty:nTF {#3}
 %<latexrelease>      { \__file_parse_full_name_base:nw { } #2 . \s__file_stop {#1} }
-%<latexrelease>      { \__file_parse_full_name_area:nw { #1 / #2 } #3 \s__file_stop }
+%<latexrelease>      { \__file_parse_full_name_area:nw { #1 / #2 }
+%<latexrelease>                                        #3 \s__file_stop }
 %<latexrelease>  }
 %<latexrelease>\cs_new:Npn \__file_parse_full_name_base:nw #1 #2 . #3 \s__file_stop
 %<latexrelease>  {
@@ -654,7 +670,8 @@
 %<latexrelease>          }
 %<latexrelease>          { \__file_parse_full_name_tidy:nnnN {#1} { .#2 } }
 %<latexrelease>      }
-%<latexrelease>      { \__file_parse_full_name_base:nw { #1 . #2 } #3 \s__file_stop }
+%<latexrelease>      { \__file_parse_full_name_base:nw { #1 . #2 }
+%<latexrelease>                                        #3 \s__file_stop }
 %<latexrelease>  }
 %<latexrelease>\cs_new:Npn \__file_parse_full_name_tidy:nnnN #1 #2 #3 #4
 %<latexrelease>  {
@@ -672,6 +689,7 @@
 %<latexrelease>\EndIncludeInRelease
 %<*2ekernel>
 %    \end{macrocode}
+% \InternalDetectionOn
 %
 %    \begin{macrocode}
 %<@@=>
@@ -844,6 +862,17 @@
 %<latexrelease>\long\def \InputIfFileExists#1#2{%
 %<latexrelease>  \IfFileExists{#1}%
 %<latexrelease>    {#2\@addtofilelist{#1}\@@input \@filef at und}}
+%    \end{macrocode}
+%
+%    Also undo the internal command as some packages unfortunately test
+%    for their existence instead of using \cs{IfFormatAtLeastTF}.
+% \changes{v1.0g}{2021/02/08}{Undo the internal for robust
+%                 \cs{InputIfFileExists} in rollback (gh/494)}
+%    \begin{macrocode}
+%<latexrelease>\expandafter\let\csname InputIfFileExists \endcsname\@undefined
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 %<latexrelease>\let\@input at file@exists at with@hooks\@undefined
 %<latexrelease>\let\unqu at tefilef@und\@undefined
 %<latexrelease>\EndIncludeInRelease
@@ -894,7 +923,8 @@
           @file-subst@
           \@@_subst_file_normalize:Nn \use_ii_iii:nnn {#1}
         }
-        { \@@_subst_file_normalize:Nn \@@_file_name_compose:nnn {#2} }
+        { \@@_subst_file_normalize:Nn \@@_file_name_compose:nnn
+                                      {#2} }
     \group_end:
   }
 \cs_new_protected:Npn \@@_subst_remove:n #1
@@ -957,12 +987,18 @@
 %<latexrelease>\EndIncludeInRelease
 %    \end{macrocode}
 %
+%    We are not fully rolling back the file substitutions in case a
+%    rollback encounters a package that contains them, but is itself
+%    not setup for rollback. So we just bypass them and hope for the
+%    best.
+% \changes{v1.0d}{2020/12/04}{Don't drop file substitution commands on
+%    rollback}
 %    \begin{macrocode}
 %<latexrelease>\IncludeInRelease{0000/00/00}%
 %<latexrelease>          {\declare at file@substitution}{File substitution}%
 %<latexrelease>
-%<latexrelease>\let \declare at file@substitution   \@undefined
-%<latexrelease>\let \undeclare at file@substitution \@undefined
+%<latexrelease>\let \declare at file@substitution   \@gobbletwo
+%<latexrelease>\let \undeclare at file@substitution \@gobble
 %<latexrelease>
 %<latexrelease>\EndIncludeInRelease
 %<*2ekernel>
@@ -981,6 +1017,7 @@
 % \subsection{Selecting a file (\cs{set at curr@file})}
 %
 % \begin{macro}{\set at curr@file,\@curr at file,\@curr at file@reqd}
+%  \changes{v1.0f}{2021/01/31}{set \cs{protect} to \cs{string} gh/481}
 %   Now we hook into \cs{set at curr@file} to resolve a possible file
 %   substitution, and add \cs{@expl@@@filehook at set@curr at file@@nNN}
 %   at the end, after \cs{@curr at file} is set.
@@ -988,7 +1025,7 @@
 %   A file name is built using
 %   \cs{expandafter}\cs{string}\cs{csname}\meta{filename}\cs{endcsname}
 %   to avoid expanding utf8 active characters.  The \cs{csname} expands
-%   the normalisation machinery and the routine to resolve a file
+%   the normalization machinery and the routine to resolve a file
 %   substitution, returning a control sequence with the same name as the
 %   file.
 %
@@ -1001,14 +1038,18 @@
 %   false positives.  Here we define \cs{csname\cs{endcsname}} to
 %   expand to itself to avoid it matching the definition of some other
 %   control sequence.
+%   \changes{v1.0i}{2021/04/20}
+%           {Make \string~ expand to a string (tracks change in l3kernel)}
 %    \begin{macrocode}
 %</2ekernel>
 %<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2020/10/01}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
 %<latexrelease>          {\set at curr@file}{Setting current file name}%
 \def\set at curr@file#1{%
   \begingroup
     \escapechar\m at ne
+    \let\protect\string
+    \edef~{\string~}%
     \expandafter\def\csname\expandafter\endcsname
       \expandafter{\csname\endcsname}%
 %    \end{macrocode}
@@ -1018,7 +1059,7 @@
 %   actual loaded file.  \cs{@curr at file} is resolved first, to check if
 %   a substitution happens.  If it doesn't,
 %   \cs{@expl@@@filehook at if@file at replaced@@TF} short-cuts and just copies
-%   \cs{@curr at file}, otherwise the full normalisation procedure is
+%   \cs{@curr at file}, otherwise the full normalization procedure is
 %   executed.
 %
 %   At this stage the file name is parsed and normalized, but if the
@@ -1046,6 +1087,29 @@
 %    \end{macrocode}
 %    
 %    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{2020/10/01}%
+%<latexrelease>          {\set at curr@file}{Setting current file name}%
+%<latexrelease>\def\set at curr@file#1{%
+%<latexrelease>  \begingroup
+%<latexrelease>    \escapechar\m at ne
+%<latexrelease>    \expandafter\def\csname\expandafter\endcsname
+%<latexrelease>      \expandafter{\csname\endcsname}%
+%<latexrelease>    \@expl@@@filehook at if@no at extension@@nTF{#1}%
+%<latexrelease>      {\@tempswatrue}{\@tempswafalse}%
+%<latexrelease>    \@kernel at make@file at csname\@curr at file
+%<latexrelease>      \@expl@@@filehook at resolve@file at subst@@w {#1}%
+%<latexrelease>    \@expl@@@filehook at if@file at replaced@@TF
+%<latexrelease>      {\@kernel at make@file at csname\@curr at file@reqd
+%<latexrelease>         \@expl@@@filehook at normalize@file at name@@w{#1}%
+%<latexrelease>       \if at tempswa \@expl@@@filehook at drop@extension@@N\@curr at file@reqd \fi}%
+%<latexrelease>      {\if at tempswa \@expl@@@filehook at drop@extension@@N\@curr at file \fi
+%<latexrelease>       \global\let\@curr at file@reqd\@curr at file}%
+%<latexrelease>    \@expl@@@filehook at clear@replacement at flag@@
+%<latexrelease>  \endgroup}
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
+%    
+%    \begin{macrocode}
 %<latexrelease>\IncludeInRelease{2019/10/01}%
 %<latexrelease>          {\set at curr@file}{Setting current file name}%
 %<latexrelease>\def\set at curr@file#1{%
@@ -1097,7 +1161,8 @@
   \expandafter\ifx\csname\endcsname#1%
     .tex\else\string#1\fi}
 %    \end{macrocode}
-%    
+%
+%   \begin{sloppypar}
 %   Then we call \cs{@expl@@@filehook at set@curr at file@@nNN} once for
 %   \cs{@curr at file} to set \cs[no-index]{CurrentFile(Path)Used} and once for
 %   \cs{@curr at file@reqd} to set \cs[no-index]{CurrentFile(Path)}.
@@ -1107,6 +1172,7 @@
 %   \cs{@curr at file} and \cs{@curr at file@reqd} differ.  This macro is
 %   issued separate from \cs{set at curr@file} because it changes
 %   \cs{CurrentFile}, and side-effects would quickly get out of control.
+%   \end{sloppypar}
 %    \begin{macrocode}
 \def\@filehook at set@CurrentFile{%
   \@expl@@@filehook at set@curr at file@@nNN{\@curr at file}%
@@ -1170,13 +1236,13 @@
 % \begin{macro}{\@@_resolve_file_subst:w}
 % \begin{macro}{\@@_normalize_file_name:w}
 % \begin{macro}{\@@_file_name_compose:nnn}
-%   Start by sanitising the file with \cs{@@_file_parse_full_name:nN}
+%   Start by sanitizing the file with \cs{@@_file_parse_full_name:nN}
 %   then do \cs{@@_file_subst_begin:nnn}\Arg{path}\Arg{name}\Arg{ext}.
 %    \begin{macrocode}
 %</2ekernel>
 %<*2ekernel|latexrelease>
 %<latexrelease>\IncludeInRelease{2020/10/01}%
-%<latexrelease>          {\@@_resolve_file_subst:w}{Replace files detect loops}%
+%<latexrelease>     {\@@_resolve_file_subst:w}{Replace files detect loops}%
 \ExplSyntaxOn
 \cs_new:Npn \@@_resolve_file_subst:w #1 \@nil
   { \@@_file_parse_full_name:nN {#1} \@@_file_subst_begin:nnn }
@@ -1195,7 +1261,7 @@
 %   a flag to remember if a substitution happened.  We use this in
 %   \cs{set at curr@file} to short-circuit some of it in case no
 %   substitution happened (by far the most common case, so it's worth
-%   optimising).  The flag raised during the file substitution algorithm
+%   optimizing).  The flag raised during the file substitution algorithm
 %   must be explicitly cleared after the \cs{@@_if_file_replaced:TF}
 %   conditional is no longer needed, otherwise further uses of
 %   \cs{@@_if_file_replaced:TF} will wrongly return true.
@@ -1258,8 +1324,8 @@
 %   the macro below, \cs{@@_file_subst_loop:cc} is called with
 %   \cs[no-index]{@file-subst@\meta{file}} and
 %   \cs[no-index]{@file-subst@\cs[no-index]{@file-subst@\meta{file}}};
-%   that is, the substitution of \meta{file} and the substution of that
-%   substution:  the Tortoise walks one step while the Hare walks two.
+%   that is, the substitution of \meta{file} and the substitution of that
+%   substitution: the Tortoise walks one step while the Hare walks two.
 %
 %   Within \cs{@@_file_subst_loop:NN} the two substitutions are
 %   compared, and if they lead to the same file it means that there is
@@ -1275,7 +1341,7 @@
 %</2ekernel>
 %<*2ekernel|latexrelease>
 %<latexrelease>\IncludeInRelease{2020/10/01}%
-%<latexrelease>         {\@@_file_subst_tortoise_hare:nn}{Tortoise and Hare}%
+%<latexrelease>  {\@@_file_subst_tortoise_hare:nn}{Tortoise and Hare}%
 \ExplSyntaxOn
 \cs_new:Npn \@@_file_subst_tortoise_hare:nn #1 #2 #3
   {
@@ -1428,7 +1494,7 @@
 %    \begin{macrocode}
 %<@@=>
 %    \end{macrocode}
-% 
+%  \InternalDetectionOff
 %    \begin{macrocode}
 %</2ekernel>
 %<*2ekernel|latexrelease>
@@ -1474,7 +1540,7 @@
 %    
 %    \begin{macrocode}
 \cs_new_eq:NN \@expl@@@filehook at file@push@@
-               \__filehook_file_push:
+              \__filehook_file_push:
 %    \end{macrocode}
 %    
 %    \begin{macrocode}
@@ -1486,6 +1552,7 @@
 \cs_new_eq:NN \@expl@@@filehook at file@pop at assign@@nnnn
               \__filehook_file_pop_assign:nnnn
 %    \end{macrocode}
+%  \InternalDetectionOn
 %    
 %
 %    \begin{macrocode}
@@ -1545,7 +1612,7 @@
 % \end{macro}
 %
 % \begin{macro}{\@@_log_file_record:n}
-%   This macro is responsible for increasing and decresing the file
+%   This macro is responsible for increasing and decreasing the file
 %   nesting level, as well as printing to the log.  The argument is
 %   either |STOPTART| or |STOP| and the action it takes on the nesting
 %   integer depends on that.
@@ -1664,8 +1731,8 @@
 %    \Finale
 %
 %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \endinput
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%  
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 

Modified: trunk/Master/texmf-dist/source/latex/base/ltfiles.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfiles.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltfiles.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -32,7 +32,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltfiles.dtx}
-             [2020/10/04 v1.2j LaTeX Kernel (File Handling)]
+             [2021/04/17 v1.2m LaTeX Kernel (File Handling)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltfiles.dtx}
@@ -49,6 +49,9 @@
 
 \providecommand\pkg[1]{\texttt{#1}}
 
+\providecommand\InternalDetectionOff{}
+\providecommand\InternalDetectionOn{}
+
 \begin{document}
  \MaintainedByLaTeXTeam{latex}
  \maketitle
@@ -192,19 +195,6 @@
 % \end{oldcomments}
 %
 %
-% \task{???}{Do we use @unused or mainaux?}
-%  \begin{macro}{\@inputcheck}
-%  \begin{macro}{\@unused}
-%    Allocate read stream for testing and output stream.
-% \changes{v1.0l}{1994/11/07}
-%      {move here from ltdefns, remove duplicate \cs{@mainaux}}
-%    \begin{macrocode}
-\newread\@inputcheck
-\newwrite\@unused
-%    \end{macrocode}
-%  \end{macro}
-%  \end{macro}
-%
 % \begin{macro}{\@mainaux}
 % \begin{macro}{\@partaux}
 %    \begin{macrocode}
@@ -334,7 +324,7 @@
 % locally in the output routine. In particular it allows hyphenation
 % in the page head even if the page break happens in verbatim.
 % If this has already been set by a package, set to the value of |\language|
-% at this spoint.
+% at this point.
 % \changes{v1.1n}{2017/03/10}{Save language default}
 %    \begin{macrocode}
   \ifx\document at default@language\m at ne
@@ -456,8 +446,9 @@
 %    harmless), however, in more complicated scenarios where several
 %    full documents are combined to a single document it might get
 %    applied several times with harmful effects. We therefore
-%    explicitly drop it at this point. the coing is somewhat obscure
+%    explicitly drop it at this point. the coding is somewhat obscure
 %    due to the name of the macro which requires constructing.
+% \InternalDetectionOff
 %    \begin{macrocode}
 \edef \@kernel at after@begindocument at before {%
   \let\expandafter\noexpand\csname
@@ -464,10 +455,16 @@
        __hook env/document/begin\endcsname
   \noexpand\@empty}
 %    \end{macrocode}
+% \InternalDetectionOn
 %
+%    These internal hooks are already declared earlier (in
+%    \texttt{ltexpl}) so that other modules could write to them.
+% \changes{v1.2m}{2021/04/17}{Move \cs{@kernel at before@begindocument} and
+%  \cs{@kernel at after@begindocument} init earlier so that other modules can
+%    write to the hooks}
 %    \begin{macrocode}
-\let \@kernel at before@begindocument \@empty
-\let \@kernel at after@begindocument \@empty
+%\let \@kernel at before@begindocument \@empty
+%\let \@kernel at after@begindocument  \@empty
 %    \end{macrocode}
 %    
 %  \end{macro}
@@ -710,8 +707,8 @@
     \@latex at error{\string\include\space cannot be nested}\@eha
   \else
 %    \end{macrocode}
-%    Here the normalisation will add |.tex| for all files, (it uses the
-%    the same normalisation as the hooks), so we need to remove that
+%    Here the normalization will add |.tex| for all files, (it uses
+%    the same normalization as the hooks), so we need to remove that
 %    manually.  \cs{@strip at tex@ext} does that.
 %    \begin{macrocode}
     \set at curr@file{#1}%
@@ -718,7 +715,7 @@
     \edef\@curr at file{\@strip at tex@ext\@curr at file}%
 %    \end{macrocode}
 %    For historical reasons \cs{@include} expects an argument
-%    delimited by a space. This is kept (though uncessary now) to avoid
+%    delimited by a space. This is kept (though unnecessary now) to avoid
 %    errors in other packages that use \cs{@include} directly.
 %    \begin{macrocode}
     \expandafter\@include\expandafter{\@curr at file} % deliberate space
@@ -726,13 +723,13 @@
 %    \end{macrocode}
 %
 %    Here in \cs{includeonly} we also need to strip |.tex| after
-%    normalisation:
+%    normalization:
 %    \begin{macrocode}
 \def\includeonly#1{%
   \@partswtrue
 %    \end{macrocode}
 %    Because the argument to |\includeonly| is a comma-separated list
-%    of filenames where there may be comma's precedeing some of the
+%    of filenames where there may be comma's preceding some of the
 %    filenames or trailing them. Therefore we need to take the list
 %    apart, remove the unwanted spaces while leaving the spaces
 %    \emph{in} the filenames intact.
@@ -996,10 +993,11 @@
 %   A side effect of the new code is that we will see quotes around
 %   file name displays where there haven't been any before.
 %
-%   For compatibilty with existing code using |{abc}.tex| or |{one.two}.png|
-%   an initial brace group is discarded before expansion and |\string| is applied
-%   The content of the brace group is discarded. This means that a leading space
-%   will be lost unless protected (by |{ }| or |" "| or |\space|) but filenames
+%   For compatibility with existing code using |{abc}.tex| or
+%   |{one.two}.png|, an initial brace group is discarded before
+%   expansion and |\string| is applied.  The content of the brace
+%   group is discarded. This means that a leading space will be lost
+%   unless protected (by |{ }| or |" "| or |\space|) but filenames
 %   with a space are hopefully rare.
 %
 %  \changes{v1.2a}{2019/07/01}{Support UTF-8}
@@ -1058,7 +1056,7 @@
 %
 % \changes{v1.2a}{2019/07/01}{Support UTF-8}
 % \changes{v1.2b}{2019/08/27}{Make command robust}
-% \changes{v1.2d}{2019/10/26}{dont quote name}
+% \changes{v1.2d}{2019/10/26}{don't quote name}
 %    \begin{macrocode}
 \DeclareRobustCommand\IfFileExists[1]{%
   \set at curr@file{#1}%
@@ -1066,30 +1064,114 @@
 %    \end{macrocode}
 %  \end{macro}
 %
+%    \begin{macrocode}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\quote at name}{Quote file names}%
+%<latexrelease>
+%<latexrelease>\let\quote at name\@undefined
+%<latexrelease>\let\quote@@name\@undefined
+%<latexrelease>\let\unquote at name\@undefined
+%<latexrelease>
+%<latexrelease>\long\def \IfFileExists#1#2#3{%
+%<latexrelease>  \openin\@inputcheck#1 %
+%<latexrelease>  \ifeof\@inputcheck
+%<latexrelease>    \ifx\input at path\@undefined
+%<latexrelease>      \def\reserved at a{#3}%
+%<latexrelease>    \else
+%<latexrelease>      \def\reserved at a{\@iffileonpath{#1}{#2}{#3}}%
+%<latexrelease>    \fi
+%<latexrelease>  \else
+%<latexrelease>    \closein\@inputcheck
+%<latexrelease>    \edef\@filef at und{#1 }%
+%<latexrelease>    \def\reserved at a{#2}%
+%<latexrelease>  \fi
+%<latexrelease>  \reserved at a}
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+%    \end{macrocode}
+%
+%
+%
 % \begin{macro}{\IfFileExists@}
 % \changes{v0.9b}{1993/12/04}{Macro added}
 % \changes{v0.9p}{1994/01/18}{New Definition}
 % \changes{v1.0t}{1995/05/25}{(CAR) added \cs{long}}
-% \changes{v1.2d}{2019/10/26}{quote on openin}%
+% \changes{v1.2d}{2019/10/26}{quote on openin}
+% \changes{v1.2k}{2021/03/12}{Allow unbalanced conditionals (gh/530)}
 % Argument |#1| is |\@curr at file| so catcode 12 string with no quotes.
+%
+%    The original definition picked up arguments |#2| and |#3| in a
+%    way that they couldn't contain unbalanced conditionals. A better
+%    implementation would have been not to pick up the arguments at
+%    all but instead use the usual \cs{@firstoftwo} and
+%    \cs{secondoftwo}. However, that changes how |#| is interpreted
+%    and so we can't do that nowaways without invalidating a lot of
+%    code. Therefore the somewhat curious construction near the end.
 %    \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>                 {\IfFileExists@}{manage unbalanced conditionals}
 \long\def \IfFileExists@#1#2#3{%
   \openin\@inputcheck"#1" %
   \ifeof\@inputcheck
     \ifx\input at path\@undefined
-      \def\reserved at a{#3}%
+      \let\reserved at a\@secondoftwo
     \else
-      \def\reserved at a{\@iffileonpath{#1}{#2}{#3}}%
+      \def\reserved at a{\@iffileonpath{#1}}%
     \fi
   \else
     \closein\@inputcheck
     \edef\@filef at und{"#1" }%
-    \def\reserved at a{#2}%
+    \let\reserved at a\@firstoftwo
   \fi
-  \reserved at a}
 %    \end{macrocode}
+%    This is just there so that any |#| inside |#2| or |#3| needs
+%    doubling (as that was the case in the past).
+%    \begin{macrocode}
+  \expandafter\def\expandafter\reserved at a
+    \expandafter{\reserved at a{#2}{#3}}%
+\reserved at a}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{2019/10/01}%
+%<latexrelease>                 {\IfFileExists@}{manage unbalanced conditionals}
+%<latexrelease>
+%<latexrelease>\long\def \IfFileExists@#1#2#3{%
+%<latexrelease>  \openin\@inputcheck"#1" %
+%<latexrelease>  \ifeof\@inputcheck
+%<latexrelease>    \ifx\input at path\@undefined
+%<latexrelease>      \def\reserved at a{#3}%
+%<latexrelease>    \else
+%<latexrelease>      \def\reserved at a{\@iffileonpath{#1}{#2}{#3}}%
+%<latexrelease>    \fi
+%<latexrelease>  \else
+%<latexrelease>    \closein\@inputcheck
+%<latexrelease>    \edef\@filef at und{"#1" }%
+%<latexrelease>    \def\reserved at a{#2}%
+%<latexrelease>  \fi
+%<latexrelease>  \reserved at a}
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\IfFileExists@}{manage unbalanced conditionals}
+%<latexrelease>
+%<latexrelease>\let\IfFileExists@\@undefined
+%<latexrelease>
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+%    \end{macrocode}
 %  \end{macro}
 %
+%
+%
+%
+%
+%
+%
 % \begin{macro}{\@iffileonpath}
 % If the file is not found by |\openin|, and |\input at path| is defined,
 % look in all the directories specified in |\input at path|.
@@ -1103,6 +1185,10 @@
 % \changes{v1.2d}{2019/10/26}{quote on openin}%
 % \changes{v1.2f}{2019/11/11}{make \cs{@filef at und} match quoting used on \cs{openin}}%
 %    \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2019/10/01}%
+%<latexrelease>                 {\@iffileonpath}{Quote file names}
 \long\def\@iffileonpath#1{%
   \let\reserved at a\@secondoftwo
   \expandafter\@tfor\expandafter\reserved at b\expandafter
@@ -1122,29 +1208,8 @@
 %</2ekernel|latexrelease>
 %<latexrelease>\EndIncludeInRelease
 %<latexrelease>\IncludeInRelease{0000/00/00}%
-%<latexrelease>                 {\quote at name}{Quote file names}%
+%<latexrelease>                 {\quote at name}{Quote file names}
 %<latexrelease>
-%<latexrelease>\let\quote at name\@undefined
-%<latexrelease>\let\quote@@name\@undefined
-%<latexrelease>\let\unquote at name\@undefined
-%<latexrelease>
-%<latexrelease>\let\IfFileExists@\@undefined
-%<latexrelease>
-%<latexrelease>\long\def \IfFileExists#1#2#3{%
-%<latexrelease>  \openin\@inputcheck#1 %
-%<latexrelease>  \ifeof\@inputcheck
-%<latexrelease>    \ifx\input at path\@undefined
-%<latexrelease>      \def\reserved at a{#3}%
-%<latexrelease>    \else
-%<latexrelease>      \def\reserved at a{\@iffileonpath{#1}{#2}{#3}}%
-%<latexrelease>    \fi
-%<latexrelease>  \else
-%<latexrelease>    \closein\@inputcheck
-%<latexrelease>    \edef\@filef at und{#1 }%
-%<latexrelease>    \def\reserved at a{#2}%
-%<latexrelease>  \fi
-%<latexrelease>  \reserved at a}
-%<latexrelease>
 %<latexrelease>\long\def\@iffileonpath#1{%
 %<latexrelease>  \let\reserved at a\@secondoftwo
 %<latexrelease>  \expandafter\@tfor\expandafter\reserved at b\expandafter

Modified: trunk/Master/texmf-dist/source/latex/base/ltfinal.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfinal.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltfinal.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -33,7 +33,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltfinal.dtx}
-             [2020-09-26 v2.2j LaTeX Kernel (Final Settings)]
+             [2021/04/18 v2.2o LaTeX Kernel (Final Settings)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltfinal.dtx}
@@ -57,7 +57,7 @@
 %
 %
 % \section{Final settings}
-% This section contains the final settings for \LaTeX.  It initialises
+% This section contains the final settings for \LaTeX.  It initializes
 % some debugging and typesetting parameters, sets the default
 % |\catcode|s and uc/lc codes, and inputs the hyphenation file.
 %
@@ -90,6 +90,9 @@
 % \changes{v2.0s}{2016/10/15}{Tidy up status of char 127}
 % \changes{v2.2i}{2020/08/21}{Integration of new hook management interface}
 %
+%
+%
+%
 % \subsection{Debugging}
 %
 % By default, \LaTeX{} shows statistics:
@@ -150,7 +153,7 @@
 %\begin{macro}{\newXeTeXintercharclass}
 % \changes{v2.0a}{2014/12/30}{macro added}
 % \changes{v2.0b}{2015/01/23}{use reserved count 257}
-% \changes{v2.0f}{2015/04/28}{define \cs{xe at alloc@intercharclass} for compatibility with older xelatex initilisation}
+% \changes{v2.0f}{2015/04/28}{define \cs{xe at alloc@intercharclass} for compatibility with older xelatex initialization}
 %\begin{macro}{\xe at alloc@intercharclass}
 %\begin{macro}{\e at alloc@intercharclass at top}
 % \changes{v2.0j}{2016/01/04}{Start allocation at one not three}
@@ -239,8 +242,74 @@
 % \end{macro}
 % \end{macro}
 %
+% \begin{macro}{trace_stack_levels}
+%   Now define the Lua function to emulate \cs{tracingstacklevels} and
+%   install it in the \texttt{input_level_string} callback.
+%    \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%    \end{macrocode}
+%   In \texttt{latexrelease} mode we always remove the function from
+%   the callback, then add the correct version later.
+%    \begin{macrocode}
+%<latexrelease>\ifx\directlua\@undefined
+%<latexrelease>\else
+%<latexrelease>  \directlua{%
+%<latexrelease>    if luatexbase.callbacktypes['input_level_string'] and %
+%<latexrelease>       luatexbase.in_callback('input_level_string','tracingstacklevels') then
+%<latexrelease>        luatexbase.remove_from_callback('input_level_string','tracingstacklevels')
+%<latexrelease>    end}%
+%<latexrelease>\fi
+%<latexrelease>\IncludeInRelease{2021/06/01}{trace_stack_levels}%
+%<latexrelease>                 {Lua trace_stack_levels function}%
+\ifx\directlua\@undefined
+\else
+%<*2ekernel>
+  \expanded{%
+    \everyjob{\the\everyjob
+    \noexpand%\directlua
+%</2ekernel>
+    \directlua{%
+      local function trace_stack_levels (input_ptr)
+        local tracingstacklevels = tex.count.tracingstacklevels
+        if tex.tracingmacros > 0 or input_ptr < tracingstacklevels then
+          if tracingstacklevels > 0 then
+            if input_ptr < tracingstacklevels then
+              return "\string\n\string~" .. string.rep(".",input_ptr)
+            else
+              return "\string~\string~"
+            end
+          else
+            return "\string\n"
+          end
+        else
+          return ""
+        end
+      end
+%<latexrelease>    if luatexbase.callbacktypes['input_level_string'] then
+      luatexbase.add_to_callback('input_level_string',
+        trace_stack_levels,'tracingstacklevels')
+%<latexrelease>    end
+    }%
+%<*2ekernel>
+  }}%
+%</2ekernel>
+\fi
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>
+%    \end{macrocode}
+%   Then for the full rollback, just do nothing, since the function
+%   was already taken out of the rollback above.
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{0000/00/00}{trace_stack_levels}%
+%<latexrelease>                 {Lua trace_stack_levels function}%
+%<latexrelease>% Nothing here
+%<latexrelease>\EndIncludeInRelease
+%</2ekernel|latexrelease>
+%<*2ekernel>
+%    \end{macrocode}
+% \end{macro}
 %
-%
 % The default values of the picture and |\fbox| parameters:
 %    \begin{macrocode}
 \unitlength = 1pt
@@ -522,12 +591,13 @@
 %</2ekernel>
 %<*2ekernel|latexrelease>
 %<latexrelease>\IncludeInRelease{2017/04/15}%
-%<latexrelease>                 {\document at default@language}{Save language for hyphenation}%
+%<latexrelease>       {\document at default@language}{Save language for hyphenation}%
 \let\document at default@language\m at ne
 %</2ekernel|latexrelease>
 %<latexrelease>\EndIncludeInRelease
 %<latexrelease>\IncludeInRelease{0000/00/00}%
-%<latexrelease>                 {\document at default@language}{Save language for hyphenation}%
+%<latexrelease>       {\document at default@language}{Save language for hyphenation}%
+%
 %<latexrelease>\let\document at default@language\@undefined
 %<latexrelease>\EndIncludeInRelease
 %<*2ekernel>
@@ -562,6 +632,52 @@
 \fi
 %    \end{macrocode}
 %
+%   For pdf\TeX\ preload and enable automatic glyph to Unicode mapping
+%   for more reliable copy and paste support.
+%   \changes{v2.2l}{2021/01/21}{Load glyphtounicode.tex for pdf\TeX}
+%   \changes{v2.2m}{2021/02/25}{Improve speed of ToUnicode everyjob loading code}
+%
+%    \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>                 {\pdfgentounicode}{Preload glyphtounicode}%
+\ifx \pdfgentounicode \@undefined \else
+%<*2ekernel>
+  \ifnum 0=0%
+    \ifdefined\pdftexversion
+% \pdftexversion<140 does not have \pdfgentounicode, so we only check higher values
+      \ifnum \pdftexversion=140 \ifnum\pdftexrevision<22 1\fi\fi
+    \fi
+    \relax
+%</2ekernel>
+    \input glyphtounicode
+%<*2ekernel>
+  \else
+    \begingroup
+      \everyeof{\noexpand}\endlinechar-1
+      \edef\x{\endgroup
+        \everyjob{\the\everyjob\@@input glyphtounicode }%
+    }\x
+  \fi
+%</2ekernel>
+  \pdfgentounicode=1
+\fi
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
+%   When rolling back we can't unload the glyphtounicode mappings, but we
+%   can reset |\pdfgentounicode| to ensure that they aren't used.
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\pdfgentounicode}{Preload glyphtounicode}%
+%<latexrelease>\ifx \pdfgentounicode \@undefined \else
+%<latexrelease>  \pdfgentounicode=0
+%<latexrelease>\fi
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+%    \end{macrocode}
+%
 % \subsection{Input encoding}
 %
 % \changes{v2.1a}{2018/03/25}{default to UTF-8}
@@ -632,7 +748,7 @@
 %
 % \begin{macro}{\UseRawInputEncoding}
 % \changes{v2.1a}{2018/03/25}{Macro added}
-% Reset 8 bit characters to catcode 12 so the input endcoing matches the ``Raw''
+% Reset 8 bit characters to catcode 12 so the input encoding matches the ``Raw''
 % font encoding.
 % Useful for special behaviours, or for compatibility with older \LaTeX\ formats.
 % \changes{v2.1b}{2018/04/06}{Undo changes to \cs{DeclareFontEncoding@} and
@@ -939,7 +1055,7 @@
       \expandafter\reserved at a\@uclclist\reserved at b{\reserved at b\@gobble}%
 %    \end{macrocode}
 %    Tell UTF-8 processing to process chars even though we are in an \cs{protected at edef}.
-% \changes{v2.1h}{2019/09/14}{Expand UTF8 chrs when case changing (github/177)}
+% \changes{v2.1h}{2019/09/14}{Expand UTF8 chars when case changing (github/177)}
 %    \begin{macrocode}
       \let\UTF at two@octets at noexpand\@empty
       \let\UTF at three@octets at noexpand\@empty

Modified: trunk/Master/texmf-dist/source/latex/base/ltfloat.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfloat.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltfloat.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -31,7 +31,7 @@
 %
 %<*driver>
 % \fi
-\ProvidesFile{ltfloat.dtx}[2020/04/09 v1.2d LaTeX Kernel (Floats)]
+\ProvidesFile{ltfloat.dtx}[2021/03/03 v1.2f LaTeX Kernel (Floats)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltfloat.dtx}
@@ -356,7 +356,7 @@
 % \changes{v1.1f}{1994/11/21}
 %     {Missing percents reinserted after 4, 8: these are not numbers.}
 % \changes{v1.1g}{1994/12/10}{Old version reinstated temporarily}
-% \changes{v1.1g}{1994/12/10}{Sanitisation added temporarily}
+% \changes{v1.1g}{1994/12/10}{Sanitization added temporarily}
 %     The first part of this sets the count register that stores all
 %     the information about the type and fps of the float.
 %
@@ -574,7 +574,7 @@
 %
 %  \begin{macro}{\@setnobreak}
 % \changes{v1.1f}{1994/11/21}{Macro added}
-% \changes{v1.1n}{1996/07/26}{remove unecessary \cs{global} before
+% \changes{v1.1n}{1996/07/26}{remove unnecessary \cs{global} before
 %                 \cs{@nobreak...}}
 %    \begin{macrocode}
 \def \@setnobreak{%
@@ -588,7 +588,7 @@
 %
 %  \begin{macro}{\@setminipage}
 % \changes{v1.1f}{1994/11/21}{Macro added}
-% \changes{v1.1n}{1996/07/26}{remove unecessary \cs{global} before
+% \changes{v1.1n}{1996/07/26}{remove unnecessary \cs{global} before
 %                 \cs{@minipage...}}
 %    \begin{macrocode}
 \def \@setminipage{%
@@ -734,7 +734,7 @@
 %         {Use new \cs{color at hbox} concept.}
 % \changes{v1.1f}{1994/11/21}{Corrected position of \cs{outer at nobreak}}
 % \changes{v1.1f}{1994/11/21}{Added reset of minipage flag}
-% \changes{v1.1n}{1996/07/26}{remove unecessary \cs{global} before
+% \changes{v1.1n}{1996/07/26}{remove unnecessary \cs{global} before
 %                 \cs{@minipage...}}
 %    \begin{macrocode}
       \@minipagefalse
@@ -1002,9 +1002,14 @@
 % \changes{v1.1f}{1994/11/21}{Added \cs{@setminipage} etc}
 % \changes{v1.1f}{1994/11/21}{Added resetting of size and font}
 % \changes{v1.1m}{1995/05/25}{(CAR) Resettings moved to hook}
-% \changes{v1.1n}{1996/07/26}{remove unecessary \cs{global} before
+% \changes{v1.1n}{1996/07/26}{remove unnecessary \cs{global} before
 %                 \cs{@minipage...}}
+% \changes{v1.2e}{2021/02/03}{Explicitly end with \cs{par} (gh/489)}
 %    \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>                 {\@savemarbox}{Explicit par for marginpar}%
 \long\def \@savemarbox #1#2{%
   \global\setbox #1%
     \color at vbox
@@ -1012,13 +1017,36 @@
         \hsize\marginparwidth
         \@parboxrestore
         \@marginparreset
-        #2%
+        #2\par
         \@minipagefalse
         \outer at nobreak
         }%
     \color at endbox
 }
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
 %    \end{macrocode}
+%
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\@savemarbox}{Explicit par for marginpar}%
+%<latexrelease>
+%<latexrelease>\long\def \@savemarbox #1#2{%
+%<latexrelease>  \global\setbox #1%
+%<latexrelease>    \color at vbox
+%<latexrelease>      \vtop{%
+%<latexrelease>        \hsize\marginparwidth
+%<latexrelease>        \@parboxrestore
+%<latexrelease>        \@marginparreset
+%<latexrelease>        #2%
+%<latexrelease>        \@minipagefalse
+%<latexrelease>        \outer at nobreak
+%<latexrelease>        }%
+%<latexrelease>    \color at endbox
+%<latexrelease>}
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+%    \end{macrocode}
 % \end{macro}
 %
 %  \begin{macro}{\@marginparreset}
@@ -1026,7 +1054,7 @@
 %
 % The rational for allowing these normally global flags to be set
 % locally here, via |\@parboxrestore| was stated originally by
-% Donald Arsenau and extended by Chris Rowley.
+% Donald Arseneau and extended by Chris Rowley.
 % It is because these flags are only set globally to
 % true by section commands, and these should never appear within
 % marginals or floats or, indeed, in any group; and they are only ever
@@ -1480,7 +1508,13 @@
 %         {Removed \cs{normalcolor} (again)}
 % \changes{v1.1t}{1997/11/19}
 %         {Missing percent, again}
+% \changes{v1.2e}{2021/02/10}{Explicitly run \cs{par} at the end of footnote text
+%      in preparation for paragraph hooks}
 %    \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>                 {\@footnotetext}{footnotetext tagging}%
 \long\def\@footnotetext#1{\insert\footins{%
     \reset at font\footnotesize
     \interlinepenalty\interfootnotelinepenalty
@@ -1493,8 +1527,33 @@
     \color at begingroup
       \@makefntext{%
         \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
+    \par
     \color at endgroup}}%
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
 %    \end{macrocode}
+%
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\@footnotetext}{footnotetext tagging}%
+%<latexrelease>
+%<latexrelease>\long\def\@footnotetext#1{\insert\footins{%
+%<latexrelease>    \reset at font\footnotesize
+%<latexrelease>    \interlinepenalty\interfootnotelinepenalty
+%<latexrelease>    \splittopskip\footnotesep
+%<latexrelease>    \splitmaxdepth \dp\strutbox \floatingpenalty \@MM
+%<latexrelease>    \hsize\columnwidth \@parboxrestore
+%<latexrelease>    \protected at edef\@currentlabel{%
+%<latexrelease>       \csname p at footnote\endcsname\@thefnmark
+%<latexrelease>    }%
+%<latexrelease>    \color at begingroup
+%<latexrelease>      \@makefntext{%
+%<latexrelease>        \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
+%<latexrelease>    \color at endgroup}}%
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+%    \end{macrocode}
 % \end{macro}
 %
 % \begin{macro}{\footnotemark}
@@ -1558,10 +1617,51 @@
 %    \begin{macrocode}
 \def\@mpfn{footnote}
 \def\thempfn{\thefootnote}
-%</2ekernel>
 %    \end{macrocode}
+%
 % \end{macro}
 % \end{macro}
 %
+%
+%
+%
+%  \begin{macro}{\footref}
+%    This command generates a footnote mark. The value is produced by
+%    referencing a \cs{label} placed into a \cs{footnote} elsewhere
+%    (can be one in the main galley or in a minipage).
+% \changes{v1.2f}{2021/02/16}{\cs{footref} added}
+%    \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>                 {\footref}{Add footref}%
+\def\footref#1{%
+  \begingroup
+    \unrestored at protected@xdef\@thefnmark{\ref{#1}}%
+  \endgroup
+  \@footnotemark
+}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
+%    We don't remove it when rolling back so that packages offered it
+%    in the past do not need to alter their behavior in a rollback
+%    situation.
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\footref}{Add footref}%
+%<latexrelease>
+%<latexrelease>  % \let\footref\@undefined
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%    \begin{macrocode}
+%</2ekernel>
+%    \end{macrocode}
+%
 % \Finale
 %

Modified: trunk/Master/texmf-dist/source/latex/base/ltfntcmd.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfntcmd.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltfntcmd.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -32,7 +32,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltfntcmd.dtx}
-             [2019/12/17 v3.4c LaTeX Kernel (Font commands)]
+             [2020/12/05 v3.4c LaTeX Kernel (Font commands)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltfntcmd.dtx}
@@ -303,7 +303,7 @@
 %    character in an unsloped font; we believe (in early 2003) that
 %    this is perhaps inefficient but not dangerous.
 %
-%    It also now checks for empty contents of the text command and optimises
+%    It also now checks for empty contents of the text command and optimizes
 %    this case.  Some care is also taken to check that doing dangerous
 %    things in vertical mode is avoided.
 %
@@ -539,7 +539,7 @@
 %
 % \begin{macro}{\ifmaybe at ic}
 % \changes{v3.4a}{2009/12/14}{Macro added}
-%    Switch used soley within |\maybe at ic| not interfering with other
+%    Switch used solely within |\maybe at ic| not interfering with other
 %    switches.
 %    \begin{macrocode}
 \newif\ifmaybe at ic
@@ -585,7 +585,7 @@
 %    \begin{macrocode}
     \do \t at st@ic
 %    \end{macrocode}
-%    Frank thinks that the next bit it is inefficient if done after
+%    Frank thinks that the next bit is inefficient if done after
 %    the second change.  Chris thinks that most all of this is
 %    inefficient for the commonest cases: but that is the price of a
 %    cleverer algorithm.  It is certainly needed to deal with the use

Modified: trunk/Master/texmf-dist/source/latex/base/ltfssaxes.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfssaxes.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltfssaxes.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 2019-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 2019-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -35,7 +35,7 @@
 %
 %
 \ProvidesFile{ltfssaxes.dtx}
-             [2020/08/21 v1.0g LaTeX Kernel (NFSS Axes handing)]
+             [2021/03/18 v1.0i LaTeX Kernel (NFSS Axes handing)]
 % \iffalse
 \documentclass{ltxdoc}
 \begin{document}
@@ -68,11 +68,11 @@
 %
 % \StopEventually{}
 %
-% Everything in the this file got introduced 2020/02/02, so we do a
-% single rollback (for now).
+% \changes{v1.0h}{2020/12/04}{Reorganized the rollback data}
+%
+% Everything in the this file got introduced 2020/02/02, so we use large rollback
+% chunks, only interrupted if necessary.
 %    \begin{macrocode}
-%<*2ekernel>
-%</2ekernel>
 %<*2ekernel|latexrelease>
 %<latexrelease>\IncludeInRelease{2020/02/02}%
 %<latexrelease>   {\DeclareFontSeriesChangeRule}{Series change rules}%
@@ -168,13 +168,13 @@
 %    request (i.e., second argument).
 %
 %    In particular this is also true for cases involving \texttt{m},
-%    e.g., \texttt{bm} (bold medium width) which automatially gets
+%    e.g., \texttt{bm} (bold medium width) which automatically gets
 %    reduced result in \texttt{b} or \texttt{mc} (medium weight
 %    condensed) which becomes \texttt{c} as a result.
 %
 % \item
 %
-%    Only a few entries have ``alterative'' values and perhaps most of
+%    Only a few entries have ``alternative'' values and perhaps most of
 %    them should get dropped. Or maybe not \ldots{} needs some thought
 %    perhaps.
 %
@@ -183,7 +183,7 @@
 %    to stay with \texttt{b} when a change to \texttt{c} is requested
 %    and \texttt{bc} doesn't exist, than to go to first change the
 %    shape to \texttt{n} and then find that \texttt{bc/n} doesn't
-%    exist either and thus ending up wth \texttt{m/n}.
+%    exist either and thus ending up with \texttt{m/n}.
 %
 % \item
 %
@@ -678,21 +678,59 @@
 %    \end{macrocode}
 %
 %
-
-
+% Supporting rollback \ldots
+%    \begin{macrocode}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>   {\DeclareFontSeriesChangeRule}{Series change rules}%
+%<latexrelease>
+%<latexrelease>\let\DeclareFontSeriesChangeRule\@undefined
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
+%
+%
+%
+%
+%
 % \subsection{Changing to a new series}
 %
 %
-
-%  \begin{macro}{\if at forced@series}
-%    If the series gets forced we need to know that fact later on.
+%    \begin{macrocode}
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>                 {\fontseries}{delay fontseries update}%
+%    \end{macrocode}
+%
+%
+%  \begin{macro}{\fontseries}
+%    The \cs{fontseries} command takes one argument which is the requested new
+%    font series. In the orginal implementation  it simply saved the
+%    expanded value in \cs{f at series}. Now we do a bit more processing
+%    and look up the final value in the font series data base. This is
+%    done by \cs{merge at font@series}. But the lookup should be done
+%    within the target family and call to \cs{fontseries} might be
+%    followed by a \cs{fontfamily} call. So we delay the processing to
+%    \cs{selectfont} and only record the necessary action in
+%    \cs{delayed at f@adjustment}.
 % \changes{v1.0c}{2020/02/10}{Switch \cs{if at forced@series} added}
+% \changes{v1.0h}{2020/12/04}{Distangle series and shape update (gh/444)}
 %    \begin{macrocode}
-\newif\if at forced@series
+\DeclareRobustCommand\fontseries[1]{\@forced at seriesfalse
+    \expandafter\def\expandafter\delayed at f@adjustment\expandafter
+        {\delayed at f@adjustment\delayed at merge@font at series{#1}}}
 %    \end{macrocode}
 %  \end{macro}
 %
 %
+%  \begin{macro}{\delayed at f@adjustment}
+%    The macro holding the delayed action(s) for use in \cs{selectfont}.
+%    \begin{macrocode}
+\let\delayed at f@adjustment\@empty
+%    \end{macrocode}
+%  \end{macro}
+%
 %  \begin{macro}{\fontseriesforce}
 %    To change unconditionally to a new series you can use
 %    \cs{fontseriesforce}. Of course, if the series doesn't exist for
@@ -700,24 +738,69 @@
 %    dependency on the current series.
 % \changes{v1.0c}{2020/02/10}{Switch \cs{if at forced@series} added}
 %    \begin{macrocode}
-\DeclareRobustCommand\fontseriesforce[1]{\@forced at seriestrue\edef\f at series{#1}}
+\DeclareRobustCommand\fontseriesforce[1]{\@forced at seriestrue
+    \expandafter\def\expandafter\delayed at f@adjustment\expandafter
+      {\delayed at f@adjustment\edef\f at series{#1}}}
 %    \end{macrocode}
 %  \end{macro}
 %
 %
-%  \begin{macro}{\fontseries}
-%    The \cs{fontseries} command takes one argument which is the requested new
-%    font series. In the orginal implementation  it simply saved the
-%    expanded value in \cs{f at series}. Now we do a bit more processing
-%    and look up the final value in the font series data base. This is
-%    done by \cs{merge at font@series}.
+%
+%  \begin{macro}{\if at forced@series}
+%    If the series gets forced we need to know that fact later on.
 % \changes{v1.0c}{2020/02/10}{Switch \cs{if at forced@series} added}
 %    \begin{macrocode}
-\DeclareRobustCommand\fontseries[1]{\@forced at seriesfalse\merge at font@series{#1}}
+\newif\if at forced@series
 %    \end{macrocode}
 %  \end{macro}
-
-
+%
+%
+%    \begin{macrocode}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{2020/02/02}%
+%<latexrelease>                 {\fontseries}{delay fontseries update}%
+%<latexrelease>
+%<latexrelease>\DeclareRobustCommand\fontseries[1]{\@forced at seriesfalse
+%<latexrelease>                                    \merge at font@series{#1}}
+%<latexrelease>\DeclareRobustCommand\fontseriesforce[1]{\@forced at seriestrue
+%<latexrelease>                                         \edef\f at series{#1}}
+%<latexrelease>\let\delayed at f@adjustment\@undefined
+%<latexrelease>
+%    \end{macrocode}
+%    For a roll forward we may have to define \cs{if at forced@series}
+%    but this needs doing in a way that \TeX{} doesn't see it when
+%    skipping over conditionals.
+% \changes{v1.0i}{2021/03/18}
+%         {Fix rollforward definition.}
+%    \begin{macrocode}
+%<latexrelease>\expandafter\newif\csname if at forced@series\endcsname
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\fontseries}{delay fontseries update}%
+%<latexrelease>
+%<latexrelease>\DeclareRobustCommand\fontseries[1]{\edef\f at series{#1}}
+%<latexrelease>\let\fontseriesforce\@undefined
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
+%
+%
+%
+%    \begin{macrocode}
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2020/02/02}%
+%<latexrelease>   {\merge at font@series}{Merge series values}%
+%    \end{macrocode}
+%
+%
 %  \begin{macro}{\merge at font@series}
 %    We look up the data base value by expanding the right command
 %    twice. If no such value exist then the result will be \cs{relax}
@@ -734,9 +817,9 @@
 }
 %    \end{macrocode}
 %  \end{macro}
-
-
-
+%
+%
+%
 %  \begin{macro}{\merge at font@series@}
 %    This now defines the new \cs{f at series}:
 %    \begin{macrocode}
@@ -758,11 +841,9 @@
 %    \end{macrocode}
 %    Otherwise we check if the desired result for the series
 %    (\texttt{\#1}) exists for the font family and the current shape.
-%    As the \texttt{.fd} is perhaps not loaded yet, we first
-%    have to do that, otherwise the test would fail even if the face
-%    is actually available.
+%    All this happens inside \cs{selectfont} which has already taken care to load
+%    the \texttt{.fd}, file if necessary.
 %    \begin{macrocode}
-    \maybe at load@fontshape
     \edef\reserved at a{\f at encoding /\f at family /#1/\f at shape}%
      \ifcsname \reserved at a \endcsname
 %    \end{macrocode}
@@ -798,9 +879,10 @@
 %    \end{macrocode}
 %    It is possible that the previous font and the new one are
 %    actually identical (and the font was not found because it still
-%    needs loading) in which case a warning  would look rather odd. So
-%    we make a quick check for that (which is the reason why we defined
-%    \cs{@reserveda} above.
+%    needs loading) in which case a warning would look rather odd. So
+%    we make a quick check for that (which is the reason why we
+%    defined \cs{@reserveda} above instead of doing inline testing
+%    inside \cs{ifcsname}).
 %    \begin{macrocode}
 \def\@font at shape@subst at warning{%
    \edef\reserved at b{\curr at fontshape}%
@@ -814,13 +896,71 @@
 %
 %
 %
+%  \begin{macro}{\merge at font@series at without@substitution,
+%                \merge at font@series at without@substitution@,
+%                \delayed at merge@font at series}
 %
+% \changes{v1.0h}{2020/12/22}{Distangle series and shape update (gh/444)}
+%
+%    \cs{merge at font@series at without@substitution} works like
+%    \cs{merge at font@series}, i.e., it looks up the combination in the
+%    rule base and if there exists an entry it uses it and if not it
+%    uses the new series value. However, it doesn't check if there is
+%    actually a font face with the new series value as
+%    \cs{merge at font@series} does. This simplified command is used in
+%    \cs{selectfont} at a point where other font attributes are not
+%    yet updated so that checking the font face might result incorrect
+%    in substitutions.
+%
+%    \begin{macrocode}
+\def\merge at font@series at without@substitution#1{%
+  \expandafter\expandafter\expandafter
+  \merge at font@series at without@substitution@
+    \csname series@\f at series @#1\endcsname
+    {#1}%
+    \@nil
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\def\merge at font@series at without@substitution@#1#2#3\@nil{%
+  \def\reserved at a{#3}%
+  \ifx\reserved at a\@empty
+    \set at target@series{#2}%
+  \else
+    \set at target@series{#1}%
+  \fi
+}
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%
+%  \begin{macro}{\delayed at merge@font at series}
+%
+%    When we delay the merge action in \cs{fontseries} we first
+%    attempt to use merging without substitution. If that results in a
+%    non-existing font face the merge is redone in \cs{selectfont}
+%    using a version with substitution. See \cs{selectfont} for details.
+%
+% \changes{v1.0h}{2020/12/22}{Distangle series and shape update
+%    (gh/444)}
+%    \begin{macrocode}
+\let\delayed at merge@font at series\merge at font@series at without@substitution
+%    \end{macrocode}
+%  \end{macro}
+%
 %  \begin{macro}{\maybe at load@fontshape}
 %    A small helper that we use a couple of times: try loading a
 %    fontshape (in a group because \cs{try at load@fontshape} normalizes
-%    catcodes).
+%    catcodes and we also want to change \cs{typeout} so that it
+%    doesn't report missing \texttt{.fd} files on the terminal).
 %    \begin{macrocode}
-\def\maybe at load@fontshape{\begingroup\try at load@fontshape\endgroup}
+\def\maybe at load@fontshape{%
+  \begingroup
+    \let \typeout \@font at info
+    \try at load@fontshape
+  \endgroup}
 %    \end{macrocode}
 %  \end{macro}
 %
@@ -845,7 +985,7 @@
 %    \end{macrocode}
 %    We need to \cs{edef} the argument first in case it starts with a
 %    conditional. Then we check (and perhaps drop) an ``m'' from the
-%    value andassign the result to \cs{f at series}.
+%    value and assign the result to \cs{f at series}.
 % \changes{v1.0d}{2020/02/27}{Drop ``m'' only in a specific set of values (gh/293)}
 %    \begin{macrocode}
     \edef\f at series{#1}%
@@ -916,9 +1056,33 @@
 }
 %    \end{macrocode}
 %  \end{macro}
+%
+%
+%
+% Supporting rollback \ldots
+%    \begin{macrocode}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>   {\merge at font@series}{Merge series values}%
+%<latexrelease>
+%<latexrelease>\let\merge at font@series\@undefined
+%<latexrelease>\let\merge at font@series@\@undefined
+%<latexrelease>\let\@font at shape@subst at warning\@undefined
+%<latexrelease>\let\merge at font@series at without@substitution\@undefined
+%<latexrelease>\let\merge at font@series at without@substitution@\@undefined
+%<latexrelease>\let\delayed at merge@font at series\@undefined
+%<latexrelease>\let\maybe at load@fontshape\@undefined
+%<latexrelease>\let\set at target@series\@undefined
+%<latexrelease>\let\series at maybe@drop at one@m\@undefined
+%<latexrelease>\let\series at drop@one at m\@undefined
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
 
 
 
+
 % \section{Changing the shape}
 %
 %    Shapes are also split in two axes (though it could be more if
@@ -925,8 +1089,14 @@
 %    that is desirable), essentially building in an ``sc''
 %    axis).
 %
+%    \begin{macrocode}
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2020/02/02}%
+%<latexrelease>   {\DeclareFontShapeChangeRule}{Font shape change rules}%
+%    \end{macrocode}
 %
 %
+%
 %  \begin{macro}{\DeclareFontShapeChangeRule}
 %    The database for shapes is done in exactly the same way, only
 %    that it is much smaller and we usually have no alternative shape
@@ -948,8 +1118,9 @@
 %    resets everything and \texttt{up} changes italic or slanted to
 %    upright and \texttt{ulc} undoes small caps.
 %
-%    So we now offer \cs{normalshape} (using \cs{shapedefault} which is normally the same as
-%    calling both \cs{ulcshape} and \cs{upshape}, only more efficient.
+%    So we now offer \cs{normalshape} (using \cs{shapedefault} which
+%    is normally the same as calling both \cs{ulcshape} and
+%    \cs{upshape}, only more efficient.
 %
 %
 %  \begin{macro}{\ulcshape}
@@ -1080,7 +1251,7 @@
 %    \texttt{n}. This is the way \texttt{fontspec} implemented its
 %    version on this interface, so this rule means we are also
 %    compatible with the way \texttt{fontspec} behaved. Still it
-%    remains an odditywhic I would rather liked to have avoided.
+%    remains an oddity which I would rather liked to have avoided.
 %    \begin{macrocode}
 %\DeclareFontShapeChangeRule {sc}{up} {sc}     {}
 \DeclareFontShapeChangeRule {sc}{up} {n}     {}
@@ -1100,7 +1271,7 @@
 %    \texttt{ulc} in \cs{f at series} which most certainly doesn't
 %    exist. So when a font is later selected that would result in a
 %    substitution (so no harm done really). Alternatively, we could in
-%    this case use \texttt{n} as aternative, which may be a bit
+%    this case use \texttt{n} as alternative, which may be a bit
 %    faster, but such a  setup would be so weird in the first place
 %    that this isn't worth the effort.
 %
@@ -1134,15 +1305,45 @@
 \DeclareFontShapeChangeRule {sw}{up} {n}      {}
 %    \end{macrocode}
 %
+% Supporting rollback \ldots
+%    \begin{macrocode}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>   {\DeclareFontShapeChangeRule}{Font shape change rules}%
+%<latexrelease>
+%<latexrelease>\let\DeclareFontShapeChangeRule\@undefined
+%<latexrelease>\let\ulcshape\@undefined
+%<latexrelease>\let\ulcdefault\@undefined
+%<latexrelease>\let\swshape\@undefined
+%<latexrelease>\let\swdefault\@undefined
+%<latexrelease>\let\sscshape\@undefined
+%<latexrelease>\let\sscdefault\@undefined
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
 %
+%
 % \subsection{Changing to a new shape}
 %
+%
+%    \begin{macrocode}
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>   {\fontshape}{Font shape change}%
+%    \end{macrocode}
+%
+%
+%
 %  \begin{macro}{\fontshape}
 %    Again the \cs{fontshape} now has to do a lookup to get to its new
 %    value in \cs{f at shape}. The method is exactly the same as in
 %    \cs{fontseries}.
+% \changes{v1.0h}{2020/12/04}{Distangle series and shape update (gh/444)}
 %    \begin{macrocode}
-\DeclareRobustCommand\fontshape[1]{\merge at font@shape{#1}}
+\DeclareRobustCommand\fontshape[1]
+   {\expandafter\def\expandafter\delayed at f@adjustment\expandafter
+        {\delayed at f@adjustment\delayed at merge@font at shape{#1}}}
 %    \end{macrocode}
 %  \end{macro}
 %
@@ -1149,11 +1350,52 @@
 %
 %  \begin{macro}{\fontshapeforce}
 %    The unconditional version:
+%
+% \changes{v1.0h}{2020/12/04}{Distangle series and shape update (gh/444)}
 %    \begin{macrocode}
-\DeclareRobustCommand\fontshapeforce[1]{\edef\f at shape{#1}}
+\DeclareRobustCommand\fontshapeforce[1]
+   {\expandafter\def\expandafter\delayed at f@adjustment\expandafter
+        {\delayed at f@adjustment\edef\f at shape{#1}}}
 %    \end{macrocode}
 %  \end{macro}
 %
+%
+% Supporting rollback \ldots
+%    \begin{macrocode}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{2020/02/02}%
+%<latexrelease>   {\fontshape}{Font shape change}%
+%<latexrelease>
+%<latexrelease>\DeclareRobustCommand\fontshape[1]{\merge at font@shape{#1}}
+%<latexrelease>\DeclareRobustCommand\fontshapeforce[1]{\edef\f at shape{#1}}
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>   {\fontshape}{Font shape change}%
+%<latexrelease>
+%<latexrelease>\DeclareRobustCommand\fontshape [1]{\edef\f at shape{#1}}
+%<latexrelease>\let\fontshapeforce\@undefined
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
+%
+
+
+
+
+
+%    \begin{macrocode}
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2020/02/02}%
+%<latexrelease>   {\merge at font@shape}{Font shape change rules}%
+%    \end{macrocode}
+%
+%
+%
 %  \begin{macro}{\merge at font@shape}
 %    Look up the database entry (if existing) and act accordingly.
 %    \begin{macrocode}
@@ -1178,9 +1420,12 @@
   \ifx\reserved at a\@empty
     \edef\f at shape{#2}%
   \else
-    \maybe at load@fontshape
+%    \end{macrocode}
+%    \cs{reserved at a} is used in \cs{@font at shape@subst at warning} so we
+%    have to define it in addition to do the \cs{ifcsname} test
+%    \begin{macrocode}
     \edef\reserved at a{\f at encoding /\f at family /\f at series/#1}%
-     \ifcsname \reserved at a\endcsname
+    \ifcsname \reserved at a\endcsname
        \edef\f at shape{#1}%
     \else
        \ifcsname \f at encoding /\f at family /\f at series/#2\endcsname
@@ -1197,7 +1442,39 @@
 %  \end{macro}
 %
 %
+%  \begin{macro}{\merge at font@shape at without@substitution,
+%                \merge at font@shape at without@substitution@,
+%                \delayed at merge@font at shape}
+%    See definition of \cs{selectfont} for how these macros are used.
+% \changes{v1.0h}{2020/12/22}{Distangle series and shape update (gh/444)}
+%    \begin{macrocode}
+\def\merge at font@shape at without@substitution#1{%
+  \expandafter\expandafter\expandafter
+  \merge at font@shape at without@substitution@
+    \csname shape@\f at shape @#1\endcsname
+    {#1}%
+    \@nil
+}
+%    \end{macrocode}
 %
+%    \begin{macrocode}
+\def\merge at font@shape at without@substitution@#1#2#3\@nil{%
+  \def\reserved at a{#3}%
+  \ifx\reserved at a\@empty
+    \edef\f at shape{#2}%
+  \else
+    \edef\f at shape{#1}%
+  \fi
+}
+%    \end{macrocode}
+%    
+%    \begin{macrocode}
+\let\delayed at merge@font at shape\merge at font@shape at without@substitution
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%
 %  \begin{macro}{\normalshape}
 %
 %    \cs{normalshape} resets both sub-axes if the default rules are used.
@@ -1255,6 +1532,7 @@
 %    \end{macrocode}
 %  \end{macro}
 %
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %
 % Supporting rollback \ldots
 %    \begin{macrocode}
@@ -1261,32 +1539,20 @@
 %</2ekernel|latexrelease>
 %<latexrelease>\EndIncludeInRelease
 %<latexrelease>\IncludeInRelease{0000/00/00}%
-%<latexrelease>   {\DeclareFontSeriesChangeRule}{Series change rules}%
+%<latexrelease>   {\merge at font@shape}{Font shape change rules}%
 %<latexrelease>
-%<latexrelease>\DeclareRobustCommand\fontseries[1]{\edef\f at series{#1}}
 %<latexrelease>\DeclareRobustCommand\fontshape [1]{\edef\f at shape{#1}}
-%<latexrelease>\let\fontseriesforce\@undefined
 %<latexrelease>\let\fontshapeforce\@undefined
 %<latexrelease>
-%<latexrelease>\let\DeclareFontSeriesChangeRule\@undefined
-%<latexrelease>\let\merge at font@series\@undefined
-%<latexrelease>\let\merge at font@series@\@undefined
-%<latexrelease>\let\@font at shape@subst at warning\@undefined
-%<latexrelease>\let\maybe at load@fontshape\@undefined
-%<latexrelease>\let\set at target@series\@undefined
-%<latexrelease>\let\series at maybe@drop at one@m\@undefined
-%<latexrelease>\let\series at drop@one at m\@undefined
-%<latexrelease>\let\DeclareFontShapeChangeRule\@undefined
 %<latexrelease>\let\merge at font@shape\@undefined
 %<latexrelease>\let\merge at font@shape@\@undefined
+%<latexrelease>
+%<latexrelease>\let\merge at font@shape at without@substitution\@undefined
+%<latexrelease>\let\merge at font@shape at without@substitution@\@undefined
+%<latexrelease>\let\delayed at merge@font at shape\@undefined
+%<latexrelease>
 %<latexrelease>\let\normalshape\@undefined
-%<latexrelease>\let\ulcshape\@undefined
-%<latexrelease>\let\ulcdefault\@undefined
-%<latexrelease>\let\swshape\@undefined
-%<latexrelease>\let\swdefault\@undefined
-%<latexrelease>\let\sscshape\@undefined
-%<latexrelease>\let\sscdefault\@undefined
-%<latexrelease>\let\normalshape\@undefined
+%<latexrelease>
 %    \end{macrocode}
 %    This is always called in \cs{document} so don't make it undefined.
 %    \begin{macrocode}
@@ -1293,14 +1559,14 @@
 %<latexrelease>
 %<latexrelease>\let\reinstall at nfss@defs\relax
 %<latexrelease>\EndIncludeInRelease
-%<*2ekernel>
 %    \end{macrocode}
 %
+%
+%
 %    This initializes the 2020/02/02 extensions to NFSS after any changes
 %    in the preamble. 
 % \changes{v1.0g}{2020/08/21}{Integration of new hook management interface}
 %    \begin{macrocode}
-%</2ekernel>
 %<*2ekernel|latexrelease>
 %<latexrelease>\IncludeInRelease{2020/10/01}%
 %<latexrelease>                 {\reinstall at nfss@defs}{NFSS series init}%

Modified: trunk/Master/texmf-dist/source/latex/base/ltfssbas.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfssbas.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltfssbas.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -35,7 +35,7 @@
 %
 %
 \ProvidesFile{ltfssbas.dtx}
-             [2020/12/10 v3.2h LaTeX Kernel (NFSS Basic Macros)]
+             [2021/04/26 v3.2i LaTeX Kernel (NFSS Basic Macros)]
 % \iffalse
 \documentclass{ltxdoc}
 \begin{document}
@@ -896,15 +896,35 @@
 %    \begin{macrocode}
 %</2ekernel>
 %<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2020/02/02}%
-%<latexrelease>                 {\usefont}{Drop m in usefont}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>                 {\usefont}{Force font face}%
 \DeclareRobustCommand\usefont[4]{\fontencoding{#1}%
    \edef\f at family{#2}%
    \set at target@series{#3}%
-   \edef\f at shape{#4}\selectfont
+   \edef\f at shape{#4}%
+%    \end{macrocode}
+%    Any earlier \cs{fontseries}, etc.\ should be canceled and we
+%    should switch unconditionally to the requested font face so we
+%    drop any  code that may have been stored in
+%    \cs{delayed at f@adjustment}.
+% \changes{v3.2i}{2021/04/26}{Unconditionally switch to the requested
+%    font face (gh/444)}
+%    \begin{macrocode}
+   \let\delayed at f@adjustment\@empty
+   \selectfont
    \ignorespaces}
 %</2ekernel|latexrelease>
 %<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{2020/02/02}%
+%<latexrelease>                 {\usefont}{Drop m in usefont}%
+%<latexrelease>
+%<latexrelease>\DeclareRobustCommand\usefont[4]{\fontencoding{#1}%
+%<latexrelease>   \edef\f at family{#2}%
+%<latexrelease>   \set at target@series{#3}%
+%<latexrelease>   \edef\f at shape{#4}\selectfont
+%<latexrelease>   \ignorespaces}
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
 %<latexrelease>\IncludeInRelease{0000/00/00}%
 %<latexrelease>                 {\usefont}{Drop m in usefont}%
 %<latexrelease>
@@ -1403,7 +1423,7 @@
 %    The idea for this macro is stolen from the \texttt{substitutefont}
 %    package by Günter Milde, with some modifications and a new name.
 %
-%    Its purpose is to provide characters in a special encoding tht
+%    Its purpose is to provide characters in a special encoding that
 %    are not available in the current font family to be taken from a
 %    different family that is visually compatible (or not if you
 %    choose badly). For example, you can match the GFS Didot Greek
@@ -1422,7 +1442,7 @@
 %</2ekernel>
 %<*2ekernel|latexrelease>
 %<latexrelease>\IncludeInRelease{2020/02/02}%
-%<latexrelease>       {\DeclareFontFamilySubstitution}{Provide family substituation}%
+%<latexrelease>       {\DeclareFontFamilySubstitution}{Provide family substitution}%
 \begingroup
 \nfss at catcodes
 \gdef\DeclareFontFamilySubstitution#1#2#3{%
@@ -1432,7 +1452,7 @@
 %    is better to handle that differently.
 %
 %    Of course the families  may still need loading at
-%    this point and so we arange for this. Otherwise we might run into
+%    this point and so we arrange for this. Otherwise we might run into
 %    trouble because the necessary \cs{DeclareFontFamily} has not been
 %    seen.
 %    \begin{macrocode}
@@ -1476,7 +1496,7 @@
 %</2ekernel|latexrelease>
 %<latexrelease>\EndIncludeInRelease
 %<latexrelease>\IncludeInRelease{0000/00/00}%
-%<latexrelease>      {\DeclareFontFamilySubstitution}{Provide family substituation}%
+%<latexrelease>      {\DeclareFontFamilySubstitution}{Provide family substitution}%
 %<latexrelease>
 %<latexrelease>\let\DeclareFontFamilySubstitution\@undefined
 %<latexrelease>\EndIncludeInRelease
@@ -1503,11 +1523,11 @@
           \noexpand\@nil}%
 %    \end{macrocode}
 %    Initialize all those internal variables which may or may not have
-%    values in the first seconds of NFSS' bootstraping process. Later
+%    values in the first seconds of NFSS' bootstrapping process. Later
 %    on such values will be updated when an encoding is selected, etc.
 %
 %    We definitely don't want to set |\f at encoding|; we can set all the
-%    others since if they are left ``blank'' any selection would grap
+%    others since if they are left ``blank'' any selection would grab
 %    ``error default values'' as well. However, this probably should
 %    go also---and now it did.
 % \changes{v2.1n}{1994/05/14}{Don't set \cs{f at encoding}}
@@ -1559,7 +1579,7 @@
 %    \begin{macrocode}
 %</2ekernel>
 %<latexrelease>\IncludeInRelease{2015/01/01}{\wrong at fontshape}%
-%<latexrelease>                 {Font substituation in preamble}%
+%<latexrelease>                 {Font substitution in preamble}%
 %<*2ekernel|latexrelease>
 \def\wrong at fontshape{%
     \csname D@\f at encoding\endcsname   % install defaults if in math
@@ -1600,9 +1620,9 @@
 %    corresponding \texttt{.fd} file may not been loaded
 %    yet. Therefore we try this now. Otherwise equating the requested
 %    font shape with the finally selected fontshape below will fail
-%    and can result in ``NFSS tables corruped''. After begin document
+%    and can result in ``NFSS tables corrupted''. After begin document
 %    that will not happen as all \texttt{.fd} files involved in
-%    substituation are loaded at |\begin{document}|.
+%    substitution are loaded at |\begin{document}|.
 %    \begin{macrocode}
            \begingroup
               \try at load@fontshape
@@ -1681,7 +1701,7 @@
 %</2ekernel|latexrelease>
 %<latexrelease>\EndIncludeInRelease
 %<latexrelease>\IncludeInRelease{0000/00/00}{\wrong at fontshape}%
-%<latexrelease>                 {Font substituation in preamble}%
+%<latexrelease>                 {Font substitution in preamble}%
 %<latexrelease>\def\wrong at fontshape{%
 %<latexrelease>    \csname D@\f at encoding\endcsname
 %<latexrelease>    \edef\reserved at a{\csname\curr at fontshape\endcsname}%
@@ -1856,7 +1876,7 @@
 %    it modifies the corresponding macro |\mv@|\meta{version}
 %    so that it calls |\getanddefine at fonts| directly in future as well.
 %    We use the macro |\extract at alph@from at version| to do this.
-%    It takes the math alphabet identifer |#1| and the math version
+%    It takes the math alphabet identifier |#1| and the math version
 %    macro as arguments.
 % \changes{v1.9a}{1992/07/26}{}
 %    \begin{macrocode}
@@ -1944,7 +1964,7 @@
               \use at mathgroup##1{#2}}}%
 %    \end{macrocode}
 % \changes{v2.1t}{1994/10/15}{Warn if math alpha is used outside math}
-%    In addtion it defines the alphabet the way it should be used from
+%    In addition it defines the alphabet the way it should be used from
 %    now on.
 %    \begin{macrocode}
        \gdef#3{\relax\ifmmode \else \non at alpherr#3\fi

Modified: trunk/Master/texmf-dist/source/latex/base/ltfsscmp.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfsscmp.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltfsscmp.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -36,7 +36,7 @@
 %
 %
 \ProvidesFile{ltfsscmp.dtx}
-             [2015/06/23 v3.0f LaTeX Kernel (NFSS1 Compatibility)]
+             [2020/12/05 v3.0f LaTeX Kernel (NFSS1 Compatibility)]
 % \iffalse
 \documentclass{ltxdoc}
 \begin{document}
@@ -181,7 +181,7 @@
       \in@{pt}{#3}%  not a proof but a good chance
       \ifin@
 %    \end{macrocode}
-%    We grap also everything after pt and discard it if people have
+%    We grab also everything after pt and discard it if people have
 %    forgotten to place a percent sign there.
 % \changes{v2.1d}{1994/02/10}{scan away stuff after pt}
 %    \begin{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/base/ltfssdcl.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfssdcl.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltfssdcl.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -36,7 +36,7 @@
 %
 %
 \ProvidesFile{ltfssdcl.dtx}
-            [2020/03/19 v3.0v LaTeX Kernel (NFSS Declarative Interface)]
+            [2021/02/15 v3.0w LaTeX Kernel (NFSS Declarative Interface)]
 % \iffalse
 \documentclass{ltxdoc}
 \begin{document}
@@ -490,8 +490,12 @@
                    in version \math at version}%
         \@eha
   \fi
- \else \expandafter\non at alpherr\fi
 %    \end{macrocode}
+% extra \cs{expandafter} to remove the \cs{expandafter} added below
+% \changes{v3.0w}{2021/02/115}{fix for (gh/501)}
+%    \begin{macrocode}
+ \else \expandafter\expandafter\expandafter\non at alpherr\fi
+%    \end{macrocode}
 %    If the legacy interface is used, e.g., \verb=$\sf -1$= the math
 %    alphabet \verb=#1= does not take an argument so we better do not
 %    surround \verb=#4= with braces, because then we get
@@ -747,7 +751,7 @@
       \@font at info{Redeclaring symbol font `#1'}%
 %    \end{macrocode}
 % \changes{v3.0f}{1997/11/13}
-%      {(DPC) Really update \cs{group at list} dont
+%      {(DPC) Really update \cs{group at list} don't
 %         leave new version in \cs{toks@}. latex/2661}
 % Update the group list.
 %    \begin{macrocode}
@@ -1526,7 +1530,7 @@
 \def\set at mathdelimiter#1#2#3#4#5#6{%
 %    \end{macrocode}
 %    We use \cs{protected} not \cs{MakeRobust} so that
-%    \verb=\bigl\lfoor= etc.\ works inside \cs{protected at edef}.
+%    \verb=\bigl\lfoor= etc.\ works inside the argument of \cs{protected at edef}.
 % \changes{v3.0s}{2019/08/27}{Make math delimiters robust}
 % \changes{v3.0t}{2020/01/20}{fix for gh/251}
 %    \begin{macrocode}
@@ -1733,7 +1737,7 @@
       \relax
 %    \end{macrocode}
 %    If it is undefined, fine otherwise check if it is a math alphabet
-%    defined via |\DeclareSymbolFontAlphabet|:
+%    defined via \\ |\DeclareSymbolFontAlphabet|:
 %    \begin{macrocode}
       \else
         \edef\reserved at a{%

Modified: trunk/Master/texmf-dist/source/latex/base/ltfssini.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfssini.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltfssini.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -36,7 +36,7 @@
 %
 %
 \ProvidesFile{ltfssini.dtx}
-             [2020/10/08 v3.2e LaTeX Kernel (NFSS Initialisation)]
+             [2021/04/26 v3.2h LaTeX Kernel (NFSS Initialisation)]
 % \iffalse
 \documentclass{ltxdoc}
 \begin{document}
@@ -56,7 +56,7 @@
 %
 % \GetFileInfo{ltfssini.dtx}
 % \title{A new font selection scheme for \TeX{} macro packages\\
-%        (Initialisation)\thanks
+%        (Initialization)\thanks
 %       {This file has version number
 %       \fileversion\ dated \filedate}}
 %
@@ -83,7 +83,7 @@
 % \changes{v3.1d}{2019/08/27}{Make various commands robust}
 %
 %
-% \section{NFSS Initialisation}
+% \section{NFSS Initialization}
 %
 % \iffalse
 %<+checkmem>\CHECKMEM
@@ -301,7 +301,7 @@
     \else
 %    \end{macrocode}
 %
-% \changes{v3.1g}{2020/02/05}{Clarrified error text}
+% \changes{v3.1g}{2020/02/05}{Clarified error text}
 %    \begin{macrocode}
        \@latex at error{Wrong syntax for \string\DeclareFontSeriesDefault}%
           {Mandatory first argument must be 'md'  or 'bf'.}
@@ -431,7 +431,7 @@
 %<+debug> \series at change@debug{No series preparation (forced \f at series)\on at line}%
    \fontfamily#2%
  \else
-%<+debug> \series at change@debug{Prepearing for switching to #1 (#2)\on at line}%
+%<+debug> \series at change@debug{Preparing for switching to #1 (#2)\on at line}%
    \expand at font@defaults
 %    \end{macrocode}
 %    We prepare for changing the current series. We have to find it
@@ -448,7 +448,7 @@
 %    \item \cs{bfseries} is called  for a family using \texttt{bx}
 %       (e.g., CMR) 
 %    \item Switch to a font family that is none of the meta
-%       families, e.g., via \verb=\fontfamily{ptm}\selectfont=
+%       families, e.g., via \verb=\fontfamily{ptm}\allowbreak\verb=\selectfont=
 %    \item Then none of the real meta families, match but the final
 %      \verb=\@elt{??}= will.
 %    \item Therefore if the current series is \cs{mddefault} or
@@ -493,7 +493,7 @@
 %    \end{macrocode}
 %    The \cs{target at series@value} may contain something like
 %    \texttt{cm} (coming from a default) and so we can't directly
-%    asign it to \cs{f at series} be have to drop any surplus \texttt{m}
+%    assign it to \cs{f at series} be have to drop any surplus \texttt{m}
 %    first.
 % \changes{v3.1j}{2020/02/25}{Drop surplus ``m'' from
 %                             \cs{target at series@value} (gh/291)}
@@ -513,7 +513,7 @@
 %    In this macro used in the look you basically find the nested
 %    \cs{ifx}s from the outline above. The only difference is that is
 %    it is parameterized instead of being written out and only for one
-%    block of tests because the code is called reatedly when looping
+%    block of tests because the code is called repeatedly when looping
 %    over the meta family list. From the list we get each meta family
 %    name in turn.
 %    \begin{macrocode}
@@ -665,7 +665,7 @@
 %    the now current series value (in \cs{f at series}).
 %
 %    But what should happen if \cs{seriesdefault} got explicitly
-%    changed?  In that case the explicit change should surive and we
+%    changed?  In that case the explicit change should survive and we
 %    should not alter \cs{seriesdefault}. This is solved by comparing
 %    the current value of \cs{seriesdefault} with a kernel version
 %    saved in the format and if they differ we do not call
@@ -915,9 +915,9 @@
 %\end{verbatim}
 %    We have to do the testing while the current family is still
 %    unchanged but we have to do the adjustment of the series after it
-%    got changed (because the new family might has different sets
-%    ofshapes available and we certainly don't want to see
-%    substituation going on. So we use \cs{target at series@value} to
+%    got changed (because the new family might have different sets
+%    of shapes available and we certainly don't want to see
+%    substitution going on. So we use \cs{target at series@value} to
 %    hold the target series (if any).
 %\begin{verbatim}
 %  \let\target at series@value\@empty
@@ -1088,6 +1088,8 @@
 %  \end{macro}
 %
 %
+% \changes{v3.2g}{2021/03/18}
+%         {Add legacy hook definitions for rollback.}
 %    \begin{macrocode}
 %</2ekernel|latexrelease>
 %<latexrelease>\EndIncludeInRelease
@@ -1140,6 +1142,9 @@
 %<latexrelease>   \prepare at family@series at update{tt}\ttdefault
 %<latexrelease>   \@ttfamilyhook
 %<latexrelease>   \selectfont}
+%<latexrelease>\let\@rmfamilyhook\@empty
+%<latexrelease>\let\@sffamilyhook\@empty
+%<latexrelease>\let\@ttfamilyhook\@empty
 %<latexrelease>
 %    \end{macrocode}
 %    
@@ -1183,7 +1188,7 @@
 %    to different NFSS axis values it becomes important to have the
 %    ability to determine the current context as we can no longer look
 %    at \cs{f at series} to answer a question such as ``am I currently
-%    typsetting in a bold typeface?''
+%    typesetting in a bold typeface?''
 %
 %    This is provided by the test \cs{IfFontSeriesContextTF}. It takes
 %    three arguments:
@@ -1221,7 +1226,7 @@
 \DeclareRobustCommand\IfFontSeriesContextTF[1]{%
   \expand at font@defaults
 %    \end{macrocode}
-%    In the beginning we haven't found the context we are loking for.
+%    In the beginning we haven't found the context we are looking for.
 %    \begin{macrocode}
   \@font at series@contextfalse
 %    \end{macrocode}
@@ -1238,7 +1243,7 @@
   \expandafter\edef\csname ??def at ult\endcsname{\f at family}%
 %    \end{macrocode}
 %    Then we run through the meta family list (currently containing
-%    just the three values) followed by the artifical meta family
+%    just the three values) followed by the artificial meta family
 %    \texttt{??} and test each of them in turn using
 %    \cs{test at font@series at context} as the testing command.
 %    \begin{macrocode}
@@ -1264,7 +1269,7 @@
 
 %  \begin{macro}{\test at font@series at context}
 %    This tests the context (stored in \cs{requested at test@context})
-%    and updates the bookean if the right context is found.
+%    and updates the boolean if the right context is found.
 %    \begin{macrocode}
 \def\test at font@series at context#1{%
 %    \end{macrocode}
@@ -1307,8 +1312,9 @@
 }
 %    \end{macrocode}
 %  \end{macro}
-
-
+%
+%
+%
 %  \begin{macro}{\if at font@series at context}
 %    The boolean to signal if we found the requested font series context.
 %    \begin{macrocode}
@@ -1334,19 +1340,21 @@
 %<latexrelease>\EndIncludeInRelease
 %<*2ekernel>
 %    \end{macrocode}
-
-
-
 %
+%
+%
+%
+%
+%
 % \section{Supporting nested emphasis}
 %
 %    By default \LaTeXe{} supports two levels of nested emphasis: if
 %    the current font has an upright shape then it switches to
 %    \cs{itshape} otherwise to \cs{eminnershape} (which defaults to
-%    \cs{upshape}). This means nested emphasis will ocssilate between
+%    \cs{upshape}). This means nested emphasis will oscillate between
 %    italic and upright shapes.
 %
-%    Sometimes it would be nice to allow for a more lengthly sequence,
+%    Sometimes it would be nice to allow for a more lengthy sequence,
 %    but instead of providing a fixed one \LaTeX{} now offers a
 %    general mechanism that allows to define arbitrary sequences.
 %
@@ -1377,7 +1385,7 @@
 %  \begin{macro}{\DeclareEmphSequence}
 %
 %    \cs{DeclareEmphSequence} expects a clist of declaration. Spaces in the
-%    argument are dropped to avoid surious spaces in the output. The
+%    argument are dropped to avoid spurious spaces in the output. The
 %    declarations are additive. At the very end the shape is reset
 %    using |\emreset| and |\emforce| so that this case is never
 %    skipped.\footnote{Maybe we should not add \cs{emforce} but allow
@@ -1401,9 +1409,9 @@
 \let\emfontdeclare at clist\@empty
 %    \end{macrocode}
 %  \end{macro}
-
-
-
+%
+%
+%
 %  \begin{macro}{\emrest}
 %    Reset the font to upright and upper/lower case. With the default rules
 %    using \cs{shapedefault} does that for us but to be on the safe side we
@@ -1412,12 +1420,13 @@
 \DeclareRobustCommand\emreset{\upshape\ulcshape}
 %    \end{macrocode}
 %  \end{macro}
-
-
-
+%
+%
+%
 %  \begin{macro}{\em}
-%    The new definition for \cs{em} (and implicitly \cs{emph} is like
-%    it was before if \cs{emfontdeclare at clist} is empty.
+%
+%    The new definition for \cs{em} (and implicitly \cs{emph}) is the
+%    same as before as long as \cs{emfontdeclare at clist} is empty.
 %    \begin{macrocode}
 \DeclareRobustCommand\em{%
   \@nomath\em
@@ -1479,7 +1488,7 @@
 %    \begin{macrocode}
   \expandafter\ifx\csname \curr at fontshape/\f at size\em at force
 %    \end{macrocode}
-%    For the comparison with \cs{ifx} we have to exand
+%    For the comparison with \cs{ifx} we have to expand
 %    \cs{em at currfont} once as the relevant info is inside.
 %    \begin{macrocode}
                           \expandafter\endcsname
@@ -1761,7 +1770,7 @@
 %    \begin{macrocode}
 %</2ekernel>
 %<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2020/02/02}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
 %<latexrelease>                 {\normalfont}{Add hook to \normalfont}%
 \DeclareRobustCommand\normalfont{%
 %    \end{macrocode}
@@ -1774,6 +1783,15 @@
    \edef\f at series{\seriesdefault}%
    \edef\f at shape{\shapedefault}%
 %    \end{macrocode}
+%    Any earlier \cs{fontseries}, etc.\ should be canceled and we
+%    should switch unconditionally to the requested font face so we
+%    drop any  code that may have been stored in
+%    \cs{delayed at f@adjustment}.
+% \changes{v3.2h}{2021/04/26}{Unconditionally switch to the requested
+%    font face (gh/444)}
+%    \begin{macrocode}
+   \let\delayed at f@adjustment\@empty
+%    \end{macrocode}
 %    
 % \changes{v3.2b}{2020/08/21}{Integration of new hook management interface}
 %    \begin{macrocode}
@@ -1785,18 +1803,54 @@
    \@defaultfamilyhook        % hookname from 2020/02 will vanish
    \selectfont}
 %    \end{macrocode}
-%    
+%
 %    \begin{macrocode}
 \let\reset at font\normalfont
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
-%    
 %
 %
+%
 %    \begin{macrocode}
+% \changes{v3.2g}{2021/03/18}
+%         {Add missing 2020/02/02 latexrelease entry.}
 %</2ekernel|latexrelease>
 %<latexrelease>\EndIncludeInRelease
+%<latexrelease>
+%<latexrelease>\IncludeInRelease{2020/10/01}%
+%<latexrelease>                 {\normalfont}{Add hook to \normalfont}%
+%<latexrelease>
+%<latexrelease>\DeclareRobustCommand\normalfont{%
+%<latexrelease>   \fontencoding\encodingdefault
+%<latexrelease>   \edef\f at family{\familydefault}%
+%<latexrelease>   \edef\f at series{\seriesdefault}%
+%<latexrelease>   \edef\f at shape{\shapedefault}%
+%<latexrelease>   \UseHook{normalfont}%
+%<latexrelease>   \@defaultfamilyhook        % hookname from 2020/02 will vanish
+%<latexrelease>   \selectfont}
+%<latexrelease>
+%<latexrelease>\let\reset at font\normalfont
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>
+%<latexrelease>\IncludeInRelease{2020/02/02}%
+%<latexrelease>                 {\normalfont}{Add hook to \normalfont}%
+%<latexrelease>
+%<latexrelease>\DeclareRobustCommand\normalfont{%
+%<latexrelease>   \fontencoding\encodingdefault
+%<latexrelease>   \edef\f at family{\familydefault}%
+%<latexrelease>   \edef\f at series{\seriesdefault}%
+%<latexrelease>   \edef\f at shape{\shapedefault}%
+%<latexrelease>   \@defaultfamilyhook
+%<latexrelease>   \selectfont}
+%<latexrelease>
+%<latexrelease>\let\reset at font\normalfont
+%<latexrelease>
+%<latexrelease>\let\@defaultfamilyhook\@empty
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>
 %<latexrelease>\IncludeInRelease{0000/00/00}%
 %<latexrelease>                 {\normalfont}{Add hook to \normalfont}%
 %<latexrelease>
@@ -1863,8 +1917,20 @@
 % \changes{v3.1c}{2019/07/09}{Explicitly set some defaults}
 %    \begin{macrocode}
 \fontfamily{cmr}
-\fontseries{m}
-\fontshape{n}
+%    \end{macrocode}
+%    
+% \changes{v3.2f}{2020/12/04}{Adjust start values for series and shape (gh/444)}
+%    Previously the default values for series and shape were set by
+%    calling \cs{fontseries} and \cs{fontshape}, but their action is
+%    now delayed until \cs{selectfont} which isn't called inside the
+%    format (to avoid unnecessarily loading a font that may never get used).
+%    We therefore have to set \cs{f at series} and \cs{f at shape} directly instead.
+%    \begin{macrocode}
+\def\f at series{m}           % \fontseries{m}
+\def\f at shape{n}            % \fontshape{n}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \fontsize{10}{10}
 %    \end{macrocode}
 %

Modified: trunk/Master/texmf-dist/source/latex/base/ltfsstrc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltfsstrc.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltfsstrc.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -30,14 +30,14 @@
 % \iffalse
 %%% From File: ltfsstrc.dtx
 %% Copyright (C) 1989-97 by Frank Mittelbach and Rainer Sch\"opf.
-%% Copyright (C) 1994-97 by LaTeX3 project. All rights reserved.
+%% Copyright (C) 1994-97 by LaTeX Project. All rights reserved.
 %
-%<package>\NeedsTeXFormat{LaTeX2e}[1995/05/16]
+%<package>\NeedsTeXFormat{LaTeX2e}[2021/06/01]
 %<package>\ProvidesPackage{tracefnt}
-%<package>     [2019/10/11 v3.0l  Standard LaTeX package (font tracing)]
+%<package>     [2020/12/22 v3.0n  Standard LaTeX package (font tracing)]
 % \fi
 % \ProvidesFile{ltfsstrc.dtx}
-%              [2020/02/03 v3.0l LaTeX Kernel (NFSS tracing)]
+%              [2021/04/26 v3.0o LaTeX Kernel (NFSS tracing)]
 %
 % \iffalse
 %<+checkmem>\CHECKMEM
@@ -190,7 +190,7 @@
 % special package file named \texttt{trace.sty}.\footnote{This package
 % is not in distribution at the moment (and probably doesn't any
 % longer work). Think of this part of the code as being historical
-% artefacts.}
+% artifacts.}
 %    \begin{macrocode}
 %<+debug> \input trace.sty
 %    \end{macrocode}
@@ -420,19 +420,25 @@
 %    \end{macrocode}
 %  \end{macro}
 %
+
+%    \begin{macrocode}
+%<*2ekernel|latexrelease|package>
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>                 {\selectfont}{Add hook to \selectfont}%
+%    \end{macrocode}
 %
+%
+%
+%
+% \begin{macro}{\selectfont}
 % \changes{v1.0j}{1990/02/18}
 %      {Redefine unprotected version \cs{p at selectfont}
 %                           instead of \cs{selectfont}.}
-%
-%
-% \begin{macro}{\selectfont}
 % \changes{v1.1a}{1989/12/16}{Changed order of calls.}
 % \changes{v2.3f}{1994/05/12}{Use \cs{DeclareRobustCommand}}
 %    The macro |\selectfont| is called whenever a font change must
 %    take place.
 %    \begin{macrocode}
-%<*2ekernel|package>
 \DeclareRobustCommand\selectfont
         {%
 %    \end{macrocode}
@@ -456,6 +462,77 @@
     \ifx\f at linespread\baselinestretch \else
       \set at fontsize\baselinestretch\f at size\f at baselineskip \fi
 %    \end{macrocode}
+%
+%    The series and shape updates are only prepared by
+%    \cs{fontseries} and \cs{fontshape} but not executed until after
+%    we are ready to change the font face. This way they happen after
+%    a possibly new family is set which is important because they
+%    look at the available font faces in that family and alter the
+%    selection based on availibility. Several calls to \cs{fontseries}
+%    or \cs{fontshape} are delayed in the order in which they appear,
+%    so that by switching them one can work around missing
+%    intermediate font faces and avoid substitutions.
+%
+%    We first attempt to do the merge without any substitution. As we
+%    might end up with a non-existing font face we may have to restart
+%    and therefore save the current values of \cs{f at series} and
+%    \cs{f at shape} before the merge.
+%
+%    But first we make a quick test to see if there are any delayed
+%    actions, because if not it is pointless to make all the
+%    assignments and try loading a missing fontshape.
+%
+% \changes{v3.0n}{2020/12/22}{Execute delayed series and shape updates (gh/444)}
+%    \begin{macrocode}
+    \ifx\delayed at f@adjustment\@empty
+    \else
+      \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
+%    \begin{macrocode}
+      \delayed at f@adjustment
+%    \end{macrocode}
+%    We then check if the resulting cominbation is valid but for this
+%    we have to make sure the the appropiate \texttt{.fd} is loaded if
+%    that hasn't happened so far.
+%    \begin{macrocode}
+      \maybe at load@fontshape
+      \ifcsname \f at encoding/\f at family/\f at series/\f at shape \endcsname
+%    \end{macrocode}
+%    If this macro is defined then we are good and no further action
+%    is necessary.
+%    
+%    Otherwise the combination is not valid, so we redo the merge but
+%    this time with substitutions.
+%    \begin{macrocode}
+      \else
+        \let\f at shape\f at shape@saved
+        \let\f at series\f at series@saved
+        \let\delayed at merge@font at shape\merge at font@shape
+        \let\delayed at merge@font at series\merge at font@series
+        \delayed at f@adjustment
+        \let\delayed at merge@font at shape\merge at font@shape at without@substitution
+        \let\delayed at merge@font at series\merge at font@series at without@substitution
+      \fi
+%    \end{macrocode}
+%    Now the series and shape values are updated and we clear
+%    \cs{delayed at f@adjustment}. This is important because on the next
+%    execution of \cs{selectfont} we should not mistakenly redo the
+%    delayed actions if there wasn't any series or shape change.
+%    \begin{macrocode}
+      \let\delayed at f@adjustment\@empty
+    \fi
+%    \end{macrocode}
+%    If the series was forced we should now cancel that in case the
+%    next series change is done with some low-level setting to
+%    \cs{f at series}.
+% \changes{v3.0o}{2021/04/26}{Unset the forced series boolean when reaching
+%    \cs{selectfont} (gh/444)}
+%    \begin{macrocode}
+    \@forced at seriesfalse
+%    \end{macrocode}
 %    Then we generate the internal name of the font
 %    by concatenating {\em family}, {\em series},
 %    {\em shape}, and current {\em size},
@@ -478,18 +555,13 @@
 %    \begin{macrocode}
     \font at name
 %    \end{macrocode}
-%    If |\tracingfonts| is
-%    greater than 2 we also show the font switch.
-%    We do this before |\glb at settings| is called since this
-%    macro might redefine |\font at name|.
-% \changes{v1.0k}{1990/03/14}{Added code for TeX3.}
-% \changes{v1.0i}{1990/02/16}{Changed \cs{f at size} to \cs{lcl at currsize}
-%         (see fam file).}
+%    
+%    After switching fonts we run a hook, so that packages can make
+%    last minute alterations based on the new font (originally provided
+%    in \pkg{everysel} but using a different interface).
+% \changes{v3.0m}{2020/12/03}{Install a hook in \cs{selectfont} (gh/444)}
 %    \begin{macrocode}
-%<*trace>
-    \ifnum \tracingfonts>\tw@
-      \@font at info{Switching to \font at name}\fi
-%</trace>
+    \UseHook{selectfont}%
 %    \end{macrocode}
 %    Finally we call |\size at update|. This macro is normally empty but
 %    will contain actions (like setting the |\baselineskip|) that have
@@ -514,11 +586,69 @@
 % \end{macro}
 %
 %
+%  \begin{macro}{selectfont}
+%    Declare the hook used in selecfont in the kernel, but not
+%    inside the \pkg{tracefnt} package.
+%    \begin{macrocode}
+%<-trace>\NewHook{selectfont}
+%    \end{macrocode}
+%  \end{macro}
 %
+%
+%    If |\tracingfonts| is
+%    greater than 2 we also show the font switch inside \cs{selectfont}.
+%    We do this by adding this code to the hook in the \pkg{tracefnt} package:
+%    macro might redefine |\font at name|.
+%    \begin{macrocode}
+%<*trace>
+\AddToHook{selectfont}
+   {\ifnum \tracingfonts>\tw@
+       \@font at info{Switching to \font at name}\fi}
+%</trace>
+%    \end{macrocode}
+%
+%
+%    \begin{macrocode}
+%</2ekernel|latexrelease|package>
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
+%
+%    With \cs{selectfont} having different definitions in different
+%    kernels we also have to provide them in the \texttt{tracefnt}
+%    package to support rollback. In packages that works a bit
+%    differently and therefore we have to provide an empty block there.   
+%    \begin{macrocode}
+%<package>\IncludeInRelease{2021/06/01}%
+%<package>                 {\selectfont}{Add hook to \selectfont}%
+%<package>\EndIncludeInRelease
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<latexrelease|package>\IncludeInRelease{0000/00/00}%
+%<latexrelease|package>                 {\selectfont}{Add hook to \selectfont}%
+%<latexrelease|package>
+%<latexrelease|package>\DeclareRobustCommand\selectfont
+%<latexrelease|package>   {%
+%<latexrelease|package>    \ifx\f at linespread\baselinestretch \else
+%<latexrelease|package>      \set at fontsize\baselinestretch\f at size\f at baselineskip \fi
+%<latexrelease|package>    \xdef\font at name{%
+%<latexrelease|package>      \csname\curr at fontshape/\f at size\endcsname}%
+%<latexrelease|package>    \pickup at font
+%<latexrelease|package>    \font at name
+%<latexrelease|package>    \size at update
+%<latexrelease|package>    \enc at update
+%<latexrelease|package>   }
+%<latexrelease|package>
+%<latexrelease|package>\EndIncludeInRelease
+%    \end{macrocode}
+%    
+%
+%
 %  \begin{macro}{\set at fontsize}
 %    The macro |\set at fontsize| does the actual work. First it assigns
 %    new values to |\f at size|, |\f at baselineskip| and |\f at linespread|.
 %    \begin{macrocode}
+%<*2ekernel|package>
 \def\set at fontsize#1#2#3{%
     \@defaultunits\@tempdimb#2pt\relax\@nnil
     \edef\f at size{\strip at pt\@tempdimb}%
@@ -1245,7 +1375,7 @@
 %  Now, we are through with the case of a simple size, except for
 %  calling the size function. This will be handled later, as it is
 %  the same mechanism for all types of size specification. We will
-%  now proceed to macors for extraction of size range specification.
+%  now proceed to macros for extraction of size range specification.
 %
 %
 %

Modified: trunk/Master/texmf-dist/source/latex/base/lthooks.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/lthooks.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/lthooks.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
-%%
-%% File: lthooks.dtx (C) Copyright 2020 Frank Mittelbach,
-%%                                      Phelype Oleinik & LaTeX Team
 %
+% Copyright (C)  2020-2021
+%       Frank Mittelbach, Phelype Oleinik & LaTeX Team
+%
 % This file is part of the LaTeX base system.
 % -------------------------------------------
 %
@@ -31,8 +31,8 @@
 %%% From File: lthooks.dtx
 %
 %    \begin{macrocode}
-\def\lthooksversion{v1.0h}
-\def\lthooksdate{2021/01/07}
+\def\lthooksversion{v1.0n}
+\def\lthooksdate{2021/05/26}
 %    \end{macrocode}
 %
 %<*driver>
@@ -54,6 +54,9 @@
   }
 \ExplSyntaxOff
 
+\providecommand\InternalDetectionOff{}
+\providecommand\InternalDetectionOn{}
+
 \EnableCrossrefs
 \CodelineIndex
 \begin{document}
@@ -64,10 +67,13 @@
 % \fi
 %
 %
-% \long\def\fmi#1{\begin{quote}\itshape FMi: #1\end{quote}}
-% \long\def\pho#1{\begin{quote}\itshape PhO: #1\end{quote}}
+% \providecommand\hook[1]{\texttt{#1}}
 %
-% \newcommand\hook[1]{\texttt{#1}}
+% \providecommand\fmi[1]{\marginpar{\footnotesize FMi: #1}}
+% \providecommand\fmiinline[1]{\begin{quote}\itshape\footnotesize FMi: #1\end{quote}}
+% \providecommand\pho[1]{\marginpar{\footnotesize PhO: #1}}
+% \providecommand\phoinline[1]{\begin{quote}\itshape\footnotesize PhO: #1\end{quote}}
+%
 %    
 %
 % \title{The \texttt{lthooks} package\thanks{This package has version
@@ -119,14 +125,15 @@
 %
 % \subsection{\LaTeXe\ interfaces}
 %
-% \subsubsection{Declaring hooks and using them in code}
+% \subsubsection{Declaring hooks}
 %
-%    With two exceptions, hooks have to be declared before they can be
-%    used. The exceptions are hooks in environments (i.e., executed at
-%    \cs{begin} and \cs{end}) and hooks run when loading files,
-%    e.g. before and after a package is loaded, etc. Their hook names
-%    depend on the environment or the file name and so declaring them
-%    beforehand is difficult.
+%    With a few exceptions, hooks have to be declared before they can
+%    be used. The exceptions are the generic hooks for commands,
+%    environments (i.e., executed at \cs{begin} and \cs{end}) and
+%    hooks run when loading files, e.g. before and after a package is
+%    loaded, etc. Their hook names depend on the command,
+%    environment or the
+%    file name and so declaring them beforehand is not practical.
 %
 %
 % \begin{function}{\NewHook}
@@ -173,8 +180,64 @@
 % \end{function}
 %
 %
+% \subsubsection{Special declarations for hooks}
 %
+%    The declarations here should normally not be used. They are available
+%    to provide support for special use cases mainly involving
+%    generic command hooks.
 %
+% \begin{function}{\DisableHook}
+%   \begin{syntax}
+%     \cs{DisableHook} \Arg{hook}
+%   \end{syntax}
+%    After this declaration the \meta{hook} is no longer usable: Any
+%    attempt to add further code to it will result in an error and any
+%    use, e.g., via \cs{UseHook}, will simply do nothing.
+%
+%    This is intended to be used with generic command hooks (see
+%    \texttt{ltcmdhooks-doc}) as depending on the definition of the
+%    command such generic hooks may be unusable. If that is known, a
+%    package developer can disable such hooks up front.
+%
+%    The \meta{hook} can be specified using the dot-syntax to denote
+%    the current package name. See section~\ref{sec:default-label}.
+% \end{function}
+%
+%
+% \begin{function}{\ProvideHook}
+%   \begin{syntax}
+%     \cs{ProvideHook} \Arg{hook}
+%   \end{syntax}
+%   Like \cs{NewHook} but does nothing if the hook was previously
+%    declared with \cs{NewHook}.  This declaration should only be used
+%    in special situations, e.g., when  command of another package
+%    need to be altered and it is is not clear if for that command a
+%    generic hook was already explicitly declared before.
+%
+%    Normally \cs{NewHook} should be used instead.
+% \end{function}
+%
+% \begin{function}{\ProvideReversedHook}
+%   \begin{syntax}
+%     \cs{ProvideReversedHook} \Arg{hook}
+%   \end{syntax}
+%   Like \cs{NewReversedHook} but does nothing if the hook was
+%    previously declared as a reversed hook.
+% \end{function}
+%
+% \begin{function}{\ProvideMirroredHookPair}
+%   \begin{syntax}
+%     \cs{ProvideMirroredHookPair} \Arg{hook-1} \Arg{hook-2}
+%   \end{syntax}
+%     A shorthand for
+%    \cs{ProvideHook}\Arg{hook-1}\cs{ProvideReversedHook}\Arg{hook-2}.
+% \end{function}
+%
+%
+%
+% \subsubsection{Using hooks in code}
+%
+%
 % \begin{function}{\UseHook}
 %   \begin{syntax}
 %     \cs{UseHook} \Arg{hook}
@@ -198,7 +261,7 @@
 %    Some hooks are only used (and can be only used) in one place, for
 %    example, those in \verb=\begin{document}= or
 %    \verb=\end{document}=. Once we have passed that point adding to
-%    the hook through a defined \cs{\meta{addto-cmd}} command (e.g.,
+%    the hook through a defined \cs[no-index]{\meta{addto-cmd}} command (e.g.,
 %    \cs{AddToHook} or \cs{AtBeginDocument}, etc.\@) would have no
 %    effect (as would the use of such a command inside the hook code
 %    itself). It is therefore customary to redefine
@@ -209,10 +272,12 @@
 %    consumed and any further attempt to add to it will result in
 %    executing the code to be added immediately.
 %
-%    \fmi{Maybe add an error version as well?}
+%    \fmiinline{Maybe add an error version as well?}
 %
 %    The \meta{hook} \emph{cannot} be specified using the dot-syntax.
-%    A leading |.| is treated literally.
+%    A leading |.| is treated literally.    See
+%    section~\ref{sec:default-label} for details.
+
 % \end{function}
 %
 %
@@ -261,9 +326,10 @@
 %    that label, the removal order takes action and the code is not
 %    added.
 %
-%    If the optional argument is \texttt{*}, then all code chunks are
+%    If the optional \meta{label} argument is \texttt{*}, then all code chunks are
 %    removed. This is rather dangerous as it drops code from other
-%    packages one may not know about!
+%    packages one may not know about and should therefore not by used
+%    by packages but only in document preambles!
 %
 %    The \meta{hook} and \meta{label} can be specified using the
 %    dot-syntax to denote the current package name.
@@ -296,7 +362,7 @@
 %\end{verbatim}
 % because that only \enquote{adds} a further empty chunk of code to
 % the hook. Adding \cs{normalsize} would work but that means the hook
-% then contained \cs{small}\cs{normalsize} which means to font size
+% then contained \cs{small}\cs{normalsize} which means two font size
 % changes for no good reason.
 %
 % The above is only needed if one wants to typeset several quotes in a
@@ -356,10 +422,9 @@
 % \meta{label} throughout the sub-packages in order to avoid
 % that the labels change if you internally reorganize your code.
 %
-% Except for \cs{UseHook}, \cs{UseOneTimeHook}, \cs{IfHookEmptyTF}, and
-% \cs{IfHookExistsTF} (and their \pkg{expl3} interfaces \cs{hook_use:n},
-% \cs{hook_use_once:n}, \cs{hook_if_empty:nTF}, and
-% \cs{hook_if_exist:nTF}), all \meta{hook}
+% Except for \cs{UseHook}, \cs{UseOneTimeHook} and \cs{IfHookEmptyTF}
+% (and their \pkg{expl3} interfaces \cs{hook_use:n},
+% \cs{hook_use_once:n} and \cs{hook_if_empty:nTF}, all \meta{hook}
 % and \meta{label} arguments are processed in the same way: first,
 % spaces are trimmed around the argument, then it is fully expanded
 % until only character tokens remain.  If the full expansion of the
@@ -367,8 +432,8 @@
 % token, a low-level \TeX{} error is raised (namely, the \meta{hook} is
 % expanded using \TeX's \cs{csname}\ldots\cs{endcsname}, as such,
 % Unicode characters are allowed in \meta{hook} and \meta{label}
-% arguments).  The arguments of \cs{UseHook}, \cs{UseOneTimeHook},
-% \cs{IfHookEmptyTF}, and \cs{IfHookExistsTF} are
+% arguments).  The arguments of \cs{UseHook}, \cs{UseOneTimeHook}, and
+% \cs{IfHookEmptyTF} are
 % processed much in the same way except that spaces are not trimmed
 % around the argument, for better performance.
 %
@@ -422,8 +487,7 @@
 % this syntax is not available in \cs{UseHook} (and \cs{hook_use:n})
 % because the hook is most of the time used outside of the package file
 % in which it was defined. This syntax is also not available in the hook
-% conditionals \cs{IfHookEmptyTF} (and \cs{hook_if_empty:nTF}) and
-% \cs{IfHookExistsTF} (and \cs{hook_if_exist:nTF}) because these
+% conditionals \cs{IfHookEmptyTF} (and \cs{hook_if_empty:nTF}), because these
 % conditionals are used in some performance-critical parts of the hook
 % management code, and because they are usually used to refer to other
 % package's hooks, so the dot-syntax doesn't make much sense.
@@ -432,7 +496,7 @@
 % it in logical parts, but still use the main package name as
 % \meta{label}, then the \meta{default label} can be set using
 % \cs{SetDefaultHookLabel} or
-% \cs{PushDefaultHookLabel}..\cs{PopDefaultHookLabel}.
+% \cs{PushDefaultHookLabel}\verb={..}=\,\ldots\cs{PopDefaultHookLabel}.
 %
 % \begin{function}{\PushDefaultHookLabel,\PopDefaultHookLabel}
 %   \begin{syntax}
@@ -595,7 +659,7 @@
 %    There can only be a single relation between two labels for a
 %    given hook,
 %    i.e., a later \cs{DeclareHookrule} overwrites any previous
-%    delcaration.
+%    declaration.
 %
 %    The \meta{hook} and \meta{label} can be specified using the
 %    dot-syntax to denote the current package name.
@@ -648,9 +712,10 @@
 %   \item exist and be non-empty; and
 %   \item not exist (in which case emptiness doesn't apply);
 % \end{itemize}
-% Hooks are a bit more complicated: they have four possible states.
-% A hook may exist or not, and either way it may or may not be empty.
-% This means that even a hook that doesn't exist may be non-empty.
+% Hooks are a bit more complicated: 
+% a hook may exist or not, and either way it may or may not be empty.
+% This means that even a hook that doesn't exist may be non-empty and
+%    it can also be disabled.
 %
 % This seemingly strange state may happen when, for example, package~$A$
 % defines hook \hook{A/foo}, and package $B$ adds some code to that
@@ -661,11 +726,17 @@
 % querying the existence of a hook doesn't imply its emptiness, neither
 % does the other way around.
 %
+% Given that code or rules can be added to a hook even if it doesn't
+% physically exist yet, means that a querying its existence has no
+% real use case (in contrast to other variables that can only be
+% update if they have already been declared). For that reason only the
+% test for emptiness has a public interface.
+%
 % A hook is said to be empty when no code was added to it, either to
 % its permanent code pool, or to its ``next'' token list.  The hook
 % doesn't need to be declared to have code added to its code pool.
 % A hook is said to exist when it was declared with \cs{NewHook} or
-% some variant thereof.  Generic \hook{file} and \hook{env} hooks are
+% some variant thereof.  Generic hooks such as \hook{file} and \hook{env} hooks are
 % automatically declared when code is added to them.
 %
 % \begin{function}[EXP]{\IfHookEmptyTF}
@@ -673,7 +744,8 @@
 %     \cs{IfHookEmptyTF} \Arg{hook} \Arg{true code} \Arg{false code}
 %   \end{syntax}
 %   Tests if the \meta{hook} is empty (\emph{i.e.}, no code was added to
-%   it using either \cs{AddToHook} or \cs{AddToHookNext}), and
+%   it using either \cs{AddToHook} or \cs{AddToHookNext}) or such code
+%    was removed again (via \cs{RemoveFromHook}), and
 %   branches to either \meta{true code} or \meta{false code} depending
 %   on the result.
 %
@@ -681,31 +753,8 @@
 %    A leading |.| is treated literally.
 % \end{function}
 %
-% \begin{function}[EXP]{\IfHookExistsTF}
-%   \begin{syntax}
-%     \cs{IfHookExistsTF} \Arg{hook} \Arg{true code} \Arg{false code}
-%   \end{syntax}
-%   Tests if the \meta{hook} exists (if it was created with either
-%   \cs{NewHook}, \cs{NewReversedHook}, or \cs{NewMirroredHookPair}), and
-%   branches to either \meta{true code} or \meta{false code} depending
-%   on the result.
 %
-%   The existence of a hook usually doesn't mean much from the viewpoint
-%   of code that tries to add/remove code from that hook, since package
-%   loading order may vary, thus the creation of hooks is asynchronous
-%   to adding and removing code from it, so this test should be used
-%   sparingly.
 %
-%   Generic hooks are declared at the time code is added to them, so the
-%   result of \cs{hook_if_exist:n} will change once code is added to
-%   said hook (unless the hook was previously declared).
-%
-%    The \meta{hook} \emph{cannot} be specified using the dot-syntax.
-%    A leading |.| is treated literally.
-% \end{function}
-%
-% \fmi{Would be helpful if we provide some use cases}
-%
 % \subsubsection{Displaying hook code}
 %
 %    If one has to adjust the code execution in a hook using a hook
@@ -807,7 +856,7 @@
 %   \meta{label-2}, in that order, as detailed in \cs{DeclareHookRule}.
 %   If the relation is \texttt{default} it means that that rule applies
 %   to \meta{label-1} and \meta{label-2} in \emph{all} hooks, (unless
-%   overrided by a non-default relation).
+%   overridden by a non-default relation).
 %
 %   Finally, line~14 lists the labels in the hook after sorting;
 %   that is, in the order they will be executed when the hook is used.
@@ -819,7 +868,7 @@
 %   \begin{syntax}
 %     \cs{DebugHooksOn}
 %   \end{syntax}
-%    Turn the debugging of hook code on or off. This displays changes
+%    Turn the debugging of hook code on or off. This displays most changes
 %    made to the hook data structures. The output is rather coarse and
 %      not really intended for normal use.
 % \end{function}
@@ -856,6 +905,53 @@
 %
 %
 %
+% \begin{function}{\hook_disable:n}
+%   \begin{syntax}
+%     \cs{hook_disable:n} \Arg{hook}
+%   \end{syntax}
+%    Marks \Arg{hook} as disabled. Any further attempt to add code to
+%    it or declare it, will result in an error and any call to
+%    \cs{hook_use:n} will simply do nothing.
+%
+%    This declaration is intended for use with generic hooks that are
+%    known not to work (see \texttt{ltcmdhooks-doc}) if they receive
+%    code.
+%
+%    The \meta{hook} can be specified using the dot-syntax to denote
+%    the current package name. See section~\ref{sec:default-label}.
+% \end{function}
+%
+% \begin{function}{\hook_provide:n}
+%   \begin{syntax}
+%     \cs{hook_provide:n} \Arg{hook}
+%   \end{syntax}
+%    Like \cs{hook_new:n} but does nothing if the hook was previously
+%    declared with \cs{hook_new:n}.  This declaration should only be used
+%    in special situations, e.g., when a command of another package
+%    needs to be altered and it is is not clear if for that command a
+%    generic \hook{cmd} hook was already explicitly declared before.
+%
+%    Normally \cs{hook_new:n} should be used instead.
+% \end{function}
+%
+% \begin{function}{\hook_provide_reversed:n}
+%   \begin{syntax}
+%     \cs{hook_provide_reversed:n} \Arg{hook}
+%   \end{syntax}
+%   Like \cs{hook_new_reversed:n} but does nothing if the hook was
+%    previously declared as a reversed hook.
+% \end{function}
+%
+% \begin{function}{\hook_provide_pair:nn}
+%   \begin{syntax}
+%     \cs{hook_provide_pair:nn} \Arg{hook-1} \Arg{hook-2}
+%   \end{syntax}
+%     A shorthand for
+%    \cs{hook_provide:n}\Arg{hook-1}\cs{hook_provide_reversed:n}\Arg{hook-2}.
+% \end{function}
+%
+%
+%
 % \begin{function}{\hook_use:n}
 %   \begin{syntax}
 %     \cs{hook_use:n} \Arg{hook}
@@ -968,29 +1064,7 @@
 %    A leading |.| is treated literally.
 % \end{function}
 %
-% \begin{function}[pTF]{\hook_if_exist:n}
-%   \begin{syntax}
-%     \cs{hook_if_exist:nTF} \Arg{hook} \Arg{true code} \Arg{false code}
-%   \end{syntax}
-%   Tests if the \meta{hook} exists (if it was created with either
-%   \cs{NewHook}, \cs{NewReversedHook}, or \cs{NewMirroredHookPair}), and
-%   branches to either \meta{true code} or \meta{false code} depending
-%   on the result.
 %
-%   The existence of a hook usually doesn't mean much from the viewpoint
-%   of code that tries to add/remove code from that hook, since package
-%   loading order may vary, thus the creation of hooks is asynchronous
-%   to adding and removing code from it, so this test should be used
-%   sparingly.
-%
-%   Generic hooks are declared at the time code is added to them, so the
-%   result of \cs{hook_if_exist:n} will change once code is added to
-%   said hook (unless the hook was previously declared).
-%
-%    The \meta{hook} \emph{cannot} be specified using the dot-syntax.
-%    A leading |.| is treated literally.
-% \end{function}
-%
 % \begin{function}{\hook_show:n,\hook_log:n}
 %   \begin{syntax}
 %     \cs{hook_show:n} \Arg{hook}
@@ -1259,8 +1333,8 @@
 %    For that reason such code is not using the hook management, but
 %    instead private kernel commands directly before or after a public
 %    hook with the following naming
-%    convention: \cs{@kernel at before@\meta{hookname}} or
-%    \cs{@kernel at after@\meta{hookname}}. For example, in
+%    convention: \cs{@kernel at before@\meta{hook}} or
+%    \cs{@kernel at after@\meta{hook}}. For example, in
 %    \cs{enddocument} you find
 %\begin{verbatim}
 %   \UseHook{enddocument}%
@@ -1336,20 +1410,14 @@
 %   Like \cs{AtBeginDocument} but for the \hook{enddocument} hook.
 % \end{function}
 %
+%    There is also \cs{AtBeginDvi}  which is discussed in conjunction
+%    with the shipout hooks.
 %
-%
-% \begin{function}{\AtBeginDvi}
-%   \begin{syntax}
-%     \cs{AtBeginDvi} \oarg{label} \Arg{code}
-%   \end{syntax}
-%   This hook is discussed in conjunction with the shipout hooks.
-% \end{function}
-%
 %    \bigskip
 %
 %    The few hooks that existed previously in \LaTeXe{} used internally
 %    commands such as \cs{@begindocumenthook} and packages sometimes
-%    augemented them directly rather than working through
+%    augmented them directly rather than working through
 %    \cs{AtBeginDocument}. For that reason there is currently support
 %    for this, that is, if the system detects that such an internal
 %    legacy hook command contains code it adds it to the new hook
@@ -1415,7 +1483,7 @@
 %
 %    The hooks are only executed if \cs{begin}\Arg{env} and
 %    \cs{end}\Arg{env} is used. If the environment code is executed
-%    via low-level calls to \cs{\meta{env}} and \cs{end\meta{env}}
+%    via low-level calls to \cs[no-index]{\meta{env}} and \cs[no-index]{end\meta{env}}
 %    (e.g., to avoid the environment grouping) they are not
 %    available. If you want them available in code using this method,
 %    you would need to add them yourself, i.e., write something like
@@ -1458,7 +1526,39 @@
 % \end{function}
 %
 %
+% \subsubsection{Generic hooks for commands}
 %
+%    Similar to environments there are now (at least in theory) two
+%    generic hooks available for any \LaTeX{} command. These are
+%    \begin{description}
+%    \item[\hook{cmd/\meta{name}/before}]
+%
+%       This hook is executed at the very start of the command
+%       execution.
+%
+%    \item[\hook{cmd/\meta{name}/after}]
+%       This hook is executed at the very end of the command body.  It is
+%       implemented as a reversed hook.
+%    \end{description}
+%    In practice there are restrictions and especially the
+%    \hook{after} hook works only with a subset of commands. Details
+%    about these restrictions are documented in
+%    \texttt{ltcmdhooks-doc.pdf} or with code in
+%    \texttt{ltcmdhooks-code.pdf}.
+%
+%
+%
+%
+% \subsubsection{Generic hooks provided by file loading operations}
+%
+%    There are several hooks added to \LaTeX{}'s process of loading
+%    file via its high-level interfaces such as \cs{input},
+%    \cs{include}, \cs{usepackage}, \cs{RequirePackage}, etc. These
+%    are documented in \texttt{ltfilehook-doc.pdf} or with code in
+%    \texttt{ltfilehook-code.pdf}.
+%
+%
+%
 % \subsubsection{Hooks provided by \cs{begin}\texttt{\{document\}}}
 % \label{sec:begindocument-hooks}
 %
@@ -1557,7 +1657,9 @@
 %      generates material for further pages. It is the right place to
 %      do some final housekeeping and possibly write out some
 %      information to the \texttt{.aux} file (which is still open at
-%      this point to receive data). It is also the correct place to
+%      this point to receive data, but since there will be no more pages you
+%      need to write to it using \cs{immediate}\cs{write}). It is also the
+%      correct place to
 %      set up any testing code to be run when the \texttt{.aux} file
 %      is re-read in the next step.
 %
@@ -1615,7 +1717,7 @@
 %
 %
 %    It is in also possible to use the generic \hook{env/document/end}
-%    hook which is execuded by \cs{end}, i.e., just in front of the
+%    hook which is executed by \cs{end}, i.e., just in front of the
 %    first hook above. Note however that the other generic \cs{end}
 %    environment hook, i.e., \hook{env/document/after} will never get
 %    executed, because by that time \LaTeX{} has finished the document
@@ -1624,7 +1726,7 @@
 %
 %
 %
-% \subsubsection{Hooks provided \cs{shipout} operations}
+% \subsubsection{Hooks provided by \cs{shipout} operations}
 % \label{sec:shipout}
 %
 %    There are several hooks and mechanisms added to \LaTeX{}'s
@@ -1633,15 +1735,7 @@
 %    \texttt{ltshipout-code.pdf}.
 %
 %
-% \subsubsection{Hooks provided by file loading operations}
 %
-%    There are several hooks added to \LaTeX{}'s
-%    process of loading file via its high-level interfaces such as
-%    \cs{input}, \cs{include}, \cs{usepackage}, etc. These are documented in
-%    \texttt{ltfilehook-doc.pdf} or with code in
-%    \texttt{ltfilehook-code.pdf}.
-%
-%
 % \subsubsection{Hooks provided in NFSS commands}
 %
 %    In languages that need to support for more than one script in
@@ -1709,27 +1803,20 @@
 % \section{The Implementation}
 %
 %
-% \subsection{Loading further extensions}
-%
 %    \begin{macrocode}
 %<@@=hook>
 %    \end{macrocode}
 %
+% \changes{v1.0i}{2021/03/18}{Use \cs{NewModuleRelease}.}
+% \changes{v1.0n}{2021/05/24}{Use \cs{msg_...} instead of \cs{__kernel_msg...}}
 %
-%    At the moment the whole module rolls back in one go, but if we
-%    make any modifications in later releases this will then need
-%    splitting.
 %    \begin{macrocode}
 %<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2020/10/01}%
-%<latexrelease>                 {\NewHook}{The hook management}%
-%    \end{macrocode}
-%    
-%    \begin{macrocode}
 \ExplSyntaxOn
+%<latexrelease>\NewModuleRelease{2020/10/01}{lthooks}
+%<latexrelease>                 {The~hook~management~system}
 %    \end{macrocode}
 %
-%
 %  \subsection{Debugging}
 %
 %  \begin{macro}{\g_@@_debug_bool}
@@ -1772,9 +1859,11 @@
 %
 % \begin{macro}[EXP]{\@@_str_compare:nn}
 %   Private copy of \cs{__str_if_eq:nn}
+% \InternalDetectionOff  
 %    \begin{macrocode}
 \cs_new_eq:NN \@@_str_compare:nn \__str_if_eq:nn
 %    \end{macrocode}
+% \InternalDetectionOn
 % \end{macro}
 %
 %  \subsection{Declarations}
@@ -1857,8 +1946,9 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\tl_gremove_once:Nx,\tl_show:x,\tl_log:x}
-%   Some variants of \pkg{expl3} functions. \fmi{should be moved to expl3}
+% \begin{macro}[int]{\tl_gremove_once:Nx,\tl_show:x,\tl_log:x}
+%   Some variants of \pkg{expl3} functions.
+%   \fmiinline{should probably be moved to expl3}
 %    \begin{macrocode}
 \cs_generate_variant:Nn \tl_gremove_once:Nn { Nx }
 \cs_generate_variant:Nn \tl_show:n { x }
@@ -1950,25 +2040,30 @@
 % \end{macro}
 %
 %
+%
 % \subsection{Providing new hooks}
 %
-% \begin{macro}{\g_@@_..._code_prop,\@@~...,\@@_next~...}
+% \subsubsection{The data structures of a hook}
 %
-%    Hooks have a \meta{name} and for each hook we have to provide a number of
-%    data structures. These are
+% \DescribeMacro{\g_@@_\meta{hook}_code_prop}
+% \DescribeMacro{\@@\textvisiblespace\meta{hook}}
+% \DescribeMacro{\@@_next\textvisiblespace\meta{hook}}
+%    Hooks have a name (called \meta{hook} in the description below)
+%    and for each hook we have to
+%    provide a number of data structures. These are
 %    \begin{description}
-%    \item[\cs{g_@@_\meta{name}_code_prop}] A property list holding the code
+%    \item[\cs{g_@@_\meta{hook}_code_prop}] A property list holding the code
 %    for the hook in separate chunks. The keys are by default the
 %    package names that add code to the hook, but it is possible
 %    for packages to define other keys. 
 %
-%    \item[{\cs[no-index]{g_@@_\meta{name}_rule_\meta{label1}\string|\meta{label2}_tl}}]
+%    \item[{\cs[no-index]{g_@@_\meta{hook}_rule_\meta{label1}\string|\meta{label2}_tl}}]
 %    A token list holding the relation between \meta{label1} and
-%    \meta{label2} in the \meta{name}.  The \meta{labels} are lexically
+%    \meta{label2} in the \meta{hook}.  The \meta{labels} are lexically
 %    (reverse) sorted to ensure that two labels always point to the same
-%    token list.  For global rules, the \meta{name} is |??|.
+%    token list.  For global rules, the \meta{hook} name is |??|.
 %
-%    \item[\cs{@@~\meta{name}}] The code that is actually executed
+%    \item[\cs{@@\textvisiblespace\meta{hook}}] The code that is actually executed
 %    when the hook is called in the document is stored in this token
 %    list. It is constructed from the code chunks applying the
 %    information.
@@ -1977,13 +2072,18 @@
 %    and to make it simpler to normalize hook names in
 %    \cs{@@_make_name:n}.
 %
-%    \item[\cs{g_@@_\meta{name}_reversed_tl}] Some hooks are
+%    \item[\cs{g_@@_\meta{hook}_reversed_tl}] Some hooks are
 %    \enquote{reversed}.  This token list stores a |-| for such hook
 %    so that it can be identified.  The |-| character is used because
 %    $\meta{reversed}1$ is $+1$ for normal hooks and $-1$ for reversed
 %    ones.
+
+%    \item[{\cs[no-index]{g_@@_\meta{hook}_declared_tl}}] This token
+%    list serves as marker for the hook being officially declared. Its
+%    existence is tested to raise an error in case another declaration
+%    is attempted.
 %
-%    \item[\cs{@@_toplevel~\meta{name}}] This token list stores the code
+%    \item[\cs{@@_toplevel\textvisiblespace\meta{hook}}] This token list stores the code
 %    inserted in the hook from the user's document, in the |top-level|
 %    label.  This label is special, and doesn't participate in sorting.
 %    Instead, all code is appended to it and executed after (or before,
@@ -1990,41 +2090,176 @@
 %    if the hook is reversed) the normal
 %    hook code, but before the |next| code chunk.
 %
-%    \item[\cs{@@_next~\meta{name}}] Finally there is extra code
-%    (normally empty) that is used on the next invocation of the hook
-%    (and then deleted). This can be used to define some special
-%    behavior for a single occasion from within the document.  This token
-%    list follows the same naming scheme than the main \cs{@@~\meta{name}}
-%    token list.  It is called \cs{@@_next~\meta{name}} rather than
-%    \cs{@@~next_\meta{name}} because otherwise a hook whose name is
-%    |next_|\meta{name} would clash with the next code-token list of the
-%    hook called \meta{name}.
+%    \item[\cs{@@_next\textvisiblespace\meta{hook}}] Finally there is
+%    extra code (normally empty) that is used on the next invocation
+%    of the hook (and then deleted). This can be used to define some
+%    special behavior for a single occasion from within the document.
+%    This token list follows the same naming scheme than the main
+%    \cs{@@\textvisiblespace\meta{hook}} token list.  It is called
+%    \cs{@@_next\textvisiblespace\meta{hook}} rather than
+%    \cs[no-index]{@@\textvisiblespace next_\meta{hook}} because
+%    otherwise a hook whose name is |next_|\meta{hook} would clash
+%    with the next code-token list of the hook called \meta{hook}.
 %
 %    \end{description}
-%  \end{macro}
 %
 %
+% \subsubsection{On the existence of hooks}
+% \label{sec:existence}
 %
+%    A hook may be in different states of existence. Here we give an
+%    overview of internal commands to set up hooks and explain how the
+%    different states are distinguished. The actual implementation
+%    then follows in the next sections.
 %
-%  \begin{macro}{\hook_new:n}
-%    The \cs{hook_new:n} declaration declare a new hook and expects
+%    One problem we have to solve is, that we need to be able to add
+%    code to hooks (e.g., with \cs{AddToHook}) even if that code has
+%    not been declared yet. For example, one package needs to write
+%    into a hook of another package, but that package ay not get
+%    loaded or only loaded later. Another problem most hooks require
+%    declaration but this is not the case for the generic hooks.
+%
+%    We therefore distinguish the following states for a hook and they
+%    are managed with four different tests: structure existence
+%    (\cs{@@_if_structure_exist:nTF}), creation
+%    (\cs{@@_if_usable:nTF}), declaration (\cs{@@_if_declared:nTF})
+%    and disabled or not (\cs{@@_if_disabled:nTF})
+%    \begin{description}
+%    \setlist[itemize]{leftmargin=5cm,format=\cs}
+%    \item[not existing]
+%
+%       Nothing is known about the hook so far. This state can be
+%       detected with \cs{@@_if_structure_exist:nTF}
+%       (which uses the  false branch).
+%
+%       In this state the hook can be declared, disabled, rules can be
+%       defined or code could be added to it, but it is not possible
+%       to use the hook (with \cs{UseHook}).
+
+%    \item[basic data structure set up]
+%
+%       A hook is this state when its basic data structure has been
+%       set up (using \cs{@@_init_structure:n}). The data structure setup happens
+%       automatically when commands such as \cs{AddToHook}  are used
+%       and the hook is at that point in state \enquote{not existing}.
+%
+%       In this state the four tests give the following results:
+%     \begin{itemize}
+%       \item [@@_if_structure_exist:nTF]      returns |true|.
+%       \item [@@_if_usable:nTF]   returns |false|.
+%       \item [@@_if_declared:nTF]  returns |false|.
+%       \item [@@_if_disabled:nTF]  returns |false|.
+%     \end{itemize}
+%
+%       The allowed acctions are the same as in the \enquote{not
+%       existing} state.
+%
+%    \item[declared]
+%
+%       A hook is in this state it is not disabled and was explicity declared (e.g.,
+%       with \cs{NewHook}). In this case the four tests give the
+%       following results:
+%     \begin{itemize}
+%       \item [@@_if_structure_exist:nTF]      returns |true|.
+%       \item [@@_if_usable:nTF]   returns |true|.
+%       \item [@@_if_declared:nTF]  returns |true|.
+%       \item [@@_if_disabled:nTF]  returns |false|.
+%     \end{itemize}
+%
+%    \item[usable]
+%
+%       A hook is in this state if it is not disabled, was not
+%       explicitly declared but nevertheless is allowed to be used
+%       (with \cs{UseHook} or \cs{hook_use:n}). This state is only
+%       possible for generic hooks as they do not need to be
+%       declared. Therefore such hooks move directly from state
+%       \enquote{not existing} to \enquote{usable} the moment a
+%       declaration such as \cs{AddToHook} wants to add to the hook
+%       data structure.  In this state the tests give the following
+%       results:
+%     \begin{itemize}
+%       \item [@@_if_structure_exist:nTF]      returns |true|.
+%       \item [@@_if_usable:nTF]   returns |true|.
+%       \item [@@_if_declared:nTF]  returns |false|.
+%       \item [@@_if_disabled:nTF]  returns |false|.
+%     \end{itemize}
+%
+%
+%    \item[disabled]
+%
+%       A hook in any state is moved to this state when
+%       \cs{DisableHook} is used. This changes the tests to give the
+%       following results:
+%     \begin{itemize}
+%       \item [@@_if_structure_exist:nTF]      \emph{unchanged}.
+%       \item [@@_if_usable:nTF]   returns |false|.
+%       \item [@@_if_declared:nTF]  returns |true|.
+%       \item [@@_if_disabled:nTF]  returns |true|.
+%     \end{itemize}
+%       The  structure test is unchanged (if the hook was unknown before it is
+%       false, otherwise true). The usable test returns false so that
+%       any \cs{UseHook} will bypass the hook from now on. The
+%       declared test returns true so that any further \cs{NewHook}
+%       generates an error and the disabled test returns true so that
+%       \cs{AddToHook} can return an error.
+% \fmiinline{maybe it should do this only after begin document?}
+%
+%    \end{description}
+%
+%
+%
+%
+% \subsubsection{Setting hooks up}
+%
+%
+%  \begin{macro}{\hook_new:n,\@@_new:n}
+%    The \cs{hook_new:n} declaration declares a new hook and expects
 %    the hook \meta{name} as its argument, e.g.,
 %    \hook{begindocument}.
 %    \begin{macrocode}
 \cs_new_protected:Npn \hook_new:n #1
   { \@@_normalize_hook_args:Nn \@@_new:n {#1} }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \cs_new_protected:Npn \@@_new:n #1
   {
 %    \end{macrocode}
-%    We check for one of the internal data structures and if it
-%    already exists we complain.
+%   We check if the hook was already \emph{explicitly} declared with
+%   \cs{hook_new:n}, and if it already exists we complain, otherwise set
+%   the \enquote{created} flag for the hook so that it errors next time
+%   \cs{hook_new:n} is used.
 %    \begin{macrocode}
-    \hook_if_exist:nTF {#1}
+    \@@_if_declared:nTF {#1}
       { \msg_error:nnn { hooks } { exists } {#1} }
+      {
+        \tl_new:c { g_@@_#1_declared_tl }
+        \@@_make_usable:n {#1}
+      }
+  }
 %    \end{macrocode}
-%    Otherwise we add the hook name to the list of all hooks and
-%    allocate the necessary data structures for the new hook.
+% \end{macro}
+%
+%  
+%  
+%  \begin{macro}{\@@_make_usable:n}
+%
+%    This initializes all hook data structures for the hook but if
+%    used on its own doesn't mark the hook as declared (as
+%    \cs{hook_new:n} does, so a later \cs{hook_new:n} on that hook will
+%    not result in an error.  This command is internally used by
+%    \cs{hook_gput_code:n} when adding code to a generic hook.
 %    \begin{macrocode}
+\cs_new_protected:Npn \@@_make_usable:n #1
+  {
+%    \end{macrocode}
+%   Now we check if the hook's data structure can be safely created
+%   without \pkg{expl3} raising errors, then
+%   we add the hook name to the list of all hooks and
+%   allocate the necessary data structures for the new hook,
+%   otherwise just do nothing.
+%    \begin{macrocode}
+    \tl_if_exist:cF { @@~#1 }
       {
         \seq_gput_right:Nn \g_@@_all_seq {#1}
 %    \end{macrocode}
@@ -2035,12 +2270,12 @@
 %    \end{macrocode}
 %    Now ensure that the base data structure for the hook exists:
 %    \begin{macrocode}
-        \@@_declare:n {#1}
+        \@@_init_structure:n {#1}
 %    \end{macrocode}
 %    The \cs{g_@@_\meta{hook}_labels_clist} holds the sorted list of
 %    labels (once it got sorted). This is used only for debugging.
 %    \begin{macrocode}
-        \clist_new:c {g_@@_#1_labels_clist}
+        \clist_new:c { g_@@_#1_labels_clist }
 %    \end{macrocode}
 %    Some hooks should reverse the default order of code chunks. To
 %    signal this we have a token list which is empty for normal hooks
@@ -2062,7 +2297,7 @@
 %
 %    \begin{macrocode}
         \@@_include_legacy_code_chunk:n {#1}
-     }
+      }
   }
 %    \end{macrocode}
 %  \end{macro}
@@ -2069,16 +2304,23 @@
 %
 %
 %
-% \begin{macro}{\@@_declare:n}
-%   This function declares the basic data structures for a hook without
-%   actually declaring the hook itself.  This is needed to allow adding
-%   to undeclared hooks.  Here it is unnecessary to check whether all
-%   variables exist, since all three are declared at the same time
-%   (either all of them exist, or none).
+% \begin{macro}{\@@_init_structure:n}
+%    This function declares the basic data structures for a hook
+%    without explicit declaring the hook itself.  This is needed to
+%    allow adding to undeclared hooks.  Here it is unnecessary to
+%    check whether all variables exist, since all three are declared
+%    at the same time (either all of them exist, or none).
+%
+%    It creates the hook code pool
+%    (\cs[no-index]{g_@@_\meta{hook}_code_prop}) and the |top-level|
+%    and |next| token lists.  A hook is initialized with
+%    \cs{@@_init_structure:n} the first time anything is added to it.
+%    Inizializing a hook just with \cs{@@_init_structure:n} will not
+%    make it usable with \cs{hook_use:n}.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_declare:n #1
+\cs_new_protected:Npn \@@_init_structure:n #1
   {
-    \@@_if_exist:nF {#1}
+    \@@_if_structure_exist:nF {#1}
       {
         \prop_new:c { g_@@_#1_code_prop }
         \tl_new:c { @@_toplevel~#1 }
@@ -2110,6 +2352,9 @@
 %    \end{macrocode}
 %  \end{macro}
 %
+%
+%
+%
 %  \begin{macro}{\hook_new_pair:nn}
 %    A shorthand for declaring a normal and a (matching) reversed hook in one go.
 %    \begin{macrocode}
@@ -2160,6 +2405,140 @@
 %
 %
 %
+% \subsubsection{Disabling and providing hooks}
+%
+% \begin{macro}{\hook_disable:n}
+% \begin{macro}{\@@_disable:n}
+% \begin{macro}[pTF]{\@@_if_disabled:n}
+%
+%    Disables a hook by creating its
+%    \cs[no-index]{g_@@_\meta{hook}_declared_tl} so that the hook
+%    errors when used with \cs{hook_new:n}, then it undefines
+%    \cs{@@\textvisiblespace\meta{hook}} so that it may not be executed.
+%
+%    This does not clear any code that may be already stored in the
+%    hook's structure, but doesn't allow adding more code.
+%    \cs{@@_if_disabled:nTF} uses that specific combination to check
+%    if the hook is disabled.
+%
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>         {\hook_disable:n}{Disable~hooks}
+%    \end{macrocode}
+%    
+%    \begin{macrocode}
+\cs_new_protected:Npn \hook_disable:n #1
+  { \@@_normalize_hook_args:Nn \@@_disable:n {#1} }
+\cs_new_protected:Npn \@@_disable:n #1
+  {
+    \tl_gclear_new:c { g_@@_#1_declared_tl }
+    \cs_undefine:c { @@~#1 }
+  }
+\prg_new_conditional:Npnn \@@_if_disabled:n #1 { p, T, F, TF }
+  {
+    \bool_lazy_and:nnTF
+        { \tl_if_exist_p:c { g_@@_#1_declared_tl } }
+        { ! \tl_if_exist_p:c { @@~#1 } }
+      { \prg_return_true: }
+      { \prg_return_false: }
+  }
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{2020/10/01}
+%<latexrelease>                 {\hook_disable:n}{Disable~hooks}
+%<latexrelease>
+%<latexrelease>\cs_new_protected:Npn \hook_disable:n #1 {}
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hook_provide:n}
+% \begin{macro}{\hook_provide_reversed:n}
+% \begin{macro}{\@@_provide:n}
+%    The \cs{hook_provide:n} declaration declares a new hook if it
+%    wasn't declared already, in which case it only checks that the
+%    already existing hook is not a reversed hook.
+%    The \cs{hook_provide_reversed:n} does the same for reversed hooks.
+%    \hook{begindocument}.
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>         {\hook_provide:n}{Providing~hooks}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\cs_new_protected:Npn \hook_provide:n #1
+  { \@@_normalize_hook_args:Nn \@@_provide:nn {#1} {   } }
+\cs_new_protected:Npn \hook_provide_reversed:n #1
+  { \@@_normalize_hook_args:Nn \@@_provide:nn {#1} { - } }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_provide:nn #1 #2
+  {
+%    \end{macrocode}
+%    If the hook to be provided was disabled we warn (for now --- this
+%    may change).
+%    \begin{macrocode}
+    \@@_if_disabled:nTF {#1}
+      { \msg_warning:nnn { hooks } { provide-disabled } {#1} }
+%    \end{macrocode}
+%    Otherwise we check if it was already declared.
+%    \begin{macrocode}
+      {
+        \@@_if_declared:nTF {#1}
+          {
+%    \end{macrocode}
+%    Issue an error if we try to provide a a hook that is reversed and
+%    the already existing one is not (or vice versa).
+%    \begin{macrocode}
+            \str_if_eq:eeF { \tl_use:c { g_@@_#1_reversed_tl } } {#2}
+              { \msg_error:nnn { hooks } { provide-error } {#1} }
+          }
+%    \end{macrocode}
+%    If it wasn't declared, we declared as a normal or reversed hook
+%    as appropriate.
+%    \begin{macrocode}
+          {
+            \tl_new:c { g_@@_#1_declared_tl }
+            \@@_make_usable:n {#1}
+            \tl_gset:cn { g_@@_#1_reversed_tl } {#2}
+          }
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hook_provide_pair:nn}
+%    A shorthand for providing a normal and a (matching) reversed hook in one go.
+%    \begin{macrocode}
+\cs_new_protected:Npn \hook_provide_pair:nn #1#2
+  { \hook_provide:n {#1} \hook_provide_reversed:n {#2} }
+%    \end{macrocode}
+% \end{macro}
+%
+%    \begin{macrocode}
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{2020/10/01}
+%<latexrelease>                 {\hook_provide:n}{Providing~hooks}
+%<latexrelease>
+%<latexrelease>\cs_new_protected:Npn \hook_provide_reversed:n #1 {}
+%<latexrelease>\cs_new_protected:Npn \hook_provide:n #1 {}
+%<latexrelease>\cs_new_protected:Npn \hook_provide_pair:nn #1#2 {}
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
+%
+%
 % \subsection{Parsing a label}
 %
 % \begin{macro}[EXP]{\@@_parse_label_default:n}
@@ -2231,7 +2610,7 @@
       {
         \tl_if_empty:NTF \@currname
           {
-            \msg_expandable_error:nnn { hooks } { should-not-happen }
+            \msg_expandable_error:nnn { kernel } { should-not-happen }
               { Empty~default~label. }
             \@@_make_name:n { label-missing }
           }
@@ -2243,15 +2622,15 @@
 % \end{macro}
 %
 % \begin{macro}[EXP]{\@@_make_name:n,\@@_make_name:w}
-%   Provides a standard sanitisation of a hook's name.
+%   Provides a standard sanitization of a hook's name.
 %   It uses \cs{cs:w} to build a control sequence out of the hook name,
 %   then uses \cs{cs_to_str:N} to get the string representation of that,
 %   without the escape character.  \cs{cs:w}-based expansion is used
 %   instead of |e|-based because Unicode characters don't behave well
-%   inside \cs{expanded}.  The macro adds the \cs{@@~} prefix to the
+%   inside \cs{expanded}.  The macro adds the \cs[no-index]{@@\textvisiblespace} prefix to the
 %   hook name to reuse the hook's code token list to build the csname
 %   and avoid leaving \enquote{public} control sequences defined
-%   (as~\cs{relax}) in TeX's memory.
+%   (as~\cs[no-index]{relax}) in TeX's memory.
 %    \begin{macrocode}
 \cs_new:Npn \@@_make_name:n #1
   {
@@ -2311,6 +2690,9 @@
 % \end{macro}
 %
 %
+%
+% \subsection{Adding or removing hook code}
+%
 % \begin{macro}{\hook_gput_code:nnn}
 % \begin{macro}{\@@_gput_code:nnn,\@@_gput_code:nxv,\@@_hook_gput_code_do:nnn}
 %
@@ -2320,6 +2702,9 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \hook_gput_code:nnn #1 #2
   { \@@_normalize_hook_args:Nnn \@@_gput_code:nnn {#1} {#2} }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \cs_new_protected:Npn \@@_gput_code:nnn #1 #2 #3
   {
 %    \end{macrocode}
@@ -2343,7 +2728,7 @@
 %    If no removal is queued, we are free to add.  Start by checking if
 %    the hook exists.
 %    \begin{macrocode}
-            \hook_if_exist:nTF {#1}
+            \@@_if_usable:nTF {#1}
 %    \end{macrocode}
 %    If so we simply add (or append) the new code to the property list
 %    holding different chunks for the hook. At \verb=\begin{document}=
@@ -2364,10 +2749,17 @@
 %    declare it as a generic hook, if its name matches one of the valid
 %    patterns.
 %    \begin{macrocode}
-              { \@@_try_declaring_generic_hook:nnn {#1} {#2} {#3} }
+              {
+                \@@_if_disabled:nTF {#1}
+                  { \msg_error:nnn { hooks } { hook-disabled } {#1} }
+                  { \@@_try_declaring_generic_hook:nnn {#1} {#2} {#3} }
+              }
           }
       }
   }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \cs_generate_variant:Nn \@@_gput_code:nnn { nxv }
 %    \end{macrocode}
 %
@@ -2379,7 +2771,7 @@
 %    However, first some debugging info if debugging is enabled:
 %    \begin{macrocode}
     \@@_debug:n{\iow_term:x{****~ Add~ to~
-                      \hook_if_exist:nF {#1} { undeclared~ }
+                      \@@_if_usable:nF {#1} { undeclared~ }
                       hook~ #1~ (#2)
                       \on at line\space <-~ \tl_to_str:n{#3}} }
 %    \end{macrocode}
@@ -2387,9 +2779,9 @@
 %    If there's code already there, then append \verb=#3= to that,
 %    otherwise just put \verb=#3=.  If the current label is |top-level|,
 %    the code is added to a dedicated token list
-%    \cs[no-index]{@@_toplevel~\meta{hook}} that goes at the end of the
+%    \cs{@@_toplevel\textvisiblespace\meta{hook}} that goes at the end of the
 %    hook (or at the beginning, for a reversed hook), just before
-%   \cs[no-index]{@@_next~\meta{hook}}.
+%   \cs[no-index]{@@_next\textvisiblespace\meta{hook}}.
 %    \begin{macrocode}
     \str_if_eq:nnTF {#2} { top-level }
       {
@@ -2397,9 +2789,9 @@
           {
 %    \end{macrocode}
 %    If the hook's basic structure does not exist, we need to declare it
-%    with \cs{@@_declare:n}.
+%    with \cs{@@_init_structure:n}.
 %    \begin{macrocode}
-            \@@_declare:n {#1}
+            \@@_init_structure:n {#1}
             \@@_tl_gput_right:cn { @@_toplevel~#1 } {#3}
           }
           { \msg_error:nnn { hooks } { misused-top-level } {#1} }
@@ -2424,14 +2816,15 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_gput_undeclared_hook:nnn #1 #2 #3
   {
-    \@@_declare:n {#1}
+    \@@_init_structure:n {#1}
     \@@_hook_gput_code_do:nnn {#1} {#2} {#3}
   }
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\@@_try_declaring_generic_hook:nnn}
-% \begin{macro}{\@@_try_declaring_generic_next_hook:nn}
+% \begin{macro}{\@@_try_declaring_generic_hook:nnn,
+%               \@@_try_declaring_generic_next_hook:nn}
+%
 %   These entry-level macros just pass the arguments along to the
 %   common \cs{@@_try_declaring_generic_hook:nNNnn} with the right
 %   functions to execute when some action is to be taken.
@@ -2458,13 +2851,14 @@
       \hook_gput_next_code:nn \@@_gput_next_do:nn
   }
 %    \end{macrocode}
+% \end{macro}
 %
-% \begin{macro}{
-%     \@@_try_declaring_generic_hook:nNNnn,
-%     \@@_try_declaring_generic_hook_split:nNNnn
-%   }
-% \begin{macro}[TF]{\@@_try_declaring_generic_hook:wn}
-%   \cs{@@_try_declaring_generic_hook:nNNnn} now splits the hook name
+%
+% \begin{macro}{\@@_try_declaring_generic_hook:nNNnn,
+%               \@@_try_declaring_generic_hook_split:nNNnn}
+%
+%   \cs{@@_try_declaring_generic_hook:nNNnn}
+%   now splits the hook name
 %   at the first \texttt{/} (if any) and first checks if it is a
 %   file-specific hook (they require some normalization) using
 %   \cs{@@_if_file_hook:wTF}. If not then check it is one of a
@@ -2482,6 +2876,9 @@
       }
       { \@@_try_declaring_generic_hook_split:nNNnn {#1} }
   }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \cs_new_protected:Npn \@@_try_declaring_generic_hook_split:nNNnn #1 #2 #3
   {
     \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1}
@@ -2488,6 +2885,15 @@
       { #2 }
       { #3 } {#1}
   }
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}[TF]{\@@_try_declaring_generic_hook:wn}
+%
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>         {\@@_try_declaring_generic_hook:wn}{Support~cmd~hooks}
 \prg_new_protected_conditional:Npnn \@@_try_declaring_generic_hook:wn
     #1 / #2 / #3 / #4 \scan_stop: #5 { TF }
   {
@@ -2496,13 +2902,29 @@
       {
         \prop_if_in:NnTF \c_@@_generics_prop {#1}
           {
-            \hook_if_exist:nF {#5} { \hook_new:n {#5} }
+            \@@_if_usable:nF {#5}
+              {
 %    \end{macrocode}
-%    After having declared the hook we check the second component (for
-%    file hooks) or the third component for environment hooks) and
-%    if it is on the list of components for which we should have declared
-%    a reversed hook we alter the hook data structure accordingly.
+%    If the hook doesn't exist yet we check if it is a \texttt{cmd}
+%    hook and if so we attempt patching the command in addition to
+%    declaring the hook.
+%
+%    For some commands this will not be possible, in which case
+%    \cs{@@_patch_cmd_or_delay:Nnn} (defined in \texttt{ltcmdhooks})
+%    will generate an appropriate error message.
 %    \begin{macrocode}
+                \str_if_eq:nnT {#1} { cmd }
+                  { \@@_try_put_cmd_hook:n {#5} }
+%    \end{macrocode}
+%
+%    Declare the hook always even if it can't really be used (error
+%    message generated elsewhere).
+%
+%    Here we use \cs{@@_make_usable:n}, so that a \cs{hook_new:n} is still
+%    possible later.
+%    \begin{macrocode}
+                \@@_make_usable:n {#5}
+              }
             \prop_if_in:NnTF \c_@@_generics_reversed_ii_prop {#2}
               { \tl_gset:cn { g_@@_#5_reversed_tl } { - } }
               {
@@ -2509,19 +2931,42 @@
                 \prop_if_in:NnT \c_@@_generics_reversed_iii_prop {#3}
                   { \tl_gset:cn { g_@@_#5_reversed_tl } { - } }
               }
-%    \end{macrocode}
-%    Now that we know that the hook is declared we can add the code to it.
-%    \begin{macrocode}
             \prg_return_true:
           }
           { \prg_return_false: }
       }
   }
+%<latexrelease>\EndIncludeInRelease
 %    \end{macrocode}
+%
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{2020/10/01}%
+%<latexrelease>         {\@@_try_declaring_generic_hook:wn}{Support~cmd~hooks}
+%<latexrelease>
+%<latexrelease>\prg_new_protected_conditional:Npnn \@@_try_declaring_generic_hook:wn
+%<latexrelease>    #1 / #2 / #3 / #4 \scan_stop: #5 { TF }
+%<latexrelease>  {
+%<latexrelease>    \tl_if_empty:nTF {#2}
+%<latexrelease>      { \prg_return_false: }
+%<latexrelease>      {
+%<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>              { \tl_gset:cn { g_@@_#5_reversed_tl } { - } }
+%<latexrelease>              {
+%<latexrelease>                \prop_if_in:NnT \c_@@_generics_reversed_iii_prop {#3}
+%<latexrelease>                  { \tl_gset:cn { g_@@_#5_reversed_tl } { - } }
+%<latexrelease>              }
+%<latexrelease>            \prg_return_true:
+%<latexrelease>          }
+%<latexrelease>          { \prg_return_false: }
+%<latexrelease>      }
+%<latexrelease>  }
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
 % \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
 %
 % \begin{macro}[pTF]{\@@_if_file_hook:w}
 %   \cs{@@_if_file_hook:wTF} checks if the argument is a valid
@@ -2529,7 +2974,7 @@
 %   |file/before/foo.tex|).  If it is a file-specific hook, then it
 %   executes the \meta{true} branch, otherwise \meta{false}.
 %
-%   A file-specific hook is \texttt{file/\meta{position}/\meta{name}}.
+%   A file-specific hook is \hook{file/\meta{position}/\meta{name}}.
 %   If any of these parts don't exist, it is a general file hook or not
 %   a file hook at all, so the conditional evaluates to \meta{false}.
 %   Otherwise, it checks that the first part is |file| and that the
@@ -2595,14 +3040,16 @@
 %    Property list holding the generic names. We don't provide any user
 %    interface to this as this is meant to be static.
 %    \begin{description}
+%    \item[\texttt{cmd}]
+%      The generic hooks used for commands.
 %    \item[\texttt{env}]
 %      The generic hooks used in \cs{begin} and \cs{end}.
-%    \item[\texttt{file}]
+%    \item[\texttt{file}, \texttt{package}, \texttt{class}, \texttt{include}]
 %      The generic hooks used when loading a file
 %    \end{description}
 %    \begin{macrocode}
 \prop_const_from_keyval:Nn \c_@@_generics_prop
-  {env=,file=,package=,class=,include=}
+     {cmd=,env=,file=,package=,class=,include=}
 %    \end{macrocode}
 %  \end{macro}
 %
@@ -2629,11 +3076,11 @@
 \cs_new_protected:Npn \@@_gremove_code:nn #1 #2
   {
 %    \end{macrocode}
-%    First check that the hook code pool exists.  \cs{hook_if_exist:nTF}
+%    First check that the hook code pool exists.  \cs{@@_if_usable:nTF}
 %    isn't used here because it should be possible to remove code from a
 %    hook before its defined (see section~\ref{sec:querying}).
 %    \begin{macrocode}
-    \@@_if_exist:nTF {#1}
+    \@@_if_structure_exist:nTF {#1}
       {
 %    \end{macrocode}
 %    Then remove the chunk and run \cs{@@_update_hook_code:n} so
@@ -2641,9 +3088,9 @@
 %    \verb=\begin{document}=.
 %
 %    If all code is to be removed, clear the code pool
-%    \cs[no-index]{g_@@_\meta{hook}_code_prop}, the top-level code
-%    \cs[no-index]{@@_toplevel~\meta{hook}}, and the next-execution code
-%    \cs[no-index]{@@_next~\meta{hook}}.
+%    \cs{g_@@_\meta{hook}_code_prop}, the top-level code
+%    \cs{@@_toplevel\textvisiblespace\meta{hook}}, and the next-execution code
+%    \cs{@@_next\textvisiblespace\meta{hook}}.
 %    \begin{macrocode}
         \str_if_eq:nnTF {#2} {*}
           {
@@ -2656,7 +3103,7 @@
 %    If the label is |top-level| then clear the token list, as all code
 %    there is under the same label.  Marked removal is not implemented
 %    for |top-level| because it is hard to reliably know that no code
-%    was added to \cs[no-index]{@@_toplevel~\meta{hook}} (granted that
+%    was added to \cs{@@_toplevel\textvisiblespace\meta{hook}} (granted that
 %    an empty code could be interpreted as that, but then it differs in
 %    behaviour from other labels, in which an empty chunk is still valid
 %    for removal).  Besides, it doesn't make much (if any) sense for
@@ -2680,7 +3127,7 @@
 %    \end{macrocode}
 %    Finally update the code, if the hook exists.
 %    \begin{macrocode}
-        \hook_if_exist:nT {#1}
+        \@@_if_usable:nT {#1}
           { \@@_update_hook_code:n {#1} }
       }
 %    \end{macrocode}
@@ -2775,10 +3222,10 @@
 %    disadvantage of that being not really distinguishable from a real
 %    hook name. I now have settled for \texttt{??} which needs some
 %    gymnastics to get it into the csname, but since this is used a
-%    lot things should be fast, so this is not done with \texttt{c}
+%    lot, the code should be fast, so this is not done with \texttt{c}
 %    expansion in the code later on.
 %
-%    \cs{@@~??} isn't used, but it has to be defined to trick
+%    \cs{@@\textvisiblespace??} isn't used, but it has to be defined to trick
 %    the code into thinking that \verb=??= is actually a hook.
 %    \begin{macrocode}
 \prop_new:c {g_@@_??_code_prop}
@@ -2799,14 +3246,12 @@
 %
 %  \begin{macro}{\hook_gset_rule:nnnn}
 %  \begin{macro}{\@@_gset_rule:nnnn}
-%
-%    \fmi{needs docu correction given new implementation}
-%
 %    With
 %    \cs{hook_gset_rule:nnnn}\Arg{hook}\Arg{label1}\Arg{relation}\Arg{label2}
 %    a relation is defined between the two code labels for the given
 %    \meta{hook}.  The special hook \texttt{??} stands for \emph{any}
-%    hook describing a default rule.
+%    hook, which sets a default rule (to be used if no other relation
+%    between the two hooks exist).
 %    \begin{macrocode}
 \cs_new_protected:Npn \hook_gset_rule:nnnn #1#2#3#4
   {
@@ -2814,7 +3259,7 @@
       {#1} {#2} {#3} {#4}
   }
 %    \end{macrocode}
-%    
+%
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_gset_rule:nnnn #1#2#3#4
   {
@@ -2821,7 +3266,7 @@
 %    \end{macrocode}
 %    First we ensure the basic data structure of the hook exists:
 %    \begin{macrocode}
-    \@@_declare:n {#1}
+    \@@_init_structure:n {#1}
 %    \end{macrocode}
 %    Then we clear any previous relationship between both labels.
 %    \begin{macrocode}
@@ -2898,9 +3343,11 @@
 %   together in hook |#1|.
 %    \begin{macrocode}
 \cs_new_protected:cpn { @@_rule_incompatible-error_gset:nnn } #1#2#3
-  { \@@_tl_gset:cn { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { xE } }
+  { \@@_tl_gset:cn { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl }
+                   { xE } }
 \cs_new_protected:cpn { @@_rule_incompatible-warning_gset:nnn } #1#2#3
-  { \@@_tl_gset:cn { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl } { xW } }
+  { \@@_tl_gset:cn { g_@@_#1_rule_ \@@_label_pair:nn {#2} {#3} _tl }
+                   { xW } }
 %    \end{macrocode}
 %  \end{macro}
 %
@@ -2937,7 +3384,7 @@
   {
     \if_int_compare:w \@@_str_compare:nn {#1} {#2} > 0 \exp_stop_f:
       \prg_return_true:
-    \else
+    \else:
       \prg_return_false:
     \fi:
   }
@@ -3037,13 +3484,13 @@
 %    If there aren't any code
 %    chunks for the current hook, there is no point in even starting
 %    the sorting routine so we make a quick test for that and in that
-%    case just update \cs{@@~\meta{hook}} to hold the |top-level| and
+%    case just update \cs{@@\textvisiblespace\meta{hook}} to hold the |top-level| and
 %    |next| code chunks. If there are code chunks we call
 %    \cs{@@_initialize_single:NNn} and pass to it ready made csnames
 %    as they are needed several times inside. This way we save a bit
 %    on processing time if we do that up front.
 %    \begin{macrocode}
-    \hook_if_exist:nT {#1}
+    \@@_if_usable:nT {#1}
       {
         \prop_if_empty:cTF {g_@@_#1_code_prop}
           {
@@ -3096,7 +3543,7 @@
 % \begin{macro}[EXP]{\@@_tl_csname:n,\@@_seq_csname:n}
 %   It is faster to pass a single token and expand it when necessary
 %   than to pass a bunch of character tokens around.
-%   \fmi{note to myself: verify}
+%   \fmiinline{note to myself: verify}
 %    \begin{macrocode}
 \cs_new:Npn \@@_tl_csname:n #1 { l_@@_label_#1_tl }
 \cs_new:Npn \@@_seq_csname:n #1 { l_@@_label_#1_seq }
@@ -3160,7 +3607,7 @@
 %    a way that one can omit a lot of tests and I have mimicked that as
 %    far as possible. The result is a restriction I do not test for at
 %    the moment: a label can't be equal to the number 0!  \fmi{Needs
-%    checking for, just in case}
+%    checking for, just in case ... maybe}
 %
 %    ^^A #1 <- \@@~#1
 %    ^^A #2 <- \g_@@_#1_labels_clist
@@ -3301,7 +3748,7 @@
 %    \end{macrocode}
 %
 %    This is not really the information one needs in the error case
-%    but will do for now \ldots \fmi{fix}
+%    but will do for now \ldots \fmi{improve output on a rainy day}
 %    \begin{macrocode}
         \@@_debug_label_data:N \l_@@_work_prop
         \iow_term:x{====================}
@@ -3572,15 +4019,20 @@
   { \@@_log_cmd:x { >~#1 } }
 \cs_new_protected:Npn \@@_log_line_indent:x #1
   { \@@_log_cmd:x { >~\@spaces #1 } }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \cs_new_protected:Npn \@@_log:nN #1 #2
   {
     \@@_preamble_hook:n {#1}
     \@@_log_cmd:x { ^^J ->~The~hook~'#1': }
 %    \end{macrocode}
-%    
+%
 %    \begin{macrocode}
-    \hook_if_exist:nF {#1}
-      { \@@_log_line:x { is~not~declared! } }
+    \@@_if_usable:nF {#1}
+      { \@@_log_line:x { The~hook~is~not~declared. } }
+    \@@_if_disabled:nT {#1}
+      { \@@_log_line:x { The~hook~is~disabled. } }
     \hook_if_empty:nTF {#1}
       { #2 { The~hook~is~empty } }
       {
@@ -3598,7 +4050,7 @@
         \@@_log_line:x
           {
             Document-level~(top-level)~code
-            \hook_if_exist:nT {#1}
+            \@@_if_usable:nT {#1}
               { ~(executed~\@@_if_reversed:nTF {#1} {first} {last} ) } :
           }
         \@@_log_line_indent:x
@@ -3649,7 +4101,7 @@
 %   to that hook) and not empty
 %    \begin{macrocode}
         \bool_lazy_and:nnTF
-            { \hook_if_exist_p:n {#1} }
+            { \@@_if_usable_p:n {#1} }
             { ! \hook_if_empty_p:n {#1} }
           {
             \@@_log_line:x
@@ -3671,10 +4123,12 @@
               }
           }
           {
+            \@@_log_line:x { Execution~order: }
             #2
               {
-                Hook~ \hook_if_exist:nTF {#1}
-                  {code~pool~empty} {not~declared}
+                \@spaces Not~set~because~the~hook~ \@@_if_usable:nTF {#1}
+                  { code~pool~is~empty }
+                  { is~\@@_if_disabled:nTF {#1} {disabled} {undeclared} }
               }
           }
       }
@@ -3766,25 +4220,37 @@
 %    \end{macrocode}
 % \end{macro}
 %
+%
+%
+%
 %  \subsection{Specifying code for next invocation}
 %
 % \begin{macro}{\hook_gput_next_code:nn}
-% \begin{macro}{%
-%     \@@_gput_next_code:nn,
-%     \@@_gput_next_do:nn,
-%     \@@_gput_next_do:Nnn,
-%     \@@_clear_next:n
-%   }
 %    \begin{macrocode}
 \cs_new_protected:Npn \hook_gput_next_code:nn #1
   { \@@_normalize_hook_args:Nn \@@_gput_next_code:nn {#1} }
+%    \end{macrocode}
+%  \end{macro}
+%
+% \begin{macro}{\@@_gput_next_code:nn,
+%               \@@_gput_next_do:nn,
+%               \@@_gput_next_do:Nnn,
+%               \@@_clear_next:n}
+%    \begin{macrocode}
 \cs_new_protected:Npn \@@_gput_next_code:nn #1 #2
   {
-    \@@_declare:n {#1}
-    \hook_if_exist:nTF {#1}
-      { \@@_gput_next_do:nn {#1} {#2} }
-      { \@@_try_declaring_generic_next_hook:nn {#1} {#2} }
+    \@@_if_disabled:nTF {#1}
+      { \msg_error:nnn { hooks } { hook-disabled } {#1} }
+      {
+        \@@_init_structure:n {#1}
+        \@@_if_usable:nTF {#1}
+          { \@@_gput_next_do:nn {#1} {#2} }
+          { \@@_try_declaring_generic_next_hook:nn {#1} {#2} }
+      }
   }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \cs_new_protected:Npn \@@_gput_next_do:nn #1
   {
     \exp_args:Nc \@@_gput_next_do:Nnn
@@ -3813,8 +4279,12 @@
   { \cs_gset_eq:cN { @@_next~#1 } \c_empty_tl }
 %    \end{macrocode}
 %  \end{macro}
-%  \end{macro}
 %
+%
+%
+%
+%
+%
 % \subsection{Using the hook}
 %
 % \begin{macro}{\hook_use:n}
@@ -3840,7 +4310,7 @@
 %   them causes an update, so \cs{hook_use:n} can be made expandable.
 %   This one is better not protected so that it can expand into nothing
 %   if containing no code. Also important in case of generic hooks that
-%   we do not generate a \cs{relax} as a side effect of checking for a
+%   we do not generate a \cs[no-index]{relax} as a side effect of checking for a
 %   csname. In contrast to the \TeX{} low-level
 %   \verb=\csname ...\endcsname= construct \cs{tl_if_exist:c} is
 %   careful to avoid this.
@@ -3877,7 +4347,7 @@
 % \end{macro}
 %
 % \begin{macro}[EXP]{\@@_use:wn}
-% \begin{macro}{\@@_try_file_hook:n,\@@_if_exist_use:n}
+% \begin{macro}{\@@_try_file_hook:n,\@@_if_usable_use:n}
 %   \cs{@@_use:wn} does a quick check to test if the current hook is a
 %   file hook: those need a special treatment.  If it is not, the hook
 %   does not exist.  If it is, then \cs{@@_try_file_hook:n} is called,
@@ -3887,7 +4357,7 @@
 %
 %   If it is a file-specific hook, it passes through the same
 %   normalization as during declaration, and then it is used if defined.
-%   \cs{@@_if_exist_use:n} checks if the hook exist, and calls
+%   \cs{@@_if_usable_use:n} checks if the hook exist, and calls
 %   \cs{@@_preamble_hook:n} if so, then uses the hook.
 %    \begin{macrocode}
 \cs_new:Npn \@@_use:wn #1 / #2 \s_@@_mark #3
@@ -3896,16 +4366,22 @@
       { \@@_try_file_hook:n {#3} }
       { } % Hook doesn't exist
   }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \cs_new_protected:Npn \@@_try_file_hook:n #1
   {
     \@@_if_file_hook:wTF #1 / / \s_@@_mark
       {
-        \exp_args:Ne \@@_if_exist_use:n
+        \exp_args:Ne \@@_if_usable_use:n
           { \exp_args:Ne \@@_file_hook_normalize:n {#1} }
       }
-      { \@@_if_exist_use:n {#1} } % file/ generic hook (e.g. file/before)
+      { \@@_if_usable_use:n {#1} } % file/ generic hook (e.g. file/before)
   }
-\cs_new_protected:Npn \@@_if_exist_use:n #1
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_if_usable_use:n #1
   {
     \tl_if_exist:cT { @@~#1 }
       {
@@ -3928,7 +4404,6 @@
 %    hook name, since \cs{hook_use:n} and \cs{hook_use_once:n} are
 %    documented to not trim spaces.
 %
-%    \pho{Should this raise an error if the hook doesn't exist?}
 %    \begin{macrocode}
 \cs_new_protected:Npn \hook_use_once:n #1
   {
@@ -3952,9 +4427,10 @@
 % exist, in which case emptiness doesn't apply (though
 % \cs{tl_if_empty:N} returns false in this case).
 %
-% Hooks are a bit more complicated: they have four possible states.
+% Hooks are a bit more complicated: they have several other states as
+%    discussed in \ref{sec:existence}.
 % A hook may exist or not, and either way it may or may not be empty
-% (even a hook that doesn't exist may be non-empty).
+% (even a hook that doesn't exist may be non-empty) or may be disabled.
 %
 % A hook is said to be empty when no code was added to it, either to
 % its permanent code pool, or to its ``next'' token list.  The hook
@@ -3964,19 +4440,19 @@
 % In this case it is important that the code added by package $B$ is
 % remembered until package $A$ is loaded).
 %
-% A hook is said to exist when it was declared with \cs{hook_new:n} or
-% some variant thereof.
-%
+%    All other states can only be queried with internal tests as the
+%    different states are irrelevant for package code.
+
 % \begin{macro}[pTF]{\hook_if_empty:n}
 %   Test if a hook is empty (that is, no code was added to that hook).
 %   A \meta{hook} being empty means that all three of its
-%   \cs[no-index]{g_@@_\meta{hook}_code_prop}, its
-%   \cs[no-index]{@@_toplevel~\meta{hook}} and its
-%   \cs[no-index]{@@_next~\meta{hook}} are empty.
+%   \cs{g_@@_\meta{hook}_code_prop}, its
+%   \cs{@@_toplevel\textvisiblespace\meta{hook}} and its
+%   \cs{@@_next\textvisiblespace\meta{hook}} are empty.
 %    \begin{macrocode}
 \prg_new_conditional:Npnn \hook_if_empty:n #1 { p , T , F , TF }
   {
-    \@@_if_exist:nTF {#1}
+    \@@_if_structure_exist:nTF {#1}
       {
         \bool_lazy_and:nnTF
             { \prop_if_empty_p:c { g_@@_#1_code_prop } }
@@ -3993,8 +4469,9 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[pTF]{\hook_if_exist:n}
-%   A canonical way to test if a hook exists.  A hook exists if the
+%
+% \begin{macro}[pTF]{\@@_if_usable:n}
+%   A hook is usable if the
 %   token list that stores the sorted code for that hook,
 %   \cs[no-index]{@@~\meta{hook}}, exists.  The property list
 %   \cs[no-index]{g_@@_\meta{hook}_code_prop} cannot be used here
@@ -4002,7 +4479,7 @@
 %   if such hook was already declared, or even if it will ever be
 %   (for example, in case the package that defines it isn't loaded).
 %    \begin{macrocode}
-\prg_new_conditional:Npnn \hook_if_exist:n #1 { p , T , F , TF }
+\prg_new_conditional:Npnn \@@_if_usable:n #1 { p , T , F , TF }
   {
     \tl_if_exist:cTF { @@~#1 }
       { \prg_return_true: }
@@ -4011,13 +4488,15 @@
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}[pTF]{\@@_if_exist:n}
-%   An internal check if the hook has already been declared with
-%   \cs{@@_declare:n}.  This means that the hook was already used somehow
+% \begin{macro}[pTF]{\@@_if_structure_exist:n}
+%
+%    An internal check if the hook has already its basic internal
+%    structure set up with
+%   \cs{@@_init_structure:n}.  This means that the hook was already used somehow
 %   (a code chunk or rule was added to it), but it still wasn't declared
 %   with \cs{hook_new:n}.
 %    \begin{macrocode}
-\prg_new_conditional:Npnn \@@_if_exist:n #1 { p , T , F , TF }
+\prg_new_conditional:Npnn \@@_if_structure_exist:n #1 { p , T , F , TF }
   {
     \prop_if_exist:cTF { g_@@_#1_code_prop }
       { \prg_return_true: }
@@ -4025,7 +4504,23 @@
   }
 %    \end{macrocode}
 % \end{macro}
+%  
+%  
+%  
+%  \begin{macro}[pTF]{\@@_if_declared:n}
 %
+%    Internal test to check if the hook was officially declared with
+%    \cs{hook_new:n} or a variant.
+%    \begin{macrocode}
+\prg_new_conditional:Npnn \@@_if_declared:n #1 { p, T, F, TF }
+  {
+    \tl_if_exist:cTF { g_@@_#1_declared_tl }
+      { \prg_return_true: }
+      { \prg_return_false: }
+  }
+%    \end{macrocode}
+%  \end{macro}
+%
 % \begin{macro}[pTF]{\@@_if_reversed:n}
 %   An internal conditional that checks if a hook is reversed.
 %    \begin{macrocode}
@@ -4043,11 +4538,21 @@
 %
 %  \subsection{Messages}
 %
+%    Hook errors are LaTeX kernel errors:  
 %    \begin{macrocode}
+\prop_gput:Nnn \g_msg_module_type_prop { hooks } { LaTeX }
+%    \end{macrocode}
+%    And so are kernel errors (this should move elsewhere eventually).
+%    \begin{macrocode}
+\prop_gput:Nnn \g_msg_module_type_prop { kernel } { LaTeX }
+%\prop_gput:Nnn \g_msg_module_name_prop { kernel } {  }   % <-- currently not working
+%    \end{macrocode}
+%    
+%    \begin{macrocode}
 \msg_new:nnnn { hooks } { labels-incompatible }
   {
-    Labels~`#1'~and~`#2'~are~incompatible
-    \str_if_eq:nnF {#3} {??} { ~in~hook~`#3' } .~
+    Labels~'#1'~and~'#2'~are~incompatible
+    \str_if_eq:nnF {#3} {??} { ~in~hook~'#3' } .~
     \int_compare:nNnTF {#4} = { 1 }
       { The~ code~ for~ both~ labels~ will~ be~ dropped. }
       { You~ may~ see~ errors~ later. }
@@ -4058,17 +4563,28 @@
 %    
 %    \begin{macrocode}
 \msg_new:nnnn { hooks } { exists }
-    { Hook~`#1'~ has~ already~ been~ declared. }
+    { Hook~'#1'~ has~ already~ been~ declared. }
     { There~ already~ exists~ a~ hook~ declaration~ with~ this~
       name.\\
       Please~ use~ a~ different~ name~ for~ your~ hook.}
 %    \end{macrocode}
 %    
+%
 %    \begin{macrocode}
+\msg_new:nnnn { hooks } { hook-disabled }
+  { Cannot~add~code~to~disabled~hook~'#1'. }
+  {
+    The~hook~'#1'~you~tried~to~add~code~to~was~previously~disabled~
+    with~\iow_char:N\\hook_disable:n~or~\iow_char:N\\DisableHook,~so~
+    it~cannot~have~code~added~to~it.
+  }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \msg_new:nnn { hooks } { empty-label }
   {
     Empty~code~label~\msg_line_context:.~
-    Using~`\@@_currname_or_default:'~instead.
+    Using~'\@@_currname_or_default:'~instead.
   }
 %    \end{macrocode}
 %
@@ -4082,19 +4598,19 @@
 %
 %    \begin{macrocode}
 \msg_new:nnnn { hooks } { unknown-rule }
-  { Unknown~ relationship~ `#3'~
-    between~ labels~ `#2'~ and~ `#4'~
-    \str_if_eq:nnF {#1} {??} { ~in~hook~`#1' }. ~
+  { Unknown~ relationship~ '#3'~
+    between~ labels~ '#2'~ and~ '#4'~
+    \str_if_eq:nnF {#1} {??} { ~in~hook~'#1' }. ~
     Perhaps~ a~ missspelling?
   }
   {
     The~ relation~ used~ not~ known~ to~ the~ system.~ Allowed~ values~ are~
-    `before'~ or~ `<',~
-    `after'~ or~ `>',~
-    `incompatible-warning',~
-    `incompatible-error',~
-    `voids'~ or~
-    `unrelated'.
+    'before'~ or~ '<',~
+    'after'~ or~ '>',~
+    'incompatible-warning',~
+    'incompatible-error',~
+    'voids'~ or~
+    'unrelated'.
   }
 %    \end{macrocode}
 %    
@@ -4101,7 +4617,7 @@
 %    \begin{macrocode}
 \msg_new:nnnn { hooks } { misused-top-level }
   {
-    Illegal~\iow_char:N \\AddToHook{#1}[top-level]{...}.\\
+    Illegal~use~of~\iow_char:N \\AddToHook{#1}[top-level]{...}.\\
     'top-level'~is~reserved~for~the~user's~document.
   }
   {
@@ -4115,7 +4631,7 @@
 %    \begin{macrocode}
 \msg_new:nnn { hooks } { set-top-level }
   {
-    You~cannot~change~the~default~label~#1~`top-level'.~Illegal \\
+    You~cannot~change~the~default~label~#1~'top-level'.~Illegal \\
     \use:nn { ~ } { ~ } \iow_char:N \\#2{#3} \\
     \msg_line_context:.
   }
@@ -4122,15 +4638,6 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\msg_new:nnn { hooks } { ddhl-deprecated }
-  {
-    \iow_char:N \\DeclareDefaultHookLabel~is~deprecated.\\
-    Use~\iow_char:N \\SetDefaultHookLabel~instead.\\ \\
-    The~deprecated~name~will~be~removed~in~the~next~release.
-  }
-%    \end{macrocode}
-%
-%    \begin{macrocode}
 \msg_new:nnn { hooks } { extra-pop-label }
   {
     Extra~\iow_char:N \\PopDefaultHookLabel. \\
@@ -4139,18 +4646,47 @@
 \msg_new:nnn { hooks } { missing-pop-label }
   {
     Missing~\iow_char:N \\PopDefaultHookLabel. \\
-    The~label~`#1'~was~pushed~but~never~popped.~Something~is~wrong.
+    The~label~'#1'~was~pushed~but~never~popped.~Something~is~wrong.
   }
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\msg_new:nnn { hooks } { should-not-happen }
+\msg_new:nnn { kernel } { should-not-happen }
   {
-    ERROR!~This~should~not~happen.~#1 \\
+    This~should~not~happen.~#1 \\
     Please~report~at~https://github.com/latex3/latex2e.
   }
 %    \end{macrocode}
 %
+%
+%
+%    \begin{macrocode}
+\msg_new:nnn { hooks } { provide-disabled }
+  {
+    Cannot~ provide~ hook~ '#1'~ because~ it~ is~ disabled!
+  }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\msg_new:nnnn { hooks } { provide-error }
+  {
+    Hook~'#1'~ already~ declared~ as~ a~
+    \@@_if_reversed:nTF {#1} { reversed } { normal }~ hook!
+  }
+  {
+    You~ attempted~ to~ provide~ the~ hook~'#1'~ as~ a~
+    \@@_if_reversed:nTF {#1} { normal } { reversed }~ hook,~ but~ it~
+    was~ already~ previously~ declared~ as~ a~
+    \@@_if_reversed:nTF {#1} { reversed } { normal }~ hook.~
+    A~ redeclaration~ is~ not~ possible.
+  }
+%    \end{macrocode}
+%
+%
+%
+%
+%
+%
 %  \subsection{\LaTeXe{} package interface commands}
 %
 %
@@ -4164,6 +4700,44 @@
 %    \end{macrocode}
 %  \end{macro}
 %
+%
+%
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>         {\hook_provide:n}{Providing~hooks}
+%    \end{macrocode}
+%
+%  \begin{macro}{\ProvideHook,\ProvideReversedHook,\ProvideMirroredHookPair}
+%    Providing new hooks \ldots
+% \changes{v1.0m}{2021/04/29}{Add \cs{ProvideHook} etc.}
+%    \begin{macrocode}
+\NewDocumentCommand \ProvideHook         { m }{ \hook_provide:n {#1} }
+\NewDocumentCommand \ProvideReversedHook { m }{ \hook_provide_reversed:n {#1} }
+\NewDocumentCommand \ProvideMirroredHookPair { mm }{ \hook_provide_pair:nn {#1}{#2} }
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%  \begin{macro}{\DisableHook}
+%    Disabling a (generic) hook.
+%    \begin{macrocode}
+\NewDocumentCommand \DisableHook { m }{ \hook_disable:n {#1} }
+%    \end{macrocode}
+%  \end{macro}
+%
+%    \begin{macrocode}
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{2020/10/01}
+%<latexrelease>                 {\hook_provide:n}{Providing~hooks}
+%<latexrelease>
+%<latexrelease>\def \ProvideHook#1{}
+%<latexrelease>\def \ProvideReversedHook#1{}
+%<latexrelease>\def \ProvideMirroredHookPair#1#2{}
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
+%
+%
 %  \begin{macro}{\AddToHook}
 %    
 %    \begin{macrocode}
@@ -4192,7 +4766,10 @@
 % \begin{macro}{\SetDefaultHookLabel}
 % \begin{macro}{\PushDefaultHookLabel}
 % \begin{macro}{\PopDefaultHookLabel}
-% \begin{macro}{\DeclareDefaultHookLabel}
+%
+% \fmiinline{Docu task: At some point this code for this should be moved to the
+%    label section earlier and here we should keep only the interface commands.}
+%
 % \begin{macro}{\@@_curr_name_push:n,\@@_curr_name_push_aux:n}
 % \begin{macro}{\@@_curr_name_pop:}
 % \begin{macro}{\@@_end_document_label_check:}
@@ -4216,8 +4793,11 @@
 %   the stack to support roll forward.  But in some rare cases,
 %   \pkg{latexrelease} may be loaded inside another package (notably
 %   \pkg{platexrelease}), so we'll first push the |top-level| entry:
+%   \changes{v1.0i}{2021/03/18}
+%           {Only add \texttt{top-level} if not already there.}
 %    \begin{macrocode}
-%<latexrelease>\seq_gput_right:Nn \g_@@_name_stack_seq { top-level }
+%<latexrelease>\seq_if_empty:NT \g_@@_name_stack_seq
+%<latexrelease>  { \seq_gput_right:Nn \g_@@_name_stack_seq { top-level } }
 %    \end{macrocode}
 %   then we dissect the \cs{@currnamestack}, adding \cs{@currname} to
 %   the stack:
@@ -4233,9 +4813,12 @@
 %<latexrelease>  \q_recursion_tail \q_recursion_tail
 %<latexrelease>  \q_recursion_tail \q_recursion_stop
 %    \end{macrocode}
-%   and finalle set the default label to be the \cs{@currname}:
+%   and finally set the default label to be the \cs{@currname}:
+%   \changes{v1.0i}{2021/03/18}
+%           {Remove the (empty) \enquote{top-level} from \cs{@currnamestack}.}
 %    \begin{macrocode}
 %<latexrelease>\tl_gset:Nx \g_@@_hook_curr_name_tl { \@currname }
+%<latexrelease>\seq_gpop_right:NN \g_@@_name_stack_seq \l_@@_tmpa_tl
 %    \end{macrocode}
 %
 %   Two commands keep track of the stack: when a file is input,
@@ -4274,7 +4857,7 @@
 %    \end{macrocode}
 %
 %   At the end of the document we want to check if there was no
-%   \cs{@@_curr_name_push:} without a matching \cs{@@_curr_name_pop:}
+%   \cs{@@_curr_name_push:n} without a matching \cs{@@_curr_name_pop:}
 %   (not a critical error, but it might indicate that something else is
 %   not quite right):
 %    \begin{macrocode}
@@ -4316,11 +4899,6 @@
       }
       { \tl_gset:Nn \g_@@_hook_curr_name_tl {#1} }
   }
-\NewDocumentCommand \DeclareDefaultHookLabel { m }
-  {
-    \msg_error:nn { hooks } { ddhl-deprecated }
-    \SetDefaultHookLabel {#1}
-  }
 %    \end{macrocode}
 %
 %   The label is only automatically updated with \cs{@onefilewithoptions}
@@ -4360,7 +4938,6 @@
 % \end{macro}
 % \end{macro}
 % \end{macro}
-% \end{macro}
 %
 %
 %
@@ -4413,7 +4990,7 @@
 %  \begin{macro}{\ClearHookRule}
 %    A special setup rule that removes an existing relation.
 %    Basically {@@_rule_gclear:nnn} plus fixing the property list for debugging.
-%    \fmi{Need an L3 interface, or maybe it should get dropped?}
+%    \fmiinline{Needs perhaps an L3 interface, or maybe it should get dropped?}
 %    \begin{macrocode}
 \NewDocumentCommand \ClearHookRule { m m m }
 { \hook_gset_rule:nnnn {#1}{#2}{unrelated}{#3} }
@@ -4421,20 +4998,34 @@
 %  \end{macro}
 %
 %
-% \begin{macro}[EXP]{\IfHookExistsTF,\IfHookEmptyTF}
+% \begin{macro}[EXP]{\IfHookEmptyTF}
 %   Here we avoid the overhead of \pkg{xparse}, since \cs{IfHookEmptyTF}
 %   is used in \cs{end} (that is, every \LaTeX{} environment).  As a
 %   further optimisation, use \cs{let} rather than \cs{def} to avoid one
 %   expansion step.
 %    \begin{macrocode}
-\cs_new_eq:NN \IfHookExistsTF \hook_if_exist:nTF
 \cs_new_eq:NN \IfHookEmptyTF \hook_if_empty:nTF
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}[EXP]{\IfHookExistsTF}
+%    Marked for removal and no longer documented in the doc section!
+% \phoinline{\cs{IfHookExistsTF} is used in \texttt{jlreq.cls},
+% \texttt{pxatbegshi.sty}, \texttt{pxeverysel.sty},
+% \texttt{pxeveryshi.sty}, so the public name may be an alias of the
+% internal conditional for a while.  Regardless, those packages' use for
+% \cs{IfHookExistsTF} is not really correct and can be changed.}
+%    \begin{macrocode}
+\cs_new_eq:NN \IfHookExistsTF \@@_if_usable:nTF
+%    \end{macrocode}
+% \end{macro}
 %
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
 %
+%
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+%
 % \subsection{Internal commands needed elsewhere}
 %
 % Here we set up a few horrible (but consistent) \LaTeXe{} names to
@@ -4449,6 +5040,7 @@
 %  \begin{macro}{\@expl@@@initialize at all@@,
 %                \@expl@@@hook at curr@name at pop@@}
 %
+% \InternalDetectionOff
 %    \begin{macrocode}
 \cs_new_eq:NN \@expl@@@initialize at all@@
               \__hook_initialize_all:
@@ -4458,30 +5050,26 @@
 \cs_new_eq:NN \@expl@@@hook at curr@name at pop@@
               \__hook_curr_name_pop:
 %    \end{macrocode}
+% \InternalDetectionOn
 %  \end{macro}
 %
-%    
-%    \begin{macrocode}
-\ExplSyntaxOff
-%    \end{macrocode}
-%
-%
 %    Rolling back here doesn't undefine the interface commands as they
 %    may be used in packages without rollback functionality. So we
 %    just make them do nothing which may or may not work depending on
 %    the code usage.
 % \changes{v1.0d}{2020/10/04}{Definition \cs{AddToHookNext} was supposed
-%                             to be for \cs{AddToHook} vize versa (gh/401)}
+%                             to be for \cs{AddToHook} vice versa (gh/401)}
 %    \begin{macrocode}
-%</2ekernel|latexrelease>
-%<latexrelease>\EndIncludeInRelease
+%
 %<latexrelease>\IncludeInRelease{0000/00/00}%
-%<latexrelease>                 {\NewHook}{The hook management}%
+%<latexrelease>                 {lthooks}{The~hook~management}%
 %<latexrelease>
-%<latexrelease>\def\NewHook#1{}
-%<latexrelease>\def\NewReversedHook#1{}
-%<latexrelease>\def\NewMirroredHookPair#1#2{}
+%<latexrelease>\def \NewHook#1{}
+%<latexrelease>\def \NewReversedHook#1{}
+%<latexrelease>\def \NewMirroredHookPair#1#2{}
 %<latexrelease>
+%<latexrelease>\def \DisableHook #1{}
+%<latexrelease>
 %<latexrelease>\long\def\AddToHookNext#1#2{}
 %<latexrelease>
 %<latexrelease>\def\AddToHook#1{\@gobble at AddToHook@args}
@@ -4508,7 +5096,9 @@
 %<latexrelease>\long\def \IfHookExistsTF #1#2#3{#3}
 %<latexrelease>\long\def \IfHookEmptyTF #1#2#3{#2}
 %<latexrelease>
-%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\EndModuleRelease
+\ExplSyntaxOff
+%</2ekernel|latexrelease>
 %    \end{macrocode}
 %
 %

Modified: trunk/Master/texmf-dist/source/latex/base/lthyphen.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/lthyphen.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/lthyphen.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -40,7 +40,7 @@
 %\iffalse        This is a META comment
 %
 % File `lthyphen.dtx'.
-% Copyright (C) 1994-94 LaTeX3 project, Frank Mittelbach and
+% Copyright (C) 1994-94 LaTeX Project, Frank Mittelbach and
 % Rainer Sch\"opf, all rights reserved.
 %
 %\fi

Modified: trunk/Master/texmf-dist/source/latex/base/ltidxglo.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltidxglo.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltidxglo.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/ltlength.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltlength.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltlength.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -33,7 +33,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltlength.dtx}
-             [2019/08/27 v1.1d LaTeX Kernel (Lengths)]
+             [2020/12/05 v1.1d LaTeX Kernel (Lengths)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltlength.dtx}
@@ -154,7 +154,7 @@
 %    This macro takes the contents of the skip register that is
 %    supplied as its argument and removes the fractional part to make
 %    it a whole number of points. This can be used in class files to
-%    avoid values like |345.4666666pt| when calulating a dimension.
+%    avoid values like |345.4666666pt| when calculating a dimension.
 % \changes{LaTeX2e}{1993/11/22}{Macro added}
 %    \begin{macrocode}
 \def\@settopoint#1{\divide#1\p@\multiply#1\p@}

Modified: trunk/Master/texmf-dist/source/latex/base/ltlists.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltlists.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltlists.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -31,7 +31,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltlists.dtx}
-             [2020/04/24 v1.0t LaTeX Kernel (List Environments)]
+             [2020/12/05 v1.0t LaTeX Kernel (List Environments)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltlists.dtx}
@@ -112,7 +112,7 @@
 % the entire environment is a single item.  It is defined by
 % letting |\quotation| == |\list{}{...}\item\relax|.  (Note the
 % |\relax|, there in case the first character in the environment is a
-% '['.)  The spacing parameters provide a great deal of flexability in
+% '['.)  The spacing parameters provide a great deal of flexibility in
 % designing the format, including the ability to let the indentation of
 % the first paragraph be different from that of the subsequent ones.
 %
@@ -589,7 +589,7 @@
 %                 when not inlabel flag is false}
 % Because |\par| is sometimes made a no-op it is possible for a missing
 % |\item| to produce a loop that does not fill memory and so never gets
-% trapped by \TeX.  We thus need to trap this here by seting |\par| to
+% trapped by \TeX.  We thus need to trap this here by setting |\par| to
 % count the number of times a paragraph ii is called with no progress
 % being made started.
 %    \begin{macrocode}
@@ -729,7 +729,7 @@
 %    If a section heading changes |\clubpenalty| to keep lines
 %    after it together then this modification is restored via the
 %   |\everypar| mechanism at the start of the next paragraph. As we
-%   destroy the contents of this token here we explicity set
+%   destroy the contents of this token here we explicitly set
 %   |\clubpenalty| back to its default.
 % \changes{v1.0t}{2015/05/10}{Explicitly reset \cs{clubpenalty} before
 %  clearing \cs{everypar}; see also pr/0462 and pr/4065}
@@ -807,7 +807,7 @@
 % \end{macro}
 %
 % \begin{macro}{\@item}
-% \changes{v1.0l}{1996/07/26}{Remove unecessary \cs{global} before
+% \changes{v1.0l}{1996/07/26}{Remove unnecessary \cs{global} before
 %                 \cs{@minipage...}}
 %    \begin{macrocode}
 \def\@item[#1]{%
@@ -889,7 +889,7 @@
       \everypar{}%
     \fi}%
 %    \end{macrocode}
-% \changes{v1.0l}{1996/07/26}{Remove unecessary \cs{global} before
+% \changes{v1.0l}{1996/07/26}{Remove unnecessary \cs{global} before
 %                 \cs{@nobreak...}}
 % \changes{v1.0m}{1996/10/23}{\cs{@nobreak...} moved into the
 %          \cs{everypar} and not executed unconditionally, see above}

Modified: trunk/Master/texmf-dist/source/latex/base/ltlogos.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltlogos.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltlogos.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/ltluatex.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltluatex.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltluatex.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 2015-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 2015-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -28,7 +28,7 @@
 \ProvidesFile{ltluatex.dtx}
 %</driver>
 %<*tex>
-[2020/09/25 v1.1s
+[2021/04/18 v1.1t
 %</tex>
 %<plain>  LuaTeX support for plain TeX (core)
 %<*tex>
@@ -38,6 +38,10 @@
 %</tex>
 %<*driver>
 \documentclass{ltxdoc}
+
+\providecommand\InternalDetectionOff{}
+\providecommand\InternalDetectionOn{}
+
 \GetFileInfo{ltluatex.dtx}
 \begin{document}
 \title{\filename\\(Lua\TeX{}-specific support)}
@@ -129,7 +133,7 @@
 % \DescribeMacro{\newluachunkname}
 % |newluachunkname{|\meta{chunkname}|}|\\
 % Allocates a number for Lua chunk register, indexed from~$1$.
-% Also enters the name of the regiser (without backslash) into the
+% Also enters the name of the register (without backslash) into the
 % \verb|lua.name| table to be used in stack traces.
 %
 % \noindent
@@ -204,6 +208,7 @@
 % The number is returned and also \meta{name} argument is added to the
 % |lua.name| array at that index.
 %
+% \begin{sloppypar}
 % \noindent
 % \DescribeMacro{new_luafunction}
 % |luatexbase.new_luafunction(|\meta{functionname}|)|\\
@@ -211,6 +216,7 @@
 % with |\luafunction|, |\lateluafunction|, and |\luadef|,
 % indexed from~$1$. The optional \meta{functionname} argument
 % is just used for logging.
+% \end{sloppypar}
 %
 % These functions all require access to a named \TeX{} count register
 % to manage their allocations. The standard names are those defined
@@ -582,7 +588,7 @@
 % \changes{v1.0a}{2015/09/24}{Macro added}
 %   Category code tables are allocated with a limit half of that used by Lua\TeX{}
 %   for everything else. At the end of allocation there needs to be an
-%   initialisation step. Table~$0$ is already taken (it's the global one for
+%   initialization step. Table~$0$ is already taken (it's the global one for
 %   current use) so the allocation starts at~$1$.
 %    \begin{macrocode}
 \ifx\e at alloc@ccodetable at count\@undefined
@@ -779,8 +785,8 @@
 % \subsection{Lua loader}
 % \changes{v1.1r}{2020/08/10}{Load ltluatex Lua module during format building}
 %
-% Lua code loaded in the format often has to to be loaded again at the
-% beginning of every job, so we define a helper whch allows us to avoid
+% Lua code loaded in the format often has to be loaded again at the
+% beginning of every job, so we define a helper which allows us to avoid
 % duplicated code:
 %
 %    \begin{macrocode}
@@ -1113,9 +1119,10 @@
 %
 % \begin{macro}{new_attribute}
 % \changes{v1.0a}{2015/09/24}{Function added}
-% \changes{v1.1c}{2017/02/18}{Parameterise count used in tracking}
+% \changes{v1.1c}{2017/02/18}{Parameterize count used in tracking}
 %   As attributes are used for Lua manipulations its useful to be able
 %   to assign from this end.
+% \InternalDetectionOff
 %    \begin{macrocode}
 local attributes=setmetatable(
 {},
@@ -1143,12 +1150,13 @@
 end
 luatexbase.new_attribute = new_attribute
 %    \end{macrocode}
+% \InternalDetectionOn
 % \end{macro}
 %
 % \subsection{Custom whatsit allocation}
 %
 % \begin{macro}{new_whatsit}
-% \changes{v1.1c}{2017/02/18}{Parameterise count used in tracking}
+% \changes{v1.1c}{2017/02/18}{Parameterize count used in tracking}
 % Much the same as for attribute allocation in Lua.
 %    \begin{macrocode}
 local whatsit_count_name = whatsit_count_name or "e at alloc@whatsit at count"
@@ -1169,7 +1177,7 @@
 % \subsection{Bytecode register allocation}
 %
 % \begin{macro}{new_bytecode}
-% \changes{v1.1c}{2017/02/18}{Parameterise count used in tracking}
+% \changes{v1.1c}{2017/02/18}{Parameterize count used in tracking}
 % Much the same as for attribute allocation in Lua.
 % The optional \meta{name} argument is used in the log if given.
 %    \begin{macrocode}
@@ -1192,7 +1200,7 @@
 % \subsection{Lua chunk name allocation}
 %
 % \begin{macro}{new_chunkname}
-% \changes{v1.1c}{2017/02/18}{Parameterise count used in tracking}
+% \changes{v1.1c}{2017/02/18}{Parameterize count used in tracking}
 % As for bytecode registers but also store the name in the
 % |lua.name| table.
 %    \begin{macrocode}
@@ -1404,6 +1412,7 @@
 % \changes{v1.1j}{2019/06/18}{make\_extensible added}
 % \changes{v1.1j}{2019/06/18}{font\_descriptor\_objnum\_provider added}
 % \changes{v1.1l}{2020/02/02}{glyph\_info added}
+% \changes{v1.1t}{2021/04/18}{input\_level\_string added}
 %    \begin{macrocode}
   define_font                     = exclusive,
   glyph_info                      = exclusive,
@@ -1411,6 +1420,7 @@
   glyph_stream_provider           = exclusive,
   make_extensible                 = exclusive,
   font_descriptor_objnum_provider = exclusive,
+  input_level_string              = exclusive,
 %    \end{macrocode}
 % \changes{v1.0m}{2016/02/11}{pdf\_stream\_filter\_callback removed}
 %    \begin{macrocode}
@@ -1469,7 +1479,7 @@
 %     functions in inverse order.
 %   \item[exclusive] is for functions with more complex signatures; functions in
 %     this type of callback are \emph{not} combined: An error is raised if
-%     a second callback is registered..
+%     a second callback is registered.
 % \end{description}
 %
 % Handler for |data| callbacks.
@@ -1735,7 +1745,7 @@
 %
 % \begin{macro}{remove_from_callback}
 % \changes{v1.0a}{2015/09/24}{Function added}
-% \changes{v1.0k}{2015/12/02}{adjust initialisation of cb local (PHG)}
+% \changes{v1.0k}{2015/12/02}{adjust initialization of cb local (PHG)}
 % \changes{v1.0k}{2015/12/02}{Give more specific error messages (PHG)}
 % \changes{v1.1m}{2020/03/07}{Do not call callback.register for user-defined callbacks}
 %   Remove a function from a callback. First check arguments.

Modified: trunk/Master/texmf-dist/source/latex/base/ltmath.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltmath.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltmath.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -38,7 +38,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltmath.dtx}
-              [2020/11/09 v1.2h LaTeX Kernel (Math Setup)]
+              [2021/04/20 v1.2i LaTeX Kernel (Math Setup)]
 % \iffalse
 %</driver>
 %
@@ -529,7 +529,7 @@
 %
 %    Originally \LaTeX{} only provided a small set of spacing commands
 %    for use in text and math, some of the commands like \cs{;} were
-%    only supported in manth mode. \texttt{amsmath} normalized  and
+%    only supported in math mode. \texttt{amsmath} normalized  and
 %    provided all of them in text and math. This code has now been
 %    moved to the kernel so that it is generally available.
 %
@@ -961,11 +961,12 @@
 % \end{macro}
 %
 % \begin{macro}{\@eqncr}
+% \changes{v1.2i}{2021/04/20}{Use \cs{protected} for \cs{\bslash} variant (gh/548)}
 % \begin{macro}{\@xeqncr}
 % \begin{macro}{\@yeqncr}
 % \changes{v1.0y}{1995/10/16}{(DPC) Use \cs{@testopt} /1911}
 %    \begin{macrocode}
-\def\@eqncr{%
+\protected\def\@eqncr{%
    {\ifnum0=`}\fi
    \@ifstar{%
       \global\@eqpen\@M\@yeqncr
@@ -1033,8 +1034,9 @@
 \let\@seqncr=\@eqncr
 %    \end{macrocode}
 %
+% \changes{v1.2i}{2021/04/20}{Use \cs{protected} for \cs{\bslash} variant (gh/548)}
 %    \begin{macrocode}
-\@namedef{eqnarray*}{\def\@eqncr{\nonumber\@seqncr}\eqnarray}
+\@namedef{eqnarray*}{\protected\def\@eqncr{\nonumber\@seqncr}\eqnarray}
 %    \end{macrocode}
 %
 %    \begin{macrocode}
@@ -1101,7 +1103,7 @@
 %    To put the equation number on the left side of an equation we
 %    have to use a little trick. The number is shifted |\displaywidth|
 %    to the left inside a box of (approximately) zero width. This
-%    fails when the quation is too wide, the equation number than may
+%    fails when the equation is too wide, the equation number than may
 %    overprint the equation itself.
 % \changes{v1.2y classes}{1995/01/12}{Added \cs{normalcolor}}
 % \changes{v1.3c classes}{1995/05/25}

Modified: trunk/Master/texmf-dist/source/latex/base/ltmiscen.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltmiscen.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltmiscen.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -32,7 +32,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltmiscen.dtx}
-             [2020/12/18 v1.1x LaTeX Kernel (Misc. Environments)]
+             [2021/02/08 v1.1y LaTeX Kernel (Misc. Environments)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltmiscen.dtx}
@@ -214,6 +214,7 @@
 % \changes{v1.1i}{2000/05/19}
 %            {Reset \cs{AtEndDocument} for latex/3060}
 %    \begin{macrocode}
+   \@kernel at before@enddocument
    \UseOneTimeHook{enddocument}%
    \@kernel at after@enddocument
 %    \end{macrocode}
@@ -390,8 +391,37 @@
 %<*2ekernel>
 %    \end{macrocode}
 %
+%  \begin{macro}{\@kernel at before@enddocument}
+%    The \cs{@kernel at before@enddocument} hook is slightly different
+%    because we initialize it with \cs{par} so that \cs{enddocument} always
+%    returns to vertical mode as its first action. 
+% \changes{v1.1x}{2020/10/26}{\cs{enddocument} should always start out in
+%    vmode (gh/385)}
+%    \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2021/06/01}%
+%<latexrelease>                 {\@kernel at before@enddocument}{kernel before hook}%
+\def\@kernel at before@enddocument{\par}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%    \end{macrocode}
 %
+%    The rollback code renders it harmless.
+%    \begin{macrocode}
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {\@kernel at before@enddocument}{kernel before hook}%
+%<latexrelease>
+%<latexrelease>\let\@kernel at before@enddocument\@empty
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+%    \end{macrocode}
+%  \end{macro}
 %
+%
+%
+%
 % \begin{macro}{\@testdef}
 %    \begin{macrocode}
 \def\@testdef #1#2#3{%
@@ -838,6 +868,15 @@
 %<latexrelease>  \expandafter\endgroup\if at endpe\@doendpe\fi
 %<latexrelease>  \if at ignore\@ignorefalse\ignorespaces\fi}
 %<latexrelease>
+%    \end{macrocode}
+%    Also undo the internal commands as some packages unfortunately test
+%    for their existence instead of using \cs{IfFormatAtLeastTF}.
+% \changes{v1.1y}{2021/02/08}{Undo the internals for robust \cs{begin}
+%    and \cs{end} in rollback (gh/494)}
+%    \begin{macrocode}
+%<latexrelease>\expandafter\let\csname begin \endcsname\@undefined
+%<latexrelease>\expandafter\let\csname end \endcsname\@undefined
+%<latexrelease>
 %<latexrelease>\EndIncludeInRelease
 %<*2ekernel>
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/base/ltoutenc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltoutenc.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltoutenc.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -37,7 +37,7 @@
 %<TS1>\ProvidesFile{ts1enc.def}[2001/06/05 v3.0e (jk/car/fm)
 %<TU>\ProvidesFile{tuenc.def}
 %<package>\ProvidesPackage{fontenc}
-%<OT1|T1|OMS|OML|OT4|TU|package> [2020/08/10 v2.0s
+%<OT1|T1|OMS|OML|OT4|TU|package> [2021/04/29 v2.0v
 %<OT1|T1|OMS|OML|OT4|TS1|TU>      Standard LaTeX file]
 %<package>                        Standard LaTeX package]
 %
@@ -44,7 +44,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltoutenc.dtx}
-             [2020/08/10 v2.0s LaTeX Kernel (font encodings)]
+             [2021/04/29 v2.0v LaTeX Kernel (font encodings)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltoutenc.dtx}
@@ -421,7 +421,7 @@
 % for |\textdollar| in \texttt{OT1} is a hack since \$ and \pounds{}
 % actually share the same slot in this encoding. Thus if such a glyph
 % becomes available in a different encoding (e.g., \texttt{TS1}) one
-% would like to get rid of the flacky one and make the default
+% would like to get rid of the flaky one and make the default
 % definition point to the new encoding. In such a case defining
 %\begin{verbatim}
 %   \DeclareTextSymbol{\textdollar}{TS1}{36}
@@ -841,7 +841,7 @@
 %    avoid that (they are some hidden inside \cs{maybe 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
-%    disable that part of the code temporaily.
+%    disable that part of the code temporarily.
 %    We also ignore \cs{ignorespaces} which has the same issue and may
 %    show up as part of \cs{normalfont} if that is used.
 % \changes{v2.0m}{2019/12/18}{Avoid code that breaks \cs{accent}}
@@ -1717,6 +1717,17 @@
 \DeclareTextSymbol{\textemdash}{OT1}{124}
 \DeclareTextSymbol{\textendash}{OT1}{123}
 %    \end{macrocode}
+%    
+%    The \verb=\nobreak\hskip\z@= is there to prevent a break after
+%    the hyphen but allow later breaks in the remainder of the word. 
+% \changes{v2.0u}{2021/02/19}{Add \cs{textnonbreakinghyphen}, \cs{textfiguredash}
+%      and \cs{texthorizontalbar} (gh/404)}
+%    \begin{macrocode}
+\DeclareTextCommand{\textnonbreakinghyphen}{OT1}{\mbox{-}\nobreak\hskip\z@}
+\DeclareTextCommand{\textfiguredash}       {OT1}{\textendash}
+\DeclareTextCommand{\texthorizontalbar}    {OT1}{\textemdash}
+%    \end{macrocode}
+%
 %    Using the ligatures helps with OT1 fonts that have
 %    |\textexclamdown| and |\textquestiondown| in unusual positions.
 % \changes{v1.95}{2002/06/17}{Definition of \cs{textexclamdown} changed (pr/3368)}
@@ -2045,6 +2056,19 @@
 \DeclareTextSymbol{\textdollar}{T1}{`\$}
 \DeclareTextSymbol{\textemdash}{T1}{22}
 \DeclareTextSymbol{\textendash}{T1}{21}
+%    \end{macrocode}
+%
+%    The \verb=\nobreak\hskip\z@= is there to prevent a break after
+%    the hyphen but allow later breaks in the remainder of the word. 
+% \changes{v2.0u}{2021/02/19}{Add \cs{textnonbreakinghyphen}, \cs{textfiguredash}
+%      and \cs{texthorizontalbar} (gh/404)}
+%    \begin{macrocode}
+\DeclareTextCommand{\textnonbreakinghyphen}{T1}{\mbox{-}\nobreak\hskip\z@}
+\DeclareTextCommand{\textfiguredash}       {T1}{\textendash}
+\DeclareTextCommand{\texthorizontalbar}    {T1}{\textemdash}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \DeclareTextSymbol{\textexclamdown}{T1}{189}
 \DeclareTextSymbol{\textgreater}{T1}{`\>}
 %\DeclareTextSymbol{\texthyphenchar}{T1}{127}
@@ -2538,7 +2562,7 @@
 %
 % The tie accent was borrowed from the |cmmi| font. The tc fonts
 % now provide four tie accents, the first two are done in the
-% classical way with assymetric glyphs hanging out of their boxes;
+% classical way with asymmetric glyphs hanging out of their boxes;
 % the new ties are centered in their boxes like all other accents.
 % They need a name: please tell us if you know what to call them.
 %
@@ -2550,7 +2574,7 @@
 \DeclareTextAccent{\capitalnewtie}{TS1}{29}
 %    \end{macrocode}
 %
-% Compund word marks.
+% Compound word marks.
 %
 % The text companion fonts contain two compound word marks of
 % different heights, one has |cap_height|, the other |asc_height|.
@@ -2583,8 +2607,31 @@
 \DeclareTextSymbol{\textquotesingle}{TS1}{39}
 %    \end{macrocode}
 %    "28 = 40
+%
+%    The symbol \cs{textasteriskcentered} ``\textasteriskcentered'' is
+%    supposed to be always available in \texttt{TS1} and that is
+%    important as it is used in footnote symbols. However, in a few
+%    fonts it is missing even though they are otherwise fairly
+%    complete. We therefore use a rather elaborate method and check if
+%    the slot has a glyph and if not produce a poor man's version by
+%    using a normal ``*'' slightly enlarged and somewhat lowered.
+%    The main application for this symbol is in footnote symbols and
+%    there it should produce a comparable size and show a similar placement.
+% \changes{v2.0t}{2021/02/17}{Special definition for
+%        \cs{textasteriskcentered} when missing in TS1 (gh/502)}
 %    \begin{macrocode}
-\DeclareTextSymbol{\textasteriskcentered}{TS1}{42}
+%\DeclareTextSymbol{\textasteriskcentered}{TS1}{42} % that's wanted
+\DeclareTextCommand \textasteriskcentered{TS1}{%    % and that's needed
+  \iffontchar\font 42 \char42 \else 
+   \begingroup\fontencoding{T1}%
+       \fontsize
+       {\the\dimexpr1.3\dimexpr\f at size pt\relax}%
+       {\f at baselineskip}%
+      \selectfont
+      \raisebox{-0.7ex}[\dimexpr\height-0.7ex][0pt]{*}%
+    \endgroup
+    \fi
+}
 %    \end{macrocode}
 % Note that '054 is a comma and '056 is a full stop: these make
 % numbers using oldstyle digits easier to input.
@@ -2837,7 +2884,7 @@
 %<*TU>
 %    \end{macrocode}
 % In the base interface the Unicode encoding is always known as TU
-% But we parameterise the encoding name to allow for modelling
+% But we parameterize the encoding name to allow for modelling
 % differences in Unicode support by different fonts.
 %    \begin{macrocode}
 \providecommand\UnicodeEncodingName{TU}
@@ -3106,8 +3153,34 @@
 \DeclareTextSymbol{\textbaht}            \UnicodeEncodingName{"0E3F}
 \DeclareTextSymbol{\SS}                  \UnicodeEncodingName{"1E9E}
 \DeclareTextSymbol{\textcompwordmark}    \UnicodeEncodingName{"200C}
+%    \end{macrocode}
+%    
+% \changes{v2.0u}{2021/02/19}{Add \cs{textnonbreakinghyphen}, \cs{textfiguredash}
+%      and \cs{texthorizontalbar} (gh/404)}
+%    \begin{macrocode}
+%\DeclareTextSymbol{\textnonbreakinghyphen} \UnicodeEncodingName{"2011}
+%\DeclareTextSymbol{\textfiguredash}        \UnicodeEncodingName{"2012}
 \DeclareTextSymbol{\textendash}          \UnicodeEncodingName{"2013}
 \DeclareTextSymbol{\textemdash}          \UnicodeEncodingName{"2014}
+%\DeclareTextSymbol{\texthorizontalbar}   \UnicodeEncodingName{"2015}
+%    \end{macrocode}
+%    Unfortunately some fonts do not implement \texttt{"2011}, \texttt{"2012} and/or
+%    \texttt{"2015} (including the \LaTeX{} default fonts for Unicode
+%    engines) so we provide some approximations if the glyph is
+%    missing, like we do for \texttt{OT1} and \texttt{T1}.
+%
+%    The \verb=\nobreak\hskip\z@= is there to prevent a break after
+%    the hyphen but allow later breaks in the remainder of the word. 
+%    \begin{macrocode}
+\DeclareTextCommand{\textnonbreakinghyphen} \UnicodeEncodingName
+     {\iffontchar\font "2011 \char "2011 \else \mbox{-}\nobreak\hskip\z@ \fi}
+\DeclareTextCommand{\textfiguredash}     \UnicodeEncodingName
+     {\iffontchar\font "2012 \char "2012 \else \char "2013 \fi}
+\DeclareTextCommand{\texthorizontalbar}     \UnicodeEncodingName
+     {\iffontchar\font "2015 \char "2015 \else \char "2014 \fi}
+%    \end{macrocode}
+%    
+%    \begin{macrocode}
 \DeclareTextSymbol{\textbardbl}          \UnicodeEncodingName{"2016}
 \DeclareTextSymbol{\textquoteleft}       \UnicodeEncodingName{"2018}
 \DeclareTextSymbol{\textquoteright}      \UnicodeEncodingName{"2019}
@@ -3159,15 +3232,17 @@
 %    \end{macrocode}
 %
 % Not all fonts have U+2217 but using U+002A requires some adjustment.
+% \changes{v2.0t}{2021/02/17}{Adjust values for
+%        \cs{textasteriskcentered} To match TS1 definition (gh/502)}
 %    \begin{macrocode}
 \DeclareTextCommand{\textasteriskcentered}\UnicodeEncodingName{%
   \iffontchar\font"2217 \char"2217 \else
     \begingroup
       \fontsize
-       {\the\dimexpr1.2\dimexpr\f at size pt\relax}%
+       {\the\dimexpr1.3\dimexpr\f at size pt\relax}%
        {\f at baselineskip}%
       \selectfont
-      \raisebox{-0.6ex}[\dimexpr\height-0.6ex][0pt]{*}%
+      \raisebox{-0.7ex}[\dimexpr\height-0.7ex][0pt]{*}%
     \endgroup
   \fi
 }
@@ -3393,8 +3468,19 @@
 \DeclareUnicodeComposite{\v}             {o}{"01D2}
 \DeclareUnicodeComposite{\v}             {U}{"01D3}
 \DeclareUnicodeComposite{\v}             {u}{"01D4}
+%    \end{macrocode}
+%
+% \changes{v2.0v}{2021/04/29}{Add composites for
+%      \texttt{\protect\string\ae/\protect\string\AE/\ae/\AE} (gh/552)}
+%    \begin{macrocode}
+\DeclareUnicodeComposite{\'}             \AE{"01FC}
+\DeclareUnicodeComposite{\'}             {Æ}{"01FC}
+\DeclareUnicodeComposite{\'}             \ae{"01FD}
+\DeclareUnicodeComposite{\'}             {æ}{"01FD}
 \DeclareUnicodeComposite{\=}             \AE{"01E2}
+\DeclareUnicodeComposite{\=}             {Æ}{"01E2}
 \DeclareUnicodeComposite{\=}             \ae{"01E3}
+\DeclareUnicodeComposite{\=}             {æ}{"01E3}
 \DeclareUnicodeComposite{\v}             {G}{"01E6}
 \DeclareUnicodeComposite{\v}             {g}{"01E7}
 \DeclareUnicodeComposite{\v}             {K}{"01E8}

Modified: trunk/Master/texmf-dist/source/latex/base/ltoutenc.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltoutenc.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltoutenc.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/ltoutput.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltoutput.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltoutput.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -37,7 +37,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltoutput.dtx}
-             [2020/08/21 v1.4f LaTeX Kernel (Output Routine)]
+             [2021/05/05 v1.4g LaTeX Kernel (Output Routine)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltoutput.dtx}
@@ -57,7 +57,7 @@
 % \iffalse
 % LATEX VERSION 2e
 % Copyright (C) 1992 by Leslie Lamport
-% Copyright (C) 1994-2000 by Leslie Lamport, LaTeX3 project
+% Copyright (C) 1994-2000 by Leslie Lamport, LaTeX Project
 %
 % LaTeX 2e kernel file for the output routine.
 %
@@ -1134,7 +1134,7 @@
   \global \advance \@colht \@tempdima
   \ifx \@dbltoplist \@empty
   \else
-    \@latexerr{Float(s) lost}\@ehb
+    \@latex at error{Float(s) lost}\@ehb
     \let \@dbltoplist \@empty
   \fi
   \@cons \@dbltoplist \@currbox
@@ -1525,7 +1525,7 @@
        \global \@colroom \@colht
        \ifx \@currlist\@empty
        \else
-          \@latexerr{Float(s) lost}\@ehb
+          \@latex at error{Float(s) lost}\@ehb
           \global \let \@currlist \@empty
        \fi
        \@makefcolumn\@deferlist
@@ -1676,7 +1676,7 @@
 %  \begin{macro}{\@makecol}
 % \changes{v0.1c}{1993/11/23}{Command changed}
 % \changes{v1.0b}{1993/11/29}{\cs{@makespecialcolbox} added}
-%    We must rewrite this macro to alllow for variations in page-makeup
+%    We must rewrite this macro to allow for variations in page-makeup
 %    required by changes in page-length.
 %
 %    This uses a different macro if a special-length column is being
@@ -1860,7 +1860,7 @@
 %    force the shortest possible column with the possibility of an
 %    overfull box.
 %
-%    This should work for bothe flush- and ragged-bottom setting since
+%    This should work for both flush- and ragged-bottom setting since
 %    it makes the contents no smaller than the size (|\@colht|) of the
 %    box into which they are put.
 %
@@ -2074,7 +2074,7 @@
 %    \end{macrocode}
 %
 %    The |\catcode`\ = 10| was removed as it was considered useless
-%    (presumably because nothing gets tokenised during shipout).
+%    (presumably because nothing gets tokenized during shipout).
 %
 %    This was put in as some error produced active spaces in a mark, I
 %    think.
@@ -2156,7 +2156,7 @@
 %
 %    The rest was always inside the box.
 %
-%    RmS 91/08/15: aded this line:
+%    RmS 91/08/15: added this line:
 %    \begin{macrocode}
   \reset at font
 %    \end{macrocode}
@@ -3864,7 +3864,7 @@
 % be printed in as small a space as possible, ie it uses any
 % shrinkability in the column. If the column was not explicitly broken
 % (\eg with |\pagebreak|) this may result in an overfull box message but
-% execpt for this it will come out as expected (if you know what to
+% except for this it will come out as expected (if you know what to
 % expect).
 %
 % The star form of this command is dedicated to Leslie Lamport, the
@@ -3920,9 +3920,9 @@
 %</trace>
    \@tempskipa#2\relax
    \ifdim \@tempskipa>.5\maxdimen
-     \@latexerr{Suggested\space extra\space height\space
-                (\the\@tempskipa)\space dangerously\space
-                large}\@eha
+     \@latex at error{Suggested\space extra\space height\space
+                   (\the\@tempskipa)\space dangerously\space
+                   large}\@eha
    \else
      \ifdim \vsize<.5\maxdimen
 %<*trace>
@@ -3940,8 +3940,8 @@
        \fi
 %</trace>
      \else
-       \@latexerr{Page\space height\space already\space
-                  too\space large}\@eha
+       \@latex at error{Page\space height\space already\space
+                     too\space large}\@eha
      \fi
    \fi
 }
@@ -3973,7 +3973,7 @@
 % It also enables the use of an extra specifier, {\tt !}, in the
 % location optional argument of a float.  If this is present then,
 % just for this particular float, whenever it is processed by the float
-% mechanism the followinhg are ignored:
+% mechanism the following are ignored:
 %
 % \begin{itemize}
 % \item  all restrictions on the number of floats which can appear;
@@ -4556,7 +4556,7 @@
 %     Yet another is to move the column count register from the multicol
 %     package into the kernel.  This has been done.
 %   \item  Where should the reinserts be put to maximise the
-%     probability that footmotes come out on the correct page?
+%     probability that footnotes come out on the correct page?
 %     Or should we go for as much compatibility as possible (but see
 %     next item)?
 %   \item  Should we continue to support (as much as possible)
@@ -4980,7 +4980,7 @@
 %
 %    At the top of the page |\@fptop| is inserted;
 %    typically this supplies some stretchable whitespace.
-%    At the bottom of the page |\@fpbot| ais inserted.
+%    At the bottom of the page |\@fpbot| is inserted.
 %    Between adjacent floats |\@fpsep| is inserted.
 %
 %    These parameters are used for all floating objects on a

Modified: trunk/Master/texmf-dist/source/latex/base/ltpage.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltpage.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltpage.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -33,7 +33,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltpage.dtx}
-             [2020/07/27 v1.0m LaTeX Kernel (page style setup)]
+             [2020/12/05 v1.0m LaTeX Kernel (page style setup)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltpage.dtx}
@@ -260,7 +260,7 @@
 %      the problem is solved.}
 % \changes{v1.0j}{2000/05/26}{Use \cs{@empty} instead of brace group
 %                             (pr/3203).}
-% \task{???}{mark initialisation solved?}
+% \task{???}{mark initialization solved?}
 %    \begin{macrocode}
 \def\@markright#1#2#3{\@temptokena {#1}%
   \unrestored at protected@xdef\@themark{{\the\@temptokena}{#3}}}

Modified: trunk/Master/texmf-dist/source/latex/base/ltpageno.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltpageno.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltpageno.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -33,7 +33,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltpageno.dtx}
-             [1994/05/19 v1.1a LaTeX Kernel (Page Numbering)]
+             [2020/12/05 v1.1a LaTeX Kernel (Page Numbering)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltpageno.dtx}
@@ -71,7 +71,7 @@
 % assigned by |\newcount|.
 %
 % \DescribeMacro{\pagenumbering}
-% The user sets the pagenumber style with the |\pagenumbering|\marg{foo}
+% The user sets the page number style with the |\pagenumbering|\marg{foo}
 % command, which sets the page counter to 1 and defines |\thepage| to be
 % |\foo|.  For example, |\pagenumbering{roman}| causes pages to be
 % numbered  i, ii, etc.

Modified: trunk/Master/texmf-dist/source/latex/base/ltpar.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltpar.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltpar.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -33,7 +33,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltpar.dtx}
-             [1995/04/29 v1.1c LaTeX Kernel (paragraphs)]
+             [2021/04/13 v1.1c LaTeX Kernel (paragraphs)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltpar.dtx}
@@ -67,11 +67,13 @@
 % |\par| and |\everypar| when ever their function needs to be
 % changed for a long time.
 %
-% \StopEventually{}
+% This file here describes the interfaces that have been in the kernel
+% forever, used to implement the scenarios described below. They
+% remain valid but are now augmented in the next file
+% (\texttt{ltpara.dtx}) to add hooks to paragraphs. At some point we
+% will consolidate the two files further.
 %
-% \subsection{Implementation}
 %
-%
 % There are two situations in which |\par| may be changed:
 %
 % \begin{itemize}
@@ -93,6 +95,12 @@
 %       \end{itemize}
 % \end{itemize}
 %
+%
+% \StopEventually{}
+%
+% \subsection{Implementation}
+%
+%
 % \DescribeMacro{\@setpar}
 % To permit the proper interaction of these two situations, long-term
 % changes are made by the |\@setpar{|\meta{VAL}|}| command.

Added: trunk/Master/texmf-dist/source/latex/base/ltpara.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltpara.dtx	                        (rev 0)
+++ trunk/Master/texmf-dist/source/latex/base/ltpara.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -0,0 +1,1223 @@
+% \iffalse meta-comment
+%
+%% File: ltpara.dtx (C) Copyright 2020-2021
+%       Frank Mittelbach, LaTeX Team
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version.  The latest version
+% of this license is in the file
+%
+%    https://www.latex-project.org/lppl.txt
+%
+%
+%%% From File: ltpara.dtx
+%
+%    \begin{macrocode}
+\def\ltparaversion{v1.0g}
+\def\ltparadate{2021/05/27}
+%    \end{macrocode}
+%<*driver>
+\documentclass{l3doc}
+
+%\usepackage{ltpara}
+
+% Fixing footnotes in  functions and variables: this should be in l3doc!
+\newcommand\fixfootnote[2]{\footnotemark
+  \AddToHookNext{env/#1/after}{\footnotetext{#2}}}
+\AddToHook{env/function/begin}{\def\footnote{\fixfootnote{function}}}
+\AddToHook{env/variable/begin}{\def\footnote{\fixfootnote{variable}}}
+
+\EnableCrossrefs
+\CodelineIndex
+\begin{document}
+  \DocInput{ltpara.dtx}
+\end{document}
+%</driver>
+%
+% \fi
+%
+% \providecommand\hook[1]{\texttt{#1}}
+% \providecommand\env[1]{\texttt{#1}}
+%
+%
+%
+% \title{The \texttt{ltpara.dtx} code\thanks{This file has version
+%    \ltparaversion\ dated \ltparadate, \copyright\ \LaTeX\
+%    Project.}}
+% \author{Frank Mittelbach}
+%
+% \maketitle
+%
+%
+% \begin{abstract}
+%    This code defines four special kernel hooks to support paragraph
+%    tagging as well as four public hooks which can be occasionally
+%    useful.
+% \end{abstract}
+%
+% \tableofcontents
+%
+%
+% \section{Introduction}
+%
+%
+%    The building of paragraphs in the \TeX{} engine(s) has a number
+%    of peculiarities that makes it on one hand fairly flexible but on
+%    the other hand somewhat awkward to control or reliably to extend.
+%    Thus to better understand the code below we start with a brief introduction
+%    of the mechanism; for more details refer to the
+%    \TeX{}book~\cite[chap.~14]{texbook} (for the full truth you may
+%    even have to study the program code).
+%
+% \subsection{The default processing done by the engine}
+%
+%    \TeX{} automatically starts building a paragraph when it is
+%    currently in vertical mode and encounters anything that can only
+%    live in horizontal mode. Most often this is a character, but
+%    there are also many commands that can be used only in horizontal mode.
+%    If any of them is encountered, \TeX{} will immediately back up
+%    (i.e., the character or command is read later again), adds a
+%    \cs{parskip} glue to the current vertical list unless the list is
+%    empty, switches to
+%    horizontal mode, starts its special \enquote{start of paragraph
+%    processing} and only then rereads the character or command that
+%    caused the mode change.\footnote{Already not quite true: the
+%    command \cs{noindent} starts the paragraph but influences the
+%    special processing by suppressing the paragraph indentation box
+%    normally inserted by it.}
+%
+%    This \enquote{start of paragraph
+%    processing} first adds an empty box at the start of the
+%    horizontal list of width \cs{parindent} (which represents the
+%    paragraph indentation) unless the paragraph was started with
+%    \cs{noindent} in which case no such box is
+%    added\footnote{That's a bit different from placing a zero-sized
+%    box!}. It then reads and processes all tokens stored in the
+%    special engine token register \cs{everypar}. After that it reads
+%    and processes whatever has caused the paragraph to start.
+%
+%    Thus out of the box, \TeX{} offers the possibility to put some
+%    special code into \cs{everypar} to gain control at (more or less)
+%    the start of the paragraph. For example, in LaTeX{} and a number
+%    of packages,  special code like the following is sometimes used:
+%\begin{verbatim}
+%  \everypar{{\setbox\z@\lastbox}\everypar{} ...}
+%\end{verbatim}
+%    This removes the paragraph indentation box again  (that was already
+%    placed by \TeX), then resets \cs{everypar} so that it doesn't do
+%    anything on the next paragraph start and then does whatever it
+%    wants to do, e.g., in an \cs{item} of a list it will typeset the label in
+%    front of the paragraph text.
+%    However, there is only one such \cs{everypar} token register and
+%    if different packages and/or the kernel all attempt to add their
+%    own code here, coordination is very difficult if not impossible.
+%
+%    The process when the paragraph ends has different mechanisms and interfaces.
+%    A paragraph ends when the engine  primitive \cs{par} is called
+%    while \TeX{} is in unrestricted horizontal mode, i.e., is
+%    building a paragraph. At other times this primitive does nothing
+%    or generates as an error depending on the mode \TeX{} is in,
+%    e.g., the \cs{par} in
+%    \verb=\hbox{a\par b}= is ignored, but \verb=$a\par b$= would complain.
+%
+%    If this primitive ends the paragraph it does some special
+%    \enquote{end of horizontal list} processing, then calls \TeX{} paragraph
+%    builder that breaks the horizontal list into lines then these
+%    lines are added as boxes to the enclosing vertical list and
+%    \TeX{} returns to vertical mode.
+%
+%    This \cs{par} command can be given explicitly, but there are also
+%    situations in which \TeX{} is generating it on the fly. Most
+%    often this happens when \TeX\ encounters a blank line which is
+%    automatically changed to a \cs{par} command which is then
+%    executed. The other possibility is that \TeX{} encounters a
+%    command which is incompatible with horizontal processing, e.g.,
+%    \cs{vskip} (a request for adding vertical space). In such case it
+%    silently backs up, and inserts a \cs{par} in the hope that this
+%    gets it out of horizontal mode and makes the offending command
+%    acceptable.
+
+%    The important point to note here is that \TeX{} really inserts
+%    the command \cs{par} which can be redefined. Thus, it may not have
+%    its original \enquote{primitive} meaning and therefore may not end the
+%    horizontal list and call the paragraph builder. This approach
+%    offers some flexibility but also allows you  to easily produce a
+%    \TeX{} document that loops forever, for example, the simple line
+%\begin{verbatim}
+%   A \let\par\relax \vskip
+%\end{verbatim}
+%    will start a horizontal list at \texttt{A}, redefines \cs{par},
+%    then sees \cs{vskip} and inserts \cs{par} to end the
+%    paragraph. But this now only runs \cs{relax} so nothing changes
+%    and \cs{vskip} is read again, issues a \cs{par} which \ldots. In
+%    short, it takes a plain \TeX{} document with five tokens to run
+%    forever (as not even memory is consumed and therefore eventually
+%    exhausted).
+%
+%    There are no other ways than changing \cs{par} to gain control at
+%    the end of a paragraph, i.e., there is no token list like
+%    \cs{everypar} that is inserted, i.e., the only way to change the
+%    default behavior is to modify the action that \cs{par} executes
+%    with similar issues as outlined before: different processes need
+%    to ensure that they do not overwrite their modifications or
+%    worse, think that the \cs{par} in front of them is the engine
+%    primitive while in fact it has already been changed by other
+%    code.
+%
+%
+%    To make matters slightly worse there are a few places where
+%    \TeX{} handles the situation differently (most likely for speed
+%    reasons back when computers were much slower). If \TeX{} finds
+%    itself in unrestricted horizontal mode at the end of building a
+%    vertical box (or an \cs{insert}, \cs{vadjust} or at the end of
+%    executing the output routine code), it will finish the horizontal
+%    list not by issuing a \cs{par} command (which would be consistent
+%    with all other places, but by simply executing the primitive version
+%    of \cs{par} regardless of the definition that \cs{par} has at the
+%    time.
+%
+%    Thus, if you have carefully crafted a redefined \cs{par} to execute
+%    some special actions at the end of a paragraph and you write
+%    something like
+%\begin{verbatim}
+%   \vbox{Some paragraph ... text.}
+%\end{verbatim}
+%    you will find that your code has never run for the last paragraph
+%    in that box. \LaTeX{} avoids this problem, by making sure that
+%    all its boxes (such as \cs{parbox} or the \env{minipage}
+%    environment, etc.) all internally add an explicit \cs{par} at the
+%    end so that such code is run and \TeX{} finds itself in vertical
+%    mode already without the need to start up the paragraph builder
+%    internally. But, of course, this only works for boxes under direct
+%    control of the \LaTeX{} kernel, if some package uses low-level
+%    \cs{vbox}es without adding this precaution the \TeX{}
+%    optimization kicks in and no special \cs{par} code is executed.
+%
+%    And there is another optimization that is painful: if a paragraph
+%    is interrupted by a mathematical display, e.g., \verb=\[...\]= in
+%    \LaTeX{} or \verb=$$...$$= in plain \TeX{}, then \TeX{} will
+%    resume horizontal mode afterward, i.e., build a new horizontal
+%    list (without inserting an indentation box or \cs{everypar} at
+%    that point). However, if that list immediately ends with an
+%    explicit or implicit \cs{par} then \TeX{} will simply throw away
+%    this \enquote{null} paragraph and not do its usual \enquote{end
+%    of horizontal list} processing, so this special case need to be
+%    accounted for when introducing some extended processing.
+%
+%
+%
+% \section{The new mechanism implemented for \LaTeX{}}
+%
+%    To improve the situation (and also to support automatic tagging
+%    of PDF documents) we now offer public as well as private hooks at
+%    the start and end of the paragraph processing. The public hooks
+%    can be used by packages (or by the user in the preamble or
+%    within the document) and using the hook mechanisms it is possible
+%    to reorder or arrange code from different packages in a way that
+%    it can safely coexist.
+%
+%    To make that happen we have to make use of the basic
+%    functionality that is offered by \TeX{}, e.g., we install
+%    special code inside \cs{everypar} to provide hooks at the
+%    beginning and we redefine \cs{par} to do some special processing
+%    when appropriate to install hooks at the end of the paragraph.
+%
+%    In order to make this work, we have to ensure that package use of
+%    \cs{everypar} is not overwriting our code. This is done through a
+%    trick: we basically hide the real \cs{everypar} from the packages
+%    and offer them a new token register (with the same name). So if
+%    they install their own code it doesn't overwrite ours. Our code
+%    then inserts the new \cs{everypar} at the right place inside the
+%    process so that it looks as if it was the primitive
+%    \cs{everypar}.\footnote{Ideally, \cs{everypar} wouldn't be used
+%    at all by packages and instead they would simply write their code
+%    into the hooks now offered by the kernel. However, while this is
+%    the longterm goal and clearly an improvement (because then the
+%    packages do no longer need to worry about getting their code
+%    overwritten or needing to account for already existing code in
+%    \cs{everypar}), this will not happen overnight. For that reason
+%    support for this legacy method is retained.}
+%
+%    At the end of the paragraph it would be great if we could use a
+%    similar trick. However, due to the fact that \TeX{} inserts the
+%    token \cs{par} (that doesn't have a defined meaning) we can't hide
+%    \enquote{the real thing\textsuperscript{TM}} and offer the
+%    package an indistinguishable alternate.
+%
+%    Fortunately, \LaTeX{} has already redefined \cs{par} for its own
+%    purposes. As a result there aren't many packages that attempt to
+%    change \cs{par}, because without a lot of extra care that would
+%    fail miserably. But bottom line, if you load a package that
+%    alters \cs{par} then the end of paragraph hooks are most likely
+%    not executing while that redefinition is
+%    active.\footnote{Similarly to the \cs{everypar} situation, the
+%    remedy is that such packages stop doing this and instead add
+%    their alterations into the paragraph hooks now provided.}
+%
+%
+%
+% \subsection{The provided hooks}
+%
+%
+%  \begin{variable}{para/before,
+%                   para/begin,
+%                   para/end,
+%                   para/after
+%                 }
+%    The following four public hooks are defined and executed for
+%    each paragraph:
+%    \begin{description}
+%
+%    \item[\hook{para/before}]
+%
+%      This hook is executed after the kernel hook
+%      \cs{@kernel at before@para at before} (discussed below) in vertical
+%      mode immediately after \TeX{} has contributed \cs{parskip} to
+%      the vertical list and before the actual paragraph processing in
+%      horizontal mode starts.
+%
+%      This hook should either not produce any typeset material or add
+%      only vertical material. If it starts a paragraph an error is
+%      generated. The reason is that we are in the starting process of
+%      processing a paragraph and so this would lead to endless
+%      recursion.\footnote{One could allow it but only if the newly
+%      started paragraph is processed without any hooks. Furthermore
+%      correct spacing would be a bit of a nightmare so for now this
+%      is forbidden.}
+%
+%    \end{description}
+%  \end{variable}
+%
+%    \vspace{-\bigskipamount}
+%
+%    \begin{description}
+%
+%    \item[\hook{para/begin}]
+%
+%      This hook is executed after the kernel hook
+%      \cs{@kernel at before@para at begin} (discussed below) in horizontal
+%      mode immediately before the indentation box is placed (if there
+%      is any, i.e., if the paragraph hasn't been started with
+%      \cs{noindent}).
+%
+%      The indentation box to be typeset is available to the hook as
+%      \cs{IndentBox} and its automatic placement (after the hook is
+%      executed) can be prevented through \cs{OmitIndent}.
+%      More precisely \cs{OmitIndent} voids the box.
+%
+%      The indentation box is then typeset directly
+%      after the hook execution by something equivalent to
+%      \cs{box}\cs{IndentBox} followed by the current content of
+%      the token register \cs{everypar} that it is available to the
+%      kernel or to packages (that run some legacy code).
+%
+%      One has to be careful not to add any code to the hook that
+%      starts its own paragraph (e.g., by adding a \cs{parbox} or a
+%      \cs{marginpar} inside) because that would call the hook inside
+%      again (as a new paragraph is started there) and thus lead to an
+%      endless recursion ending only after exhausting the available
+%      memory. This can only be done by making sure that is not
+%      executed for the inner paragraphs (or at least not recursively
+%      forever).
+%
+%
+%    \item[\hook{para/end}]
+%
+%      This hook is executed at the end of a paragraph when \TeX{} is
+%      ready to return to vertical mode and after it has removed the
+%      last horizontal glue (but not kern) placed on the horizontal
+%      list. The code is still executed in horizontal mode so it is
+%      possible to add further horizontal material at this point, but
+%      it should not alter the mode (even a temporary exit from
+%      horizontal mode would create chaos---any attempt will cause an
+%      error message)! After the hook has ended the kernel hook
+%      \cs{@kernel at after@para at end} is executed and then \TeX{} returns to
+%      vertical mode.
+%
+%      The hook is offered as public hook, but because of the
+%      requirement to stay within horizontal mode one needs to be
+%      careful in what is placed into the hook.\footnote{Maybe we
+%      should guard against that, but it would be rather tricky to
+%      implement as mode changes can happen across group boundaries so
+%      one would need to keep a private stack just for that. Well,
+%      something to ponder.}
+%
+%      This hook is implemented as a reversed hook.
+%
+%    \item[\hook{para/after}]
+%
+%      This hook is executed directly after \TeX{} has returned to
+%      vertical mode and after any material that migrated out of the
+%      horizontal list (e.g., from a \cs{vadjust}) has processed.
+%
+%      This hook should either not produce any typeset material or add
+%      only vertical material.
+%      However, for this hook starting a new paragraph is not a
+%      disaster so that it isn't prevented.
+%
+%      This hook is implemented as a reversed hook.
+%
+%      Once that hook code has been processed the kernel hook
+%      \cs{@kernel at after@para at after} is executed as the final action
+%      of the paragraph processing.
+%
+%    \end{description}
+%
+%  \begin{variable}{\@kernel at before@para at before,
+%                   \@kernel at after@para at after,
+%                    \@kernel at before@para at begin,
+%                   \@kernel at after@para at end,
+%                  }
+%    As already mentioned above there are also four kernel hooks that
+%    are executed at the start and end of the processing.
+%    \begin{description}
+%
+%    \item[\cs{@kernel at before@para at before}]
+%       For future extensions, not currently used by the kernel.
+%
+%
+%    \item[\cs{@kernel at after@para at after}]
+%       For future extensions, not currently used by the kernel.
+%
+%
+%    \item[\cs{@kernel at before@para at begin}]
+%
+%      Used by the kernel to implement tagging. This hook is executed
+%      at the very beginning of a paragraph after \TeX{} has switched to
+%      horizontal mode but before any indentation box got added or any
+%      \cs{everypar} was run.
+%
+%      It should not generate typeset material that could alter the
+%      position.  Note that it should never leave hmode, otherwise you
+%      will end with a loop! We could guard against this, but since it
+%      is an internal kernel hook that shouldn't be touched this isn't
+%      checked.
+%    \end{description}
+%  \end{variable}
+%
+%    \vspace{-\bigskipamount}
+%
+%    \begin{description}
+%
+%    \item[\cs{@kernel at after@para at end}]
+%
+%      Used by the kernel to implement tagging. It is executed
+%      directly after the public \hook{para/end} hook. After it there
+%      is a quick check that we are still in horizontal mode, i.e.,
+%      that the public hook has not mistakenly ended horizontal mode
+%      prematurely (this is an incomplete check just testing the mode
+%      and could perhaps be improved (at the cost of speed)).
+%
+%    \end{description}
+%
+%
+% \subsection{Altered and newly provided commands}
+%
+% \begin{function}{\par,\endgraf,\para_end:}
+%    An explicit request for ending a paragraph is known in plain
+%    \TeX{} under the name \cs{endgraf} where it simply calls the
+%    paragraph primitive (regardless of what \cs{par} may have as its
+%    current definition). In \LaTeX{} \cs{endgraf} with that behavior
+%    was also made available.
+%
+%    With the new paragraph handling in \LaTeX{}, ending a paragraph
+%    means a bit more than just calling the engine's paragraph
+%    builder: the process also has to add any hook code for the end of
+%    a paragraph. Thus
+%    \cs{endgraf} was changed to provide this additional functionality
+%    (and so by extension \cs{par} subject to its current meaning).
+%
+%    The \pkg{expl3} name for the functionality is \cs{para_end:}.
+% \end{function}
+%
+% \begin{quote}
+%    \textbf{Note:} \em The next two commands are still under
+%    discussion and may slightly change their semantics (as described
+%    in the document) and/or their names between now and the 2021
+%    Spring release!
+% \end{quote}
+%
+% \begin{function}{\OmitIndent,\para_omit_indent:}
+%    Inside the \hook{para/begin} hook one can use this command to
+%    suppress the indentation box at the start of the
+%    paragraph. (Technically it is possible to use this command
+%    outside the hook as well, but this should not be relied upon.)
+%    The box itself remains available for use.
+%
+%    The \pkg{expl3} name for the function is \cs{para_omit_indent:}.
+% \end{function}
+%
+% \begin{variable}{\IndentBox,\g_para_indent_box}
+%    The box register holding the indentation box for the paragraph is
+%    available for inspection (or changes) inside hooks. It remains
+%    available even if the \cs{OmitIndent} command was
+%    used; in that case it  will just not be automatically placed.
+%
+%    The \pkg{expl3} name for the box register is \cs{g_para_indent_box}.
+% \end{variable}
+%
+%
+% \begin{function}{\RawIndent,\para_raw_indent:,
+%                  \RawNoindent,\para_raw_noindent:,
+%                  \RawParEnd,\para_raw_end:}
+% \begin{syntax}
+%   \cs{RawIndent}   \textit{hmode material} \cs{RawParEnd}
+%   \cs{RawNoindent} \textit{hmode material} \cs{RawParEnd}
+% \end{syntax}
+%
+%    The commands \cs{RawIndent} and \cs{RawNoindent} are not meant
+%    for normal paragraph building (where the result is a textual
+%    paragraph in the the traditional meaning of the word), but for
+%    special cases where \TeX{}'s low-level algorithm is used to
+%    achieve special effects, but where the result is not a
+%    \enquote{paragraph}.
+%
+%    They are called \enquote{raw}, because they bypass \LaTeX{}'s
+%    hook mechanism for paragraphs and simply invoke the low-level
+%    \TeX{} algorithm.  I.e., they are like the original \TeX{}
+%    primitives \cs{indent} and \cs{noindent} (that is they execute no
+%    hooks other than \cs{everypar}) except that they can only be used
+%    in vertical mode and generate an error if found elsewhere.
+%
+%    To avoid issues a paragraph started by them should always be
+%    ended by \cs{RawParEnd}\footnote{Technical note for those who
+%    know their \textit{\TeX book\/}: the \cs{RawParEnd} comand
+%    invokes the original \TeX{} engine definition of \cs{par} that
+%    (soley) triggers the paragraph builder in \TeX{} when found
+%    inside unrestricted horizontal mode and does nothing in other
+%    processing modes.}
+%    and not by \cs{par} (or a blank line), because the latter will execute
+%    hooks which then have no counterpart at the beginning of the
+%    paragraph. It is the responsibility of the programmer to make
+%    sure that they are properly paired. This also means that one
+%    should not put arbitrary user content between these commands if
+%    that content could contain stray \cs{par}s.
+%
+%    The \pkg{expl3} names for the functions are
+%    \cs{para_raw_indent:}, \cs{para_raw_indent:} and
+%    \cs{para_raw_end:}.
+% \end{function}
+%
+%
+%
+% \subsection{Examples}
+%
+%    None of the examples in this section are meant for real use as
+%    they are far too simpleminded  but they should give some ideas of
+%    what could be possible if a bit more care is applied.
+%
+% \subsubsection{Testing the mechanism}
+%
+%    The idea is to output for each paragraph encountered some
+%    information: a paragraph sequence number, a level number in roman
+%    numerals, the environment in which this paragraph appears, and
+%    the line number where the start or end of the paragraph is, e.g.,
+%    something like
+%\begin{verbatim}
+%  PARA: 1-i start (document env. on input line 38)
+%  PARA: 1-i end   (document env. on input line 38)
+%  PARA: 2-i start (document env. on input line 40)
+%  PARA: 3-ii start (minipage env. on input line 40)
+%  PARA: 3-ii end   (minipage env. on input line 40)
+%  PARA: 2-i end   (document env. on input line 41)
+%\end{verbatim}
+%    As you can see paragraph 2 starts on line 40 and ends on 41 and
+%    inside a minipage started paragraph 3 (start and end on line 40).
+%    If you run this on some document you will find that \LaTeX{}
+%    considers more things \enquote{a paragraph} than you have
+%    probably thought.
+%
+%    This was generated by the following hook code:
+%\begin{verbatim}
+%  \newcounter{paracnt}         % sequence counter
+%  \newcounter{paralevel}       % level counter
+%\end{verbatim}
+%
+%    To support paragraph nesting we need to maintain a stack of the
+%    sequence numbers. This is most easily done using \pkg{expl3}
+%    functions, so we switch over. This is not a very general
+%    implementation, just enough for what we need and a bit of
+%    \LaTeXe{} thrown in as well. When popping the result gets stored
+%    in \cs{paracntvalue} and the \cs{ERROR}  should never happen
+%    because it means we have tried to pop from an empty stack.
+%\begin{verbatim}
+%  \ExplSyntaxOn
+%  \seq_new:N \g_para_seq
+%  \cs_new:Npn \ParaPush
+%    {\seq_gpush:No  \g_para_seq {\the\value{paracnt}}}
+%  \cs_new:Npn \ParaPop  {\seq_gpop:NNF  \g_para_seq \paracntvalue \ERROR }
+%  \ExplSyntaxOff
+%\end{verbatim}
+%    At the start of the paragraph increment both sequence counter and
+%    level and also save the then current sequence number on our stack.
+%\begin{verbatim}
+%  \AddToHook{para/begin}{%
+%    \stepcounter{paracnt}\stepcounter{paralevel}%
+%    \ParaPush
+%\end{verbatim}
+%    To display the sequence number we \cs{typeout} the current
+%    sequence and level number. The command \cs{@currenvir} gives us
+%    the current environment and \cs{on at line} produces a space and
+%    the current input line number.
+%\begin{verbatim}
+%    \typeout{PARA: \arabic{paracnt}-\roman{paralevel} start
+%      (\@currenvir\space env.\on at line)}%
+%\end{verbatim}
+%    We also typeset the sequence number as a tiny red number in a box
+%    that takes up no horizontal space. This helps us seeing where
+%    \LaTeX{} sees the start and end of the paragraphs in the
+%    document.
+%\begin{verbatim}
+%    \llap{\color{red}\tiny\arabic{paracnt}\ }%
+%  }
+%\end{verbatim}
+%
+%   At the end of the paragraph we display sequence number and
+%    level again. The level counter has the correct value but we need
+%    to retrieve the right sequence value by popping it off the stack
+%    after which it is available in \cs{paracntvalue} the way we have
+%    set this up above.
+%\begin{verbatim}
+%  \AddToHook{para/end}{%
+%    \ParaPop
+%    \typeout{PARA: \paracntvalue-\roman{paralevel} end \space\space
+%      (\@currenvir\space env.\on at line)}%
+%\end{verbatim}
+%    We also typeset again a tiny red number with that value, this
+%    time sticking out to the right.\footnote{Note that this can alter
+%    the document pagination, because a paragraph ending in a display
+%    (e.g., an equation) will get an extra line---in that case our tiny number
+%    has an effect even though it doesn't take up any space, because
+%    it paragraph is no longer empty and thus isn't dropped!}
+%    We also decrement the level counter since our level has finished.
+%\begin{verbatim}
+%    \rlap{\color{red}\tiny\ \paracntvalue}%
+%    \addtocounter{paralevel}{-1}%
+%  }
+%  \makeatother
+%\end{verbatim}
+%
+%
+%
+% \subsubsection{Mark the first paragraph of each \env{itemize}}
+%
+%    The code for this is rather simple. We apply  hook code that is
+%    executed only once inside a hook that is executed at the begin of
+%    each \env{itemize}. We explicitly change the color back and
+%    forth so that we don't introduce grouping around the paragraph.
+%\begin{verbatim}
+%  \AddToHook{env/itemize/begin}{%
+%    \AddToHookNext{para/begin}{\color{blue}}%
+%    \AddToHookNext{para/end}{\color{black}}%
+%  }
+%\end{verbatim}
+%    As a result the first paragraph of each \env{itemize} will appear
+%    in blue.
+%
+%
+%
+% \subsection{Some technical notes}
+%
+%    The code tries hard to be transparent for package code, but of
+%    course any change means that there is a potential for breaking
+%    other code. So in section we collect a few cases that may be of
+%    importance if low-level code is dealing with paragraphs that are
+%    now behaving slightly differently. The notes are from issues we
+%    observed and will probably grow over time.
+%
+% \subsubsection{Glue items between paragraphs (found with \pkg{fancypar})}
+%
+%    In the past \LaTeX{} placed two glue items between two
+%    consecutive paragraph, e.g.,
+%\begin{verbatim}
+%   text1 \par text2 \par
+%\end{verbatim}
+%   would show something like
+%\begin{verbatim}
+% \glue(\parskip) 0.0 plus 1.0
+% \glue(\baselineskip) 5.16669
+%\end{verbatim}
+%   but now there is anothe \cs{parskip} glue (that is always 0pt):
+%\begin{verbatim}
+% \glue(\parskip) 0.0 plus 1.0
+% \glue(\parskip) 0.0
+% \glue(\baselineskip) 5.16669
+%\end{verbatim}
+%    The reason is that we generate a \enquote{fake}'' paragraph to
+%    gain control and safely add the early hooks, but this generates
+%    an additional glue item. That item doesn't contribute anything
+%    vertically but ifsomebody writes code the unravels a constructed
+%    list using \cs{lastbox}, \cs{unskip} and \cs{unpenalty} then the
+%    code has to remove one additional glue item  or else will fail.
+
+%
+% ^^A \subsubsection{}
+%
+%
+%
+% ^^A \subsubsection{}
+%
+%
+%
+%
+%
+%
+% \StopEventually{\setlength\IndexMin{200pt}  \PrintIndex  }
+%
+%
+% \section{The Implementation}
+%
+%    \begin{macrocode}
+%<@@=para>
+%    \end{macrocode}
+%
+% \changes{v1.0g}{2021/05/24}{Use \cs{msg_...} instead of \cs{__kernel_msg...}}
+%
+%
+%    \begin{macrocode}
+%<*2ekernel|latexrelease>
+\ExplSyntaxOn
+%<latexrelease>\NewModuleRelease{2021/06/01}{ltpara}
+%<latexrelease>                 {Paragraph~handling~and~hooks}
+%    \end{macrocode}
+%
+%
+%
+% \subsection{Providing hooks for paragraphs}
+%
+%
+%  \begin{macro}{para/before,para/after,para/begin,para/end}
+%    The public hooks. They are implemented as a paired set of hooks.
+%    \begin{macrocode}
+\hook_new_pair:nn{para/before}{para/after}
+\hook_new_pair:nn{para/begin}{para/end}
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%
+%  \begin{macro}{\@kernel at before@para at before,
+%                \@kernel at after@para at after,
+%                \@kernel at before@para at begin,
+%                \@kernel at after@para at end}
+%    The corresponding kernel hooks (for tagging and future extensions).
+%    \begin{macrocode}
+\let \@kernel at before@para at before \@empty
+\let \@kernel at before@para at begin  \@empty
+\let \@kernel at after@para at end     \@empty
+\let \@kernel at after@para at after   \@empty
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%
+%
+%
+%  \begin{macro}{\g_@@_standard_everypar_tl}
+%    Whenever \TeX{} starts a paragraph it inserts first an
+%    indentation box and then executes the tokens stored in
+%    \cs{tex_everypar:D} (known to \LaTeX{} as \cs{everypar}). We
+%    alter this behavior slightly here, so that hooks are added
+%    into the right place. Otherwise the process change remains
+%    transparent to any legacy code for this space.
+%
+%    We keep the standard code to be used by \cs{tex_everypar:D} in a
+%    separate token list because we have to switch back and forth
+%    for error recovery and so altering \cs{tex_everypar:D}  all the
+%    time should be a tiny bit faster.
+%    \begin{macrocode}
+\tl_new:N \g_@@_standard_everypar_tl
+%    \end{macrocode}
+%    Here is now its definition:
+%    \begin{macrocode}
+\tl_gset:Nn \g_@@_standard_everypar_tl {
+%    \end{macrocode}
+%    First we remove the indentation box and store it in
+%    \cs{g_para_indent_box}. If there was none because the paragraph
+%    was started by \cs{noindent} the box register will be void.
+%    \begin{macrocode}
+  \box_gset_to_last:N \g_para_indent_box
+%    \end{macrocode}
+%
+%    This will make the newly started horizontal list empty, so if we
+%    stop it now and return to vertical mode it will be dropped by
+%    \TeX{}. We do that but inside a group so that any \cs{parshape}
+%    settings will not get lost as we need them for later.
+%    \begin{macrocode}
+  \group_begin:
+    \tex_par:D
+  \group_end:
+%    \end{macrocode}
+%    We then change \cs{tex_everypar:D} to generate an error so that
+%    we can detect and report if the \hook{para/before} hook illegally
+%    changed out of vmode.
+%    \begin{macrocode}
+  \tex_everypar:D { \msg_error:nnnn { hooks }{ para-mode }{before}{vertical} }
+  \@kernel at before@para at before
+  \hook_use:n {para/before}
+%    \end{macrocode}
+%    Assuming the hooks have been well behaved it is time to return to
+%    horizontal mode and start the paragraph in earnest. We already
+%    have the indentation box saved away so we now have to restart the
+%    paragraph with an empty \cs{tex_everypar:D} and with
+%    \cs{tex_noindent:D}. And we need to make sure not to get another
+%    \cs{parskip} or rather (since we can't prevent that) that it is
+%    of zero size.
+%    \begin{macrocode}
+  \group_begin:
+    \tex_everypar:D {}
+    \skip_zero:N \tex_parskip:D
+    \tex_noindent:D
+  \group_end:
+%    \end{macrocode}
+%    That brings us back to the start of the horizontal list but we
+%    need to change \cs{tex_everypar:D} back to its normal content in
+%    case there are nested paragraphs coming up.
+%    \begin{macrocode}
+  \tex_everypar:D{\g_@@_standard_everypar_tl}
+%    \end{macrocode}
+%
+%    This is followed by executing the kernel and the public hook. The
+%    kernel hook is there to enable tagging.
+%    \begin{macrocode}
+  \@kernel at before@para at begin
+  \hook_use:n {para/begin}
+%    \end{macrocode}
+%    If we aren't in horizontal mode any longer the hooks above misbehaved.
+%    \begin{macrocode}
+  \if_mode_horizontal: \else:
+    \msg_error:nnnn { hooks }{ para-mode }{begin}{vertical} \fi:
+%    \end{macrocode}
+%    Finally we reinsert the indentation box (unless suppressed) and
+%    then call \cs{everypar} the way legacy \LaTeX\ code expects it.
+%
+%    However, adding the public \cs{everypar} is a bit tricky (see below) so
+%    we add that later, and indirectly.
+%    \begin{macrocode}
+  \@@_handle_indent:
+% \the \everypar           % <--- done differently below
+}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}[int]{\tex_everypar:D}
+%    \cs{tex_everypar:D} then only has to execute
+%    \cs{g_@@_standard_everypar_tl} by default.
+%    \begin{macrocode}
+\tex_everypar:D{\g_@@_standard_everypar_tl}
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%
+%  \begin{macro}[int]{\everypar}
+%
+%    Tokens inserted at the beginning of the paragraph are placed into
+%    \cs{everypar} inside legacy \LaTeX{} code, e.g., by the list
+%    environments or by headings to handle \cs{clubpenalty}, etc. Now
+%    this isn't any longer the primitive but simply a toks register
+%    used in the code above but to legacy \LaTeX{} code that is
+%    transparent.
+%
+%    There is, however, a problem: a handful packages use exactly the
+%    same trick and replace the primitive with a token register and
+%    call the token register inside the renamed primitive. That is
+%    they assume that \cs{everypar} is the primitive and that it will
+%    still be called at the start of the paragraph even if renamed.
+%
+%    But if we have already replaced it by a token register then all
+%    they do is to give that token register a new name. Thus our code
+%    in \cs{tex_everypar:D} would call \cs{everypar} (which is their
+%    now token register) and the code that they added ends up in our
+%    token register which is then never used at all. A bit mind
+%    boggling I guess.
+%
+%    So what we have to do is not to call the token register
+%    \cs{everypar} by its name inside \cs{tex_everypar:D} but by using
+%    its actual register number.
+%    \begin{macrocode}
+\newtoks \everypar
+%    \end{macrocode}
+%
+%    After we have allocated a new toks register with the name
+%    \cs{everypar} the actual register number is available (briefly)
+%    inside \cs{allocationnumber}. So instead of \cs{the}\cs{everypar}
+%    we have to put \cs{the}\cs{toks}\meta{allocated number} at the end of
+%    \cs{tex_everypar:D}.
+%
+%    So what remains doing is to append a few tokens to the token list
+%    \cs{g_@@_standard_everypar_tl} which we do now. We use \texttt{x}
+%    expansion here to get the value of \cs{allocationnumber} in, all
+%    the other tokens should not be expanded at this point.
+
+%    One important point here is to terminate the register allocation
+%    number with a real space. This space will get swallowed up when
+%    the number is read. Anything else, such as \cs{scan_stop:} would
+%    remain in the input and that would mean that it would interfere
+%    with \cs{everypar} code that attempts to scan ahead to see how
+%    the paragraph text starts.
+%    \begin{macrocode}
+\tl_gput_right:Nx \g_@@_standard_everypar_tl {
+    \exp_not:N \the
+    \exp_not:N \toks
+    \the \allocationnumber
+    \c_space_tl
+}
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%  \begin{macro}{\g_para_indent_box}
+%    For managing the indentation we need to provide a public
+%    accessible box register
+%    \begin{macrocode}
+\box_new:N \g_para_indent_box
+%    \end{macrocode}
+%  \end{macro}
+
+%  \begin{macro}{\@@_handle_indent:}
+%    Adding (typesetting) the indent box is straight forward.
+%    If it was emptied before it does nothing.
+%    \begin{macrocode}
+\cs_new:Npn \@@_handle_indent: {
+  \box_use_drop:N \g_para_indent_box
+}
+%    \end{macrocode}
+%     The declaration \cs{para_omit_indent:} (or
+%    \cs{OmitIndent}) changes that to do nothing.
+%    \begin{macrocode}
+\cs_new:Npn \para_omit_indent: {
+  \box_gclear:N \g_para_indent_box
+}
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%  \begin{macro}{\IndentBox,\OmitIndent}
+%    The \LaTeXe{} names for the indentation box and for suppressing it
+%    for use in the \hook{para/begin} hook.
+%    \begin{macrocode}
+\cs_set_eq:NN \IndentBox \g_para_indent_box
+\cs_set_eq:NN \OmitIndent \para_omit_indent:
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%
+%
+%
+%
+%  \begin{macro}{\para_end:}
+%    Adding hooks to the end of a paragraph is similar but here we
+%    need to alter the command that is used by \TeX{} to end horizontal
+%    mode and return to vertical mode, i.e., \cs{par}.
+%
+%    This is a bit more complicated as this command can appear anywhere
+%    either explicitly or implicitly added by \TeX{} in certain
+%    situations:
+%    \begin{itemize}
+%    \item
+%      when using \cs{par} in the code or the document
+%    \item
+%      when using a blank line (which is converted to \cs{par})
+%    \item
+%      when \TeX{} finds any commands incompatible with horizontal
+%      mode it issues a \cs{par} and then rereads the command.
+%    \end{itemize}
+%
+%    Unfortunately, \TeX{} has some (these days) unnecessary
+%    optimization: if a \cs{vbox} ends and \TeX{} is still in
+%    horizontal mode it simply exercises the paragraph builder instead
+%    of issuing a \cs{par}. It is therefore necessary for \LaTeX{} to
+%    ensure that this case doesn't happen and all boxes internally
+%    have a \cs{par} command at their end.
+%
+%    This \cs{par} may or may not run the ``par primitive'' (which is
+%    always available as \cs{tex_par:D} in \pkg{expl3}); it is
+%    permissible to have a changed meaning and it is in fact changed
+%    by \LaTeX{} in various ways at various points inside
+%    \texttt{latex.ltx}.  For this \LaTeXe{} code has the following
+%    conventions: \cs{@@@@par} and \cs{endgraf} both refer to the
+%    default meaning (in the past this was the initex primitive) while
+%    \cs{par} is the current meaning which may does something else.
+%
+%
+%    We are now going to change this default meaning to run
+%    \cs{para_end:} instead, which ultimately executes the initex
+%    primitive but additionally adds our hooks when appropriate.
+%    This way the change is again transparent to the legacy \LaTeXe{}
+%    code.
+%
+%    In most cases \cs{para_end:} should behave exactly like the
+%    primitive and we achieve this by simply expanding it to the
+%    primitive which is available to us as \cs{tex_par:D}. This way we
+%    don't have to care about whether \TeX{} just does nothing (e.g.,
+%    if in vertical mode already) or generate an error, etc.
+%    \begin{macrocode}
+\cs_new_protected:Npn \para_end: {
+%    \end{macrocode}
+%
+%    The only case we care about is when we are in horizontal mode
+%    (i.e., doing typesetting) and not also in inner mode (i.e.,
+%    making paragraphs and not building an \cs{hbox}.
+%    \begin{macrocode}
+%  \bool_lazy_and:nnT
+%       { \mode_if_horizontal_p: }
+%       { \bool_not_p:n { \mode_if_inner_p: } }
+%       { ...
+%    \end{macrocode}
+%    Since this is executed for each and every paragraph in a document
+%    we try to stay a fast as possible, So we are aren't using the
+%    above construct but two conditionals instead. Using low-level
+%    \cs{if_mode...} conditions would be even faster but has the
+%    danger to conflict with conditionals in the user hooks.
+%    \begin{macrocode}
+  \mode_if_horizontal:TF {
+    \mode_if_inner:F {
+%    \end{macrocode}
+%    In that case the action of the primitive would be to remove the
+%    last glue (not kern) from the horizontal list constructed to form
+%    a paragraph then append the a penalty of 10000 and the
+%    \cs{parfillskip} at the end and pass the whole list to the
+%    paragraph builder which breaks it into lines and \TeX{} then
+%    returns to vertical mode.
+%
+%    What we want to do instead is to add our hook code at the end of
+%    the horizontal list before that happens and the code is passed to
+%    the paragraph builder. If there was a glue item at the end then
+%    it should get removed before the hook code gets added so we have
+%    to arrange for its removal ourselves.
+%
+%    There is not much point in checking if there was really a glue
+%    item at the end of the horizontal list, instead we simply try to
+%    remove one using \cs{tex_unskip:D}, if there wasn't one this will
+%    do nothing.
+%    \begin{macrocode}
+         \tex_unskip:D
+%    \end{macrocode}
+%    The we execute the public hook (which may add final typesetting
+%    material) followed by the kernel hook we need for adding tagging
+%    support. None of this is supposed to change the mode---at the
+%    moment we make only a very simple test for this, more devious
+%      changes go unnoticed, but too bad, that will then probably
+%      badly backfire.
+%    \begin{macrocode}
+         \hook_use:n{para/end}
+         \@kernel at after@para at end
+         \mode_if_horizontal:TF {
+%    \end{macrocode}
+%    The final action (before getting to the point where
+%    \cs{tex_par:D} is called) is to add a kern item so that the
+%    primitive is prevented from removing glue (if there was some). If
+%      we don't do this and the
+%    horizontal list ended in several glue items we would end up  with
+%    removing two instead of just the last one, which would be wrong.
+%    We use a kern as that is minimally faster.
+%
+%    There is however one other \TeX{} optimization that hurts: in a
+%    sequence like this \verb=$$ ... $$ \par=  \TeX{} will be in
+%    horizontal mode after the display, ready to receive further
+%    paragraph text, but since the \cs{par} follows immediately there
+%    is a ``null'' paragraph at the end and \TeX{} simply throws that
+%    away. The space between \verb=$$= and \cs{par} got already
+%    dropped during the display processing so the \cs{par} is not
+%    removing any space and appending \cs{parfillskip}, instead it
+%    simply goes silently to vmode. Now if we would had added something (to
+%    prevent glue removal) that would look to \TeX{} like material
+%    after the display and so we would end up with an empty paragraph
+%    just containing \cs{parfillskip}.
+%
+%    We therefore check if the current hlist is empty
+%    (\cs{tex_lastnodetype:D} has the value \texttt{-1} and
+%    only if not we add our kern.
+%    \begin{macrocode}
+           \if_int_compare:w 0 < \tex_lastnodetype:D
+             \tex_kern:D \c_zero_dim
+           \fi:
+%    \end{macrocode}
+%    To run the \hook{para/after} hook we first end the
+%    paragraph. This means that the \cs{tex_par:D} at the very end is
+%    unnecessary but executing it there unnecessarily is better than
+%    having code that test for all the different mode possibilities.
+%    \begin{macrocode}
+           \tex_par:D
+           \hook_use:n{para/after}
+           \@kernel at after@para at after
+         }
+%    \end{macrocode}
+%    If we haven't been in horizontal mode then the earlier hook
+%    \hook{para/end} is at fault and we report that.
+%    \begin{macrocode}
+         { \msg_error:nnnn { hooks }{ para-mode }{end}{horizontal} }
+%    \end{macrocode}
+%    Finally close out the nested conditionals.
+%    \begin{macrocode}
+    }
+  }  
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+  \tex_par:D
+}
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%
+%
+%  \begin{macro}{\para_raw_indent:,
+%                \para_raw_noindent:,
+%                \para_raw_end:}
+%
+%    The commands \cs{para_raw_indent:} and \cs{para_raw_noindent:}
+%    are like the primitives \cs{indent} and \cs{noindent} except that
+%    they can only be used in vertical mode.
+%
+%    To avoid issues a paragraph started by them should always be
+%    ended by \cs{para_raw_end:} and not by \cs{para_end:} or
+%    \cs{par} as the latter will execute hooks which then have no
+%    counterpart at the beginning of the paragraph. It is the
+%    responsibility of the programmer to make sure that they are
+%    properly paired.
+%    \begin{macrocode}
+\cs_new:Npn \para_raw_indent: {
+  \mode_if_vertical:TF
+       {
+         \tex_everypar:D {
+           \box_gset_to_last:N \g_para_indent_box
+           \tex_everypar:D { \g_@@_standard_everypar_tl }
+           \@@_handle_indent:
+           \the\everypar }
+       }
+       { \msg_error:nn { kernel }{ raw-para } }
+  \tex_indent:D
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\cs_new:Npn \para_raw_noindent: {
+  \mode_if_vertical:TF
+       {
+         \tex_everypar:D {
+           \tex_everypar:D { \g_@@_standard_everypar_tl }
+           \the\everypar }
+       }
+       { \msg_error:nn { kernel }{ raw-para } }
+  \tex_noindent:D
+}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\cs_new_eq:NN \para_raw_end: \tex_par:D
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%  \begin{macro}{\RawIndent,\RawNoIndent,\RawParEnd}
+%    The \LaTeXe{} names for starting and ending a paragraph without adding any hooks.
+%    \begin{macrocode}
+\cs_set_eq:NN \RawIndent   \para_raw_indent:
+\cs_set_eq:NN \RawNoindent \para_raw_noindent:
+\cs_set_eq:NN \RawParEnd   \para_raw_end:
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%    This ends the \texttt{para} module code.
+%    \begin{macrocode}
+%<@@=>
+%    \end{macrocode}
+%
+%  \begin{macro}{\par,\endgraf}
+%  \begin{macro}[int]{\@@par}
+%
+%    Having the new default definition for \cs{par} we also have to
+%    set it up so that it gets used. This is needed in three places
+%    \cs{par}, \cs{@@par} (to which \LaTeX{} resets \cs{par}
+%    occasionally) and \cs{endgraf} which is another name for the
+%    ``default'' action of \cs{par}.
+%    \begin{macrocode}
+\cs_set_eq:NN \par     \para_end:
+\cs_set_eq:NN \@@par   \para_end:
+\cs_set_eq:NN \endgraf \para_end:
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%
+%    While this is not integrated properly into the format we have to
+%    redo the \cs{everypar} setting from the kernel, otherwise that
+%    gets lost (as it happens before that file is loaded).
+%    \begin{macrocode}
+\everypar{\@nodocument} %% To get an error if text appears before the
+%    \end{macrocode}
+%
+%
+%   \subsection{The error messages}
+%
+%    This one is used when we detect that some hook code has changed
+%    the mode where it shouldn't, e.g., by starting or ending a
+%    paragraph.
+%    The first argument is the hook name second the mode
+%    it should have stayed in but didn't.
+%
+%    \begin{macrocode} 
+\msg_new:nnnn { hooks } { para-mode }
+  {
+    Illegal~mode~ change~ in~ hook~ 'para/#1'.\\
+    Hook~ code~ did~ not~ remain~ in~ #2~ mode.
+  }
+  {
+    Paragraph~ hooks~ cannot~ change~ the~ TeX~ mode~ without~ causing~
+    endless~ recursion.~ The~ hook~ code~ in~ 'para/#1'~ needs~ to~ stay~
+    in~ #2~ mode,~ but~ it~ didn't.~ Examine~ the~ hook~
+    code~ with~ \iow_char:N \\ShowHook~ to~ find~ the~ issue.
+  }
+%    \end{macrocode}
+%
+%    And here is one used in the \enquote{raw} commands when they are
+%    used outside of vertical mode. 
+%    \begin{macrocode}
+\msg_new:nnnn { kernel } { raw-para }
+  {
+     Not~ in~ vertical~ mode.
+  }
+  {
+    Starting~ a~ paragraph~ with~ \iow_char:N \\RawIndent~ or~
+    \iow_char:N \\RawNoindent \\
+    (or~ \iow_char:N \\para_raw_indent:~ or~
+    \iow_char:N \\para_raw_noindent:)~ is~ only~ allowed \\
+    if~ LaTeX~ is~ in~ vertical~ mode.
+  }
+%    \end{macrocode}
+
+
+%    \begin{macrocode}
+%
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease>                 {ltpara}{Undo~hooks~for~paragraphs}
+%<latexrelease>
+%<latexrelease>\let \OmitIndent  \@undefined
+%<latexrelease>\let \IndentBox   \@undefined
+%<latexrelease>\let \RawIndent   \@undefined
+%<latexrelease>\let \RawNoindent \@undefined
+%<latexrelease>\let \RawParEnd   \@undefined
+%<latexrelease>
+%<latexrelease>\cs_set_eq:NN \par     \tex_par:D
+%<latexrelease>\cs_set_eq:NN \@@par   \tex_par:D
+%<latexrelease>\cs_set_eq:NN \endgraf \tex_par:D
+%<latexrelease>  
+%<latexrelease>\EndModuleRelease
+\ExplSyntaxOff
+%</2ekernel|latexrelease>
+%    \end{macrocode}
+%
+%
+%
+%
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\endinput
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%
+


Property changes on: trunk/Master/texmf-dist/source/latex/base/ltpara.dtx
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/source/latex/base/ltpictur.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltpictur.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltpictur.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -32,7 +32,7 @@
 %<*driver>
 % \fi
       \ProvidesFile{ltpictur.dtx}
-                      [2020/08/14 v1.2a LaTeX Kernel (Picture Mode)]
+                      [2021/04/20 v1.2b LaTeX Kernel (Picture Mode)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltpictur.dtx}
@@ -454,9 +454,10 @@
 % \end{macro}
 %
 % \begin{macro}{\@stackcr}
+% \changes{v1.2b}{2021/04/20}{Use \cs{protected} for \cs{\bslash} variant (gh/548)}
 % \begin{macro}{\@ixstackcr}
 %    \begin{macrocode}
-\def\@stackcr{\@ifstar\@ixstackcr\@ixstackcr}
+\protected\def\@stackcr{\@ifstar\@ixstackcr\@ixstackcr}
 \def\@ixstackcr{\@ifnextchar[\@istackcr{\cr\ignorespaces}}
 %    \end{macrocode}
 % \end{macro}
@@ -1773,7 +1774,7 @@
 %
 % Initialization: ``|\thinlines|''
 % \changes{v1.1f}{1995/10/27}
-%      {Move initialisation to kernel from autoload file}
+%      {Move initialization to kernel from autoload file}
 %    \begin{macrocode}
 \let\@linefnt\tenln
 \let\@circlefnt\tencirc

Modified: trunk/Master/texmf-dist/source/latex/base/ltplain.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltplain.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltplain.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -32,7 +32,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltplain.dtx}
-             [2020/08/20 v2.3d LaTeX Kernel (Plain TeX)]
+             [2021/04/18 v2.3f LaTeX Kernel (Plain TeX)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltplain.dtx}
@@ -695,7 +695,7 @@
 %         {Define \cs{alloc@} in terms of \cs{e at alloc}}
 % Since |\e at alloc| was added in 2015, |\@alloc| has not been used,
 % but was left as some legacy code calls it. However the original
-% defnition gives spurious errors once the ``classic'' registers
+% definition gives spurious errors once the ``classic'' registers
 % run out, so it is now defined to call |\e at alloc| internally.
 %    \begin{macrocode}
 %</2ekernel>
@@ -754,8 +754,8 @@
   \chardef\e at insert@top\e at alloc@top
 \fi
 %    \end{macrocode}
-% If the classic registers are exausted, take an insert from the free float list
-% and use |\extrafloats| to add a new float to that list.
+% If the classic registers are exhausted, take an insert from the free
+% float list and use |\extrafloats| to add a new float to that list.
 % \changes{v2.2c}{2016/07/29}{fix for tlb-newinsert-001}
 %    \begin{macrocode}
 \def\newinsert#1{%
@@ -823,6 +823,28 @@
 %    \end{macrocode}
 % \end{macro}
 %
+%
+%
+%  \begin{macro}{\@inputcheck}
+%  \begin{macro}{\@unused}
+%    Allocate read stream for testing and output stream that is never open an
+%    thus writes to the terminal.
+% \changes{v1.0l}{1994/11/07}
+%      {move here from ltdefns, remove duplicate \cs{@mainaux}}
+% \changes{v2.3e}{2021/03/26}{Allocate \cs{@inputcheck} and
+%    \cs{@unused} early so that they are before expl3 allocates
+%    more streams (gh/538)}
+%    \begin{macrocode}
+\newread\@inputcheck
+\newwrite\@unused
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%
+%
+%
+%
+%
 % \begin{macro}{\maxdimen}
 % \begin{macro}{\hideskip}
 % Here are some examples of allocation.
@@ -898,6 +920,37 @@
 %    \end{macrocode}
 % \tracingcommands=0
 % \tracingrestores=0
+%    \end{macrocode}
+%
+% \begin{macro}{\tracingstacklevels}
+%   For Lua\TeX, the \cs{tracingstacklevels} functionality was
+%   implemented as a callback, so here we just define the count register
+%   to hold the value of the parameter.
+%    \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2021/06/01}{\tracingstacklevels}%
+%<latexrelease>                 {tracingstacklevels}%
+\ifx\directlua\@undefined
+  % \tracingstacklevels=0 % added in 2021
+\else
+  \newcount\tracingstacklevels
+  % Code for \tracingstacklevels defined in ltfinal.dtx
+\fi
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>
+%<latexrelease>\IncludeInRelease{0000/00/00}{\tracingstacklevels}%
+%<latexrelease>                 {tracingstacklevels}%
+%<latexrelease>\ifx\directlua\@undefined
+%<latexrelease>\else
+%<latexrelease>  \let\tracingstacklevels\@undefined
+%<latexrelease>\fi
+%<latexrelease>\EndIncludeInRelease
+%</2ekernel|latexrelease>
+%<*2ekernel>
+%    \end{macrocode}
+% \end{macro}
+%
 % \language=0
 %    \begin{macrocode}
 \uchyph=1
@@ -1481,43 +1534,69 @@
 % \changes{v1.1x}{2002/02/24}{Macro added}
 % \changes{v2.0b}{2012/01/20}{etex tracing if available}
 % \changes{v2.0d}{2015/02/20}{Spell commands correctly :-)}
-% \changes{v2.0g}{2015/03/10}{Reorganise to be less noisy}
+% \changes{v2.0g}{2015/03/10}{Reorganize to be less noisy}
+% \changes{v2.3f}{2021/04/18}{Drop pre-$\varepsilon$-\TeX{} support}
+% \changes{v2.3f}{2021/04/18}
+%                {Add \cs{tracingstacklevels} and \cs{tracinglostchars}=3}
 %    \begin{macrocode}
-%<latexrelease>\IncludeInRelease{2015/01/01}{\loggingall}{etex tracing}%
+%<latexrelease>\IncludeInRelease{2021/06/01}{\loggingall}
+%<latexrelease>                 {\tracingstacklevels and \tracinglostchars=3}%
 %<*2ekernel|latexrelease>
-\ifx\tracingscantokens\@undefined
-\gdef\loggingall{%
+\edef\loggingall{%
   \tracingstats\tw@
   \tracingpages\@ne
-  \tracinglostchars\@ne
+  \tracinglostchars\thr@@
   \tracingparagraphs\@ne
-  \errorcontextlines\maxdimen
-  \loggingoutput
-  \tracingmacros\tw@
-  \tracingcommands\tw@
-  \tracingrestores\@ne
-  }%
-\else
-\gdef\loggingall{%
-  \tracingstats\tw@
-  \tracingpages\@ne
-  \tracinglostchars\tw@
-  \tracingparagraphs\@ne
   \tracinggroups\@ne
   \tracingifs\@ne
   \tracingscantokens\@ne
   \tracingnesting\@ne
   \errorcontextlines\maxdimen
-  \loggingoutput
+  \ifdefined\tracingstacklevels \tracingstacklevels\maxdimen \fi
+  \noexpand \loggingoutput
   \tracingmacros\tw@
   \tracingcommands\thr@@
   \tracingrestores\@ne
   \tracingassigns\@ne
 }%
-\fi
-\gdef\tracingall{\showoverfull\loggingall}
+\def\tracingall{\showoverfull\loggingall}
 %</2ekernel|latexrelease>
 %<latexrelease>\EndIncludeInRelease
+%<latexrelease>
+%<latexrelease>\IncludeInRelease{2015/01/01}{\loggingall}{etex tracing}%
+%<latexrelease>\ifx\tracingscantokens\@undefined
+%<latexrelease>\gdef\loggingall{%
+%<latexrelease>  \tracingstats\tw@
+%<latexrelease>  \tracingpages\@ne
+%<latexrelease>  \tracinglostchars\@ne
+%<latexrelease>  \tracingparagraphs\@ne
+%<latexrelease>  \errorcontextlines\maxdimen
+%<latexrelease>  \loggingoutput
+%<latexrelease>  \tracingmacros\tw@
+%<latexrelease>  \tracingcommands\tw@
+%<latexrelease>  \tracingrestores\@ne
+%<latexrelease>  }%
+%<latexrelease>\else
+%<latexrelease>\gdef\loggingall{%
+%<latexrelease>  \tracingstats\tw@
+%<latexrelease>  \tracingpages\@ne
+%<latexrelease>  \tracinglostchars\tw@
+%<latexrelease>  \tracingparagraphs\@ne
+%<latexrelease>  \tracinggroups\@ne
+%<latexrelease>  \tracingifs\@ne
+%<latexrelease>  \tracingscantokens\@ne
+%<latexrelease>  \tracingnesting\@ne
+%<latexrelease>  \errorcontextlines\maxdimen
+%<latexrelease>  \loggingoutput
+%<latexrelease>  \tracingmacros\tw@
+%<latexrelease>  \tracingcommands\thr@@
+%<latexrelease>  \tracingrestores\@ne
+%<latexrelease>  \tracingassigns\@ne
+%<latexrelease>}%
+%<latexrelease>\fi
+%<latexrelease>\gdef\tracingall{\showoverfull\loggingall}
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>
 %<latexrelease>\IncludeInRelease{0000/00/00}{\loggingall}{etex tracing}%
 %<latexrelease>\gdef\loggingall{\tracingcommands\tw@\tracingstats\tw@
 %<latexrelease>  \tracingpages\@ne\tracinglostchars\@ne
@@ -1532,29 +1611,14 @@
 %
 % \begin{macro}{\tracingnone}
 % \changes{v2.0g}{2015/03/10}{macro added}
-% \begin{macro}{\hideoutput}
-% \changes{v2.0g}{2015/03/10}{macro added}
+% \changes{v2.3f}{2021/04/18}{Drop pre-$\varepsilon$-\TeX{} support}
+% \changes{v2.3f}{2021/04/18}
+%                {Add \cs{tracingstacklevels} and \cs{tracinglostchars}=3}
 %    \begin{macrocode}
 %<latexrelease>\IncludeInRelease{2015/01/01}{\tracingnone}%
 %<latexrelease>                             {turn off etex tracing}%
 %<*2ekernel|latexrelease>
-\ifx\tracingscantokens\@undefined
-\def\tracingnone{%
-  \tracingonline\z@
-  \tracingcommands\z@
-  \showboxdepth\m at ne
-  \showboxbreadth\m at ne
-  \tracingoutput\z@
-  \errorcontextlines\m at ne
-  \tracingrestores\z@
-  \tracingparagraphs\z@
-  \tracingmacros\z@
-  \tracinglostchars\@ne
-  \tracingpages\z@
-  \tracingstats\z@
-}%
-\else
-\def\tracingnone{%
+\edef\tracingnone{%
   \tracingassigns\z@
   \tracingrestores\z@
   \tracingonline\z@
@@ -1563,6 +1627,7 @@
   \showboxbreadth\m at ne
   \tracingoutput\z@
   \errorcontextlines\m at ne
+  \ifdefined\tracingstacklevels \tracingstacklevels\z@ \fi
   \tracingnesting\z@
   \tracingscantokens\z@
   \tracingifs\z@
@@ -1573,10 +1638,62 @@
   \tracingpages\z@
   \tracingstats\z@
 }%
-\fi
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>
+%<latexrelease>\IncludeInRelease{2015/01/01}{\tracingnone}%
+%<latexrelease>                             {turn off etex tracing}%
+%<latexrelease>\ifx\tracingscantokens\@undefined
+%<latexrelease>\def\tracingnone{%
+%<latexrelease>  \tracingonline\z@
+%<latexrelease>  \tracingcommands\z@
+%<latexrelease>  \showboxdepth\m at ne
+%<latexrelease>  \showboxbreadth\m at ne
+%<latexrelease>  \tracingoutput\z@
+%<latexrelease>  \errorcontextlines\m at ne
+%<latexrelease>  \tracingrestores\z@
+%<latexrelease>  \tracingparagraphs\z@
+%<latexrelease>  \tracingmacros\z@
+%<latexrelease>  \tracinglostchars\@ne
+%<latexrelease>  \tracingpages\z@
+%<latexrelease>  \tracingstats\z@
+%<latexrelease>}%
+%<latexrelease>\else
+%<latexrelease>\def\tracingnone{%
+%<latexrelease>  \tracingassigns\z@
+%<latexrelease>  \tracingrestores\z@
+%<latexrelease>  \tracingonline\z@
+%<latexrelease>  \tracingcommands\z@
+%<latexrelease>  \showboxdepth\m at ne
+%<latexrelease>  \showboxbreadth\m at ne
+%<latexrelease>  \tracingoutput\z@
+%<latexrelease>  \errorcontextlines\m at ne
+%<latexrelease>  \tracingnesting\z@
+%<latexrelease>  \tracingscantokens\z@
+%<latexrelease>  \tracingifs\z@
+%<latexrelease>  \tracinggroups\z@
+%<latexrelease>  \tracingparagraphs\z@
+%<latexrelease>  \tracingmacros\z@
+%<latexrelease>  \tracinglostchars\@ne
+%<latexrelease>  \tracingpages\z@
+%<latexrelease>  \tracingstats\z@
+%<latexrelease>}%
+%<latexrelease>\fi
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>
+%<latexrelease>\IncludeInRelease{0000/00/00}{\tracingnone}%
+%<latexrelease>                             {turn off etex tracing}%
+%<latexrelease>\let\tracingnone\@undefined
+%<latexrelease>\EndIncludeInRelease
 %    \end{macrocode}
+% \end{macro}
 %
+% \begin{macro}{\hideoutput}
+% \changes{v2.0g}{2015/03/10}{macro added}
 %    \begin{macrocode}
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2015/01/01}{\hideoutput}%
+%<latexrelease>                             {hide output from tracing}%
 \def\hideoutput{%
   \tracingoutput\z@
   \showboxbreadth\m at ne
@@ -1583,21 +1700,16 @@
   \showboxdepth\m at ne
   \tracingonline\m at ne
 }%
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-%</2ekernel|latexrelease>
 %<latexrelease>\EndIncludeInRelease
-%<latexrelease>\IncludeInRelease{0000/00/00}{\tracingnone}%
-%<latexrelease>                             {turn off etex tracing}%
-%<latexrelease>\let\tracingnone\@undefined
+%<latexrelease>
+%<latexrelease>\IncludeInRelease{0000/00/00}{\hideoutput}%
+%<latexrelease>                             {hide output from tracing}%
 %<latexrelease>\let\hideoutput\@undefined
 %<latexrelease>\EndIncludeInRelease
+%</2ekernel|latexrelease>
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
 %
-%
 % \LaTeX\ change: |\showhyphens| Defined later.
 %
 % Punctuation affects the spacing.

Modified: trunk/Master/texmf-dist/source/latex/base/ltsect.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltsect.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltsect.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -31,7 +31,7 @@
 %%% From File: ltsect.dtx
 %<*driver>
 % \fi
-\ProvidesFile{ltsect.dtx}[2020/07/27 v1.1e LaTeX Kernel (Sectioning)]
+\ProvidesFile{ltsect.dtx}[2020/12/05 v1.1e LaTeX Kernel (Sectioning)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltsect.dtx}
@@ -779,7 +779,7 @@
 % \changes{v1.1c}{2018/09/26}{Sometimes mask the endline char when
 %    writing to files (github/73)}
 % \changes{v1.1e}{2020/10/01}{add a fourth argument for better
-%    hyperref compability}
+%    hyperref compatibility}
 %    \begin{macrocode}
 %</2ekernel>
 %<*2ekernel|latexrelease>

Modified: trunk/Master/texmf-dist/source/latex/base/ltshipout.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltshipout.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltshipout.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,6 +1,7 @@
 % \iffalse meta-comment
 %%
-%% File: ltshipout.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team
+%% Copyright (C) 2020-2021
+%%               Frank Mittelbach, LaTeX Team
 %%
 %
 % This file is part of the LaTeX base system.
@@ -31,8 +32,8 @@
 %%% From File: ltshipout.dtx
 %
 %    \begin{macrocode}
-\providecommand\ltshipoutversion{v1.0d}
-\providecommand\ltshipoutdate{2020/11/24}
+\providecommand\ltshipoutversion{v1.0i}
+\providecommand\ltshipoutdate{2021/03/17}
 %    \end{macrocode}
 %
 %<*driver>
@@ -55,6 +56,9 @@
   }
 \ExplSyntaxOff
 
+\providecommand\InternalDetectionOff{}
+\providecommand\InternalDetectionOn{}
+
 \EnableCrossrefs
 \CodelineIndex
 \begin{document}
@@ -75,7 +79,7 @@
 %    \ltshipoutversion\ dated \ltshipoutdate, \copyright\ \LaTeX\
 %    Project.}}
 %
-% \author{Frank Mittelbach}
+% \author{Frank Mittelbach, \LaTeX{} Project Team}
 %
 % \maketitle
 %
@@ -108,11 +112,56 @@
 %    It then stores it in a named box register.  This box can then be
 %    manipulated through a set of hooks after which it is shipped out
 %    for real.
+%
+%    Each shipout that actually happens (i.e., where the material is
+%    not discarded for one or the other reason) is recorded and the
+%    total number is available in a readonly variable and in a
+%    \LaTeX{} counter.
 % \end{function}
 %
+%
+% \begin{function}{\RawShipout}
+%    This command implements a simplified shipout that bypasses the
+%    foreground and background 
+%    hooks, e.g., only \hook{shipout/firstpage} and
+%    \hook{shipout/lastpage} are executed and the total shipout
+%    counters are incremented.
+%
+%    The command doesn't use \cs{ShipoutBox} but its own private box
+%    register so that it can be used inside of shipout hooks to do
+%    some additional shipouts while already in the output routine with
+%    the current page being stored in \cs{ShipoutBox}. It does have
+%    access to \cs{ShipoutBox} if it is used in \hook{shipout/before}
+%    (or \hook{shipout/after}) and can use its content.
+%
+%    It is safe to use it in \hook{shipout/before} or
+%    \hook{shipout/after} but not necessarily in the other
+%    \hook{shipout/...} hooks as they are intended for special
+%    processing.
+% \end{function}
+%
 %  \begin{variable}{\ShipoutBox,\l_shipout_box}
-%    This box register is called \cs{ShipoutBox} (alternatively available via the
-%    L3 name \cs{l_shipout_box}).
+%    This box register is called \cs{ShipoutBox} (alternatively
+%    available via the L3 name \cs{l_shipout_box}).
+%
+%    This box is a ``local'' box and assignments to it should be done
+%    only locally. Global assignments (as done by some packages with
+%    older code where this is box is known as 255) may work but they are
+%    conceptually wrong and may result in errors under certain
+%    circumstances.
+%
+%    During the execution of \hook{shipout/before} this box contains
+%    the accumulated material for the page, but not yet any material
+%    added by other shipout hooks.
+%    During execution of \hook{shipout/after}, i.e., after the shipout
+%    has happened, the box also contains any background or foreground
+%    material.
+%
+%    Material from the hooks \hook{shipout/firstpage} or
+%    \hook{shipout/lastpage} is not included (but only used during the
+%    actual shipout) to facilitate reuse of the box data (e.g.,
+%    \hook{shipout/firstpage} material should never be added to a
+%    later page of the output).
 %  \end{variable}
 %
 %
@@ -133,11 +182,11 @@
 %
 % \subsection{Provided hooks}
 %
-%  \begin{variable}{shipout/before,
+%  \begin{variable}{shipout/before,shipout/after,
 %                   shipout/foreground,shipout/background,
 %                   shipout/firstpage,
 %                   shipout/lastpage}
-%    The code offers a number of hooks into which packages (or the
+%    The code for \cs{shipout} offers a number of hooks into which packages (or the
 %    user) can add code to support different use cases.
 %    These are:
 %    \begin{description}
@@ -148,6 +197,20 @@
 %       It can be used to alter that box content or to discard it
 %       completely (see \cs{DiscardShipoutBox} below).
 %
+%       You can use \cs{RawShipout} inside this hook for special use
+%       cases. It can make use of \cs{ShipoutBox} (which doesn't yet
+%       include the background and foreground material).
+%
+%       \textbf{Note:} It is not possible (or say advisable) to try
+%       and use this hook to typeset material with the intention to
+%       return it to main vertical list, it will go wrong and give
+%       unexpected results in many cases---for starters it will appear
+%       after the current page not before or it will vanish or the
+%       vertical spacing will be wrong!
+%    \end{description}
+%  \end{variable}
+%
+%    \begin{description}
 %    \item[\hook{shipout/background}]
 %
 %       This hook adds a picture environment into the background of
@@ -186,15 +249,22 @@
 %       not discarded at the last minute). It should only contain
 %       \cs{special} or similar commands needed to direct post processors
 %       handling the \texttt{.dvi} or \texttt{.pdf} output.\footnotemark
+%  \footnotetext{In
+%         \LaTeXe{} that was already existing, but implemented using a box
+%         register with the name \cs{@begindvibox}.}
 %
 %       ^^A \fmi{not sure it has to be that restrictive.}
 %
+%       This hook is added to the very first page regardless of how it
+%       is shipped out (i.e., with \cs{shipout} or \cs{RawShipout}).
 %
 %    \item[\hook{shipout/lastpage}]
 %
 %       The corresponding hook to add \cs{special}s at the very end of
-%       the output file. It is only executed on the very last page ---
+%       the output file. It is only executed on the very last page of
+%       the output file ---
 %       or rather on the page that \LaTeX{} believes is the last one.
+%       Again it is executed regardless of the shipout method.
 %
 %       It may not be possible for \LaTeX{} to correctly determine
 %       which page is the last one without several reruns. If this
@@ -202,17 +272,32 @@
 %       extra page to place the material and also request a rerun to
 %       get the correct placement sorted out.
 %
+%    \item[\hook{shipout/after}]
+%
+%       This hook is executed after a shipout has happened. If the
+%       shipout box is discarded this hook is not looked at.
+%
+%       You can use \cs{RawShipout} inside this hook for special use
+%       cases and the main \cs{ShipoutBox} is still available at this
+%       point (but in contrast to \hook{shipout/before} it now
+%       includes the background and foreground material).
+%
+%       \textbf{Note:} Just like \hook{shipout/before} this hook is
+%       not meant to be used for adding adding typeset material back
+%       to the main vertical list---it might vanish or the
+%       vertical spacing will be wrong!
+%
+%
 %    \end{description}
-%  \end{variable}\footnotetext{In
-%         \LaTeXe{} that was already existing, but implemented using a box
-%         register with the name \cs{@begindvibox}.}
 %
 %    As mentioned above the hook \hook{shipout/before} is executed
 %    first and can manipulate the prepared shipout box stored in
 %    \cs{ShipoutBox} or set things up for use in \cs{write} during the
-%    actual shipout. The other hooks are added inside hboxes to the
-%    box being shipped out in the following
-%    order:
+%    actual shipout. It is even run if there was a
+%    \cs{DiscardShipoutBox} request in the document.
+%
+%    The other hooks (except \hook{shipout/after}) are added inside
+%    hboxes to the box being shipped out in the following order:
 %    \begin{center}
 %    \begin{tabular}{ll}
 %       \hook{shipout/firstpage}   & only on the first page \\
@@ -225,32 +310,50 @@
 %    If any of the hooks has no code then that particular no box is
 %    added at that point.
 %
+%    Once the (page) box has been shipped out the \hook{shipout/after}
+%    hook is called (while you are still inside the output routine). It
+%    is not called if the shipout box was discarded.
+%
 %    In a document that doesn't produce pages, e.g., only makes
-%    \cs{typeout}s, none of the hooks are executed (as there is no
+%    \cs{typeout}s, none of the hooks are ever executed (as there is no
 %    \cs{shipout}) not even the \hook{shipout/lastpage} hook.
 %
+%    If \cs{RawShipout} is used instead of \cs{shipout} then only the
+%    hooks \hook{shipout/firstpage} and \hook{shipout/lastpage} are
+%    executed (on the first or last page), all others are bypassed.
+%
+%
+%
+% \subsection{Legacy \LaTeX{} commands}
+%
 % \begin{function}{\AtBeginDvi,\AtEndDvi}
 %    \cs{AtBeginDvi} is the existing \LaTeXe{} interface to fill the
 %    \hook{shipout/firstpage} hook. This is not really a good name
 %    as it is not just supporting \texttt{.dvi} but also \texttt{.pdf}
-%    output or \texttt{.dvx}.
+%    output or \texttt{.xdv}.
 %
 %    \cs{AtEndDvi} is the counterpart that was not available in the
 %    kernel but only through the package \pkg{atenddvi}. It fills the
 %    \hook{shipout/lastpage} hook.
+% \end{function}
 %
-%    \fmi{better names? Any suggestions?}
+%    As these two wrappers have been available for a long time we
+%    continue offering them. However, for new code we suggest using
+%    the high-level hook management commands directly instead of
+%    ``randomly-named'' wrappers.  This will lead to code that is
+%    easier to understand and to maintain.  For this reason we do not
+%    provide any other wrapper commands for the above hooks in the
+%    kernel.
 %
-% \end{function}
 %
 % \subsection{Special commands for use inside the hooks}
 %
-% \begin{function}{\DiscardShipoutBox,\shipout_discard_box:}
+% \begin{function}{\DiscardShipoutBox,\shipout_discard:}
 %   \begin{syntax}
 %     \cs{AddToHookNext} \texttt{\{shipout/before\} \{...\cs{DiscardShipoutBox}...\}}
 %   \end{syntax}
 %    The \cs{DiscardShipoutBox} declaration (L3 name
-%    \cs{shipout_discard_box:})
+%    \cs{shipout_discard:})
 %    requests that on the next
 %    shipout the page box is thrown away instead of being shipped to
 %    the \texttt{.dvi} or \texttt{.pdf} file.
@@ -261,6 +364,8 @@
 %    Note that if this declaration is used directly in the document it
 %    may depend on the placement to which page it applies, given that
 %    \LaTeX{} output routine is called in an asynchronous manner!
+%    Thus normally one would use this only as part of the
+%    \hook{shipout/before} code.
 %
 %    \fmi{Once we have a new mark mechanism available we can improve
 %    on that and make sure that the declaration applies to the page
@@ -279,12 +384,28 @@
 %    names as given below.
 %
 %
+%
+% \subsection{Provided Lua\TeX\ callbacks}
+% 
+%  \begin{variable}{pre_shipout_filter}
+%    Under Lua\TeX{} the \texttt{pre\_shipout\_filter} Lua callback is
+%    provided which gets called immediately before the shipout primitive gets invoked.
+%    The signature is
+%    \begin{verbatim}
+%     function(<node> head)
+%       return true
+%     end
+%    \end{verbatim}
+%    The \texttt{head} is the list node corresponding to the box to be shipped out.
+%    The return value should always be \texttt{true}.
+%  \end{variable}
+%
 % \subsection{Information counters}
 %
 %
 %  \begin{variable}{\ReadonlyShipoutCounter,\g_shipout_readonly_int}
 %   \begin{syntax}
-%     \cs{ifnum}\cs{ReadOnlyShipoutCounter}\texttt{=...}
+%     \cs{ifnum}\cs{ReadonlyShipoutCounter}\texttt{=...}
 %     \cs{int_use:N} \cs{g_shipout_readonly_int} \texttt{\% expl3 usage}
 %   \end{syntax}
 %    This integer holds the number of pages shipped out up to now
@@ -292,6 +413,7 @@
 %    routine). More precisely, it is incremented only after it is
 %    clear that a page will be shipped out, i.e., after the
 %    \hook{shipout/before} hook (because that might discard the page)!
+%    In contrast \hook{shipout/after} sees the incremented value.
 %
 %    Just like with the \texttt{page} counter its value is
 %    only accurate within the output routine. In the body of the
@@ -299,10 +421,11 @@
 %    asynchronously!
 %
 %    Also important: it \emph{must not} be set, only read. There are
-%    no provisions to prevent that but if you do, chaos will be the
-%    result. To emphasize this fact it is not provided as a \LaTeX{}
-%    counter but as a \TeX{} counter (i.e., a command), so
-%    \cs{Alph}\Arg{\cs{ReadonlyShipoutCounter}} etc, would not work.
+%    no provisions to prevent that restriction, but if you manipulate
+%    it, chaos will be the result. To emphasize this fact it is not
+%    provided as a \LaTeX{} counter but as a \TeX{} counter (i.e., a
+%    command), so \cs{Alph}\verb={=\cs{ReadonlyShipoutCounter}\verb=}=
+%    etc, would not work.
 %  \end{variable}
 %
 %  \begin{variable}{totalpages,\g_shipout_totalpages_int}
@@ -314,7 +437,8 @@
 %    \texttt{totalpages} counter is a \LaTeX{} counter and incremented
 %    for each shipout attempt including those pages that are discarded
 %    for one or the other reason. Again \hook{shipout/before} sees
-%    the counter before it is incremented).
+%    the counter before it is incremented. In contrast
+%    \hook{shipout/after} sees the incremented value.
 %
 %    Furthermore, while it is incremented for each page, its value is
 %    never used by \LaTeX. It can therefore be freely reset or changed by user
@@ -331,9 +455,9 @@
 %     \cs{thetotalpages}/\cs{PreviousTotalPages}
 %   \end{syntax}
 %    Command that expands to the number of total pages from the
-%    previous run.  If there was no previous run or if usedin the
+%    previous run.  If there was no previous run or if used in the
 %    preamble it expands to
-%    \texttt{0}. Note that this is a command to a counter, so in order
+%    \texttt{0}. Note that this is a command and not a counter, so in order
 %    to display the number in, say, Roman numerals you have to assign
 %    its value to a counter and then use \cs{Roman} on that counter.
 %  \end{variable}
@@ -356,11 +480,17 @@
 %
 % \section{Emulating commands from other packages}
 %
-%    The packages in this section are no longer necessary but as they
-%    are used in other packages they are emulated when they are loaded
-%    via \cs{usepackage} or \cs{RequirePackage}.
+%    The packages in this section are no longer necessary, but as they
+%    are used by other packages, they are emulated when they are
+%    explicitly loaded with \cs{usepackage} or \cs{RequirePackage}.
 %
+%    Please note that the emulation only happens if the package is
+%    explicitly requested, i.e., the commands documented below are not
+%    automatically available in the \LaTeX{} kernel!  If you write a
+%    new package we suggest to use the appropriate kernel hooks
+%    directly instead of loading the emulation.
 %
+%
 % \subsection{Emulating \pkg{atbegshi}}
 %
 %
@@ -410,6 +540,21 @@
 %    This is the name of the shipout box as \pkg{atbegshi} knows it.
 % \end{function}
 %
+%
+% \begin{function}{\AtBeginShipoutOriginalShipout}
+%    This is the name of the \cs{shipout} primitive as \pkg{atbegshi}
+%    knows it. This bypasses all the mechanisms set up by the \LaTeX{}
+%    kernel and there are various scenarios in which it can therefore
+%    fail. It should only be used to run existing legacy
+%    \pkg{atbegshi} code but not in newly developed applications.
+%
+%    The kernel alternative is \cs{RawShipout} which is integrated
+%    with the \LaTeX{} mechanisms and updates, for example, the
+%    \cs{ReadonlyShipoutCounter} counter. Please use \cs{RawShipout}
+%    for new code if you want to bypass the before, foreground and
+%    background hooks.
+% \end{function}
+%
 % \begin{function}{\AtBeginShipoutInit}
 %   By default \pkg{atbegshi} delayed its action until
 %    \verb=\begin{document}=.  This command was forcing it in an earlier
@@ -434,6 +579,13 @@
 %
 % \subsection{Emulating \pkg{everyshi}}
 %
+%    The \pkg{everyshi} package is providing commands to run arbitrary
+%    code just before the shipout starts.
+%    One point of difference: in the new shipout hooks the page is
+%    available as \cs{ShipoutBox} for inspection of change, one should
+%    not manipulate box 255 directly inside \hook{shipout/before}, so
+%    old code doing this would change to use \cs{ShipoutBox} instead
+%    of \texttt{255} or \cs{@cclv}.
 %
 % \begin{function}{\EveryShipout}
 %   \begin{syntax}
@@ -447,24 +599,51 @@
 %   \end{syntax}
 % \end{function}
 %
+%    However, most use cases for \pkg{everyshi} are attempts to put
+%    some picture or text into the background or foreground of the page
+%    and that can be done today simply by using the
+%    \hook{shipout/background} and 
+%    \hook{shipout/foreground} hooks without any need to coding.
 %
 %
 % \subsection{Emulating \pkg{atenddvi}}
 %
-% The \pkg{atenddvi} package implemented only a single command:
-%    \cs{AtEndDvi} and that is now available out of the box.
+%    The \pkg{atenddvi} package implemented only a single command:
+%    \cs{AtEndDvi} and that is now available out of the box so the
+%    emulation makes the package a no-op.
 %
 %
 %
 % \subsection{Emulating \pkg{everypage}}
 %
-%    This page takes over the original \cs{@begindvi} hook and replaces 
-%    it. It should be all covered by the hooks offered here (details
-%    need checking) and thus could simply use the provided hooks
-%    rather than defining its own.
+%    This package patched the original \cs{@begindvi} hook and replaced 
+%    it with its own version.
+%    Its functionality is now covered by the hooks offered by the
+%    kernel so that there is no need for such patching any longer.
 %
+% \begin{function}{\AddEverypageHook}
+%   \begin{syntax}
+% \cs{AddEverypageHook}\Arg{code} $\equiv$
+% \qquad\cs{AddToHook}\texttt{\{shipout/background\}\{\cs{put}(1in,-1in)\Arg{code}\}}
+%   \end{syntax}
+%    \cs{AddEverypageHook} is adding something into the
+%    background of every page at a position of 1in to the right and
+%    1in down from the top left corner of the page.
+%     By using the kernel hook directly you can put your material
+%    directly to the right place, i.e., use other coordinates in the
+%    \cs{put} statement above.
+% \end{function}
 %
+% \begin{function}{\AddThispageHook}
+%   \begin{syntax}
+% \cs{AddThispageHook}\Arg{code} $\equiv$
+% \qquad\cs{AddToHookNext}\texttt{\{shipout/background\}\{\cs{put}(1in,-1in)\Arg{code}\}}
+%   \end{syntax}
+%    The \cs{AddThispageHook} wrapper is similar but uses
+%    \cs{AddToHookNext}.
+% \end{function}
 %
+%
 % \StopEventually{\setlength\IndexMin{200pt}  \PrintIndex  }
 %
 %
@@ -479,7 +658,7 @@
 %    \begin{macrocode}
 %<*2ekernel|latexrelease>
 %<latexrelease>\IncludeInRelease{2020/10/01}%
-%<latexrelease>                 {\shipout}{Hook mangement (shipout)}%
+%<latexrelease>                 {\shipout}{Hook management (shipout)}%
 %    \end{macrocode}
 %
 %
@@ -540,8 +719,43 @@
 %  \end{macro}
 %
 %
+%  \begin{macro}{\l_@@_raw_box}
+%    The \cs{RawShipout} gets its own box but it is internal as there
+%    is no hook manipulation for it.
+%    \begin{macrocode}
+\box_new:N  \l_@@_raw_box
+%    \end{macrocode}
+%  \end{macro}
 %
 %
+%  \begin{macro}{\@@_finalize_box:}
+%    For Lua\TeX{} invoke the \texttt{pre\_shipout\_filter} callback.
+%  \changes{v1.0i}{2021/01/22}{Add \texttt{pre\_shipout\_filter} Lua callback}
+%    \begin{macrocode}
+\sys_if_engine_luatex:TF
+  {
+    \newluafunction \@@_finalize_box:
+    \exp_args:Nx \everyjob {
+      \exp_not:V \everyjob
+      \exp_not:N \lua_now:n {
+        luatexbase.create_callback('pre_shipout_filter', 'list')
+        local~call, getbox, setbox = luatexbase.call_callback, tex.getbox, tex.setbox~
+        lua.get_functions_table()[\the \@@_finalize_box:] = function()
+          local~result = call('pre_shipout_filter', getbox(\the \l_shipout_box))
+          if~not (result == true) then~
+            setbox(\the \l_shipout_box, result~or~nil)
+          end~
+        end
+      }
+    }
+    \protected \luadef \@@_finalize_box: \the \@@_finalize_box:
+  } {
+    \cs_set_eq:NN \@@_finalize_box: \scan_stop:
+  }
+%    \end{macrocode}
+%  \end{macro}
+%
+%
 %  \begin{macro}{\@@_execute:}
 %    This is going to the be the code run by \cs{shipout}. The code
 %    follows closely the  ideas from \pkg{atbegshi}, so not
@@ -567,7 +781,8 @@
 %
 %  \begin{macro}{\l_@@_group_level_tl}
 %    Helper token list to record the group level at which
-%    \cs{@@_execute:} is encountered.  \begin{macrocode}
+%    \cs{@@_execute:} is encountered.
+%    \begin{macrocode}
 \tl_new:N \l_@@_group_level_tl
 %    \end{macrocode}
 %  \end{macro}
@@ -581,8 +796,7 @@
 \cs_new:Npn \@@_execute_test_level: {
   \int_compare:nNnT
      \l_@@_group_level_tl < \tex_currentgrouplevel:D 
-     \tex_aftergroup:D
-  \@@_execute_cont:
+     \tex_aftergroup:D \@@_execute_cont:
 }
 %    \end{macrocode}
 %  \end{macro}
@@ -589,20 +803,71 @@
 %
 %
 %  \begin{macro}{\@@_execute_cont:}
+%    This does the actual shipout running several hooks as part of it.
+%    The code for them is passed as argument \verb=#2= to \verb=#4=
+%    to \cs{@@_execute_main_cont:Nnnn}; the first argument is the box
+%    to be shipped out.
+%    \begin{macrocode}
+\cs_new:Npn \@@_execute_cont: {
+  \@@_execute_main_cont:Nnnn
+     \l_shipout_box
+     { \hook_use:n {shipout/before} }
+     { \hook_if_empty:nF {shipout/foreground}
+         { \@@_add_foreground_picture:n
+             { \hook_use:n {shipout/foreground} } }
+%    \end{macrocode}
+%    If the user hook for the background (\hook{shipout/background}) has
+%    no code, there might still code in the kernel hook so we need to
+%    test for this too.
+%    We only test for the \cs{@kernel at before@shipout at background}
+%    though. If the  \cs{@kernel at after@shipout at background} needs
+%    executing even if the user hook is empty then we can add another
+%    test (or the kernel could put something into the before hook).
+%                   
+% \changes{v1.0d}{2020/11/23}{Check for both kernel and user hook (gh/431)}
+% \changes{v1.0f}{2021/01/08}{Added another kernel hook for more
+%    flexibility (cf \texttt{https://github.com/pgf-tikz/pgf/issues/960}}
+%    \begin{macrocode}
+       \bool_lazy_and:nnF
+         { \hook_if_empty_p:n {shipout/background} }
+         { \tl_if_empty_p:N \@kernel at before@shipout at background }
+         { \@@_add_background_picture:n
+           { \@kernel at before@shipout at background
+             \hook_use:n {shipout/background}
+             \@kernel at after@shipout at background }
+         }
+     }
+     { \hook_use:n {shipout/after} }
+}
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%  \begin{macro}{\@@_execute_main_cont:Nnnn}
 %    When we have reached this point the shipout box has been
 %    processed and is available in \cs{l_shipout_box} and ready for
-%    real ship out (perhaps)..
+%    real ship out (unless it gets discarded during the process).
 %
+%    The three arguments hold hook code that is executed just before the
+%    actual shipout (\verb=#1=), within the shipout adding
+%    background and foreground material (\verb=#2=) and after the
+%    shipout has happened (\verb=#3=).
+%    These are passed as arguments because the same code without those
+%    hooks is also used when doing a ``raw'' shipout implemented by
+%    \cs{RawShipout}.
+%    The only hook that is always executed is that for the very last
+%    page, i.e., \hook{shipout/lastpage}.
+%
 %    First we quickly check if it is void (can't happen in the
 %    standard \LaTeX{} output routine but \cs{shipout} might be called
 %    from a package that has some special processing logic). If it is
 %    void we aren't shipping anything out and processing ends.\footnote{In that
-%    case we don't reset the deadcyles, that would be up to the OR
+%    case we don't reset the deadcycles, that would be up to the OR
 %    processing logic to do.}
 %    \begin{macrocode}
-\cs_new:Npn \@@_execute_cont: {
-  \box_if_empty:NTF \l_shipout_box
-    { \PackageWarning{ltshipout}{Ignoring~ void~ shipout~ box} }
+\cs_new:Npn \@@_execute_main_cont:Nnnn #1#2#3#4 {
+  \box_if_empty:NTF #1
+    { \@latex at warning{Ignoring~ void~ shipout~ box} }
     {
 %    \end{macrocode}
 %    Otherwise we assume that we will ship something and prepare for
@@ -610,7 +875,8 @@
 %    \cs{protect} while we are running the hook code).
 %    We also save the current \cs{protect} state to restore it later.
 %    \begin{macrocode}
-      \bool_gset_false:N \g_@@_discard_bool
+%      \bool_gset_false:N \g_@@_discard_bool  % setting this would disable
+                                              % \DiscardShipoutBox on doc-level
       \cs_set_eq:NN \@@_saved_protect: \protect
       \set at typeset@protect
 %    \end{macrocode}
@@ -619,11 +885,12 @@
 %    necessary as the code could access them via \cs{box_ht:N}, etc.,
 %    but it is perhaps convenient.}
 %    \begin{macrocode}
-      \@@_get_box_size:N \l_shipout_box
+      \@@_get_box_size:N #1
 %    \end{macrocode}
-%    Then we execute the \hook{shipout/before} hook.
+%    Then we execute the \hook{shipout/before} hook (or nothing in
+%    case of \cs{RawShipout}).
 %    \begin{macrocode}
-      \hook_use:n {shipout/before}
+      #2
 %    \end{macrocode}
 %    In \cs{g_shipout_totalpages_int} we count all shipout attempts so
 %    we increment that counter already here (the other one is
@@ -631,7 +898,8 @@
 %    \cs{shipout}.
 %
 %     We increment it after running the above hook so that the values
-%    for \cs{g_shipout_totalpages_int} and \cs{} are in sync while the
+%    for \cs{g_shipout_totalpages_int} and \cs{g_shipout_readonly_int}
+%    are in sync while the
 %    hook is executed (in the case that totalpages isn't manually
 %    altered or through discarding pages that is).
 %    \begin{macrocode}
@@ -641,7 +909,7 @@
 %    we now test for it.
 %    \begin{macrocode}
       \bool_if:NTF \g_@@_discard_bool
-        { \PackageInfo{ltshipout}{Completed~ page~ discarded}
+        { \@latex at info@no at line{Completed~ page~ discarded}
           \bool_gset_false:N \g_@@_discard_bool
 %    \end{macrocode}
 %    As we are discarding the page box and not shipping anything out,
@@ -655,7 +923,7 @@
 %    needed? Or the resetting of \cs{protect} to its kernel value?}
 %    \begin{macrocode}
 %          \group_begin:
-%            \box_set_eq_drop:NN \l_shipout_box \l_shipout_box
+%            \box_set_eq_drop:NN #1 #1
 %          \group_end:
 %          \cs_set_eq:NN \protect \exp_not:N
         }
@@ -666,8 +934,8 @@
 %    once more but this time make it a warning, because the best
 %    practice way is to use the request mechanism.
 %    \begin{macrocode}
-        { \box_if_empty:NTF \l_shipout_box
-            { \PackageWarning{ltshipout}{
+        { \box_if_empty:NTF #1
+            { \@latex at warning{
                 Shipout~ box~ was~ voided~ by~ hook,\MessageBreak
                 ignoring~ shipout~ box  }
             }
@@ -691,39 +959,54 @@
 %    changed) and then look at the hooks \hook{shipout/foreground}
 %    and \hook{shipout/background}. If either or both are non-empty
 %    we add a \texttt{picture} environment to the box (in the
-%    foreground and or in the background) and execute the hook code
+%    foreground and/or in the background) and execute the hook code
 %    inside that environment.
 %    
 %    \begin{macrocode}
-              \@@_get_box_size:N \l_shipout_box
-              \hook_if_empty:nF {shipout/foreground}
-                   { \@@_add_foreground_picture:n
-                     { \hook_use:n {shipout/foreground} } }
-              \hook_if_empty:nF {shipout/background}
-                   { \@@_add_background_picture:n
-                     { \@kernel at before@shipout at background
-                       \hook_use:n {shipout/background} } }
+              \@@_get_box_size:N #1
 %    \end{macrocode}
-%    We then run \cs{@@_execute_firstpage_hook:} that adds
+%    The first hook we run is the \hook{shipout/firstpage} hook. This
+%    is only done once, then the \cs{@@_run_firstpage_hook:}
+%    command redefines itself to do nothing. If the hook contains
+%    \cs{special}s for integration at the top of the page they will be
+%    temporarily stored in a safe place and added later with
+%    \cs{@@_add_firstpage_specials:}.
+%    \begin{macrocode}
+              \@@_run_firstpage_hook:
+%    \end{macrocode}
+%    Run the hooks for background and foreground or, if this
+%    is called by \cs{RawShipout}, copy the box \cs{l_@@_raw_box} to
+%    \cs{l_shipout_box} so that firstpage and lastpage material gets
+%    added if necessary (that is always done to \cs{l_shipout_box}.
+%    \begin{macrocode}
+              #3
+%    \end{macrocode}
+%    We then run \cs{@@_add_firstpage_specials:} that adds
 %    the content of the hook \hook{shipout/firstpage} to the
 %    start of the first page (if non-empty). It is then redefined to
 %    do nothing on later pages.
 %    \begin{macrocode}
-              \@@_execute_firstpage_hook:
+              \@@_add_firstpage_specials:
 %    \end{macrocode}
-%    The we check if we have to add the \hook{shipout/lastpage} hook
+%    Then we check if we have to add the \hook{shipout/lastpage} hook
+%    or the corresponding kernel hook
 %    because we have reached the last page. This test will be false for
 %    all but one (and hopefully the correct) page.
+% \changes{v1.0d}{2020/11/23}{Check for both kernel and user hook (gh/431)}
 %    \begin{macrocode}
               \int_compare:nNnT \@abspage at last = \g_shipout_readonly_int
-                { \hook_if_empty:nF {shipout/lastpage}
+                { \bool_lazy_and:nnF
+                    { \hook_if_empty_p:n {shipout/lastpage} }
+                    { \tl_if_empty_p:N \@kernel at after@shipout at lastpage }
                     { \@@_debug:n { \typeout{Executing~ lastpage~ hook~
-                          on~ page~ \int_use:N \g_shipout_readonly_int }        }
-                      \_@@_add_foreground_box:n { \UseHook{shipout/lastpage}
-                                                  \@kernel at after@shipout at lastpage }
+                          on~ page~ \int_use:N \g_shipout_readonly_int } }
+                      \_@@_add_foreground_box:n
+                          { \UseHook{shipout/lastpage}
+                            \@kernel at after@shipout at lastpage }
                     }
                     \bool_gset_true:N \g_@@_lastpage_handled_bool
                 }
+              \@@_finalize_box:
 %    \end{macrocode}
 %    Finally we run the actual \TeX{} primitive for shipout. As that will
 %    expand delayed \cs{write} statements inside the page in which
@@ -732,6 +1015,21 @@
 %    \begin{macrocode}
               \cs_set_eq:NN \protect \exp_not:N
               \tex_shipout:D \box_use:N \l_shipout_box
+%    \end{macrocode}
+%    The \cs{l_shipout_box} may contain the firstpage material if this
+%    was the very first shipout. That makes it unsuitable for reuse in
+%    another shipout, so as a safety measure the next command resets
+%    \cs{l_shipout_box} to its earlier state if that is necessary. On
+%    later pages this is then a no-op.
+%    \begin{macrocode}
+              \@@_drop_firstpage_specials:
+%    \end{macrocode}
+%    The \hook{shipout/after} hook (if in \verb=#4=) needs to run with
+%    \cs{protect}ed commands again being executed, because that hook
+%    will ``typeset'' material added at the top of the next page.
+%    \begin{macrocode}
+              \set at typeset@protect
+              #4
             }
         }
 %    \end{macrocode}
@@ -746,14 +1044,62 @@
 %  \end{macro}
 %
 %
+%
+%
+%  \begin{macro}{\@@_execute_raw:,
+%                \@@_execute_test_level_raw:}
+%
+%    This implements the ``raw'' shipout which bypasses the before,
+%    foreground, background and after hooks. It follows the same pattern than
+%    \cs{_@@_execute_raw:} except that it finally calls
+%    \cs{_@@_execute_main_cont:Nnnn} with three empty arguments.
+%    instead of the hook code.
+%    \begin{macrocode}
+\cs_set_protected:Npn \@@_execute_raw: {
+  \tl_set:Nx \l_@@_group_level_tl
+     { \int_value:w \tex_currentgrouplevel:D }
+  \tex_afterassignment:D \@@_execute_test_level_raw:
+  \tex_setbox:D \l_@@_raw_box
+}
+%    \end{macrocode}
+%    
+%    \begin{macrocode}
+\cs_new:Npn \@@_execute_test_level_raw: {
+  \int_compare:nNnT
+     \l_@@_group_level_tl < \tex_currentgrouplevel:D
+     \tex_aftergroup:D \@@_execute_nohooks_cont:
+}
+%    \end{macrocode}
+%    Well, not totally empty arguments, we add some debugging if we
+%    are actually doing a shipout.
+%    \begin{macrocode}
+\cs_new:Npn \@@_execute_nohooks_cont: {
+  \@@_execute_main_cont:Nnnn \l_@@_raw_box
+     {} { \@@_debug:n{ \typeout{Doing~ raw~ shipout~ ...} }
+          \box_set_eq:NN \l_shipout_box \l_@@_raw_box } {} 
+} 
+%    \end{macrocode}
+%  \end{macro}
+
+%  \begin{macro}{\RawShipout}
+%    The interface name for raw shipout.
+% \changes{v1.0g}{2021/01/10}{Macro added}
+%    \begin{macrocode}
+\cs_gset_eq:NN \RawShipout \@@_execute_raw:
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%
+%
 %  \begin{macro}{\@@_saved_protect:}
-%    Remeber the current \cs{protect} state.
+%    Remember the current \cs{protect} state.
 %    \begin{macrocode}
 \cs_new_eq:NN  \@@_saved_protect: \protect
 %    \end{macrocode}
 %  \end{macro}
 %
-%  \begin{macro}{shipout/before,
+%  \begin{macro}{shipout/before,shipout/after,
 %                   shipout/foreground,shipout/background,
 %                   shipout/firstpage,
 %                   shipout/lastpage}
@@ -760,6 +1106,7 @@
 %    Declaring all hooks for the shipout code.
 %    \begin{macrocode}
 \hook_new:n{shipout/before}
+\hook_new:n{shipout/after}
 \hook_new:n{shipout/foreground}
 \hook_new:n{shipout/background}
 \hook_new:n{shipout/firstpage}
@@ -770,36 +1117,71 @@
 %
 %
 %  \begin{macro}{\@kernel at after@shipout at lastpage,
-%                \@kernel at before@shipout at background}
+%                \@kernel at before@shipout at background,
+%                \@kernel at after@shipout at background}
 %    And here are the internal kernel hooks going before or after the
 %    public ones where needed.
+% \changes{v1.0g}{2021/01/10}{Internal hook
+%                             \cs{@kernel at after@shipout at background} added}
 %    \begin{macrocode}
 \let\@kernel at after@shipout at lastpage\@empty
 \let\@kernel at before@shipout at background\@empty
+\let\@kernel at after@shipout at background\@empty
 %    \end{macrocode}
 %  \end{macro}
 %
 %
-%  \begin{macro}{\@@_execute_firstpage_hook: }
-%    This command adds any specials into a box and adds that to the
-%    very beginning of the first box shipped out. After that we
-%    redefine it to do nothing on later pages.
+%  \begin{macro}{\@@_run_firstpage_hook:}
+%
+% \changes{v1.0h}{2021/01/19}{Handling of firstpage hook altered}
+%
+%    There are three commands to handle the \hook{shipout/firstpage}
+%    hook:
+%    \cs{@@_run_firstpage_hook:}, \cs{@@_add_firstpage_specials:} and
+%    \cs{@@_drop_firstpage_specials:}. 
+%
+%    That hook is supposed to contain \cs{special}s and similar
+%    material to be placed at the very beginning of the output page
+%    and so it needs careful placing to avoid that anything else gets
+%    in front of it. And this means we have to wait with this until
+%    other hooks such as \hook{shipout/background} have added their
+%    bits. It is also important that such \cs{special}s show up only
+%    on the very first page, so if this page gets saved before
+%    \cs{shipout} for later reuse, we have to make sure that they
+%    aren't in the saved version.
+%
+%    In addition the hook may also contain code to be executed ``first'', e.g.,
+%    visible from code in \hook{shipout/background} and this conflicts
+%    with adding the \cs{special}s late.
+%
+%    Therefore the processing is split into different parts:
+%    \cs{@@_run_firstpage_hook:} is done early and checks if there is
+%    any material in the hook. 
 %    \begin{macrocode}
-\cs_new:Npn \@@_execute_firstpage_hook: {
+\cs_new:Npn \@@_run_firstpage_hook: {
+  \hook_if_empty:nTF {shipout/firstpage}
 %    \end{macrocode}
-%    Adding something to the beginning means adding it to the
-%    background as that  layer is done first in the output. Of course
-%    that is only needed if the hook actually contains anything.
+%    If not then we define the other two commands to do nothing.
 %    \begin{macrocode}
-  \hook_if_empty:nF {shipout/firstpage}
-       { \@@_add_background_box:n { \UseHook{shipout/firstpage} } }
+       {
+         \cs_gset_eq:NN \@@_add_firstpage_specials:  \prg_do_nothing:
+         \cs_gset_eq:NN \@@_drop_firstpage_specials: \prg_do_nothing:
+       }
 %    \end{macrocode}
+%    If there is material we execute inside a box, which means any
+%    \cs{special} will end up in that box and any other code is
+%    executed and can have side effects (as long as they are global).
+%    \begin{macrocode}
+       {
+         \hbox_set:Nn \l_@@_firstpage_box { \UseHook{shipout/firstpage} }
+       }
+%    \end{macrocode}
 %    Once we are here we change the definition to do nothing next time
 %    and we also change the command used to implement \cs{AtBeginDvi}
-%    to become a warning and not  add further material to a hook that
+%    to become a warning and not add further material to a hook that
 %    is never used again.
 %    \begin{macrocode}
-  \cs_gset_eq:NN \@@_execute_firstpage_hook: \prg_do_nothing:
+  \cs_gset_eq:NN \@@_run_firstpage_hook: \prg_do_nothing:
   \cs_gset:Npn \@@_add_firstpage_material:Nn ##1 ##2 {
     \@latex at warning{
         First~ page~ is~ already~ shipped~ out,~ ignoring\MessageBreak
@@ -807,8 +1189,67 @@
   }
 }
 %    \end{macrocode}
+% \end{macro}
+%
+%
+%
+%  \begin{macro}{\@@_add_firstpage_specials:,\@@_drop_firstpage_specials:}
+%    The \cs{@@_add_firstpage_specials:} then adds the \cs{special}s
+%    stored in \cs{l_@@_firstpage_box} to the page to be shipped out
+%    when the time is ready. Note that if there was no material in the
+%    \hook{shipout/firstpage} hook then this command gets redefined to
+%    do nothing. But for most documents there is something, e.g., some
+%    PostScript header, or some meta data declaration, etc.\ so by 
+%    default we assume there is something to do.
+%    \begin{macrocode}
+\cs_new:Npn \@@_add_firstpage_specials: {
+%    \end{macrocode}
+%    First we make a copy of the \cs{l_shipout_box} that we can
+%    restore it later on.
+%    \begin{macrocode}
+  \box_set_eq:NN \l_@@_raw_box \l_shipout_box
+%    \end{macrocode}
+%    Adding something to the beginning means adding it to the
+%    background as that layer is done first in the output. 
+%    \begin{macrocode}
+  \@@_add_background_box:n { \hbox_unpack_drop:N \l_@@_firstpage_box }
+%    \end{macrocode}
+%    After the actual shipout \cs{@@_drop_firstpage_specials:} is
+%    run to
+%    restore the earlier content of \cs{l_shipout_box} and then
+%    redefines itself again to do nothing.
+%
+%    As a final act we change the definition to do nothing next time.
+%    \begin{macrocode}
+  \cs_gset_eq:NN \@@_add_firstpage_specials: \prg_do_nothing:
+}
+%    \end{macrocode}
+%
+%    The \cs{@@_drop_firstpage_specials:} is run after the shipout has
+%    occurred but before the \hook{shipout/afterpage} hook is executed.
+%    That is the point where we have to restore the \cs{ShipoutBox} to
+%    its state without the \hook{shipout/firstpage} material.
+%    \begin{macrocode}
+\cs_new:Npn \@@_drop_firstpage_specials: {
+    \box_set_eq:NN \l_shipout_box \l_@@_raw_box
+%    \end{macrocode}
+%    If there was no such material then \cs{@@_run_firstpage_hook:}
+%    will have changed the definition to a no-op already. Otherwise
+%    this is what we do here.
+%    \begin{macrocode}
+    \cs_gset_eq:NN \@@_drop_firstpage_specials:  \prg_do_nothing:
+  }
+%    \end{macrocode}
 %  \end{macro}
 %
+
+%  \begin{macro}{\l_@@_firstpage_box}
+%    The box to hold any firstpage \cs{special}s.
+%    \begin{macrocode}
+\box_new:N \l_@@_firstpage_box
+%    \end{macrocode}
+%  \end{macro}
+
 %
 %  \begin{macro}{\g_@@_lastpage_handled_bool}
 %    A boolean to signal if we have already handled the
@@ -849,8 +1290,8 @@
   \dim_set:Nn \l_shipout_box_ht_dim { \box_ht:N #1 }
   \dim_set:Nn \l_shipout_box_dp_dim { \box_dp:N #1 }
   \dim_set:Nn \l_shipout_box_wd_dim { \box_wd:N #1 }
-  \dim_set:Nn \l_shipout_box_ht_plus_dp_dim { \l_shipout_box_ht_dim +
-                                         \l_shipout_box_dp_dim }
+  \dim_set:Nn \l_shipout_box_ht_plus_dp_dim
+      { \l_shipout_box_ht_dim + \l_shipout_box_dp_dim }
 }
 %    \end{macrocode}
 %  \end{macro}
@@ -883,7 +1324,7 @@
 %  \begin{macro}{\l_@@_tmp_box,\l_@@_saved_badness_tl}
 %    We need a box for the background and foreground material and a
 %    token register to remember badness settings as we disable  them
-%    during te buildup below.
+%    during the buildup below.
 %    \begin{macrocode}
 \box_new:N \l_@@_tmp_box
 \tl_new:N  \l_@@_saved_badness_tl
@@ -1088,7 +1529,7 @@
 %    \begin{macrocode}
 \cs_new:Npn \@@_picture_overlay:n #1 {
 %    \end{macrocode}
-%    The very first time this is executed we have to initializes (and
+%    The very first time this is executed we have to initialize (and
 %    freeze) the origins.
 %    \begin{macrocode}
     \@@_init_page_origins:
@@ -1183,7 +1624,7 @@
 %
 %  \begin{macro}{\g_shipout_totalpages_int,\c at totalpages}
 %    We count every shipout attempt (even those that are discarded) in
-%    tis counter. It is not used in the code but may get used in user
+%    this counter. It is not used in the code but may get used in user
 %    code.
 %    \begin{macrocode}
 \int_new:N \g_shipout_totalpages_int
@@ -1207,7 +1648,7 @@
 %    or the statement is missing from it we initialize it with the
 %    largest possible number in \TeX{}. We use this as the default
 %    because then we are inserting the \hook{shipout/lastpage} on
-%    the last page (or after the last page but not on page 1 for a
+%    the last page (or after the last page) but not on page 1 for a
 %    multipage document.
 %    \begin{macrocode}
 \xdef\@abspage at last{\number\maxdimen}
@@ -1219,11 +1660,11 @@
 %
 %    Instead of using the hooks \hook{enddocument} and
 %    \hook{enddocument/afterlastpage} we add this code to private
-%    kernel hooks to be 100\% when it is executed and to avoid
+%    kernel hooks to be 100\% sure when it is executed and to avoid
 %    cluttering the hooks with data that is always there.
 %
 %    Inside \cs{enddocument} there is a \cs{clearpage}. Just before
-%    that we execute this code here. There is a good change that we
+%    that we execute this code here. There is a good chance that we
 %    are on the last page. Therefore, if we don't know the value from
 %    the last run, we assume that the current page is the right
 %    one. So we set \cs{@abspage at last} and as a result the next
@@ -1307,7 +1748,7 @@
 %    At this point we also signal to \LaTeX{}'s endgame that a rerun is
 %    necessary so that an appropriate message can be shown on the
 %    terminal. We do this by simply defining a command used as a flag and
-%    tested \cs{enddocument}.
+%    tested in \cs{enddocument}.
 %    \begin{macrocode}
               \cs_gset_eq:NN \@extra at page@added \relax
             }
@@ -1380,7 +1821,8 @@
 %    defined so we better not use \cs{cs_new_protected:Npn} here.
 % \changes{v1.0d}{2020/11/24}{Support for roll forward (gh/434)}
 %    \begin{macrocode}
-\cs_set_protected:Npn \AtBeginDvi {\@@_add_firstpage_material:Nn \AtBeginDvi}
+\cs_set_protected:Npn \AtBeginDvi
+                      {\@@_add_firstpage_material:Nn \AtBeginDvi}
 %    \end{macrocode}
 %  \end{macro}
 %
@@ -1409,6 +1851,7 @@
 %                \@expl@@@shipout at add@foreground at picture@@n}
 %    Some internals needed elsewhere.
 %
+%  \InternalDetectionOff
 %    \begin{macrocode}
 \cs_set_eq:NN \@expl@@@shipout at add@firstpage at material@@Nn
               \__shipout_add_firstpage_material:Nn
@@ -1433,6 +1876,7 @@
 \cs_set_eq:NN \@expl@@@shipout at add@foreground at picture@@n
               \__shipout_add_foreground_picture:n
 %    \end{macrocode}
+%  \InternalDetectionOn
 %  \end{macro}
 %
 %    \begin{macrocode}
@@ -1449,7 +1893,7 @@
 %    
 %    \begin{macrocode}
 %<latexrelease>\IncludeInRelease{0000/00/00}%
-%<latexrelease>                 {\shipout}{The hook management (shipout)}%
+%<latexrelease>                 {\shipout}{Hook management (shipout)}%
 %<latexrelease>
 %    \end{macrocode}
 %    If we roll forward then \cs{tex\_shipout:D} may not be defined in
@@ -1462,6 +1906,7 @@
 %<latexrelease>                \csname tex_shipout:D\endcsname
 %<latexrelease>\fi
 %<latexrelease>
+%<latexrelease>\let \RawShipout\@undefined
 %<latexrelease>\let \ShipoutBox\@undefined
 %<latexrelease>\let \ReadonlyShipoutCounter \@undefined
 %<latexrelease>\let \c at totalpages \@undefined
@@ -1485,23 +1930,13 @@
 %<latexrelease>\let \ShipoutBoxDepth \@undefined
 %<latexrelease>\let \ShipoutBoxWidth \@undefined
 %<latexrelease>
-%<latexrelease>\let \AtBeginShipoutDiscard \@undefined
-%<latexrelease>
-%<latexrelease>\let \AtBeginShipoutAddToBox \@undefined
-%<latexrelease>\let \AtBeginShipoutAddToBoxForeground \@undefined
-%<latexrelease>\let \AtBeginShipoutUpperLeft \@undefined
-%<latexrelease>\let \AtBeginShipoutUpperLeftForeground \@undefined
-%<latexrelease>
 %    \end{macrocode}
 %    We do not undo a substitution when rolling back. As the file
 %    support gets undone the underlying data is no longer used (and
-%    sufficiently obscure that should not interfer with existing
+%    sufficiently obscure that it should not interfere with existing
 %    commands) and properly removing it would mean we need to make the
-%    \cs{unclare at ...} and its support macros available in all earlier
+%    \cs{undeclare at ...} and its support macros available in all earlier
 %    kernel releases which is pointless (and actually worse).
-%    \begin{macrocode}
-%\undeclare at file@substitution{everyshi.sty}
-%    \end{macrocode}
 %    
 %    \begin{macrocode}
 %<latexrelease>
@@ -1509,7 +1944,7 @@
 %    \end{macrocode}
 %    We do not reenable a disabled package load when rolling back. As the file
 %    support gets undone the underlying data is no longer checked (and
-%    sufficiently obscure that it should not interfer with existing
+%    sufficiently obscure that it should not interfere with existing
 %    commands) and properly removing it would mean we need to make the
 %    \cs{reenable at package@load} command available in all earlier
 %    kernel releases which is pointless (and actually worse).
@@ -1585,8 +2020,8 @@
 %    \begin{macrocode}
 %<*atbegshi-ltx>
 \ProvidesPackage{atbegshi-ltx}
-   [2020/08/17 v1.0a
-     Emulation of the original atbegshi package^^Jwith kernel methods]
+   [2021/01/10 v1.0c
+     Emulation of the original atbegshi^^Jpackage with kernel methods]
 %    \end{macrocode}
 %
 %
@@ -1597,6 +2032,7 @@
 %  \end{macro}
 %
 %
+%
 %  \begin{macro}{\AtBeginShipoutInit}
 %    Compatibility only, we aren't delaying \ldots
 %    \begin{macrocode}
@@ -1650,15 +2086,27 @@
 %    \end{macrocode}
 %  \end{macro}
 %
+%  \begin{macro}{\AtBeginShipoutOriginalShipout}
+%    This offers the raw \cs{shipout} primitive of the engine. A page
+%    shipped out with this is not counted by
+%    \cs{ReadonlyShipoutCounter} counter and thus the mechanism to
+%    place \cs{special}s at the very end of the output might fail,
+%    etc. It should therefore not be used in new applications but is
+%    only provided to allow  running legacy code. For new code use the
+%    commands provided by the kernel instead.
+%    \begin{macrocode}
+\ExplSyntaxOn
+\cs_new_eq:NN \AtBeginShipoutOriginalShipout \tex_shipout:D
+%    \end{macrocode}
+%  \end{macro}
 %
 %
-%  \begin{macro}{\ShipoutBoxHeight,\ShipoutBoxWidth,\ShipoutoBoxDepth}
+%  \begin{macro}{\ShipoutBoxHeight,\ShipoutBoxWidth,\ShipoutBoxDepth}
 %    This is somewhat different from the original in \pkg{atbegshi}
 %    where \cs{ShipoutBoxHeight} etc.\ only holds the
 %    \verb=\the\ht<box>= value. This may has some implications in some
 %    use cases and if that is a problem then it might need changing.
 %    \begin{macrocode}
-\ExplSyntaxOn  
 \cs_new:Npn \ShipoutBoxHeight { \dim_use:N \l_shipout_box_ht_dim }
 \cs_new:Npn \ShipoutBoxDepth  { \dim_use:N \l_shipout_box_dp_dim }
 \cs_new:Npn \ShipoutBoxWidth  { \dim_use:N \l_shipout_box_wd_dim }
@@ -1685,58 +2133,10 @@
 %
 % \subsection{Package \pkg{everyshi} emulation}
 %
-%    \begin{macrocode}
-%<*everyshi-ltx>
-%    \end{macrocode}
+%    This is now directly handled in that package so emulation is not
+%    necessary any more.
 %
-%    \begin{macrocode}
-\ProvidesPackage{everyshi-ltx}
-   [2020/08/17 v1.0a
-    Emulation of the original everyshi package^^Jwith kernel methods]
-%    \end{macrocode}
-%    
-%  \begin{macro}{\EveryShipout,\AtNextShipout}
-%    This package has only two public commands so simulating it is easy:
-%    \begin{macrocode}
-\protected \def \EveryShipout  {\AddToHook{shipout/before}}
-\protected \def \AtNextShipout {\AddToHookNext{shipout/before}}
-%    \end{macrocode}
-%  \end{macro}
 %
-%    \begin{macrocode}
-%    This is one difference between \pkg{everyshi} and the kernel
-%    implementation, the latter does not directly use box 255.
-%
-%    For usage by ordinary users this makes no difference but of a
-%    package use complicated code together with \pkg{everyshi} and
-%    directly manipulates box 255 then this package needs updating.
-%    In most cases the updates are simple because the kernel offers
-%    hooks that makes such complicated code unnecessary.
-%
-%    We therefore add a little file into the adjusted package
-%    \begin{macrocode}
-%%
-%%   In normal circumstances the above emulation is sufficient and in
-%%   all known packages (we know of) that use everyshi it either works or
-%%   the packages have been adjusted. 
-%%
-%%   Code that directly manipulates box 255, however, might fail. 
-%%   If that is the case look at the shipout hooks offered now as
-%%   they are normally sufficienct to avoid such minpulations (or
-%%   replace box 255 with \ShipoutBox in the code.
-%%
-%</everyshi-ltx>
-%    \end{macrocode}
-%
-%
-%    If the package is requested we substitute the one above:
-%    \begin{macrocode}
-%<*2ekernel>
-\declare at file@substitution{everyshi.sty}{everyshi-ltx.sty}
-%</2ekernel>
-%    \end{macrocode}
-%
-%
 %    Rather important :-)
 %    \begin{macrocode}
 %<@@=>

Modified: trunk/Master/texmf-dist/source/latex/base/ltspace.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltspace.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltspace.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/lttab.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/lttab.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/lttab.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -31,7 +31,7 @@
 %%% From File: lttab.dtx
 %<*driver>
 % \fi
-\ProvidesFile{lttab.dtx}[2020/04/24 v1.1r LaTeX Kernel (Columns)]
+\ProvidesFile{lttab.dtx}[2021/04/20 v1.1s LaTeX Kernel (Columns)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{lttab.dtx}
@@ -464,7 +464,7 @@
 %
 % \begin{macro}{\@tabcr}
 %    \begin{macrocode}
-\def\@tabcr{\@stopline \@ifstar{\penalty \@M \@xtabcr}\@xtabcr}
+\protected\def\@tabcr{\@stopline \@ifstar{\penalty \@M \@xtabcr}\@xtabcr}
 %    \end{macrocode}
 % \end{macro}
 %
@@ -964,8 +964,9 @@
 %
 %  \begin{macro}{\@arraycr}
 % Array version of |\\|.
+% \changes{v1.1s}{2021/04/20}{Use \cs{protected} for \cs{\bslash} variant (gh/548)}
 %    \begin{macrocode}
-\def\@arraycr{%
+\protected\def\@arraycr{%
   ${\ifnum0=`}\fi\@ifstar\@xarraycr\@xarraycr}
 %    \end{macrocode}
 % \end{macro}
@@ -994,8 +995,9 @@
 % \end{macro}
 %
 %  \begin{macro}{\@tabularcr}
+% \changes{v1.1s}{2021/04/20}{Use \cs{protected} for \cs{\bslash} variant (gh/548)}
 %    \begin{macrocode}
-\def\@tabularcr{%
+\protected\def\@tabularcr{%
   {\ifnum0=`}\fi\@ifstar\@xtabularcr\@xtabularcr}
 %    \end{macrocode}
 % \end{macro}

Modified: trunk/Master/texmf-dist/source/latex/base/lttextcomp.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/lttextcomp.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/lttextcomp.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 2019-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 2019-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -26,6 +26,9 @@
 % extension .ins) which are part of the distribution.
 %
 % \fi
+%
+%%% From File: lttextcomp.dtx
+%
 % \iffalse
 %
 %<*driver>
@@ -33,7 +36,7 @@
 %
 %
 \ProvidesFile{lttextcomp.dtx}
-             [2020/04/29 v1.0d LaTeX Kernel (text companion symbols)]
+             [2021/04/16 v1.0f LaTeX Kernel (text companion symbols)]
 % \iffalse
 \documentclass{ltxdoc}
 \begin{document}
@@ -46,7 +49,7 @@
 %
 %
 % \GetFileInfo{lttextcomp.dtx}
-% \title{Providing addtional text symbols\\
+% \title{Providing additional text symbols\\
 %        (previously available through the \texttt{textcomp} package)\thanks
 %       {This file has version number
 %       \fileversion\ dated \filedate}}
@@ -67,11 +70,17 @@
 %
 % \StopEventually{}
 %
+% \changes{v1.0e}{2021/03/19}
+%         {Use \cs{NewModuleRelease}}
+%    \begin{macrocode}
+%<*2ekernel|latexrelease>
+%<latexrelease>\NewModuleRelease{2020/02/02}{lttextcomp}
+%<latexrelease>                 {Text Companion symbols}
+%    \end{macrocode}
 %
 %  \begin{macro}{\oldstylenums}
 %  \begin{macro}{\legacyoldstylenums}
 %
-%
 %    Preserve the old definition of \cs{oldstylenums} under a different name.
 %
 %    This macro implements old style numerals but only works if we
@@ -78,9 +87,6 @@
 %    assume that the standard math fonts are used. Thus it needs
 %    changing in case other math encodings are used.
 %    \begin{macrocode}
-%<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2020/02/02}%
-%<latexrelease>                 {\oldstylenums}{Old style numerals}%
 \DeclareRobustCommand\legacyoldstylenums[1]{%
    \begingroup
 %    \end{macrocode}
@@ -112,7 +118,7 @@
    \mathgroup\symletters #1%
   \else
 %    \end{macrocode}
-%    The \cs{CheckEncodingSubset} is discused below.
+%    The \cs{CheckEncodingSubset} is discussed below.
 %    \begin{macrocode}
    \CheckEncodingSubset\@use at text@encoding{TS1}\tc at oldstylesubst2{{#1}}%
  \fi
@@ -154,44 +160,6 @@
 %    \end{macrocode}
 % \end{macro}
 %
-%
-%    \begin{macrocode}
-%</2ekernel|latexrelease>
-%<latexrelease>\EndIncludeInRelease
-%<latexrelease>\IncludeInRelease{0000/00/00}%
-%<latexrelease>                 {\oldstylenums}{Old style numerals}%
-%<latexrelease>
-%<latexrelease>\DeclareRobustCommand\oldstylenums[1]{%
-%<latexrelease>   \begingroup
-%<latexrelease>    \spaceskip\fontdimen\tw@\font
-%<latexrelease>    \usefont{OML}{\rmdefault}{\f at series}{it}%
-%<latexrelease>    \mathgroup\symletters #1%
-%<latexrelease>   \endgroup
-%<latexrelease>}
-%<latexrelease>\let\legacyoldstylenums\@undefined
-%<latexrelease>\def\textcompsubstdefault{cmr}
-%<latexrelease>
-%<latexrelease>\EndIncludeInRelease
-%    \end{macrocode}
-%
-%
-
-
-
-
-
-%    Everything else in the this file got introduced 2020/02/02, so we do a
-%    single rollback (for now).
-%    \begin{macrocode}
-%<*2ekernel>
-%</2ekernel>
-%<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2020/02/02}%
-%<latexrelease>   {\DeclareEncodingSubset}{Text companion symbols}%
-%    \end{macrocode}
-%
-%
-%
 %  \begin{macro}{\DeclareEncodingSubset}
 %
 %     The declaration takes 3 mandatory arguments: an \emph{encoding}
@@ -200,7 +168,7 @@
 %    declare the subset and finally the \emph{subset} number (between \texttt{0} (all
 %    of the encoding is supported) and \texttt{9} many glyphs are missing.
 %
-%    For \texttt{TS1} the numbers have been choosen in a way that most
+%    For \texttt{TS1} the numbers have been chosen in a way that most
 %    fonts can be fairly correctly categorized, but the default
 %    settings are always conservative, that is they may claim that
 %    less glyphs are supported than there actually are.
@@ -362,13 +330,14 @@
 }
 %    \end{macrocode}
 %  \end{macro}
-
-
-
-
+%
+%
+%
+%
+%
 % \begin{macro}{\tc at fake@euro}
 %    |\tc at fake@euro|  is an example of a ``fake'' definition to use in  arg |#3| of
-%    |\CheckEncodingSubset| when a symbol is not available in a
+%    the command |\CheckEncodingSubset| when a symbol is not available in a
 %    certain font family. Here we produce a poor man's Euro symbol by combining
 %    a ``C'' with a ``=''.
 %    \begin{macrocode}
@@ -386,10 +355,10 @@
 }
 %    \end{macrocode}
 % \end{macro}
-
-
-
-
+%
+%
+%
+%
 % \begin{macro}{\tc at check@symbol}
 % \begin{macro}{\tc at check@accent}
 %    These are two abbreviations that we use below to check symbols
@@ -401,14 +370,14 @@
 %    to ensure that |\textcurrency| is only typeset if the current
 %    font has a \texttt{TS1} subset id of less than 3. Otherwise
 %    |\tc at error| is called telling the user that for this font family
-%    |\textcurreny| is not available.
+%    |\textcurrency| is not available.
 %    \begin{macrocode}
 \def\tc at check@symbol{\CheckEncodingSubset\UseTextSymbol{TS1}\tc at subst}
 %    \end{macrocode}
 %
-%    Accents and been mad an error in the \texttt{textcomp} package when
+%    Accents have been made an error in the \texttt{textcomp} package when
 %    not available. Now that we provide the functionality in the
-%    kernel we avoid the eror by swapping in a \texttt{T1} accent if
+%    kernel we avoid the error by swapping in a \texttt{T1} accent if
 %    the \texttt{TS1} accent is not available.
 %    \begin{macrocode}
 %\def\tc at check@accent{\CheckEncodingSubset\UseTextAccent{TS1}\tc at error}
@@ -415,7 +384,8 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\def\tc at check@accent#1{\CheckEncodingSubset\UseTextAccent{TS1}{\tc at swap@accent#1}}
+\def\tc at check@accent#1{\CheckEncodingSubset\UseTextAccent
+                                           {TS1}{\tc at swap@accent#1}}
 \def\tc at swap@accent#1#2{\UseTextAccent{T1}#1}
 %    \end{macrocode}
 % \end{macro}
@@ -430,17 +400,17 @@
 %
 %    \begin{macrocode}
 \DeclareTextSymbolDefault{\textdollar}{TS1}
-\UndeclareTextCommand{\textdollar}  {OT1}         % don't use the OT1 def any longer
+\UndeclareTextCommand{\textdollar}{OT1}  % don't use the OT1 def any longer
 %    \end{macrocode}
 %
 %    \begin{macrocode}
 \DeclareTextSymbolDefault{\textsterling}{TS1}
-\UndeclareTextCommand{\textsterling}{OT1}         % don't use the OT1 def any longer
+\UndeclareTextCommand{\textsterling}{OT1}% don't use the OT1 def any longer
 %    \end{macrocode}
 %
 %    \begin{macrocode}
 \DeclareTextSymbolDefault{\textperthousand}{TS1}
-\UndeclareTextCommand{\textperthousand}{T1}       % don't use the T1 def
+\UndeclareTextCommand{\textperthousand}{T1} % don't use the T1 def
 %    \end{macrocode}
 %    Using \cs{UndeclareTextCommand} above is enough only if the
 %    encoding definition files are not reloaded afterwards. In the
@@ -462,9 +432,9 @@
 %    \end{macrocode}
 %
 %    And here are the other \texttt{TS1} glyphs that are implemented
-%    by every font (or nearly everyone---a few are commented out and
+%    by every font (or nearly every---a few are commented out and
 %    moved to sub-encoding 9,
-%    because they aren't around in one or two fonts.
+%    because they aren't around in some fonts.
 %    \begin{macrocode}
 %%\DeclareTextSymbolDefault{\textbardbl}{TS1} % subst in sub-enc 9 above
 \DeclareTextSymbolDefault{\textbrokenbar}{TS1}
@@ -541,31 +511,49 @@
 %
 %    \begin{macrocode}
 \ifx\Umathcode\@undefined
-  \DeclareTextCommandDefault{\capitalacute}       {\tc at check@accent{\'}2\capitalacute}
-  \DeclareTextCommandDefault{\capitalbreve}       {\tc at check@accent{\u}2\capitalbreve}
-  \DeclareTextCommandDefault{\capitalcaron}       {\tc at check@accent{\v}2\capitalcaron}
-  \DeclareTextCommandDefault{\capitalcedilla}     {\tc at check@accent{\c}2\capitalcedilla}
-  \DeclareTextCommandDefault{\capitalcircumflex}  {\tc at check@accent{\^}2\capitalcircumflex}
-  \DeclareTextCommandDefault{\capitaldieresis}    {\tc at check@accent{\"}2\capitaldieresis}
-  \DeclareTextCommandDefault{\capitaldotaccent}   {\tc at check@accent{\.}2\capitaldotaccent}
-  \DeclareTextCommandDefault{\capitalgrave}       {\tc at check@accent{\`}2\capitalgrave}
-  \DeclareTextCommandDefault{\capitalhungarumlaut}{\tc at check@accent{\H}2\capitalhungarumlaut}
-  \DeclareTextCommandDefault{\capitalmacron}      {\tc at check@accent{\=}2\capitalmacron}
-  \DeclareTextCommandDefault{\capitalogonek}      {\tc at check@accent{\k}2\capitalogonek}
-  \DeclareTextCommandDefault{\capitalring}        {\tc at check@accent{\r}2\capitalring}
-  \DeclareTextCommandDefault{\capitaltie}         {\tc at check@accent{\t}2\capitaltie}
-  \DeclareTextCommandDefault{\capitaltilde}       {\tc at check@accent{\~}2\capitaltilde}
+  \DeclareTextCommandDefault{\capitalacute}
+                            {\tc at check@accent{\'}2\capitalacute}
+  \DeclareTextCommandDefault{\capitalbreve}
+                            {\tc at check@accent{\u}2\capitalbreve}
+  \DeclareTextCommandDefault{\capitalcaron}
+                            {\tc at check@accent{\v}2\capitalcaron}
+  \DeclareTextCommandDefault{\capitalcedilla}
+                            {\tc at check@accent{\c}2\capitalcedilla}
+  \DeclareTextCommandDefault{\capitalcircumflex}
+                            {\tc at check@accent{\^}2\capitalcircumflex}
+  \DeclareTextCommandDefault{\capitaldieresis}
+                            {\tc at check@accent{\"}2\capitaldieresis}
+  \DeclareTextCommandDefault{\capitaldotaccent}
+                            {\tc at check@accent{\.}2\capitaldotaccent}
+  \DeclareTextCommandDefault{\capitalgrave}
+                            {\tc at check@accent{\`}2\capitalgrave}
+  \DeclareTextCommandDefault{\capitalhungarumlaut}
+                            {\tc at check@accent{\H}2\capitalhungarumlaut}
+  \DeclareTextCommandDefault{\capitalmacron}
+                            {\tc at check@accent{\=}2\capitalmacron}
+  \DeclareTextCommandDefault{\capitalogonek}
+                            {\tc at check@accent{\k}2\capitalogonek}
+  \DeclareTextCommandDefault{\capitalring}
+                            {\tc at check@accent{\r}2\capitalring}
+  \DeclareTextCommandDefault{\capitaltie}
+                            {\tc at check@accent{\t}2\capitaltie}
+  \DeclareTextCommandDefault{\capitaltilde}
+                            {\tc at check@accent{\~}2\capitaltilde}
 %    \end{macrocode}
 %    For \cs{newtie} and \cs{capitalnewtie} this is actually wrong, they should pick up
 %    the accent from the substitution font (not done yet).
 %    \begin{macrocode}
-  \DeclareTextCommandDefault{\newtie}             {\tc at check@accent{\t}2\newtie}
-  \DeclareTextCommandDefault{\capitalnewtie}      {\tc at check@accent{\t}2\capitalnewtie}
+  \DeclareTextCommandDefault{\newtie}
+                            {\tc at check@accent{\t}2\newtie}
+  \DeclareTextCommandDefault{\capitalnewtie}
+                            {\tc at check@accent{\t}2\capitalnewtie}
 %    \end{macrocode}
 %
 %    In Unicode engines we just execute the simple accents:
-% \changes{v1.0c}{2020/02/10}{Use \cs{@tabacckludge} for tabbing where necessary (gh/271)}
-% \changes{v1.0d}{2020/04/29}{Make all captial accents text commands for hyperref (gh/332)}
+% \changes{v1.0c}{2020/02/10}{Use \cs{@tabacckludge} for
+%      tabbing where necessary (gh/271)}
+% \changes{v1.0d}{2020/04/29}{Make all capital accents text
+%      commands for hyperref (gh/332)}
 %    \begin{macrocode}
 \else
   \DeclareTextCommandDefault\capitalacute{\@tabacckludge'}
@@ -593,8 +581,10 @@
 %    The next two symbols exist in some fonts (faked?), but we ignore
 %    that to keep the subsets reasonable compact and most important linear.
 %    \begin{macrocode}
-\DeclareTextCommandDefault{\textlbrackdbl}      {\tc at check@symbol2\textlbrackdbl}
-\DeclareTextCommandDefault{\textrbrackdbl}      {\tc at check@symbol2\textrbrackdbl}
+\DeclareTextCommandDefault{\textlbrackdbl}
+                          {\tc at check@symbol2\textlbrackdbl}
+\DeclareTextCommandDefault{\textrbrackdbl}
+                          {\tc at check@symbol2\textrbrackdbl}
 %    \end{macrocode}
 %
 %
@@ -603,35 +593,54 @@
 %    claim they aren't in sub-encoding 2 as that's true for most
 %    fonts.
 %    \begin{macrocode}
-\DeclareTextCommandDefault{\texteightoldstyle}  {\tc at check@symbol2\texteightoldstyle}
-\DeclareTextCommandDefault{\textfiveoldstyle}   {\tc at check@symbol2\textfiveoldstyle}
-\DeclareTextCommandDefault{\textfouroldstyle}   {\tc at check@symbol2\textfouroldstyle}
-\DeclareTextCommandDefault{\textnineoldstyle}   {\tc at check@symbol2\textnineoldstyle}
-\DeclareTextCommandDefault{\textoneoldstyle}    {\tc at check@symbol2\textoneoldstyle}
-\DeclareTextCommandDefault{\textsevenoldstyle}  {\tc at check@symbol2\textsevenoldstyle}
-\DeclareTextCommandDefault{\textsixoldstyle}    {\tc at check@symbol2\textsixoldstyle}
-\DeclareTextCommandDefault{\textthreeoldstyle}  {\tc at check@symbol2\textthreeoldstyle}
-\DeclareTextCommandDefault{\texttwooldstyle}    {\tc at check@symbol2\texttwooldstyle}
-\DeclareTextCommandDefault{\textzerooldstyle}   {\tc at check@symbol2\textzerooldstyle}
+\DeclareTextCommandDefault{\texteightoldstyle}
+                          {\tc at check@symbol2\texteightoldstyle}
+\DeclareTextCommandDefault{\textfiveoldstyle}
+                          {\tc at check@symbol2\textfiveoldstyle}
+\DeclareTextCommandDefault{\textfouroldstyle}
+                          {\tc at check@symbol2\textfouroldstyle}
+\DeclareTextCommandDefault{\textnineoldstyle}
+                          {\tc at check@symbol2\textnineoldstyle}
+\DeclareTextCommandDefault{\textoneoldstyle}
+                          {\tc at check@symbol2\textoneoldstyle}
+\DeclareTextCommandDefault{\textsevenoldstyle}
+                          {\tc at check@symbol2\textsevenoldstyle}
+\DeclareTextCommandDefault{\textsixoldstyle}
+                          {\tc at check@symbol2\textsixoldstyle}
+\DeclareTextCommandDefault{\textthreeoldstyle}
+                          {\tc at check@symbol2\textthreeoldstyle}
+\DeclareTextCommandDefault{\texttwooldstyle}
+                          {\tc at check@symbol2\texttwooldstyle}
+\DeclareTextCommandDefault{\textzerooldstyle}
+                          {\tc at check@symbol2\textzerooldstyle}
 %    \end{macrocode}
 %
 %
 %
-%    The next set of glyphs is special to TeX fonts (and available
-%    with a few older PS fonts supported in the virtual fonts), but
+%    The next set of glyphs is special to \TeX{} fonts (and available
+%    with a few older PS fonts supported through virtual fonts), but
 %    not any longer in the majority of fonts provided through
 %    autoinst, so we pretend there aren't available in sub-encoding 2
 %    and below.
 %    \begin{macrocode}
-\DeclareTextCommandDefault{\textacutedbl}       {\tc at check@symbol2\textacutedbl}
-\DeclareTextCommandDefault{\textasciiacute}     {\tc at check@symbol2\textasciiacute}
-\DeclareTextCommandDefault{\textasciibreve}     {\tc at check@symbol2\textasciibreve}
-\DeclareTextCommandDefault{\textasciicaron}     {\tc at check@symbol2\textasciicaron}
-\DeclareTextCommandDefault{\textasciidieresis}  {\tc at check@symbol2\textasciidieresis}
-\DeclareTextCommandDefault{\textasciigrave}     {\tc at check@symbol2\textasciigrave}
-\DeclareTextCommandDefault{\textasciimacron}    {\tc at check@symbol2\textasciimacron}
-\DeclareTextCommandDefault{\textgravedbl}       {\tc at check@symbol2\textgravedbl}
-\DeclareTextCommandDefault{\texttildelow}       {\tc at check@symbol2\texttildelow}
+\DeclareTextCommandDefault{\textacutedbl}
+                          {\tc at check@symbol2\textacutedbl}
+\DeclareTextCommandDefault{\textasciiacute}
+                          {\tc at check@symbol2\textasciiacute}
+\DeclareTextCommandDefault{\textasciibreve}
+                          {\tc at check@symbol2\textasciibreve}
+\DeclareTextCommandDefault{\textasciicaron}
+                          {\tc at check@symbol2\textasciicaron}
+\DeclareTextCommandDefault{\textasciidieresis}
+                          {\tc at check@symbol2\textasciidieresis}
+\DeclareTextCommandDefault{\textasciigrave}
+                          {\tc at check@symbol2\textasciigrave}
+\DeclareTextCommandDefault{\textasciimacron}
+                          {\tc at check@symbol2\textasciimacron}
+\DeclareTextCommandDefault{\textgravedbl}
+                          {\tc at check@symbol2\textgravedbl}
+\DeclareTextCommandDefault{\texttildelow}
+                          {\tc at check@symbol2\texttildelow}
 %    \end{macrocode}
 %
 %
@@ -638,37 +647,64 @@
 %    Finally those below are only available in CM-based fonts but in
 %    no font that has its origin outside of the \TeX{} world.
 %    \begin{macrocode}
-\DeclareTextCommandDefault{\textbaht}           {\tc at check@symbol2\textbaht}
-\DeclareTextCommandDefault{\textbigcircle}      {\tc at check@symbol2\textbigcircle}
-\DeclareTextCommandDefault{\textborn}           {\tc at check@symbol2\textborn}
-\DeclareTextCommandDefault{\textcentoldstyle}   {\tc at check@symbol2\textcentoldstyle}
-\DeclareTextCommandDefault{\textcircledP}       {\tc at check@symbol2\textcircledP}
-\DeclareTextCommandDefault{\textcopyleft}       {\tc at check@symbol2\textcopyleft}
-\DeclareTextCommandDefault{\textdblhyphenchar}  {\tc at check@symbol2\textdblhyphenchar}
-\DeclareTextCommandDefault{\textdblhyphen}      {\tc at check@symbol2\textdblhyphen}
-\DeclareTextCommandDefault{\textdied}           {\tc at check@symbol2\textdied}
-\DeclareTextCommandDefault{\textdiscount}       {\tc at check@symbol2\textdiscount}
-\DeclareTextCommandDefault{\textdivorced}       {\tc at check@symbol2\textdivorced}
-\DeclareTextCommandDefault{\textdollaroldstyle} {\tc at check@symbol2\textdollaroldstyle}
-\DeclareTextCommandDefault{\textguarani}        {\tc at check@symbol2\textguarani}
-\DeclareTextCommandDefault{\textleaf}           {\tc at check@symbol2\textleaf}
-\DeclareTextCommandDefault{\textlquill}         {\tc at check@symbol2\textlquill}
-\DeclareTextCommandDefault{\textmarried}        {\tc at check@symbol2\textmarried}
-\DeclareTextCommandDefault{\textmho}            {\tc at check@symbol2\textmho}
-\DeclareTextCommandDefault{\textmusicalnote}    {\tc at check@symbol2\textmusicalnote}
-\DeclareTextCommandDefault{\textnaira}          {\tc at check@symbol2\textnaira}
-\DeclareTextCommandDefault{\textopenbullet}     {\tc at check@symbol2\textopenbullet}
-\DeclareTextCommandDefault{\textpeso}           {\tc at check@symbol2\textpeso}
-\DeclareTextCommandDefault{\textpilcrow}        {\tc at check@symbol2\textpilcrow}
-\DeclareTextCommandDefault{\textrecipe}         {\tc at check@symbol2\textrecipe}
-\DeclareTextCommandDefault{\textreferencemark}  {\tc at check@symbol2\textreferencemark}
-\DeclareTextCommandDefault{\textrquill}         {\tc at check@symbol2\textrquill}
-\DeclareTextCommandDefault{\textservicemark}    {\tc at check@symbol2\textservicemark}
-\DeclareTextCommandDefault{\textsurd}           {\tc at check@symbol2\textsurd}
+\DeclareTextCommandDefault{\textbaht}
+                          {\tc at check@symbol2\textbaht}
+\DeclareTextCommandDefault{\textbigcircle}
+                          {\tc at check@symbol2\textbigcircle}
+\DeclareTextCommandDefault{\textborn}
+                          {\tc at check@symbol2\textborn}
+\DeclareTextCommandDefault{\textcentoldstyle}
+                          {\tc at check@symbol2\textcentoldstyle}
+\DeclareTextCommandDefault{\textcircledP}
+                          {\tc at check@symbol2\textcircledP}
+\DeclareTextCommandDefault{\textcopyleft}
+                          {\tc at check@symbol2\textcopyleft}
+\DeclareTextCommandDefault{\textdblhyphenchar}
+                          {\tc at check@symbol2\textdblhyphenchar}
+\DeclareTextCommandDefault{\textdblhyphen}
+                          {\tc at check@symbol2\textdblhyphen}
+\DeclareTextCommandDefault{\textdied}
+                          {\tc at check@symbol2\textdied}
+\DeclareTextCommandDefault{\textdiscount}
+                          {\tc at check@symbol2\textdiscount}
+\DeclareTextCommandDefault{\textdivorced}
+                          {\tc at check@symbol2\textdivorced}
+\DeclareTextCommandDefault{\textdollaroldstyle}
+                          {\tc at check@symbol2\textdollaroldstyle}
+\DeclareTextCommandDefault{\textguarani}
+                          {\tc at check@symbol2\textguarani}
+\DeclareTextCommandDefault{\textleaf}
+                          {\tc at check@symbol2\textleaf}
+\DeclareTextCommandDefault{\textlquill}
+                          {\tc at check@symbol2\textlquill}
+\DeclareTextCommandDefault{\textmarried}
+                          {\tc at check@symbol2\textmarried}
+\DeclareTextCommandDefault{\textmho}
+                          {\tc at check@symbol2\textmho}
+\DeclareTextCommandDefault{\textmusicalnote}
+                          {\tc at check@symbol2\textmusicalnote}
+\DeclareTextCommandDefault{\textnaira}
+                          {\tc at check@symbol2\textnaira}
+\DeclareTextCommandDefault{\textopenbullet}
+                          {\tc at check@symbol2\textopenbullet}
+\DeclareTextCommandDefault{\textpeso}
+                          {\tc at check@symbol2\textpeso}
+\DeclareTextCommandDefault{\textpilcrow}
+                          {\tc at check@symbol2\textpilcrow}
+\DeclareTextCommandDefault{\textrecipe}
+                          {\tc at check@symbol2\textrecipe}
+\DeclareTextCommandDefault{\textreferencemark}
+                          {\tc at check@symbol2\textreferencemark}
+\DeclareTextCommandDefault{\textrquill}
+                          {\tc at check@symbol2\textrquill}
+\DeclareTextCommandDefault{\textservicemark}
+                          {\tc at check@symbol2\textservicemark}
+\DeclareTextCommandDefault{\textsurd}
+                          {\tc at check@symbol2\textsurd}
 %    \end{macrocode}
 %
 %    The \cs{textpertenthousand} also belongs in this group but here
-%    we have a choice: in T1 there is definition for
+%    we have a choice: in T1 there is a definition for
 %    \cs{textpertenthousand} making the symbol up from \% and
 %    \verb=\char 24= (twice) but in many fonts that char doesn't exist
 %    and the slot is reused for random ligatures. So better not use it
@@ -679,7 +715,8 @@
 %    Alternatively we could just state that the symbol is unavailable in
 %    those fonts. For now I substitute.
 %    \begin{macrocode}
-\DeclareTextCommandDefault{\textpertenthousand} {\tc at check@symbol2\textpertenthousand}
+\DeclareTextCommandDefault{\textpertenthousand}
+                          {\tc at check@symbol2\textpertenthousand}
 \UndeclareTextCommand{\textpertenthousand}{T1}
 %    \end{macrocode}
 %
@@ -691,8 +728,10 @@
 %    symbols. In the higher-numbered sub-encodings we see only a few
 %    dropped additionally.
 %    \begin{macrocode}
-\DeclareTextCommandDefault{\textlangle}         {\tc at check@symbol3\textlangle}
-\DeclareTextCommandDefault{\textrangle}         {\tc at check@symbol3\textrangle}
+\DeclareTextCommandDefault{\textlangle}
+                          {\tc at check@symbol3\textlangle}
+\DeclareTextCommandDefault{\textrangle}
+                          {\tc at check@symbol3\textrangle}
 %    \end{macrocode}
 %
 %
@@ -702,14 +741,22 @@
 % \subsection{Sub-encoding \texttt{4}}
 %
 %    \begin{macrocode}
-\DeclareTextCommandDefault{\textcolonmonetary}  {\tc at check@symbol4\textcolonmonetary}
-\DeclareTextCommandDefault{\textdong}           {\tc at check@symbol4\textdong}
-\DeclareTextCommandDefault{\textdownarrow}      {\tc at check@symbol4\textdownarrow}
-\DeclareTextCommandDefault{\textleftarrow}      {\tc at check@symbol4\textleftarrow}
-\DeclareTextCommandDefault{\textlira}           {\tc at check@symbol4\textlira}
-\DeclareTextCommandDefault{\textrightarrow}     {\tc at check@symbol4\textrightarrow}
-\DeclareTextCommandDefault{\textuparrow}        {\tc at check@symbol4\textuparrow}
-\DeclareTextCommandDefault{\textwon}            {\tc at check@symbol4\textwon}
+\DeclareTextCommandDefault{\textcolonmonetary}
+                          {\tc at check@symbol4\textcolonmonetary}
+\DeclareTextCommandDefault{\textdong}
+                          {\tc at check@symbol4\textdong}
+\DeclareTextCommandDefault{\textdownarrow}
+                          {\tc at check@symbol4\textdownarrow}
+\DeclareTextCommandDefault{\textleftarrow}
+                          {\tc at check@symbol4\textleftarrow}
+\DeclareTextCommandDefault{\textlira}
+                          {\tc at check@symbol4\textlira}
+\DeclareTextCommandDefault{\textrightarrow}
+                          {\tc at check@symbol4\textrightarrow}
+\DeclareTextCommandDefault{\textuparrow}
+                          {\tc at check@symbol4\textuparrow}
+\DeclareTextCommandDefault{\textwon}
+                          {\tc at check@symbol4\textwon}
 %    \end{macrocode}
 %
 %
@@ -720,7 +767,7 @@
 %
 %    Most older PS fonts (supported in \TeX{} since the early nineties
 %    when virtual fonts became available) are sorted under this
-%    sub-encoding. But in reality, many of them don't have all glpyhs
+%    sub-encoding. But in reality, many of them don't have all glyphs
 %    that should be available in sub-encoding \texttt{5}. Instead they
 %    show little squares, i.e., they produce ``tofu'' if you are
 %    unlucky.
@@ -727,15 +774,17 @@
 %
 %    But the coverage is so random that it is impossible to sort them
 %    properly and if we tried to ensure that they only typeset those
-%    glyphs that are really  always available wouput put them all into
-%    sub-encoding \texttt{9} so that's a compromise really.
+%    glyphs that are really  always available, we would have to put them all into
+%    sub-encoding \texttt{9}; so putting them into 5 is really a compromise.
 %
-%    Modern fonts that don't typeset a tofu character if a glyph is
-%    missing are only cataloged as sub-encoding \texttt{5} if they
-%    really support of its glyph set.
+%    Modern fonts usually don't typeset a tofu character if a glyph is
+%    missing. They are therefore only classified as sub-encoding \texttt{5} if they
+%    really support its glyph set completely.
 %    \begin{macrocode}
-\DeclareTextCommandDefault{\textestimated}      {\tc at check@symbol5\textestimated}
-\DeclareTextCommandDefault{\textnumero}         {\tc at check@symbol5\textnumero}
+\DeclareTextCommandDefault{\textestimated}
+                          {\tc at check@symbol5\textestimated}
+\DeclareTextCommandDefault{\textnumero}
+                          {\tc at check@symbol5\textnumero}
 %    \end{macrocode}
 %
 %
@@ -744,8 +793,10 @@
 % \subsection{Sub-encoding \texttt{6}}
 %
 %    \begin{macrocode}
-\DeclareTextCommandDefault{\textflorin}         {\tc at check@symbol6\textflorin}
-\DeclareTextCommandDefault{\textcurrency}       {\tc at check@symbol6\textcurrency}
+\DeclareTextCommandDefault{\textflorin}
+                          {\tc at check@symbol6\textflorin}
+\DeclareTextCommandDefault{\textcurrency}
+                          {\tc at check@symbol6\textcurrency}
 %    \end{macrocode}
 %
 %
@@ -753,10 +804,14 @@
 % \subsection{Sub-encoding \texttt{7}}
 %
 %    \begin{macrocode}
-\DeclareTextCommandDefault{\textfractionsolidus}{\tc at check@symbol7\textfractionsolidus}
-\DeclareTextCommandDefault{\textohm}            {\tc at check@symbol7\textohm}
-\DeclareTextCommandDefault{\textmu}             {\tc at check@symbol7\textmu}
-\DeclareTextCommandDefault{\textminus}          {\tc at check@symbol7\textminus}
+\DeclareTextCommandDefault{\textfractionsolidus}
+                          {\tc at check@symbol7\textfractionsolidus}
+\DeclareTextCommandDefault{\textohm}
+                          {\tc at check@symbol7\textohm}
+\DeclareTextCommandDefault{\textmu}
+                          {\tc at check@symbol7\textmu}
+\DeclareTextCommandDefault{\textminus}
+                          {\tc at check@symbol7\textminus}
 %    \end{macrocode}
 %
 %
@@ -764,9 +819,12 @@
 % \subsection{Sub-encoding \texttt{8}}
 %
 %    \begin{macrocode}
-\DeclareTextCommandDefault{\textblank}          {\tc at check@symbol{8}\textblank}
-\DeclareTextCommandDefault{\textinterrobangdown}{\tc at check@symbol{8}\textinterrobangdown}
-\DeclareTextCommandDefault{\textinterrobang}    {\tc at check@symbol{8}\textinterrobang}
+\DeclareTextCommandDefault{\textblank}
+                          {\tc at check@symbol{8}\textblank}
+\DeclareTextCommandDefault{\textinterrobangdown}
+                          {\tc at check@symbol{8}\textinterrobangdown}
+\DeclareTextCommandDefault{\textinterrobang}
+                          {\tc at check@symbol{8}\textinterrobang}
 %    \end{macrocode}
 %
 %    Fonts with this sub-encoding don't have a Euro symbol, but
@@ -773,7 +831,7 @@
 %    instead of substituting we fake it.
 %    \begin{macrocode}
 \DeclareTextCommandDefault{\texteuro}
-            {\CheckEncodingSubset\UseTextSymbol{TS1}\tc at fake@euro{8}\texteuro}
+  {\CheckEncodingSubset\UseTextSymbol{TS1}\tc at fake@euro{8}\texteuro}
 %    \end{macrocode}
 %
 %
@@ -782,13 +840,20 @@
 % \subsection{Sub-encoding \texttt{9} (most missing)}
 %
 %    \begin{macrocode}
-\DeclareTextCommandDefault{\textcelsius}{\tc at check@symbol{9}\textcelsius}
-\DeclareTextCommandDefault{\textonesuperior}{\tc at check@symbol{9}\textonesuperior}
-\DeclareTextCommandDefault{\textthreequartersemdash}{\tc at check@symbol{9}\textthreequartersemdash}
-\DeclareTextCommandDefault{\textthreesuperior}{\tc at check@symbol{9}\textthreesuperior}
-\DeclareTextCommandDefault{\texttwelveudash}{\tc at check@symbol{9}\texttwelveudash}
-\DeclareTextCommandDefault{\texttwosuperior}{\tc at check@symbol{9}\texttwosuperior}
-\DeclareTextCommandDefault{\textbardbl}{\tc at check@symbol{9}\textbardbl}
+\DeclareTextCommandDefault{\textcelsius}
+                          {\tc at check@symbol{9}\textcelsius}
+\DeclareTextCommandDefault{\textonesuperior}
+                          {\tc at check@symbol{9}\textonesuperior}
+\DeclareTextCommandDefault{\textthreequartersemdash}
+                          {\tc at check@symbol{9}\textthreequartersemdash}
+\DeclareTextCommandDefault{\textthreesuperior}
+                          {\tc at check@symbol{9}\textthreesuperior}
+\DeclareTextCommandDefault{\texttwelveudash}
+                          {\tc at check@symbol{9}\texttwelveudash}
+\DeclareTextCommandDefault{\texttwosuperior}
+                          {\tc at check@symbol{9}\texttwosuperior}
+\DeclareTextCommandDefault{\textbardbl}
+                          {\tc at check@symbol{9}\textbardbl}
 %    \end{macrocode}
 %
 %
@@ -830,20 +895,20 @@
 \DeclareTextCommand{\texteightoldstyle}\UnicodeEncodingName{\oldstylenums{8}}
 \DeclareTextCommand{\textnineoldstyle} \UnicodeEncodingName{\oldstylenums{9}}
 %    \end{macrocode}
-%    These have Unicode slots so this should be integrated into TU explictly
+%    These have Unicode slots so this should be integrated into TU explicitly
 %    \begin{macrocode}
-\DeclareTextSymbol{\textpilcrow}       \UnicodeEncodingName{"00B6}
-\DeclareTextSymbol{\textborn}          \UnicodeEncodingName{"002A}
-\DeclareTextSymbol{\textdied}          \UnicodeEncodingName{"2020}
-\DeclareTextSymbol{\textlbrackdbl}     \UnicodeEncodingName{"27E6}
-\DeclareTextSymbol{\textrbrackdbl}     \UnicodeEncodingName{"27E7}
-\DeclareTextSymbol{\textguarani}       \UnicodeEncodingName{"20B2}
+\DeclareTextSymbol{\textpilcrow}        \UnicodeEncodingName{"00B6}
+\DeclareTextSymbol{\textborn}           \UnicodeEncodingName{"002A}
+\DeclareTextSymbol{\textdied}           \UnicodeEncodingName{"2020}
+\DeclareTextSymbol{\textlbrackdbl}      \UnicodeEncodingName{"27E6}
+\DeclareTextSymbol{\textrbrackdbl}      \UnicodeEncodingName{"27E7}
+\DeclareTextSymbol{\textguarani}        \UnicodeEncodingName{"20B2}
 %    \end{macrocode}
 %    We could make \cs{textcentoldstyle} and \cs{textdollaroldstyle}
 %    point to dollar and cent in the Unicode encoding
 %    \begin{macrocode}
-%\DeclareTextSymbol{\textcentoldstyle}            \UnicodeEncodingName{"00A2}
-%\DeclareTextSymbol{\textdollaroldstyle}          \UnicodeEncodingName{"0024}
+%\DeclareTextSymbol{\textcentoldstyle}  \UnicodeEncodingName{"00A2}
+%\DeclareTextSymbol{\textdollaroldstyle}\UnicodeEncodingName{"0024}
 %    \end{macrocode}
 %    but I think it is better to pick them up from TS1 even if that
 %    usually means LMR fonts
@@ -908,7 +973,8 @@
 \DeclareEncodingSubset{TS1}{lmss}    {1}
 \DeclareEncodingSubset{TS1}{lmssq}   {1}
 \DeclareEncodingSubset{TS1}{lmvtt}   {1}
-\DeclareEncodingSubset{TS1}{lmtt}    {1} % missing TM, SM, pertenthousand for some reason
+\DeclareEncodingSubset{TS1}{lmtt}    {1} % missing TM, SM and
+                                         % pertenthousand for some reason
 %    \end{macrocode}
 %
 %    \begin{macrocode}
@@ -918,33 +984,33 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\DeclareEncodingSubset{TS1}{bch}     {5}  % tofu for blank, ohm
-\DeclareEncodingSubset{TS1}{futj}    {5}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{futs}    {5}  % tofu for blank, ohm
-\DeclareEncodingSubset{TS1}{futx}    {5}  % probably (currently broken distrib)
-\DeclareEncodingSubset{TS1}{pag}     {5}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{pbk}     {5}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{pcr}     {5}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{phv}     {5}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{pnc}     {5}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{pplj}    {5}  % tofu for blank
-\DeclareEncodingSubset{TS1}{pplx}    {5}  % tofu for blank
-\DeclareEncodingSubset{TS1}{ppl}     {5}  % tofu for blank interrobang/down
-\DeclareEncodingSubset{TS1}{ptm}     {5}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{pzc}     {5}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{ul9}     {5}  % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{bch} {5} % tofu for blank, ohm
+\DeclareEncodingSubset{TS1}{futj}{5} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{futs}{5} % tofu for blank, ohm
+\DeclareEncodingSubset{TS1}{futx}{5} % probably (currently broken distrib)
+\DeclareEncodingSubset{TS1}{pag} {5} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{pbk} {5} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{pcr} {5} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{phv} {5} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{pnc} {5} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{pplj}{5} % tofu for blank
+\DeclareEncodingSubset{TS1}{pplx}{5} % tofu for blank
+\DeclareEncodingSubset{TS1}{ppl} {5} % tofu for blank interrobang/down
+\DeclareEncodingSubset{TS1}{ptm} {5} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{pzc} {5} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{ul9} {5} % tofu for blank, interrobang/down, ohm
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\DeclareEncodingSubset{TS1}{dayroms} {6}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{dayrom}  {6}  % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{dayroms}{6} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{dayrom} {6} % tofu for blank, interrobang/down, ohm
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\DeclareEncodingSubset{TS1}{augie}   {8}  % really only missing euro
-\DeclareEncodingSubset{TS1}{put}     {8}
-\DeclareEncodingSubset{TS1}{uag}     {8}  % probably (currently broken distrib)
-\DeclareEncodingSubset{TS1}{ugq}     {8}
+\DeclareEncodingSubset{TS1}{augie}{8} % really only missing euro
+\DeclareEncodingSubset{TS1}{put}  {8}
+\DeclareEncodingSubset{TS1}{uag}  {8} % probably (currently broken distrib)
+\DeclareEncodingSubset{TS1}{ugq}  {8}
 %    \end{macrocode}
 %
 %    \begin{macrocode}
@@ -976,14 +1042,14 @@
 %    substituted.
 %
 %    \begin{macrocode}
-\DeclareEncodingSubset{TS1}{lato-*}                   {0}  % with a bunch of tofu inside
-\DeclareEncodingSubset{TS1}{opensans-*}               {0}  % with a bunch of tofu inside
-\DeclareEncodingSubset{TS1}{cantarell-*}              {0}  % with a bunch of tofu inside
-\DeclareEncodingSubset{TS1}{fbb-*}                    {0}  % missing centoldstyle
+\DeclareEncodingSubset{TS1}{lato-*}       {0}  % with a bunch of tofu inside
+\DeclareEncodingSubset{TS1}{opensans-*}   {0}  % with a bunch of tofu inside
+\DeclareEncodingSubset{TS1}{cantarell-*}  {0}  % with a bunch of tofu inside
+\DeclareEncodingSubset{TS1}{fbb-*}        {0}  % missing centoldstyle
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\DeclareEncodingSubset{TS1}{tli}                      {1}  % with lots of tofu inside
+\DeclareEncodingSubset{TS1}{tli}          {1}  % with lots of tofu inside
 %    \end{macrocode}
 %
 %    \begin{macrocode}
@@ -1109,7 +1175,7 @@
 \DeclareEncodingSubset{TS1}{erewhon-*}                {7}
 \DeclareEncodingSubset{TS1}{ComicNeue-TLF}            {7}
 \DeclareEncodingSubset{TS1}{ComicNeueAngular-TLF}     {7}
-\DeclareEncodingSubset{TS1}{Forum-LF}                 {7}  % the superiors are missing
+\DeclareEncodingSubset{TS1}{Forum-LF}      {7}  % the superiors are missing
 %    \end{macrocode}
 %
 %    \begin{macrocode}
@@ -1156,7 +1222,7 @@
 %  \begin{macro}{\textlegacysection}
 %
 %    Here are new names for the legacy symbols that \LaTeX{} used to
-%    pick up from the \texttt{OMS} encoded fonts (and used dor itemize
+%    pick up from the \texttt{OMS} encoded fonts (and used for itemize
 %    lists or footnote symbols.
 %
 %    We go the roundabout way via separate OMS declarations so that
@@ -1199,10 +1265,20 @@
 % Supporting rollback \ldots
 %    \begin{macrocode}
 %</2ekernel|latexrelease>
-%<latexrelease>\EndIncludeInRelease
+%<latexrelease>
 %<latexrelease>\IncludeInRelease{0000/00/00}%
-%<latexrelease>   {\DeclareEncodingSubset}{Text companion symbols}%
+%<latexrelease>     {lttextcomp}{Undefine text companion symbols}%
 %<latexrelease>
+%<latexrelease>\DeclareRobustCommand\oldstylenums[1]{%
+%<latexrelease>   \begingroup
+%<latexrelease>    \spaceskip\fontdimen\tw@\font
+%<latexrelease>    \usefont{OML}{\rmdefault}{\f at series}{it}%
+%<latexrelease>    \mathgroup\symletters #1%
+%<latexrelease>   \endgroup
+%<latexrelease>}
+%<latexrelease>\let\legacyoldstylenums\@undefined
+%<latexrelease>\def\textcompsubstdefault{cmr}
+%<latexrelease>
 %<latexrelease>\let\DeclareEncodingSubset\@undefined
 %<latexrelease>\let\CheckEncodingSubset\@undefined
 %<latexrelease>
@@ -1237,7 +1313,8 @@
 %<latexrelease>\let\textbrokenbar\@undefined
 %<latexrelease>\let\textcelsius\@undefined
 %<latexrelease>\let\textcent\@undefined
-%<latexrelease>\DeclareTextCommandDefault{\textcopyright}{\textcircled{c}}
+%<latexrelease>\DeclareTextCommandDefault{\textcopyright}
+%<latexrelease>                          {\textcircled{c}}
 %<latexrelease>\let\textdegree\@undefined
 %<latexrelease>\let\textdiv\@undefined
 %<latexrelease>\let\textlnot\@undefined
@@ -1244,19 +1321,24 @@
 %<latexrelease>\let\textonehalf\@undefined
 %<latexrelease>\let\textonequarter\@undefined
 %<latexrelease>\let\textonesuperior\@undefined
-%<latexrelease>\DeclareTextCommandDefault{\textordfeminine}{\textsuperscript{a}}
-%<latexrelease>\DeclareTextCommandDefault{\textordmasculine}{\textsuperscript{o}}
+%<latexrelease>\DeclareTextCommandDefault{\textordfeminine}
+%<latexrelease>                          {\textsuperscript{a}}
+%<latexrelease>\DeclareTextCommandDefault{\textordmasculine}
+%<latexrelease>                          {\textsuperscript{o}}
 %<latexrelease>\let\textpm\@undefined
 %<latexrelease>\let\textquotesingle\@undefined
 %<latexrelease>\let\textquotestraightbase\@undefined
 %<latexrelease>\let\textquotestraightdblbase\@undefined
-%<latexrelease>\DeclareTextCommandDefault{\textregistered}{\textcircled{%
-%<latexrelease>     \check at mathfonts\fontsize\sf at size\z@\math at fontsfalse\selectfont R}}
+%<latexrelease>\DeclareTextCommandDefault{\textregistered}
+%<latexrelease>    {\textcircled{%
+%<latexrelease>        \check at mathfonts\fontsize\sf at size\z@
+%<latexrelease>        \math at fontsfalse\selectfont R}}
 %<latexrelease>\let\textthreequartersemdash\@undefined
 %<latexrelease>\let\textthreequarters\@undefined
 %<latexrelease>\let\textthreesuperior\@undefined
 %<latexrelease>\let\texttimes\@undefined
-%<latexrelease>\DeclareTextCommandDefault{\texttrademark}{\textsuperscript{TM}}
+%<latexrelease>\DeclareTextCommandDefault{\texttrademark}
+%<latexrelease>                          {\textsuperscript{TM}}
 %<latexrelease>\let\texttwelveudash\@undefined
 %<latexrelease>\let\texttwosuperior\@undefined
 %<latexrelease>\let\textyen\@undefined
@@ -1386,9 +1468,7 @@
 %<latexrelease>\let\textlegacyperiodcentered\@undefined
 %<latexrelease>\let\textlegacysection\@undefined
 %<latexrelease>
-%<latexrelease>\EndIncludeInRelease
-%<*2ekernel>
-%</2ekernel>
+%<latexrelease>\EndModuleRelease
 %    \end{macrocode}
 %
 %
@@ -1433,9 +1513,12 @@
 %    kernel is info only). Using the package options you can change this behavior.
 % \changes{v2.0n}{2020/02/05}{Changed the package default to info (gh/262)}
 %    \begin{macrocode}
-\DeclareOption{error}{\gdef\tc at errorwarn{\PackageError{textcomp}}}
-\DeclareOption{warn}{\gdef\tc at errorwarn#1#2{\PackageWarning{textcomp}{#1}}}
-\DeclareOption{info}{\gdef\tc at errorwarn#1#2{\PackageInfo{textcomp}{#1}}}
+\DeclareOption{error}
+              {\gdef\tc at errorwarn{\PackageError{textcomp}}}
+\DeclareOption{warn}
+              {\gdef\tc at errorwarn#1#2{\PackageWarning{textcomp}{#1}}}
+\DeclareOption{info}
+              {\gdef\tc at errorwarn#1#2{\PackageInfo{textcomp}{#1}}}
 \DeclareOption{quiet}{\gdef\tc at errorwarn#1#2{}}
 %    \end{macrocode}
 %
@@ -1443,7 +1526,7 @@
 %    of the default (which, unless changes, is 9 these days), i.e., it
 %    no longer depends on the font in use. This is mainly there
 %    because it might have been used in older documents, but not
-%    somehting that is recommended.
+%    something that is recommended.
 %    \begin{macrocode}
 \DeclareOption{force}{%
     \def\CheckEncodingSubset#1#2#3#4#5{%
@@ -1483,7 +1566,7 @@
 %    This section contains the old code for the textcomp package and
 %    its documentation. It is only used if we roll back prior to 2020.
 %    Thus all the rest is mainly for historians. Note that the old
-%    code categorised in the sub-encodings only into 6 classes not 10.
+%    code categorized in the sub-encodings only into 6 classes not 10.
 %
 %    \begin{macrocode}
 %<*TS1oldsty>
@@ -1773,7 +1856,7 @@
 %    to ensure that |\textcurrency| is only typeset if the current
 %    font has a \texttt{TS1} subset id of less than 3. Otherwise
 %    |\tc at error| is called telling the user that for this font family
-%    |\textcurreny| is not available.
+%    |\textcurrency| is not available.
 %    \begin{macrocode}
 \def\tc at check@symbol{\CheckEncodingSubset\UseTextSymbol{TS1}\tc at subst}
 \def\tc at check@accent{\CheckEncodingSubset\UseTextAccent{TS1}\tc at error}
@@ -2008,7 +2091,7 @@
 %
 %    Finally input the encoding-specific definitions for
 %    \texttt{TS1} thus making the top-level definitions
-%    optimised for this encoding (and not for the default
+%    optimized for this encoding (and not for the default
 %    encoding).
 % \changes{v1.9o}{1998/03/20}{Load decls after defaults for speed.}
 %    \begin{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/base/ltthm.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltthm.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltthm.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/ltvers.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltvers.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltvers.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -33,7 +33,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltvers.dtx}
-             [2020/03/02 v1.1e LaTeX Kernel (Version Info)]
+             [2021/04/16 v1.1g LaTeX Kernel (Version Info)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltvers.dtx}
@@ -112,10 +112,10 @@
 %</2ekernel>
 %<latexrelease>\edef\latexreleaseversion
 %<*2ekernel|latexrelease>
-   {2020-10-01}
+   {2021-06-01}
 %</2ekernel|latexrelease>
 %<*2ekernel>
-\def\patch at level{4}
+\def\patch at level{0}
 %    \end{macrocode}
 %
 % \begin{macro}{\development at branch@name}
@@ -125,7 +125,7 @@
 %    intended to help us internally when we locally install a
 %    format out of some development branch.
 %    \begin{macrocode}
-\edef\development at branch@name{}
+\edef\development at branch@name{develop \the\year-\the\month-\the\day}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -181,28 +181,30 @@
 %    \begin{macrocode}
   \ifnum0\ifnum\patch at level=0 \ifx\development at branch@name\@empty 1\fi\fi>0 %
     \everyjob\expandafter{\the\everyjob
-      \typeout{\fmtname \space<\fmtversion>}}
+      \typeout{\fmtname\space <\fmtversion>}}
     \immediate
     \write16{\fmtname \space<\fmtversion>}
   \else\ifnum\patch at level>0
     \everyjob\expandafter{\the\everyjob
-      \typeout{\fmtname \space<\fmtversion> patch level \patch at level}}
+      \typeout{\fmtname\space <\fmtversion> patch level \patch at level}}
     \immediate
-    \write16{\fmtname \space<\fmtversion> patch level \patch at level}
+    \write16{\fmtname\space <\fmtversion> patch level \patch at level}
   \else
     \everyjob\expandafter{\the\everyjob
-      \typeout{\fmtname \space<\fmtversion> pre-release-\number-\patch at level\space
-        \ifx\development at branch@name\@undefined  \else
-          \ifx\development at branch@name\@empty  \else
-            \space (\development at branch@name\space branch)%
+      \typeout{\fmtname\space <\fmtversion>
+               pre-release-\number-\patch at level\space
+               \ifx\development at branch@name\@undefined  \else
+                 \ifx\development at branch@name\@empty  \else
+                  \space (\development at branch@name\space branch)%
           \fi
         \fi
     }}
     \immediate
-    \write16{\fmtname \space<\fmtversion> pre-release-\number-\patch at level\space
-        \ifx\development at branch@name\@undefined  \else
-          \ifx\development at branch@name\@empty  \else
-            \space (\development at branch@name\space branch)%
+    \write16{\fmtname\space <\fmtversion>
+             pre-release-\number-\patch at level\space
+            \ifx\development at branch@name\@undefined  \else
+             \ifx\development at branch@name\@empty  \else
+               \space (\development at branch@name\space branch)%
           \fi
         \fi
     }
@@ -212,6 +214,11 @@
 %    \end{macrocode}
 %
 % \begin{macro}{\IncludeInRelease}
+% \begin{macro}{\EndIncludeInRelease}
+% \begin{macro}{\@IncludeInRelease}
+% \begin{macro}{\@IncludeInRele at se}
+% \begin{macro}{\@gobble at IncludeInRelease}
+% \begin{macro}{\@check at IncludeInRelease}
 % \changes{v1.0w}{2015/02/21}
 %         {set \cs{@currname} empty here (in case \cs{IncludeInRelease} input early)}
 %    \begin{macrocode}
@@ -222,6 +229,7 @@
 % \changes{v1.0m}{2015/01/17}{modified with \cs{@currname}}
 % \changes{v1.0o}{2015/01/19}{Optional argument}
 % \changes{v1.0q}{2015/02/19}{Swap argument order}
+% \changes{v1.1f}{2021/03/18}{Add support for usage in \cs{NewModuleRelease}}
 %
 %    \begin{macrocode}
 %<*2ekernel|latexrelease>
@@ -235,9 +243,29 @@
                 {There is an \string\EndIncludeRelease\space missing}%
   \@includeinreleasefalse
   \fi
-  \kernel at ifnextchar[%
-  {\@IncludeInRelease{#1}}
-  {\@IncludeInRelease{#1}[#1]}}
+  \ifnum0%
+      \ifx\new at moduledate\@empty\else 1\fi
+      \ifnum \expandafter\@parse at version#1//00\@nil=0 1\fi
+      =11
+    \expandafter\@firstoftwo
+  \else
+    \expandafter\@secondoftwo
+  \fi
+    {\finish at module@release{#1}}%
+    {\kernel at ifnextchar[%
+      {\@IncludeInRelease{#1}}
+      {\@IncludeInRelease{#1}[#1]}}}
+\def\finish at module@release#1#2#3{%
+  \toks@{[#1] #3}%
+  \ifnum\expandafter\@parse at version\new at moduledate//00\@nil
+       >\expandafter\@parse at version\fmtversion//00\@nil
+    \GenericInfo{}{Applying: \the\toks@}%
+  \else
+    \GenericInfo{}{Skipping: \the\toks@}%
+    \expandafter\gobble at finish@module at release
+  \fi}
+\long\def\gobble at finish@module at release#1\EndModuleRelease{%
+  \EndModuleRelease}
 %    \end{macrocode}
 %
 % If a specific date has not been specified in |latexrelease|
@@ -255,13 +283,13 @@
 %    that is actually reapplying what is already in the format, i.e.,
 %    it is useless and possibly allocating new registers. However, it
 %    makes the logic simpler so this is the way it is for now. In
-%    theory we could always jump overthe first patch because that is
+%    theory we could always jump over the first patch because that is
 %    only really needed for rolling forward. So maybe one day \dots
 %    \begin{macrocode}
     \ifnum\expandafter\@parse at version#1//00\@nil
-          >\expandafter\@parse at version\fmtversion//00\@nil
+         >\expandafter\@parse at version\fmtversion//00\@nil
       \GenericInfo{}{Skipping: \the\toks@}%
-     \expandafter\expandafter\expandafter\@gobble at IncludeInRelease
+      \expandafter\expandafter\expandafter\@gobble at IncludeInRelease
     \else
       \GenericInfo{}{Applying: \the\toks@}%
       \@includeinreleasetrue
@@ -280,6 +308,9 @@
   \@includeinreleasefalse
 \else
   \PackageError{latexrelease}{mis-matched EndIncludeInRelease}{}%
+\fi
+\if at skipping@module
+  \expandafter\new at module@skip
 \fi}
 %    \end{macrocode}
 %
@@ -294,13 +325,87 @@
                                    #2#3\@end at check@IncludeInRelease{%
   \ifx\@check at IncludeInRelease#2\else
     \PackageError{latexrelease}{skipped IncludeInRelease for tag \string#2}{}%
+  \fi
+  \if at skipping@module
+    \expandafter\new at module@skip
   \fi}
 %    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
 %
+% \subsection{Declaring an all-new module}
+%
+% \begin{macro}{\if at skipping@module}
+% \begin{macro}{\NewModuleRelease}
+% \begin{macro}{\EndModuleRelease}
+% \begin{macro}{\new at module@skip}
+% \begin{macro}{\new at modulename}
+% \begin{macro}{\new at moduledate}
+%
+%   When we have a whole new module, we can't roll back to a date where
+%   such module exists, otherwise hundreds of \enquote{command already
+%   defined} errors will pop up.  But we can't skip it altogether
+%   either, because the module might have changes we still want applied,
+%   so a more detailed cherry-picking of code chunks have to be done.
+%
+%   \changes{v1.1f}{2021/03/18}{Added \cs{NewModuleRelease}.}
+%   \changes{v1.1g}{2021/04/16}
+%           {\cs{NewModuleRelease} with the same arguments as \cs{IncludeInRelease}.}
 %    \begin{macrocode}
+\let\if at skipping@module\iffalse
+\def\@skipping at moduletrue{\let\if at skipping@module\iftrue}
+\def\@skipping at modulefalse{\let\if at skipping@module\iffalse}
+\let\new at modulename\@empty
+\let\new at moduledate\@empty
+\def\NewModuleRelease#1#2#3{%
+  \ifx\new at modulename\@empty \else
+    \@latex at error{Nested \noexpand\NewModuleRelease forbidden.}\@ehd \fi
+  \edef\new at moduledate{#1}%
+  \edef\new at modulename{#2}%
+  \GenericInfo{}{BEGIN module: \new at modulename\space (\new at moduledate)}%
+  \GenericInfo{}{ \@spaces\@spaces\@spaces\space#3\@gobble}%
+  \ifnum\sourceLaTeXdate<%
+      \expandafter\@parse at version\new at moduledate//00\@nil\relax
+    \ifnum\expandafter\@parse at version\fmtversion//00\@nil<%
+          \expandafter\@parse at version\new at moduledate//00\@nil\relax
+      \GenericInfo{}{Skipping module \new at modulename}%
+      \expandafter\expandafter
+      \expandafter\gobble at finish@module at release
+    \else
+      \GenericInfo{}{Applying module \new at modulename}
+      \@skipping at modulefalse
+    \fi
+  \else
+    \GenericInfo{}{Skipping module \new at modulename}
+    \@skipping at moduletrue
+    \expandafter\new at module@skip
+  \fi}
+\long\def\new at module@skip#1\IncludeInRelease{\IncludeInRelease}
+\def\EndModuleRelease{%
+  \ifx\new at modulename\@empty
+    \@latex at error{Extra \string\EndModuleRelease.}\@eha
+  \else
+    \GenericInfo{}{END module: \new at modulename\space (\new at moduledate)}%
+    \let\new at modulename\@empty
+    \let\new at moduledate\@empty
+    \@skipping at modulefalse
+  \fi}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%    \begin{macrocode}
 %</2ekernel|latexrelease>
 %    \end{macrocode}
-% \end{macro}
+%
 % \Finale
 %
 \endinput

Modified: trunk/Master/texmf-dist/source/latex/base/ltxdoc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltxdoc.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltxdoc.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -30,7 +30,7 @@
 %
 %<class>\NeedsTeXFormat{LaTeX2e}
 %<class>\ProvidesClass{ltxdoc}
-%<class>         [2020/10/04 v2.1b Standard LaTeX documentation class]
+%<class>         [2020/12/05 v2.1b Standard LaTeX documentation class]
 %
 %<*driver>
 \documentclass{ltxdoc}
@@ -484,7 +484,7 @@
 %    \end{macrocode}
 %   Set \cs{protect} to a suitable value in the index entries (we
 %   can't use |\set at display@protect| as that would result in different
-%   numer of spaces after a command depending on the number of
+%   number of spaces after a command depending on the number of
 %   expansion happening prior to writing the index).
 %    \begin{macrocode}
       \begingroup

Modified: trunk/Master/texmf-dist/source/latex/base/ltxref.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/ltxref.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/ltxref.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -33,7 +33,7 @@
 %<*driver>
 % \fi
 \ProvidesFile{ltxref.dtx}
-             [2020/08/23 v1.1o LaTeX Kernel (Cross Referencing)]
+             [2020/12/05 v1.1o LaTeX Kernel (Cross Referencing)]
 % \iffalse
 \documentclass{ltxdoc}
 \GetFileInfo{ltxref.dtx}
@@ -68,10 +68,10 @@
 %  The user writes  |\label|\marg{foo}  to define the following
 %  cross-references:
 %
-%   |\ref|\marg{foo}: value of most recently incremented referencable
+%   |\ref|\marg{foo}: value of most recently incremented referenceable
 %             counter. in the current environment. (Chapter, section,
 %             theorem and enumeration counters are
-%             referencable, footnote counters are not.)
+%             referenceable, footnote counters are not.)
 %
 %   |\pageref|\marg{foo}: page number at which |\label{foo}|  command
 %             appeared.  where  foo  can be any string of characters not
@@ -98,7 +98,7 @@
 \message{x-ref,}
 %    \end{macrocode}
 %
-%  This is implemented as follows.  A referencable counter  CNT  is
+%  This is implemented as follows.  A referenceable counter  CNT  is
 %  incremented by the command  \refstepcounter{CNT} , which sets
 %  \@currentlabel == {CNT}{eval(\p at cnt\theCNT)}.   The command
 %  \label{FOO} then writes the following on file \@auxout :

Modified: trunk/Master/texmf-dist/source/latex/base/makeindx.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/makeindx.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/makeindx.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -28,7 +28,7 @@
 % \fi
 %\iffalse
 % Copyright (C) 1985 by Leslie Lamport
-% Copyright (C) 1994-98 by \LaTeX3 Project and Johannes Braams
+% Copyright (C) 1994-98 by LaTeX Project and Johannes Braams
 %\fi
 %
 % \changes{1.0b}{1994/01/21}{added a missing \cs{end\{macro\}}, a

Modified: trunk/Master/texmf-dist/source/latex/base/makeindx.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/makeindx.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/makeindx.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/newdc.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/newdc.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/newdc.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/newlfont.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/newlfont.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/newlfont.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/nfssfont.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/nfssfont.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/nfssfont.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -27,7 +27,7 @@
 %
 % \fi
 \def\nfssfontfileversion{v2.2e}
-\def\nfssfontfiledate{2019/10/12}
+\def\nfssfontfiledate{2020/11/26}
 
 %
 % \iffalse
@@ -55,7 +55,7 @@
 %
 % Within the \NFSS{} distribution there is a \LaTeX{} file
 % \texttt{nfssfont.tex} which can be used to test new fonts, produce
-% font tables showing all characters, etc. This is an addaption of a
+% font tables showing all characters, etc. This is an adaption of a
 % program originally written by Don Knuth.
 
 % When you run this file through \LaTeX{} you will be asked to enter
@@ -79,7 +79,7 @@
 % |\help|.
 %
 % This is at
-% the moment only a crude addaption of the test program for the
+% the moment only a crude adaption of the test program for the
 % Computer Modern fonts by Donald Knuth.
 %
 % \StopEventually{}

Modified: trunk/Master/texmf-dist/source/latex/base/nfssfont.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/nfssfont.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/nfssfont.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/olddc.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/olddc.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/olddc.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/oldlfont.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/oldlfont.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/oldlfont.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/preload.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/preload.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/preload.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/proc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/proc.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/proc.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -28,8 +28,8 @@
 % \fi
 %
 % \iffalse
-% Copyright (C) 1991,1992 by Leslie Lamport \and
-% Copyright (C) 1994,1995 by the \LaTeX3 project \and Johannes Braams
+% Copyright (C) 1991,1992 by Leslie Lamport and
+% Copyright (C) 1994-2020 by the LaTeX Project and Johannes Braams
 %
 % \changes{v1.1}{1994/01/25}{Made `proc' a document class and provide
 %    a .sty file for compatibility mode}
@@ -73,7 +73,7 @@
 %</driver>
 %<+class>\ProvidesClass{proc}
 %<+style>\ProvidesFile{proc.sty}
-              [2014/09/29 v1.3l
+              [2020/11/23 v1.3l
 %<+class>               Standard LaTeX document class]
 %<+style>               LaTeX 2.09 compatibility style option `proc']
 %    \end{macrocode}
@@ -147,7 +147,7 @@
 %
 % \section{Implementation}
 %
-%    In this case a check is needed to see wether \LaTeXe\ runs in
+%    In this case a check is needed to see whether \LaTeXe\ runs in
 %    compatibility mode.
 % \changes{v1.3i}{1994/05/27}{Added missing docstrip guard}
 %    \begin{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/base/proc.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/proc.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/proc.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/slides.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/slides.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/slides.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -28,7 +28,7 @@
 % \fi
 %
 % \iffalse
-% Copyright (C) 1994-97 LaTeX3 project, Frank Mittelbach
+% Copyright (C) 1994-97 LaTeX Project, Frank Mittelbach
 % and Rainer Sch\"opf, all rights reserved.
 %
 %    \begin{macrocode}
@@ -53,7 +53,7 @@
 %<*driver>
        \ProvidesFile{slides.drv}
 %</driver>
-              [2020/02/20 v2.4b
+              [2020/11/23 v2.4b
 %<+class>               Standard LaTeX document class]
 %<+cmd>               SLiTeX definitions]
 %    \end{macrocode}
@@ -220,7 +220,7 @@
 % \end{quote}
 %
 % The code is divided into two parts, we first implement the class
-% related functions and declarations and then define lowlevel stuff
+% related functions and declarations and then define low level stuff
 % that is necessary within every class. By placing such commands into
 % a separate file it will be possible to share it with other slide
 % classes.
@@ -288,7 +288,7 @@
 %    \end{macrocode}
 %
 %    The option \Lopt{landscape} switches the values of |\paperheight|
-%    and |\paperwidth|, assuming the dimensions wer given for portrait
+%    and |\paperwidth|, assuming the dimensions were given for portrait
 %    paper.
 %    \begin{macrocode}
 \DeclareOption{landscape}
@@ -705,7 +705,7 @@
 %
 % \begin{macro}{\clubpenalty}
 % \begin{macro}{\widowpenalty}
-%    These penalties are use to discourrage club and widow lines.
+%    These penalties are use to discourage club and widow lines.
 %    Because we use their default values we only show them here,
 %    commented out.
 %    \begin{macrocode}
@@ -718,7 +718,7 @@
 % \begin{macro}{\displaywidowpenalty}
 % \begin{macro}{\predisplaypenalty}
 % \begin{macro}{\postdisplaypenalty}
-%    Discourrage (but not so much) widows in front of a math display
+%    Discourage (but not so much) widows in front of a math display
 %    and forbid breaking directly in front of a display. Allow break
 %    after a display without a penalty. Again the default values are
 %    used, therefore we only show them here.
@@ -1721,7 +1721,7 @@
      \if at titlepage \break \fi}
 %    \end{macrocode}
 
-% \section{Initialisation}
+% \section{Initialization}
 %
 % \subsection{Date}
 %
@@ -2348,8 +2348,8 @@
 %  any output when the |@visible| switch is false.
 %
 % \changes{v2.2j}{1994/03/11}{Corrected \cs{@oval}, like previous
-% \changes{v2.4a}{2016/03/29}{initialise in \cs{@oval}tests added for latex/4452}
-%    change to \file{latex.dtx}.}
+% \changes{v2.4a}{2016/03/29}{Initialize in \cs{@oval}tests added for
+%    latex/4452} change to \file{latex.dtx}.}
 %    \begin{macrocode}
 \def\line(#1,#2)#3{\if at visible\@xarg #1\relax \@yarg #2\relax
 \@linelen #3\unitlength

Modified: trunk/Master/texmf-dist/source/latex/base/slides.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/slides.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/slides.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.
@@ -96,8 +96,8 @@
 
 This is a generated file.
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.
@@ -138,8 +138,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/slifonts.fdd
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/slifonts.fdd	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/slifonts.fdd	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
 % Copyright 1993-2019
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -30,7 +30,7 @@
 %\iffalse        This is a META comment
 %
 % File `slifonts.fdd'.
-% Copyright (C) 1989-1998 LaTeX3 project, Frank Mittelbach and
+% Copyright (C) 1989-1998 LaTeX Project, Frank Mittelbach and
 % Rainer Sch\"opf, all rights reserved.
 %
 %<lcmss&!ec>\ProvidesFile{ot1lcmss.fd}

Modified: trunk/Master/texmf-dist/source/latex/base/syntonly.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/syntonly.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/syntonly.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/syntonly.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/syntonly.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/syntonly.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/tulm.fdd
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/tulm.fdd	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/tulm.fdd	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
 % Copyright 2016-2019
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -30,7 +30,7 @@
 %\iffalse        This is a META comment
 %
 % File `cmfonts.fdd'.
-% Copyright (C) 2016-2019 LaTeX3 Project
+% Copyright (C) 2016-2019 LaTeX Project
 %
 %
 %<TUlmr>\ProvidesFile{tulmr.fd}
@@ -51,7 +51,7 @@
 \title{The file \texttt{tulm.fdd} for use with
       \LaTeXe.\thanks{This file has version
            number \fileversion, dated \filedate.}}
-\date{\filedate}\author{LaTeX3 Project}
+\date{\filedate}\author{\LaTeX\ Project}
 \addtolength\textwidth{30pt}
 \begin{document}
 \MaintainedByLaTeXTeam{latex}

Modified: trunk/Master/texmf-dist/source/latex/base/tulm.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/tulm.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/tulm.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 2016-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 2016-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.
@@ -48,8 +48,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 2016-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 2016-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/unpack.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/unpack.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/unpack.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the LaTeX base system.

Modified: trunk/Master/texmf-dist/source/latex/base/utf8ienc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/base/utf8ienc.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/base/utf8ienc.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.
@@ -216,7 +216,7 @@
 %<+ts1> \ProvidesFile{ts1enc.dfu}
 %<+x2>  \ProvidesFile{x2enc.dfu}
 %<+all> \ProvidesFile{utf8enc.dfu}
-%<-utf8-2018>   [2019/11/14 v1.2k UTF-8 support for inputenc]
+%<-utf8-2018>   [2021/01/27 v1.2l UTF-8 support for inputenc]
 %    \end{macrocode}
 %
 %    \begin{macrocode}
@@ -318,7 +318,7 @@
 %    However, if we are not doing typesetting, then we execute the
 %    command \cs{UTFviii at two@octets at noexpand} which works like
 %    \cs{UTF at two@octets at string} but uses \cs{noexpand} instead of
-%    \cs{string}. This way the sequence is temporay rendered harmless,
+%    \cs{string}. This way the sequence is temporary rendered harmless,
 %    e.g., would display as is or stays put inside a
 %    \cs{protected at edef}. But if the result is later reused the
 %    starting octet is still active and so will be able to construct
@@ -363,7 +363,7 @@
 % \begin{macro}{\UTFviii at two@octets at noexpand}
 % \begin{macro}{\UTFviii at three@octets at noexpand}
 % \begin{macro}{\UTFviii at four@octets at noexpand}
-%    These tempoarily prevent the active chars from expanding.
+%    These temporarily prevent the active chars from expanding.
 %    \begin{macrocode}
 \long\def\UTF at two@octets at noexpand#1#2{\noexpand#2\noexpand}
 \long\def\UTF at three@octets at noexpand#1#2#3{\noexpand#2\noexpand#3\noexpand}
@@ -530,10 +530,11 @@
 %
 %
 % \begin{macro}{\UTFviii at loop}
-%    This bit of code derived from \texttt{xmltex}  defines the active character
-%    correspnding to starting octets to call |\UTFviii at two@octets| etc as appropriate.
-%    The starting octet itself is passed directly as the first argument, the others
-%    are picked up later en route.
+%    This bit of code derived from \texttt{xmltex}  defines the active
+%    character corresponding to starting octets to call |\UTFviii at two@octets|
+%    etc as appropriate. 
+%    The starting octet itself is passed directly as the first
+%    argument, the others are picked up later en route.
 %
 %    The |\UTFviii at loop| loops through the numbers starting at
 %    |\count@| and ending at |\@tempcnta|${} - 1$, each time executing
@@ -691,7 +692,7 @@
 %    \end{macrocode}
 %
 %    Here is an example of what is happening, for the pair \texttt{"C2 "A3}
-%    (which is the utf8 represenation for the character \textsterling{}).
+%    (which is the utf8 representation for the character \textsterling{}).
 %    After |\parse at XML@charref| we have, stored in |\UTFviii at tmp|, a
 %    single command with two character tokens as arguments:
 %    \begin{quote}
@@ -849,7 +850,7 @@
 %
 % \begin{macro}{\decode at UTFviii}
 % \changes{v1.1o}{2015/08/28}{Macro added}
-%    In the reverse direction, take a sequence of octects(bytes)
+%    In the reverse direction, take a sequence of octets(bytes)
 %    representing a character in UTF-8 and construct the Unicode number.
 %    The sequence is terminated by |\relax|.
 %
@@ -1134,9 +1135,9 @@
 %
 % \changes{v1.1o}{2015/08/28}{Add U+00A0 and U+00AD}
 % \changes{v1.1q}{2015/12/02}{Add remaining latin uses of accents in T1}
-% \changes{v1.1r}{2015/12/03}{Add some more ogoneck cases}
+% \changes{v1.1r}{2015/12/03}{Add some more ogonek cases}
 % \changes{v1.1s}{2016/01/11}{Add some more caron and acute}
-% \changes{v1.1t}{2017/01/28}{Add caron cominations for GgYy}
+% \changes{v1.1t}{2017/01/28}{Add caron combinations for GgYy}
 %    \begin{macrocode}
 %<all,t1,ot1,ly1>\DeclareUnicodeCharacter{00A0}{\nobreakspace}
 %<all,t1,ot1,ly1>\DeclareUnicodeCharacter{00A1}{\textexclamdown}
@@ -1537,7 +1538,7 @@
 %    two mappings are wrong or rather the names in OT2 should change for
 %    consistency.
 %
-%    On the other hand the names |\CYROTLD| are somewhat questionabled as the
+%    On the other hand the names |\CYROTLD| are somewhat questionable as the
 %    Unicode standard only describes ``Cyrillic barred O'' while |TLD| refers
 %    to a tilde (which is more less what the ``Cyrillic FITA looks according
 %    to the Unicode book).
@@ -1700,6 +1701,18 @@
 %<all,ts1>\DeclareUnicodeCharacter{0E3F}{\textbaht}
 %<all,t1>\DeclareUnicodeCharacter{1E02}{\.B}
 %<all,t1>\DeclareUnicodeCharacter{1E03}{\.b}
+%    \end{macrocode}
+% \changes{v1.2k}{2021/01/27}{Added various additional dot accents (gh/484)}
+%    \begin{macrocode}
+%<all,t1>\DeclareUnicodeCharacter{1E0D}{\d d}
+%<all,t1>\DeclareUnicodeCharacter{1E25}{\d h}
+%<all,t1>\DeclareUnicodeCharacter{1E37}{\d l}
+%<all,t1>\DeclareUnicodeCharacter{1E43}{\d m}
+%<all,t1>\DeclareUnicodeCharacter{1E45}{\.n}
+%<all,t1>\DeclareUnicodeCharacter{1E47}{\d n}
+%<all,t1>\DeclareUnicodeCharacter{1E5B}{\d r}
+%<all,t1>\DeclareUnicodeCharacter{1E63}{\d s}
+%<all,t1>\DeclareUnicodeCharacter{1E6D}{\d t}
 %<all,t1>\DeclareUnicodeCharacter{1E9E}{\SS}
 %<all,x2,t2c,t2b,t2a,t1,utf8>\DeclareUnicodeCharacter{200C}{\textcompwordmark}
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/graphics/color.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/graphics/color.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/graphics/color.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -2,7 +2,9 @@
 % \iffalse
 %
 %% color.dtx Copyright (C) 1994--1999 David Carlisle
-%%           Copyright (C) 2005-2020 David Carlisle, LaTeX3 Project
+%%           Copyright (C) 2005-2021
+%% The LaTeX Project and any individual authors listed elsewhere
+%% in this file.
 %%
 %% This file is part of the Standard LaTeX `Graphics Bundle'.
 %% It may be distributed under the terms of the LaTeX Project Public

Modified: trunk/Master/texmf-dist/source/latex/graphics/drivers.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/graphics/drivers.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/graphics/drivers.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,7 +3,9 @@
 %
 %% drivers.dtx Copyright (C) 1994      David Carlisle Sebastian Rahtz
 %%             Copyright (C) 1995 1996 1997 1998 1999 David Carlisle
-%%             Copyright (C) 2000-2020 David Carlisle, LaTeX3 Project
+%%             Copyright (C) 2000-2021
+%% The LaTeX Project and any individual authors listed elsewhere
+%% in this file.
 %%
 %% This file is part of the Standard LaTeX `Graphics Bundle'.
 %% It may be distributed under the terms of the LaTeX Project Public

Modified: trunk/Master/texmf-dist/source/latex/graphics/epsfig.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/graphics/epsfig.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/graphics/epsfig.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -2,7 +2,9 @@
 % \iffalse
 %
 %% epsfig.dtx Copyright (C) 1994-1996 1999 Sebastian Rahtz
-%%            Copyright (C) 2000-2020 David Carlisle, LaTeX3 Project
+%%            Copyright (C) 2000-2021
+%% The LaTeX Project and any individual authors listed elsewhere
+%% in this file.
 %%
 %% This file is part of the Standard LaTeX `Graphics Bundle'.
 %% It may be distributed under the terms of the LaTeX Project Public

Modified: trunk/Master/texmf-dist/source/latex/graphics/graphics.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/graphics/graphics.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/graphics/graphics.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -2,7 +2,9 @@
 % \iffalse
 %
 %% graphics.dtx Copyright (C) 1994      David Carlisle Sebastian Rahtz
-%%              Copyright (C) 1995-2020 David Carlisle, LaTeX3 Project
+%%              Copyright (C) 1995-2021
+%% The LaTeX Project and any individual authors listed elsewhere
+%% in this file.
 %%
 %% This file is part of the Standard LaTeX `Graphics Bundle'.
 %% It may be distributed under the terms of the LaTeX Project Public
@@ -25,7 +27,7 @@
 %<driver> \ProvidesFile{graphics.drv}
 % \fi
 %         \ProvidesFile{graphics.dtx}
-          [2020/08/30 v1.4c  Standard LaTeX Graphics (DPC,SPQR)]
+          [2021/03/04 v1.4d  Standard LaTeX Graphics (DPC,SPQR)]
 %
 % \iffalse
 %<*driver>
@@ -1123,7 +1125,12 @@
     \ifx\filename at ext\relax
       \let\filename at ext\Gin at gzext
     \else
-      \edef\Gin at ext{\Gin at ext\Gin at sepdefault\Gin at gzext}%
+%    \end{macrocode}
+% \changes{v1.4d}{2021/03/04}
+%     {\cs{filename at ext} instead of \cs{Gin at ext} when
+%      checking for \texttt{gzip}ped graphics file.}
+%    \begin{macrocode}
+      \edef\filename at ext{\filename at ext\Gin at sepdefault\Gin at gzext}%
     \fi
   \fi
   \ifx\filename at ext\relax
@@ -1146,14 +1153,17 @@
 %     {Try adding an extension even if the filename had a dot AND
 %      if the filename without the extension exists (but doesn't have
 %      a known extension).}
+% \changes{v1.4d}{2021/03/03}
+%     {Avoid warning when loading a file using a generic rule.}
 %    \begin{macrocode}
     \ifnum0%
         \ifx\Gin at ext\relax 1%
         \else \@ifundefined{Gin at rule@\Gin at ext}{1}{0}%
         \fi >0
-      \let\Gin at ext\relax
+      \let\Gin at extsaved\Gin at ext
       \let\Gin at savedbase\filename at base
       \let\Gin at savedext\filename at ext
+      \let\Gin at ext\relax
       \edef\filename at base{\filename at base\Gin at sepdefault\filename at ext}%
       \let\filename at ext\relax
       \@for\Gin at temp:=\Gin at extensions\do{%
@@ -1164,6 +1174,7 @@
 % Restore if no file found using the known extensions.
 %    \begin{macrocode}
       \ifx\Gin at ext\relax
+        \let\Gin at ext\Gin at extsaved
         \let\filename at base\Gin at savedbase
         \let\filename at ext\Gin at savedext
       \fi

Modified: trunk/Master/texmf-dist/source/latex/graphics/graphicx.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/graphics/graphicx.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/graphics/graphicx.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -2,7 +2,9 @@
 % \iffalse
 %
 %% graphicx.dtx Copyright (C) 1994      David Carlisle Sebastian Rahtz
-%%              Copyright (C) 1995-2020 David Carlisle, LaTeX3 Project
+%%              Copyright (C) 1995-2021
+%% The LaTeX Project and any individual authors listed elsewhere
+%% in this file.
 %%
 %% This file is part of the Standard LaTeX `Graphics Bundle'.
 %% It may be distributed under the terms of the LaTeX Project Public
@@ -17,7 +19,7 @@
 %<driver> \ProvidesFile{graphicx.drv}
 % \fi
 %         \ProvidesFile{graphicx.dtx}
-          [2020/09/09 v1.2b  Enhanced LaTeX Graphics (DPC,SPQR)]
+          [2020/12/05 v1.2c  Enhanced LaTeX Graphics (DPC,SPQR)]
 %
 % \iffalse
 %<*driver>
@@ -88,7 +90,7 @@
 % name (or key) and any options that must be set are set by explicitly
 % associating this name with the desired value.
 %
-% The members of the \LaTeX3 project do appreciate the importance of
+% The members of the \LaTeX\ Project do appreciate the importance of
 % this kind of syntax, but felt that rather than extending the syntax of
 % \LaTeX\ in an uncoordinated way, it would be better to keep with
 % `standard arguments' in \LaTeXe, which is intended as a `consolidation
@@ -507,9 +509,10 @@
 %
 % \begin{key}{Gin}{quiet}
 % \changes{v1.1a}{2017/06/01}{New quiet key}
+% \changes{v1.2c}{2020/12/05}{fix missing default value}
 %   Skip writing to the log.
 %    \begin{macrocode}
-\define at key{Gin}{quiet}{%
+\define at key{Gin}{quiet}[]{%
   \let\Gin at log\@gobble
 }
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/graphics/keyval.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/graphics/keyval.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/graphics/keyval.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,9 @@
 %
 % \iffalse
 %% keyval.dtx Copyright (C) 1993 1994 1995 1997 1998 1999 David Carlisle
-%%            Copyright (C) 2000-2020 David Carlisle, LaTeX3 Project
+%%            Copyright (C) 2000-2021 David Carlisle, LaTeX Project
+%% The LaTeX Project and any individual authors listed elsewhere
+%% in this file.
 %%
 %% This file is part of the Standard LaTeX `Graphics Bundle'.
 %% It may be distributed under the terms of the LaTeX Project Public

Modified: trunk/Master/texmf-dist/source/latex/graphics/lscape.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/graphics/lscape.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/graphics/lscape.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -2,7 +2,9 @@
 % \iffalse
 %
 %% lscape.dtx Copyright (C) 1994 1999-2000 David Carlisle
-%%            Copyright (C) 2000-2020 David Carlisle, LaTeX3 Project
+%%            Copyright (C) 2000-2021
+%% The LaTeX Project and any individual authors listed elsewhere
+%% in this file.
 %%
 %% This file is part of the Standard LaTeX `Graphics Bundle'.
 %% It may be distributed under the terms of the LaTeX Project Public

Modified: trunk/Master/texmf-dist/source/latex/graphics/rotating.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/graphics/rotating.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/graphics/rotating.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,9 +3,11 @@
 %
 %
 % File: rotating.dtx
-%% Copyright (C) 1995--1999 Sebastian Rahtz and Leonor Barroca
-%% Copyright (C) 2001--2003,2007--2009 Robin Fairbairns
-%% Copyright (C) 2016-2020 LaTeX3 Project
+%% Copyright (C) 1995-1999 Sebastian Rahtz and Leonor Barroca
+%% Copyright (C) 2001-2003,2007-2009 Robin Fairbairns
+%% Copyright (C) 2016-2021 LaTeX Project
+%% The LaTeX Project and any individual authors listed elsewhere
+%% in this file.
 %
 % 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/graphics/trig.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/graphics/trig.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/graphics/trig.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,6 +1,8 @@
 % \iffalse
-%% File: trig.dtx Copyright (C) 1993 1994 1995 1996 1997 1999 David Carlisle
-%%                Copyright (C) 2000-2020 David Carlisle, LaTeX3 Project
+%% File: trig.dtx Copyright (C) 1993-1999 David Carlisle
+%%                Copyright (C) 2000-2021
+%% The LaTeX Project and any individual authors listed elsewhere
+%% in this file.
 %%
 %% This file is part of the Standard LaTeX `Graphics Bundle'.
 %% It may be distributed under the terms of the LaTeX Project Public

Modified: trunk/Master/texmf-dist/source/latex/tools/afterpage.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/afterpage.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/afterpage.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/afterpage.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/afterpage.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/afterpage.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the Standard LaTeX `Tools Bundle'.
@@ -45,8 +45,8 @@
 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-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/array.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/array.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/array.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.
@@ -33,7 +33,7 @@
 %<+package>\DeclareCurrentRelease{}{2020-10-01}
 %<+package>
 %<+package>\ProvidesPackage{array}
-%<+package>         [2020/10/01 v2.5c Tabular extension package (FMi)]
+%<+package>         [2021/04/20 v2.5e Tabular extension package (FMi)]
 %
 % \fi
 %
@@ -188,7 +188,7 @@
 %         David Carlisle\thanks{David kindly agreed on the inclusion
 %         of the \texttt{\textbackslash{}newcolumntype} implementation,
 %         formerly in
-%         \texttt{newarray.sty} into this package }}
+%         \texttt{newarray.sty} into this package.}}
 %
 % \date{Printed \today}
 %
@@ -361,6 +361,56 @@
 %       columns have predefined widths.
 % \end{itemize}
 %
+%
+% \subsection{The behavior of the \texttt{\string\\} command}
+%
+% In the basic \texttt{tabular} implementation of \LaTeX{} the \cs{\bslash}
+% command ending the rows of the \texttt{tabular} or \texttt{array} has
+% a somewhat inconsistent behavior if its optional argument is used. The
+% result then depends on the type of rightmost column and as remarked in
+% Leslie Lamport's \LaTeX{} manual~\cite{bk:lamport} may not always produce the
+% expected extra space.
+%
+%
+% Without the \textsf{array} package the extra space requested by the
+% optional argument of \cs{\bslash} is measured from the last baseline of
+% the rightmost column (indicated by ``x'' in the following
+% example). As a result, swapping the column will give different
+% results:
+% \begin{verbatim}
+%   \begin{tabular}[t]{lp{1cm}}
+%       1 & 1\newline x   \\[20pt]     2 & 2    \end{tabular}
+%   \begin{tabular}[t]{p{1cm}l}
+%       1\newline 1 & x   \\[20pt]     2 & 2    \end{tabular}
+%   \end{verbatim}
+% \pagebreak
+% If you run this without the \textsf{array} package you will get the
+% following result:
+% \begin{center}
+% \begin{tabular}[t]{lp{1cm}}
+%   1 & 1\newline x \\[32pt]      2 & 2 \end{tabular}
+% \begin{tabular}[t]{p{1cm}l}
+%   1\newline 1 & x \\[20pt]      2 & 2 \end{tabular}
+% \end{center}
+% In contrast, when the \textsf{array} package is loaded, the requested
+% space in the optional argument is always measured from the baseline of
+% the whole row and not from the last baseline of the rightmost column, thus
+% swapping columns doesn't change the spacing and we same table height
+% with an effective 8pt of extra space (as the second line already takes
+% up 12pt of the requested 20pt):
+% \begin{center}
+% \begin{tabular}[t]{lp{1cm}}
+%   1 & 1\newline x \\[20pt]      2 & 2 \end{tabular}
+% \begin{tabular}[t]{p{1cm}l}
+%   1\newline 1 & x \\[20pt]      2 & 2 \end{tabular}
+% \end{center}
+%
+% This correction of behavior only makes a difference if the rightmost column
+% is a \texttt{p}-column. Thus if you add the \textsf{array}
+% package to an existing document, you should verify the spacing in all
+% tables that have this kind of structure.
+%
+%
 % \subsection{Defining new column specifiers}
 %
 % \DeleteShortVerb{\=}
@@ -1958,8 +2008,9 @@
 % \changes{v2.2d}{1994/05/16}{Use \LaTeXe \cs{@finalstrut}}
 % \changes{v2.3g}{1996/05/07}{Add \cs{hfil} for tools/2120}
 % \changes{v2.4i}{2018/09/13}{Add group to prevent color leak (gh/72)}
+% \changes{v2.5d}{2021/02/10}{Explicitly run \cs{par} at the end of pboxes}
 %    \begin{macrocode}
-\def\@endpbox{\@finalstrut\@arstrutbox \color at endgroup \egroup\hfil}
+\def\@endpbox{\@finalstrut\@arstrutbox \par \color at endgroup \egroup\hfil}
 %    \end{macrocode}
 % \end{macro}
 %
@@ -2142,8 +2193,9 @@
 %    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}
-\def\@arraycr{\relax\iffalse{\fi\ifnum 0=`}\fi
+\protected\def\@arraycr{\relax\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

Modified: trunk/Master/texmf-dist/source/latex/tools/bm.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/bm.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/bm.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.
@@ -36,7 +36,7 @@
 %<driver>\ProvidesFile{bm.drv}
 % \fi
 %         \ProvidesFile{bm.dtx}
-          [2019/07/24 v1.2d Bold Symbol Support (DPC/FMi)]
+          [2021/04/25 v1.2e Bold Symbol Support (DPC/FMi)]
 %
 % \iffalse
 %<*driver>
@@ -295,6 +295,23 @@
 % between these two packages, this package defines |\boldsymbol| and
 % |\heavysymbol| as alternative names for |\bm| and |\hm|.
 %
+% \section{Package Options}
+%
+% \subsection{Logging level}
+% As described above, the \textsf{bm} package has to interrogate the font
+% setup to try to find matching bold fonts for each font used in the |normal|
+% math version. This can fail in various ways as there may be no bold font
+% or a bold font may be found but no room is available to allocate it.
+% The options |warn|, |info| and |silent| control whether messages that \textsf{bm}
+% produces are sent to the terminal, or just to the log file (the default) or suppressed.
+%
+% \subsection{Poor Man's Bold}
+% As discussed above, by default, if no real bold font is available, \textsf{bm} will use
+% ``poor man's bold''. That is, over-printing the character with slight offsets.
+% Since version 1.2e, the package now warns if a font is set up to use this over-printing and
+% the package option |nopbm|  is available which prevents its use in which case |\bm| will
+% use the non-bold for characters from the affected font,
+%
 % \StopEventually{}
 %
 % \section{Implementation}
@@ -320,6 +337,20 @@
 %      {minor doc changes latex/3058}
 %
 %
+% \changes{v1.2e}{2021/04/25}
+%      {Package options gh/71}
+% Options to use or not use poor mans bold (over-printing)
+% and level of warning messages.
+%    \begin{macrocode}
+%<*package>
+\DeclareOption{nopmb}{\let\bm at pmb@\@firstofone}
+\DeclareOption{warn}{\def\bm at info{\PackageWarningNoLine{bm}}}
+\DeclareOption{info}{\def\bm at info#1{\PackageInfo{bm}{#1\@gobble}}}
+\DeclareOption{silent}{\let\bm at info\@gobble}
+\ExecuteOptions{info}
+\ProcessOptions\relax
+%</package>
+%    \end{macrocode}
 %
 % The commands |\bm| and |\hm| work by defining a number of additional
 % symbol fonts corresponding to the standard ones
@@ -368,6 +399,7 @@
 % code, which is temporarily defined to |\bm|, to save wasting a csname.
 % Similarly |\bm at pmb|\ldots\ (which will be defined later) are used
 % as scratch macros.
+% (This csname saving no longer used, setup command is |\bm at setup| not |\bm|).
 %
 % The general plan. Run through the fonts allocated to the normal math
 % version. Ignore \meta{math alphabet} allocations\footnote{For now?}
@@ -393,15 +425,15 @@
 % using |\boldmath| or poor man's bold.)
 %
 %    \begin{macrocode}
-\def\bm#1#2{%
+\def\bm at setup#1#2{%
 %    \end{macrocode}
 % This code can not work inside a group, as that would affect any symbol
 % font allocations, so instead use some scratch macros to save and
 % restore the definitions of commands we need to change locally.
 %    \begin{macrocode}
-  \let\bm at pmb\install at mathalphabet
-  \let\bm at pmb@\getanddefine at fonts
-  \let\bm at pmb@@\or
+  \let\bm at install@mathalphabet\install at mathalphabet
+  \let\bm at getanddefine@fonts\getanddefine at fonts
+  \let\bm at or\or
   \edef\bm at general{\f at encoding/\f at family/\f at series/\f at shape/\f at size}%
 %    \end{macrocode}
 %
@@ -465,8 +497,12 @@
 %    \end{macrocode}
 % If they are the same, set this offset to $-1$, as a flag to use
 % poor man's bold.
+% \changes{v1.2e}{2021/04/25}
+%      {make use of pmb optional and warn about it gh/71}
 %    \begin{macrocode}
       \bm at define\m at ne
+      \bm at info{No #1 for \string##2%
+               \ifx\bm at pmb@\@firstofone\else, using \string\pmb\fi}%
     \else
 %    \end{macrocode}
 % Else make a new name by adjoining |#1| to the name of the symbol font
@@ -569,7 +605,7 @@
 %    \end{macrocode}
 % If the font has been allocated already, use the existing allocation.
 %    \begin{macrocode}
-          \PackageInfo{bm}%
+          \bm at info
             {Symbol font \@tempa\space already defined.\MessageBreak
              Not overwriting it}%
         \fi
@@ -613,9 +649,9 @@
 % Put things back as they were.
 %    \begin{macrocode}
   \expandafter\split at name\bm at general\@nil
-  \let\install at mathalphabet\bm at pmb
-  \let\getanddefine at fonts\bm at pmb@
-  \let\or\bm at pmb@@}
+  \let\install at mathalphabet\bm at install@mathalphabet
+  \let\getanddefine at fonts\bm at getanddefine@fonts
+  \let\or\bm at or}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -647,13 +683,13 @@
   \def\bm at boldtable{\m at ne}
   \AtEndOfPackage{%
     \def\bm at gr@up#1#2{%
-      \bm at pmb{#2}}}
+      \bm at install@mathalphabet{#2}}}
 \else
 %    \end{macrocode}
 % Otherwise use the definition of |\bm| above to set up |\bm at boldtable|
 % by comparing the fonts available in the normal and bold math versions.
 %    \begin{macrocode}
-  \bm{bold}\bmmax
+  \bm at setup{bold}\bmmax
 %    \end{macrocode}
 %
 % \begin{macro}{\mathbf}
@@ -689,7 +725,7 @@
 %    \begin{macrocode}
 \ifx\mv at heavy\@undefined
 \else
-  \bm{heavy}\hmmax
+  \bm at setup{heavy}\hmmax
 \fi
 %    \end{macrocode}
 % \end{macro}
@@ -781,6 +817,8 @@
 % you put something really strange in the arguments.
 % \changes{v0.11}{1997/01/06}
 %      {\cs{@ifnextchar} made safe.}
+% \changes{v1.2e}{2021/04/25}
+%      {treat \cs{kernel at ifnextchar} like \cs{@ifnextchar}}
 %    \begin{macrocode}
     \def\@ifnextchar##1##2##3##4{%
       \if##1##4%
@@ -789,6 +827,7 @@
         \expandafter\@secondoftwo
       \fi
       {##2##4}{##3{##4}}}%
+    \let\kernel at ifnextchar\@ifnextchar
 %    \end{macrocode}
 % For Vladimir Volovich\ldots
 % \changes{v1.0f}{1998/12/10}
@@ -1397,6 +1436,8 @@
 % \begin{macro}{\bm at pmb}
 % \changes{v0.10}{1997/01/04}
 %      {Macro added}
+% \changes{v1.2e}{2021/04/25}
+%      {option to make pmb a no-op}
 % Add a poor man's bold construction to the list being built.
 %    \begin{macrocode}
 \def\bm at pmb#1{%
@@ -1410,6 +1451,7 @@
 % |\pmb| variant. (See \TeX{}Book, or AMS \textsf{amsbsy} package).
 % This one takes a bit more care to use smaller offsets in subscripts.
 %    \begin{macrocode}
+\ifx\bm at pmb@\@firstofone\else
 \def\bm at pmb@#1{{%
   \setbox\tw@\hbox{$\m at th\mkern.4mu$}%
   \mathchoice
@@ -1434,6 +1476,7 @@
   \raise1.5\dimen@\rlap{\copy\z@}%
   \kern\dimen@
   \box\z@}}%
+\fi
 %    \end{macrocode}
 % \end{macro}
 %

Modified: trunk/Master/texmf-dist/source/latex/tools/bm.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/bm.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/bm.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the Standard LaTeX `Tools Bundle'.
@@ -45,8 +45,8 @@
 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-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/calc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/calc.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/calc.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.
@@ -25,7 +25,7 @@
 %% Copyright (C) 1992--1995
 %%          Kresten Krab Thorup and Frank Jensen.
 %% Copyright (C) 1997--2007
-%%          Kresten Krab Thorup, Frank Jensen and the LaTeX3 Project.
+%%          Kresten Krab Thorup, Frank Jensen and the LaTeX Project.
 %%
 %% The original authors (fj at hugin.dk and  krab at daimi.aau.dk) have
 %% contributed this package to the LaTeX distribution.

Modified: trunk/Master/texmf-dist/source/latex/tools/dcolumn.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/dcolumn.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/dcolumn.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/delarray.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/delarray.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/delarray.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/enumerate.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/enumerate.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/enumerate.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/fileerr.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/fileerr.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/fileerr.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/fontsmpl.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/fontsmpl.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/fontsmpl.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/ftnright.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/ftnright.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/ftnright.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.
@@ -314,7 +314,7 @@
 % \newblock Addison-Wesley, Reading, Massachusetts, 1986.
 %
 % \bibitem{src:ltxiii94}
-% \LaTeX3 project.
+% \LaTeX\ Project.
 % \newblock \LaTeXe distribution, 1994.
 % \newblock Sources for {\LaTeXe} the successor to \LaTeX~2.09.
 %

Modified: trunk/Master/texmf-dist/source/latex/tools/hhline.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/hhline.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/hhline.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/indentfirst.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/indentfirst.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/indentfirst.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/layout.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/layout.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/layout.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.
@@ -30,7 +30,7 @@
 %<+package>\ProvidesPackage{layout}
 %<+driver>\ProvidesFile{layout.drv}
 %\ProvidesFile{layout.dtx}
-                [2014/10/28 v1.2c Show layout parameters]
+                [2021-03-10 v1.2e Show layout parameters]
 %
 %    A short driver is provided that can be extracted if necessary by
 %    the \textsf{DocStrip} program provided with \LaTeXe.
@@ -54,6 +54,17 @@
 % \changes{v1.1d}{1994/09/08}{Stored texts in control sequences to
 %    allow other languages}
 %
+% \makeatletter
+% \def\allowtofu{^^A
+%\def\UTFviii at undefined@err##1{^^A
+%  \PackageWarning{inputenc}{Unicode character \expandafter
+%                          \UTFviii at splitcsname\string##1\relax
+%                          \MessageBreak
+%                          not set up for use with LaTeX}^^A
+%  \raisebox{.8pt}{\fboxsep1pt\kern.1pt\fbox{$\cdot$}\kern.1pt}^^A
+%   }}
+% \makeatother
+%
 % \GetFileInfo{layout.dtx}
 % \title{Displaying page layout variables}
 % \author{Kent McPherson a.o.\thanks{Converted for \LaTeXe\ by
@@ -172,6 +183,32 @@
   \def\notshown{non mostrato}
   }
 %    \end{macrocode}
+%    
+% \changes{v1.2e}{2021-03-10}{Added option for Romanian (gh529)}
+%    \begin{macrocode}
+\DeclareOption{romanian}{%
+  \def\Headertext{Antet}
+  \def\Bodytext{Corp}
+  \def\Footertext{Subsol}
+  \def\MarginNotestext{Note\\ Marginale}
+  \def\oneinchtext{un inch}
+  \def\notshown{neafi\textcommabelow sat}
+  }
+%    \end{macrocode}
+%    
+%    \changes{v1.2d}{2020-07-25}{Added option for Japanese (gh353)}
+% \begin{allowtofu}
+%    \begin{macrocode}
+\DeclareOption{japanese}{%
+  \def\Headertext{天}
+  \def\Bodytext{基本版面}
+  \def\Footertext{地}
+  \def\MarginNotestext{傍\\注}
+  \def\oneinchtext{1インチ}
+  \def\notshown{非表示}
+  }
+%    \end{macrocode}
+% \end{allowtofu}
 %
 %    This package has an option \Lopt{verbose}. Using it will make the
 %    command |\layout| type some of the parameters on the terminal.

Modified: trunk/Master/texmf-dist/source/latex/tools/longtable.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/longtable.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/longtable.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.
@@ -27,11 +27,17 @@
           \ProvidesFile{longtable.dtx}
 %</dtx>
 %<package>\NeedsTeXFormat{LaTeX2e}[1995/06/01]
+%<package>\providecommand\DeclareRelease[3]{}
+%<package>\providecommand\DeclareCurrentRelease[2]{}
+%<package>
+%<package>\DeclareRelease{v4.13}{2020-01-02}{longtable-2020-01-07.sty}
+%<package>\DeclareCurrentRelease{}{2020-02-07}
+%<package>
 %<package>\ProvidesPackage{longtable}
 %<driver> \ProvidesFile{longtable.drv}
 % \fi
 %         \ProvidesFile{longtable.dtx}
-          [2020/01/07 v4.13 Multi-page Table package (DPC)]
+          [2021-05-07 v4.16 Multi-page Table package (DPC)]
 %
 % \iffalse
 %<*driver>
@@ -303,7 +309,7 @@
 % (see below), the "LTchunksize" must be at least  as large as the
 % number of rows in each of the head or foot sections.
 %
-% This document specifies "\setcounter{LTchunksize}{10}".  If you look
+% This document specifies "\setcounter{LTchunksize}{200}".  If you look
 % at the previous table, after the \emph{first} run of \LaTeX\  you will
 % see that various parts of the table do not line up.
 % \LaTeX\ will also have printed a warning that the column
@@ -877,9 +883,11 @@
 % \end{macro}
 %
 % \begin{macro}{\LTchunksize}
-% Chunk size (The number of rows taken per "\halign"). Default 20.
+% \changes{v4.14}{2020/02/07}
+%      {Increase default chunksize from 20 to 200}
+% Chunk size (The number of rows taken per "\halign"). Default 200.
 %    \begin{macrocode}
-\newcount\LTchunksize \LTchunksize=20
+\newcount\LTchunksize \LTchunksize=200
 %    \end{macrocode}
 % \end{macro}
 %
@@ -916,6 +924,14 @@
 % \end{macro}
 % \end{macro}
 %
+% \begin{macro}{\LT at gbox}
+% \changes{v4.14}{2020/02/07}
+%      {global box added (tools/2914)}
+%    \begin{macrocode}
+\newbox\LT at gbox
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{\LT at cols}
 % Counter for number of columns.
 %    \begin{macrocode}
@@ -1212,7 +1228,7 @@
 % \end{macro}
 %
 % \begin{macro}{\LT at start}
-% % \changes{v4.13}{2020/01/07}
+% \changes{v4.13}{2020/01/07}
 %      {fix issue https://github.com/davidcarlisle/dpctex/issues/8}
 % This macro starts the process of putting the table on the current
 % page. It is not called until either a "\\" or "\endlongtable" command
@@ -1228,6 +1244,34 @@
   \let\LT at start\endgraf
   \endgraf\penalty\z@\vskip\LTpre\endgraf
 %    \end{macrocode}
+% \changes{v4.14}{2020/02/07}
+%      {Guard against shrink glue on current page tools/3396 and github 183}
+% This next block was suggested by Lars Hellström in pr tools/3396
+% He documents it as:
+%
+% The original problem occurs because TeX has not yet found an awfully bad
+% "(b=*)" breakpoint and is therefore still collecting material to see if there
+% is a really good break somewhere just ahead. As we know there aren't, we
+% want to make it stop looking and break the page, so that "\pagetotal" will be
+% for the page  where the table will actually end up. To achieve this, we
+% need to give \TeX\ an awfully bad, but legal, breakpoint. The simplest way of
+% doing this seems to be to insert a "\kern" that counters the "\pageshrink" for
+% the page, followed by a "\penalty" and a "\par" (to exercise the page builder).
+% We also have to make sure that this breakpoint doesn't affect how the next
+% page is broken, so we make the penalty 9999 (10000 is infinite and thus not
+% a legal breakpoint) and cancel out the "\kern" with a new "\kern".
+% 
+% I don't think this is the \emph{right} solution to the problem (that would be
+% that the standard output routine has a feature for syncronizing with
+% typesetting, as part of the preparations for switching output routine), but
+% it's OK. Perhaps XOR will make it better.
+%    \begin{macrocode}
+   \ifdim \pagetotal<\pagegoal \else
+      \dimen@=\pageshrink
+      \advance \dimen@ 1sp %
+      \kern\dimen@\penalty 9999\endgraf \kern-\dimen@
+   \fi
+%    \end{macrocode}
 % Start a new page if there is not enough room for the table head, foot,
 % and one extra line.
 %    \begin{macrocode}
@@ -1238,6 +1282,8 @@
 %    \end{macrocode}
 % \changes{v3.16}{1995/11/09}
 %      {Measure the first line of the table}
+% \changes{v4.15}{2021/04/18}
+%      {silence \cs{vbadness}}
 % At this point I used to add "\ht\@arstrutbox" and "\dp\@arstrutbox"
 % as a measure of a row size. However this can fail spectacularly
 % for "p" columns which might be much larger. Previous versions could
@@ -1245,12 +1291,13 @@
 % a head \emph{then} a `first head'! So now measure the first line of
 % the table accurately by "\vsplit"ting it out of the first chunk.
 %    \begin{macrocode}
-  \dimen at ii\vfuzz
+  \edef\LT at reset@vfuzz{\vfuzz\the\vfuzz\vbadness\the\vbadness\relax}%
   \vfuzz\maxdimen
-    \setbox\tw@\copy\z@
-    \setbox\tw@\vsplit\tw@ to \ht\@arstrutbox
-    \setbox\tw@\vbox{\unvbox\tw@}%
-  \vfuzz\dimen at ii
+  \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
@@ -1259,8 +1306,19 @@
 %
 %    \begin{macrocode}
   \advance\dimen@ -\pagegoal
-  \ifdim \dimen@>\z@\vfil\break\fi
+  \ifdim \dimen@>\z@
+    \vfil\break
+  \else
 %    \end{macrocode}
+%
+% \changes{v4.14}{2020/02/07}
+%      {Guard against shrink glue on current page see github 183}
+% The LT output routine does not handle shrink on the page, which can cause
+% The first page to be over-long, so forget it is there.
+%    \begin{macrocode}
+    \ifdim\pageshrink>\z@\pageshrink\z@\fi
+  \fi
+%    \end{macrocode}
 % Store height of page minus table foot in  "\@colroom".
 % \changes{v3.14}{1995/05/02}
 %      {Set \cs{@colroom}, for tools/1584}
@@ -1269,9 +1327,12 @@
 %    \end{macrocode}
 % If the foot is non empty, reduce the "\vsize" and "\@colroom"
 % accordingly.
+% \changes{v4.14}{2020/02/07}
+%      {Rearrange vertical space tests for tools/3512 (floats on same page)}
 %    \begin{macrocode}
   \ifvoid\LT at foot\else
-    \advance\vsize-\ht\LT at foot
+%    \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@
     \maxdepth\z@
@@ -1350,8 +1411,15 @@
   \fi
 %    \end{macrocode}
 % Force one more go with the \env{longtable} output routine.
+% \changes{v4.14}{2020/02/07}
+%      {Rearrange vertical space tests for tools/3512 (floats on same page)}
 %    \begin{macrocode}
   \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
 %    \end{macrocode}
 % Now close the group to return to the standard routine.
 %    \begin{macrocode}
@@ -1361,9 +1429,11 @@
 % table.\footnote{This can not be the correct. However if it is omitted,
 % there is a problem with marginpars, for example on page~3 of this
 % document. Any Output Routine Gurus out there?}
+% \changes{v4.14}{2020/02/07}
+%      {Rearrange vertical space tests for tools/3512 (floats on same page)}
 %    \begin{macrocode}
   \global\@mparbottom\z@
-  \pagegoal\vsize
+%  \pagegoal\vsize
   \endgraf\penalty\z@\addvspace\LTpost
 %    \end{macrocode}
 % Footnotes. As done in  the \package{multicol} package.
@@ -1431,8 +1501,10 @@
 % So use the following variant. Added in v3.14.
 % \changes{v3.14}{1995/04/25}
 %      {More fun with \cs{ifnum} cf tools/1571}
+% \changes{v4.15}{2021/04/21}
+%      {protected (gh/584)}
 %    \begin{macrocode}
-\def\LT at tabularcr{%
+\protected\def\LT at tabularcr{%
   \relax\iffalse{\fi\ifnum0=`}\fi
   \@ifstar
     {\def\crcr{\LT at crcr\noalign{\nobreak}}\let\cr\crcr
@@ -1452,6 +1524,8 @@
 % \begin{macro}{\LT at setprevdepth}
 % \changes{v4.05}{1996/11/12}
 %      {Macro added}
+% \changes{v4.14}{2020/02/07}
+%      {spurious \cs{global} removed}
 % This will be redefined to set the "\prevdepth"
 %  at the start of a chunk.
 %    \begin{macrocode}
@@ -1471,7 +1545,7 @@
   \global\advance\LT at rows\@ne
   \ifnum\LT at rows=\LTchunksize
     \gdef\LT at setprevdepth{%
-      \prevdepth\z@\global
+      \prevdepth\z@
       \global\let\LT at setprevdepth\relax}%
     \expandafter\LT at xtabularcr
   \else
@@ -1528,11 +1602,13 @@
 % \begin{macro}{\LT at echunk}
 % \changes{v4.05}{1996/11/12}
 %      {\cs{unskip} added for pagebreak support}
+% \changes{v4.14}{2020/02/07}
+%      {allocated global box  (tools/2914)}
 % This ends the current chunk, and removes the dummy row.
 %    \begin{macrocode}
 \def\LT at echunk{%
   \crcr\LT at save@row\cr\egroup
-  \global\setbox\@ne\lastbox
+  \global\setbox\LT at gbox\lastbox
 %    \end{macrocode}
 % The following line was added in v4.05.
 % \package{longtable} relies on "\lineskip" glue (which is 0pt) to
@@ -1753,9 +1829,11 @@
 % Loop through the last row, discarding glue, and saving box widths. At
 % V3.04 changed the scratch box to 2, as the new "\kill" requires that
 % "\box0" be preserved.
+% \changes{v4.14}{2020/02/07}
+%      {allocated global box  (tools/2914)}
 %    \begin{macrocode}
   \setbox\tw@\hbox{%
-    \unhbox\@ne
+    \unhbox\LT at gbox
     \let\LT at old@row\LT at save@row
     \global\let\LT at save@row\@empty
     \count@\LT at cols
@@ -1892,6 +1970,8 @@
 %      {Call \cs{LT at makecaption} not \cs{LT at mkcaption}}
 % \changes{v3.14}{1995/05/24}
 %      {Add new control argument}
+% \changes{v4.16}{2021/05/07}
+%      {use \cs{ext at table} gh/561}
 %    \begin{macrocode}
 \def\LT at c@ption#1[#2]#3{%
   \LT at makecaption#1\fnum at table{#3}%
@@ -1898,7 +1978,7 @@
   \def\@tempa{#2}%
   \ifx\@tempa\@empty\else
      {\let\\\space
-     \addcontentsline{lot}{table}{\protect\numberline{\thetable}{#2}}}%
+     \addcontentsline{\ext at table}{table}{\protect\numberline{\thetable}{#2}}}%
   \fi}
 %    \end{macrocode}
 % \end{macro}
@@ -1927,6 +2007,8 @@
 %       and modified to call \cs{@makecaption}}
 % \changes{v3.14}{1995/05/02}
 %      {Use the first arg to remove counter for star form}
+% \changes{v4.15}{2021/03/28}
+%      {\cs{reset at font} for gh/133}
 %    \begin{macrocode}
 \def\LT at makecaption#1#2#3{%
   \LT at mcol\LT at cols c{\hbox to\z@{\hss\parbox[t]\LTcapwidth{%
@@ -1934,6 +2016,7 @@
 % Based on article class "\@makecaption", "#1" is "\@gobble" in star
 % form, and "\@firstofone" otherwise.
 %    \begin{macrocode}
+    \reset at font
     \sbox\@tempboxa{#1{#2: }#3}%
     \ifdim\wd\@tempboxa>\hsize
       #1{#2: }#3%
@@ -1973,13 +2056,17 @@
 % vsplit off a bit of the last chunk, so that the last page did not just
 % have head and foot sections, but it is hard to do this in a consistent
 % manner.}
+% \changes{v4.14}{2020/02/07}
+%      {Rearrange vertical space tests for tools/3512 (floats on same page)}
 %    \begin{macrocode}
         \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}%
 %    \end{macrocode}
 % End of "\ifdim\dimen@<\ht\@cclc".
@@ -1993,14 +2080,17 @@
 % Reset "\@colroom".
 % \changes{v3.14}{1995/05/02}
 %      {Reset \cs{@colroom}, for tools/1584}
+% \changes{v4.14}{2020/02/07}
+%      {Rearrange vertical space tests for tools/3512 (floats on same page)}
 %    \begin{macrocode}
-      \global\@colroom\@colht
-      \global\vsize\@colht
+%      \global\@colroom\@colht
+%      \global\vsize\@colht
 %    \end{macrocode}
 % Put the last page of the table on to the main vertical list.
+% \changes{v4.14}{2020/02/07}
+%      {Remove box from final page tools/3512}
 %    \begin{macrocode}
-      \vbox
-        {\unvbox\z@\box\ifvoid\LT at lastfoot\LT at foot\else\LT at lastfoot\fi}%
+        \unvbox\z@\box\ifvoid\LT at lastfoot\LT at foot\else\LT at lastfoot\fi
 %    \end{macrocode}
 % End of "\ifnum\outputpenalty > -\LT at end@pen".
 %    \begin{macrocode}
@@ -2139,10 +2229,12 @@
 % \end{macro}
 %
 % \begin{macro}{\LT at p@ftntext}
+% \changes{v4.15}{2021/03/28}
+%      {make long for gh/364}
 % Inside the `p' column, just save up the footnote text in a token
 % register.
 %    \begin{macrocode}
-\def\LT at p@ftntext#1{%
+\long\def\LT at p@ftntext#1{%
   \edef\@tempa{\the\LT at p@ftn\noexpand\footnotetext[\the\c at footnote]}%
   \global\LT at p@ftn\expandafter{\@tempa{#1}}}%
 %    \end{macrocode}

Modified: trunk/Master/texmf-dist/source/latex/tools/longtable.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/longtable.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/longtable.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the Standard LaTeX `Tools Bundle'.
@@ -45,8 +45,8 @@
 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-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/multicol.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/multicol.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/multicol.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -77,7 +77,7 @@
 %% not for the payment of a license fee per se (which might or might
 %% not follow from this evaluation).
 %%
-%% The license fee, if any, can be payed either to the LaTeX3 fund
+%% The license fee, if any, can be payed either to the LaTeX fund
 %% (see ltx3info.txt in the base LaTeX distribution) or to the author of
 %% the program who can be contacted at
 %%

Modified: trunk/Master/texmf-dist/source/latex/tools/multicol.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/multicol.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/multicol.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the Standard LaTeX `Tools Bundle'.
@@ -45,8 +45,8 @@
 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-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/rawfonts.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/rawfonts.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/rawfonts.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/shellesc.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/shellesc.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/shellesc.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse
 %% Source File: shellesc.dtx
-%% Copyright (C) 2015-2020
+%% Copyright (C) 2015-2021
 %%
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file may be distributed under the terms of the LPPL.
@@ -36,7 +36,7 @@
 % \title{The \textsf{shellesc} Package\thanks{This file
 %        has version number \fileversion, last
 %        revised \filedate.}}
-% \author{\LaTeX3 project}
+% \author{\LaTeX\ project}
 % \date{\filedate}
 %
 %

Modified: trunk/Master/texmf-dist/source/latex/tools/showkeys.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/showkeys.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/showkeys.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.
@@ -22,7 +22,7 @@
 % \fi
 % \iffalse
 %% File: showkeys.dtx Copyright (C) 1992-1997 David Carlisle
-%% File: showkeys.dtx Copyright (C) 2006-2019 David Carlisle, LaTeX3 Project
+%% File: showkeys.dtx Copyright (C) 2006-2019 David Carlisle, LaTeX Project
 %
 %<*dtx>
           \ProvidesFile{showkeys.dtx}

Modified: trunk/Master/texmf-dist/source/latex/tools/somedefs.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/somedefs.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/somedefs.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/tabularx.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/tabularx.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/tabularx.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/tabularx.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/tabularx.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/tabularx.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the Standard LaTeX `Tools Bundle'.
@@ -45,8 +45,8 @@
 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-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/theorem.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/theorem.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/theorem.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/tools.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/tools.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/tools.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the Standard LaTeX `Tools Bundle'.
@@ -49,8 +49,8 @@
 (but please observe conditions on bug reports sent to that address!)
 
 
-Copyright (C) 1993-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/trace.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/trace.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/trace.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.
@@ -33,7 +33,7 @@
 %<driver>\ProvidesFile{trace.drv}
 % \fi
 %         \ProvidesFile{trace.dtx}
-          [2018/10/13 v1.1e trace LaTeX code]
+          [2021/04/18 v1.1f trace LaTeX code]
 %
 % \iffalse
 %<*driver>
@@ -343,7 +343,7 @@
 %
 % \begin{macro}{\traceon}
 %    This macro ensures that |\conditionally at traceoff| is actually
-%    turning off switches (since |\tracinall| might have disabled it)
+%    turning off switches (since |\tracingall| might have disabled it)
 %    and then calls |\tr at ce@n| to setup tracing.
 %    \begin{macrocode}
 \def\traceon{\let\conditionally at traceoff\unconditionally at traceoff
@@ -470,6 +470,8 @@
 %    |\tr at ce@n|, however there is no point in resetting
 %    |\tracinglostchars| so we leave it alone.
 %  \changes{v1.1c}{2003/04/30}{Reset \cs{tracingstats} to one}
+%  \changes{v1.1f}{2021/04/18}
+%                {Add \cs{tracingstacklevels} and \cs{tracinglostchars}=3}
 %    \begin{macrocode}
 %   \tracingstats\@ne
 %% \tracinglostchars\z@
@@ -498,13 +500,14 @@
 %    on last (in fact like before we disassemble |\tracingall|
 %    and reorder it partially).
 %    \begin{macrocode}
-  \def\tr at ce@n{%
-    \@tracingtrue
+  \edef\tr at ce@n{%
+    \noexpand\@tracingtrue
     \tracingstats\tw@
     \tracingpages\@ne
-    \tracinglostchars\@ne
+    \tracinglostchars\thr@@
     \tracingparagraphs\@ne
     \errorcontextlines\maxdimen
+    \ifdefined\tracingstacklevels \tracingstacklevels\maxdimen \fi
 %    \end{macrocode}
 %    We only change |\tracingoutput| if it hasn't already been enabled by
 %    |\showoutput|. If that's not the case, we set it to 2 so that we
@@ -512,12 +515,12 @@
 %  \changes{v1.1e}{2018/10/13}{Only reset \cs{tracingoutput} if not
 %    set by \cs{showoutput} earlier}
 %    \begin{macrocode}
-    \ifnum\tracingoutput=\@ne
-    \else
+    \noexpand\ifnum\tracingoutput=\@ne
+    \noexpand\else
       \tracingoutput\tw@
       \showboxbreadth\maxdimen
       \showboxdepth\maxdimen
-    \fi
+    \noexpand\fi
 %    \end{macrocode}
 %
 %    \begin{macrocode}
@@ -543,8 +546,11 @@
 %    |@tracing| switch and always set the primitives back to zero.
 %  \changes{v1.1c}{2003/04/30}{Turn off \cs{tracingoutput}}
 %  \changes{v1.1c}{2003/04/30}{Reset \cs{tracingstats} to one}
+%  \changes{v1.1f}{2021/04/18}{Add missing reset of \cs{errorcontextlines}}
+%  \changes{v1.1f}{2021/04/18}
+%                {Add \cs{tracingstacklevels} and \cs{tracinglostchars}=3}
 %    \begin{macrocode}
-  \def\conditionally at traceoff{%
+  \edef\conditionally at traceoff{%
     \tracingassigns\z@
     \tracingrestores\z@
     \tracingcommands\z@
@@ -557,15 +563,17 @@
 %  \changes{v1.1e}{2018/10/13}{Only reset \cs{tracingoutput} if not
 %    set by \cs{showoutput} earlier}
 %    \begin{macrocode}
-    \ifnum\tracingoutput=\tw@
+    \noexpand\ifnum\tracingoutput=\tw@
       \tracingoutput\z@
       \showboxbreadth\m at ne
       \showboxdepth\m at ne
-    \fi
+    \noexpand\fi
 %    \end{macrocode}
 %
 %    \begin{macrocode}
     \tracingstats\@ne
+    \ifdefined\tracingstacklevels \tracingstacklevels\z@ \fi
+    \errorcontextlines\m at ne
     \tracingparagraphs\z@
     \tracinggroups\z@
   }

Modified: trunk/Master/texmf-dist/source/latex/tools/varioref.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/varioref.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/varioref.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/varioref.ins
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/varioref.ins	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/varioref.ins	2021-06-01 21:12:14 UTC (rev 59424)
@@ -3,8 +3,8 @@
 %% driver files from the doc files in this package when run through
 %% LaTeX or TeX.
 %%
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %%
 %% This file is part of the Standard LaTeX `Tools Bundle'.
@@ -45,8 +45,8 @@
 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-2020
-The LaTeX3 Project and any individual authors listed elsewhere
+Copyright (C) 1993-2021
+The LaTeX Project and any individual authors listed elsewhere
 in this file.
 
 This file was generated from file(s) of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/verbatim.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/verbatim.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/verbatim.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/xr.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/xr.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/xr.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/source/latex/tools/xspace.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/tools/xspace.dtx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/source/latex/tools/xspace.dtx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,8 +1,8 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
+% Copyright (C) 1993-2021
 %
-% The LaTeX3 Project and any individual authors listed elsewhere
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the Standard LaTeX `Tools Bundle'.

Modified: trunk/Master/texmf-dist/tex/latex/base/alltt.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/alltt.sty	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/alltt.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -44,12 +44,12 @@
 %%
 %% File `alltt.dtx'.
 %% Copyright (C) 1987 by Leslie Lamport
-%% Copyright (C) 1994--1997 LaTeX3 project, Johannes Braams
+%% Copyright (C) 1994-2021 LaTeX Project, Johannes Braams
 %%                       all rights reserved.
 %%
 \NeedsTeXFormat{LaTeX2e}
 \ProvidesPackage{alltt}
-              [1997/06/16 v2.0g defines alltt environment]
+              [2021/01/29 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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/ansinew.def	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -44,7 +44,7 @@
 
 
   \ProvidesFile{ansinew.def}
-   [2020/08/01 v1.3d Input encoding file]
+   [2021/02/14 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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/applemac.def	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -44,7 +44,7 @@
 
 
   \ProvidesFile{applemac.def}
-   [2020/08/01 v1.3d Input encoding file]
+   [2021/02/14 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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/article.cls	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 \NeedsTeXFormat{LaTeX2e}[1995/12/01]
 \ProvidesClass{article}
-              [2020/04/10 v1.4m
+              [2021/02/12 v1.4n
  Standard LaTeX document class]
 \newcommand\@ptsize{}
 \newif\if at restonecol
@@ -355,7 +355,7 @@
 \newcommand\labelitemi  {\labelitemfont \textbullet}
 \newcommand\labelitemii {\labelitemfont \bfseries \textendash}
 \newcommand\labelitemiii{\labelitemfont \textasteriskcentered}
-\newcommand\labelitemiv{ \labelitemfont \textperiodcentered}
+\newcommand\labelitemiv {\labelitemfont \textperiodcentered}
 \newcommand\labelitemfont{\normalfont}
 \newenvironment{description}
                {\list{}{\labelwidth\z@ \itemindent-\leftmargin

Modified: trunk/Master/texmf-dist/tex/latex/base/article.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/article.sty	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/article.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/tex/latex/base/ascii.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/ascii.def	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/ascii.def	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -44,7 +44,7 @@
 
 
  \ProvidesFile{ascii.def}
-   [2020/08/01 v1.3d Input encoding file]
+   [2021/02/14 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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/atbegshi-ltx.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -42,14 +42,15 @@
 %% and covered by LPPL is defined by the unpacking scripts (with
 %% extension .ins) which are part of the distribution.
 %%
-%% File: ltshipout.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team
+%% Copyright (C) 2020-2021
+%%               Frank Mittelbach, LaTeX Team
 %%
 %%% From File: ltshipout.dtx
-\providecommand\ltshipoutversion{v1.0d}
-\providecommand\ltshipoutdate{2020/11/24}
+\providecommand\ltshipoutversion{v1.0i}
+\providecommand\ltshipoutdate{2021/03/17}
 \ProvidesPackage{atbegshi-ltx}
-   [2020/08/17 v1.0a
-     Emulation of the original atbegshi package^^Jwith kernel methods]
+   [2021/01/10 v1.0c
+     Emulation of the original atbegshi^^Jpackage with kernel methods]
 \let \AtBeginShipoutBox \ShipoutBox
 \let \AtBeginShipoutInit \@empty
 \protected \def \AtBeginShipout     {\AddToHook{shipout/before}}
@@ -66,6 +67,7 @@
 \let \AtBeginShipoutUpperLeftForeground
               \@expl@@@shipout at add@foreground at picture@@n
 \ExplSyntaxOn
+\cs_new_eq:NN \AtBeginShipoutOriginalShipout \tex_shipout:D
 \cs_new:Npn \ShipoutBoxHeight { \dim_use:N \l_shipout_box_ht_dim }
 \cs_new:Npn \ShipoutBoxDepth  { \dim_use:N \l_shipout_box_dp_dim }
 \cs_new:Npn \ShipoutBoxWidth  { \dim_use:N \l_shipout_box_wd_dim }

Modified: trunk/Master/texmf-dist/tex/latex/base/atveryend-ltx.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/atveryend-ltx.sty	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/atveryend-ltx.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -41,12 +41,9 @@
 %% 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.
-%%
-%% File: ltfilehook.dtx (C) Copyright 2020 Frank Mittelbach,
-%%                                         Phelype Oleinik & LaTeX Team
 %%% From File: ltfilehook.dtx
-\providecommand\ltfilehookversion{v1.0e}
-\providecommand\ltfilehookdate{2021/01/07}
+\providecommand\ltfilehookversion{v1.0k}
+\providecommand\ltfilehookdate{2021/05/25}
 \ProvidesPackage{atveryend-ltx}
    [2020/08/19 v1.0a
      Emulation of the original atvery package^^Jwith kernel methods]

Modified: trunk/Master/texmf-dist/tex/latex/base/bezier.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/bezier.sty	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/bezier.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/tex/latex/base/bk10.clo
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/bk10.clo	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/bk10.clo	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -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}
-              [2020/04/10 v1.4m
+              [2021/02/12 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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/bk11.clo	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -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}
-              [2020/04/10 v1.4m
+              [2021/02/12 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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/bk12.clo	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -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}
-              [2020/04/10 v1.4m
+              [2021/02/12 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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/book.cls	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 \NeedsTeXFormat{LaTeX2e}[1995/12/01]
 \ProvidesClass{book}
-              [2020/04/10 v1.4m
+              [2021/02/12 v1.4n
  Standard LaTeX document class]
 \newcommand\@ptsize{}
 \newif\if at restonecol
@@ -457,7 +457,7 @@
 \newcommand\labelitemi  {\labelitemfont \textbullet}
 \newcommand\labelitemii {\labelitemfont \bfseries \textendash}
 \newcommand\labelitemiii{\labelitemfont \textasteriskcentered}
-\newcommand\labelitemiv{ \labelitemfont \textperiodcentered}
+\newcommand\labelitemiv {\labelitemfont \textperiodcentered}
 \newcommand\labelitemfont{\normalfont}
 \newenvironment{description}
                {\list{}{\labelwidth\z@ \itemindent-\leftmargin

Modified: trunk/Master/texmf-dist/tex/latex/base/book.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/book.sty	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/book.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/tex/latex/base/cp1250.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/cp1250.def	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/cp1250.def	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -44,7 +44,7 @@
 
 
   \ProvidesFile{cp1250.def}
-   [2020/08/01 v1.3d Input encoding file]
+   [2021/02/14 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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/cp1252.def	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -44,7 +44,7 @@
 
 
   \ProvidesFile{cp1252.def}
-   [2020/08/01 v1.3d Input encoding file]
+   [2021/02/14 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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/cp1257.def	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -44,7 +44,7 @@
 
 
   \ProvidesFile{cp1257.def}
-   [2020/08/01 v1.3d Input encoding file]
+   [2021/02/14 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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/cp437.def	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -44,7 +44,7 @@
 
 
   \ProvidesFile{cp437.def}
-   [2020/08/01 v1.3d Input encoding file]
+   [2021/02/14 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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/cp437de.def	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -44,7 +44,7 @@
 
 
   \ProvidesFile{cp437de.def}
-   [2020/08/01 v1.3d Input encoding file]
+   [2021/02/14 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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/cp850.def	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -44,7 +44,7 @@
 
 
   \ProvidesFile{cp850.def}
-   [2020/08/01 v1.3d Input encoding file]
+   [2021/02/14 v1.3d Input encoding file]
 %%
 %% If you need a Euro symbol, try cp858 instead.
 %%

Modified: trunk/Master/texmf-dist/tex/latex/base/cp852.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/cp852.def	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/cp852.def	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -44,7 +44,7 @@
 
 
   \ProvidesFile{cp852.def}
-   [2020/08/01 v1.3d Input encoding file]
+   [2021/02/14 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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/cp858.def	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -44,7 +44,7 @@
 
 
   \ProvidesFile{cp858.def}
-   [2020/08/01 v1.3d Input encoding file]
+   [2021/02/14 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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/cp865.def	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -44,7 +44,7 @@
 
 
   \ProvidesFile{cp865.def}
-   [2020/08/01 v1.3d Input encoding file]
+   [2021/02/14 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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/decmulti.def	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -44,7 +44,7 @@
 
 
  \ProvidesFile{decmulti.def}
-   [2020/08/01 v1.3d Input encoding file]
+   [2021/02/14 v1.3d Input encoding file]
 \ProvideTextCommandDefault{\textdegree}{\ensuremath{{^\circ}}}
 \ProvideTextCommandDefault{\textonehalf}{\ensuremath{\frac12}}
 \ProvideTextCommandDefault{\textonequarter}{\ensuremath{\frac14}}

Added: trunk/Master/texmf-dist/tex/latex/base/doc-v3beta.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/doc-v3beta.sty	                        (rev 0)
+++ trunk/Master/texmf-dist/tex/latex/base/doc-v3beta.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -0,0 +1,1241 @@
+%%
+%% This is file `doc-v3beta.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% doc.dtx  (with options: `package,beta')
+%% 
+%% 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 1993-2018
+%% The LaTeX3 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 2005/12/01 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.
+\NeedsTeXFormat{LaTeX2e}[1994/12/01]
+
+\providecommand\DeclareRelease[3]{}
+\providecommand\DeclareCurrentRelease[2]{}
+
+\DeclareRelease{v2}{2016-02-15.sty}
+               {doc-2016-02-15.sty}
+\DeclareCurrentRelease{v3}{2018-04-16}
+
+\ProvidesPackage{doc-v3beta}
+  [2021/02/07 v3.0e
+   Standard LaTeX documentation package V3 (FMi)]
+%%
+%% Package `doc' to use with LaTeX 2e
+%% Copyright (C) 1989-2018 Frank Mittelbach, all rights reserved.
+
+
+
+
+
+\@ifundefined{macro at cnt}{}{\endinput}
+\catcode`\^^A=14
+\AtBeginDocument{\catcode`\^^A=14\relax}
+\RequirePackage{kvoptions}
+\SetupKeyvalOptions{family=doc,prefix=doc@}
+\DeclareBoolOption{noprint}
+\DeclareBoolOption{noindex}
+\DeclareBoolOption[true]{hyperref}
+\DeclareBoolOption[true]{multicol}
+\DeclareBoolOption[false]{debugshow}
+\DeclareBoolOption[true]{toplevel}
+\DeclareComplementaryOption{notoplevel}{toplevel}
+\DeclareBoolOption{macrolike}
+\DeclareComplementaryOption{envlike}{macrolike}
+\DeclareStringOption{idxtype}
+\DeclareStringOption{idxgroup}
+\DeclareStringOption{printtype}
+\DeclareBoolOption[false]{outer}
+\ProcessKeyvalOptions*
+\newif\ifscan at allowed    \scan at allowedtrue
+\def\SetupDoc#1{%
+  \setkeys{doc}{#1}%
+    \edef\doc at noprintdefault{\ifdoc at noprint true\else false\fi}%
+  \ifdoc at noindex
+    \def\doc at noindexdefault{true}%
+    \scan at allowedfalse
+  \else
+    \def\doc at noindexdefault{false}%
+  \fi
+}
+\SetupDoc{}              % just save the default values
+\def\macrocode{\macro at code
+   \frenchspacing \@vobeyspaces
+   \xmacro at code}
+\def\macro at code{%
+   \topsep \MacrocodeTopsep
+   \@beginparpenalty \predisplaypenalty
+   \if at inlabel\leavevmode\fi
+   \trivlist \parskip \z@ \item[]%
+   \macro at font
+   \leftskip\@totalleftmargin \advance\leftskip\MacroIndent
+   \rightskip\z@ \parindent\z@ \parfillskip\@flushglue
+   \blank at linefalse \def\par{\ifblank at line
+                             \leavevmode\fi
+                             \blank at linetrue\@@par
+                             \penalty\interlinepenalty}
+   \obeylines
+   \let\do\do at noligs \verbatim at nolig@list
+   \let\do\@makeother \dospecials
+   \global\@newlistfalse
+   \global\@minipagefalse
+   \ifcodeline at index
+     \everypar{\global\advance\c at CodelineNo\@ne
+               \llap{\theCodelineNo\ \hskip\@totalleftmargin}%
+               \check at module}%
+   \else \everypar{\check at module}%
+   \fi
+   \init at crossref}
+\newif\ifblank at line
+\def\endmacrocode{%
+                 \ifpm at module \endgroup \pm at modulefalse \fi
+                 \everypar{}%
+                 \global\@inlabelfalse
+                 \endtrivlist
+                 \close at crossref}
+\@ifundefined{MacroFont}{%
+  \if at compatibility
+    \def\MacroFont{\small
+                   \usefont\encodingdefault
+                           \ttdefault
+                           \mddefault
+                           \updefault
+                   }%
+  \else
+    \def\MacroFont{\fontencoding\encodingdefault
+                   \fontfamily\ttdefault
+                   \fontseries\mddefault
+                   \fontshape\updefault
+                   \small}%
+  \fi
+  }{}
+\@ifundefined{AltMacroFont}{%
+  \if at compatibility
+    \def\AltMacroFont{\small
+                      \usefont\encodingdefault
+                              \ttdefault
+                              \mddefault
+                              \sldefault
+                      }%
+  \else
+    \def\AltMacroFont{\fontencoding\encodingdefault
+                      \fontfamily\ttdefault
+                      \fontseries\mddefault
+                      \fontshape\sldefault
+                      \small
+                      }%
+ \fi
+  }{}
+\AtBeginDocument{\let\macro at font\MacroFont}
+\def\check at module{%
+  \ifcheck at modules
+    \ifpm at module \endgroup \pm at modulefalse \fi
+    \expandafter\futurelet\expandafter\next\expandafter\ch at percent
+  \fi}
+\newif\ifpm at module
+\def\DontCheckModules{\check at modulesfalse}
+\def\CheckModules{\check at modulestrue}
+\newif\ifcheck at modules  \check at modulestrue
+\def\ch at percent{%
+  \if \percentchar\next
+    \expandafter\check at angle
+  \fi}
+\def\check at angle#1{\futurelet\next\ch at angle}
+\begingroup
+\catcode`\<\active
+\gdef\ch at angle{\ifx<\next
+    \expandafter\ch at plus@etc
+  \else \percentchar \fi}
+\gdef\ch at plus@etc<{\futurelet\next\check at plus@etc}
+\gdef\check at plus@etc{%
+    \if +\next
+      \let\next\pm at module
+    \else\if -\next
+      \let\next\pm at module
+    \else\if *\next
+      \let\next\star at module
+    \else\if /\next
+      \let\next\slash at module
+    \else\ifx <\next
+      \percentchar
+    \else
+      \let\next\pm at module
+    \fi\fi\fi\fi\fi
+    \next}
+\endgroup
+\begingroup
+\catcode`\~=\active
+\lccode`\~=`\>
+\lowercase{\gdef\pm at module#1~}{\pm at moduletrue
+   \Module{#1}\begingroup
+     \advance\guard at level\@ne
+     \ifnum\guard at level>\c at StandardModuleDepth\AltMacroFont\fi
+}
+\lowercase{\gdef\star at module#1~}{%
+  \Module{#1}%
+  \global \advance \guard at level\@ne
+  \ifnum \guard at level>\c at StandardModuleDepth
+    \global\let\macro at font=\AltMacroFont \macro at font
+  \fi}
+\catcode`\>=\active
+\gdef\slash at module#1>{%
+  \Module{#1}%
+  \global \advance \guard at level\m at ne
+  \ifnum \guard at level=\c at StandardModuleDepth
+    \global\let\macro at font\MacroFont  \macro at font
+  \fi
+}
+\endgroup
+\newcounter{StandardModuleDepth}
+\newcount \guard at level
+
+\@ifundefined{Module}{%
+      \def\Module#1{\mod at math@codes$\langle\mathsf{#1}\rangle$}
+  }{}
+\def\mod at math@codes{\mathcode`\|="226A \mathcode`\&="2026
+                    \mathcode`\-="702D \mathcode`\+="702B
+                    \mathcode`\:="703A \mathcode`\=="703D }
+\newskip\MacrocodeTopsep \MacrocodeTopsep = 3pt plus 1.2pt minus 1pt
+\newdimen\MacroIndent
+\settowidth\MacroIndent{\rmfamily\scriptsize 00\ }
+\@namedef{macrocode*}{\macro at code\sxmacro at code}
+\expandafter\let\csname endmacrocode*\endcsname = \endmacrocode
+\catcode`\!=\catcode`\%   ^^A In this section there must not be
+                              ^^A any exclamation marks.
+                              ^^A
+\begingroup
+\catcode`\|=\z@ \catcode`\[=\@ne \catcode`\]=\tw@
+\catcode`\{=12 \catcode`\}=12
+\catcode`\%=12 \catcode`\ =\active \catcode`\\=\active
+!%    \end{macrocode*}
+!    Next follows the actual definition of  |\macro at code|;
+!    notice the
+!    use of the new escape character.  We manage to get the argument
+!    surrounded by the string |\end{macrocode}|, but at the end
+!    however, in spite of the actual characters used during the
+!    definition of
+!    this macro, |\end| with the argument |{macrocode}|
+!    will be executed, to ensure a balanced environment.
+!    \begin{macrocode*}
+|gdef|xmacro at code#1%    \end{macrocode}[#1|end[macrocode]]
+!%    \end{macrocode*}
+! \begin{macro}{\sxmacro at code}
+!    The definition of |\sxmacro at code| is completely analogous,
+!    only
+!    here a slightly different terminating string will be used.
+!    Note that the space is not active in this environment.
+!    \begin{macrocode}
+|catcode`| =12
+|gdef|sxmacro at code#1%    \end{macrocode*}[#1|end[macrocode*]]
+!%    \end{macrocode}
+!    because the |\catcode| changes have been made local by
+!    commencing a
+!    new group, there now follows the matching |\endgroup|
+!    in a rather
+!    unusual style of writing.
+!    \begin{macrocode}
+|endgroup
+!%    \end{macrocode}
+\catcode`\!=12
+
+\reversemarginpar
+\setlength\marginparpush{0pt}  \setlength\marginparwidth{8pc}
+\setlength\marginparsep{\labelsep}
+{\catcode`\|=\z@ \catcode`\\=12
+|gdef|bslash{\}}
+\def\verbatim{\@beginparpenalty \predisplaypenalty \@verbatim
+              \MacroFont \frenchspacing \@vobeyspaces \@xverbatim}
+\@namedef{verbatim*}{\@beginparpenalty \predisplaypenalty \@verbatim
+              \MacroFont \@sxverbatim}
+\def\@verbatim{\trivlist \item[]\if at minipage\else\vskip\parskip\fi
+      \leftskip\@totalleftmargin\rightskip\z@
+      \parindent\z@\parfillskip\@flushglue\parskip\z@
+      \@@par
+      \@tempswafalse
+ \def\par{\if at tempswa\hbox{}\fi\@tempswatrue\@@par
+          \penalty\interlinepenalty
+   \check at percent}%
+ \obeylines
+ \let\do\do at noligs \verbatim at nolig@list
+ \let\do\@makeother \dospecials}
+{\catcode`\%=12
+ \long\gdef\check at percent#1{\ifx #1%\let\next\@empty \else
+                                    \let\next=#1\fi \next}}
+\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}}
+\let\verb at balance@group\@empty
+
+\def\verb at egroup{\global\let\verb at balance@group\@empty\egroup}
+
+\begingroup
+  \obeylines%
+  \gdef\verb at eol@error{\obeylines%
+    \def^^M{\verb at egroup\@latex at error{%
+           Text for \noexpand\verb command ended by end of line}\@ehc}}%
+\endgroup
+\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}}
+\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}}}
+\newcount\macro at cnt \macro at cnt=0
+\newskip\MacroTopsep     \MacroTopsep = 7pt plus 2pt minus 2pt
+\begingroup
+\catcode`\~\active
+\gdef\SpecialEscapechar#1{%
+    \begingroup
+     \uccode`\~`#1%
+     \uppercase{\gdef\active at escape@char{~}}%
+     \escapechar\m at ne  \xdef\special at escape@char{\string#1}%
+   \endgroup}
+\endgroup
+\begingroup   \catcode`\|=\z@  \catcode`\\=\active
+|gdef|init at crossref{|catcode`|\|active   |let\|bslash
+    |MakePrivateLetters
+    |catcode|expandafter`|special at escape@char|active
+    |expandafter|let|active at escape@char|scan at macro}
+|endgroup
+\SpecialEscapechar{\\}
+\@ifundefined{MakePrivateLetters}
+    {\let\MakePrivateLetters\makeatletter}{}
+\def\close at crossref{\SpecialEscapechar\\}
+\def\scan at macro{%
+   \special at escape@char
+   \step at checksum
+   \ifscan at allowed
+      \let\macro at namepart\@empty
+      \def\next{\futurelet\next\macro at switch}%
+   \else \let\next\@empty \fi
+   \next}
+\def\DisableCrossrefs{\@bsphack\scan at allowedfalse\@esphack}
+\def\EnableCrossrefs{\@bsphack\scan at allowedtrue
+                     \def\DisableCrossrefs{\@bsphack\@esphack}\@esphack}
+\def\macro at switch{\ifcat\noexpand\next a%
+     \let\next\macro at name
+     \else \let\next\short at macro  \fi
+   \next}
+\begingroup
+\catcode`\&=12
+\gdef\short at macro#1{\begingroup
+   \uccode`\&=\expandafter`\string#1%
+   \uppercase{\def\x{\def\macro at namepart{&}}}%
+   \expandafter\endgroup\x
+     \maybe at index@short at macro\macro at namepart
+    \scan at allowedfalse#1%
+    \scan at allowedtrue }
+\endgroup
+\def\macro at name#1{\edef\macro at namepart{\macro at namepart#1}%
+     \futurelet\next\more at macroname}
+\def\more at macroname{\ifcat\noexpand\next a%
+     \let\next\macro at name
+     \else \let\next\macro at finish \fi
+     \next}
+\def\macro at finish{%
+  \macro at namepart
+  \maybe at index@macro \macro at namepart
+}
+
+\RequirePackage{expl3}
+\ExplSyntaxOn
+\seq_new:N  \l__doc_donotindex_seq
+\prop_new:N \g__doc_idxtype_prop
+\cs_new:Npn\__doc_trace:x {
+  \ifdoc at debugshow
+    \expandafter \iow_term:x
+  \else
+    \expandafter \use_none:n
+  \fi
+}
+\cs_new:Npn \doc_dont_index:n {
+  \group_begin:
+    \MakePrivateLetters
+    \__doc_dont_index:n
+}
+\cs_new:Npn \__doc_dont_index:n #1 {
+  \group_end:
+  \__doc_trace:x{Disable~ indexing~ for~ '\tl_to_str:n{#1}' }
+  \clist_map_function:nN {#1} \__doc_dont_index_aux:n
+}
+\cs_new:Npn \__doc_dont_index_aux:n #1 {
+  \seq_put_right:Nx \l__doc_donotindex_seq {\expandafter\@gobble \string#1}
+}
+\cs_set_eq:NN \DoNotIndex \doc_dont_index:n
+\def \ShowIndexingState {
+  \__doc_trace:x{Show~ doc~ indexing~ state:}
+  \seq_show:N  \l__doc_donotindex_seq
+  \prop_show:N \g__doc_idxtype_prop
+}
+
+\cs_new:Npn \__doc_idxtype_put:Nn #1#2 {
+  \exp_args:Nx \__doc_idxtype_put:nn { \cs_to_str:N #1 }{#2}
+  \protected at write\@auxout{}
+     {\string\RecordIndexTypeAux {\string#1 }{#2} }
+}
+\cs_new:Npn \RecordIndexTypeAux #1#2 {
+  \exp_args:Nx \__doc_idxtype_put:nn { \cs_to_str:N #1 }{#2}
+}
+\AtEndDocument{
+  \cs_set_eq:NN \RecordIndexTypeAux \use_none:nn
+}
+\cs_set_eq:NN \RecordIndexType \__doc_idxtype_put:Nn
+\cs_new:Npn \__doc_idxtype_put_scan:nn #1#2 {
+  \exp_args:Nf \__doc_idxtype_put:nn { \tl_to_str:n {#1} }{#2}
+  \protected at write\@auxout{}
+     {\string\RecordIndexTypeAux {\bslash #1 }{#2} }
+}
+\cs_generate_variant:Nn \__doc_idxtype_put_scan:nn {o}
+\cs_set_eq:NN \record at index@type at save \__doc_idxtype_put_scan:on
+\cs_new:Npn \__doc_idxtype_put:nn #1#2 {
+  \exp_args:NNf
+  \seq_if_in:NnTF \l__doc_donotindex_seq {\tl_to_str:n{#1}}
+     {
+       \__doc_trace:x{Not~ recording~ index~ type~ for~ '\bslash #1' }
+     }
+     {
+       \__doc_trace:x{Recording~ index~ type~ for~ '\bslash #1' ~ as~ #2 }
+       \prop_gput:Nnn \g__doc_idxtype_prop {#1}{#2}
+     }
+}
+\cs_new:Npn \exp_args:co #1#2
+   { \cs:w #1 \exp_after:wN \cs_end:\exp_after:wN {#2} }
+\cs_generate_variant:Nn \tl_to_str:n {o}
+
+\cs_new:Npn \__doc_maybe_index:o #1 {
+  \exp_args:Nf \__doc_maybe_index_aux:nN { \tl_to_str:o {#1} }
+                                         \SpecialIndex
+}
+\cs_set_eq:NN \maybe at index@macro \__doc_maybe_index:o
+\cs_new:Npn \__doc_maybe_index_short:o #1 {
+  \exp_args:Nf \__doc_maybe_index_aux:nN { \tl_to_str:o {#1} }
+                                         \SpecialShortIndex
+}
+\cs_set_eq:NN \maybe at index@short at macro \__doc_maybe_index_short:o
+\cs_new:Npn \__doc_maybe_index_aux:nN #1#2 {
+  \__doc_trace:x{Searching~ for~ '\bslash #1'}
+  \seq_if_in:NnTF \l__doc_donotindex_seq {#1}
+    {
+     \__doc_trace:x{Not~ indexing~ '\bslash #1' }
+    }
+    {
+     \prop_get:NnNTF \g__doc_idxtype_prop {#1} \l__doc_idxtype_tl
+       {
+        \exp_args:Ncno \__doc_maybe_index_aux:Nnn
+              { Code \tl_use:N \l__doc_idxtype_tl Index }
+              {code} {\bslash #1}
+        }
+        {
+          \__doc_trace:x{Indexing~ '\bslash #1'\space (\string #2)}
+          \exp_args:No #2 {\bslash #1}
+        }
+    }
+}
+\cs_new:Npn \SpecialShortIndex #1 {
+    \@SpecialIndexHelper@ #1\@nil
+  \@bsphack
+  \ifdoc at noindex \else
+    \str_case_e:nnF {\@gtempa }
+        {
+          {\cs_to_str:N \^^M } {\def\reserved at a{ \string \space \actualchar }
+                                \def\reserved at b { \space }
+                                \let\reserved at c \@empty                          }
+          { }                  {\def\reserved at a{ \string \space \actualchar }
+                                \def\reserved at b { \space }
+                                \let\reserved at c \@empty                          }
+          {\c_left_brace_str} { \def\reserved at a{ \bgroup \actualchar }
+                                \def\reserved at b { \c_left_brace_str }
+                                \def\reserved at c { \noexpand\iffalse
+                                                  \c_right_brace_str
+                                                  \noexpand\fi }                 }
+          {\c_right_brace_str} { \def\reserved at a{ \egroup \actualchar
+                                                  \noexpand\iffalse
+                                                    \c_left_brace_str
+                                                  \noexpand\fi }
+                                 \def\reserved at b { \c_right_brace_str }
+                                 \let\reserved at c \@empty                         }
+          {\verbatimchar}  { \def\reserved at a{ \quotechar\verbatimchar
+                                              \actualchar }
+                             \let\reserved at b \@empty
+                             \def\reserved at c
+                                 { \string\texttt{\string\string\verbatimchar} } }
+        }
+        { \def\reserved at a {\quotechar \@gtempa \actualchar }
+          \def\reserved at b {\quotechar \@gtempa  }
+          \let\reserved at c \@empty                             }
+    \special at index {
+    \reserved at a
+    \string\verb
+    \quotechar *\verbatimchar \quotechar \bslash
+    \reserved at b
+    \verbatimchar
+    \reserved at c
+    \encapchar code}
+  \fi
+  \@esphack
+}
+
+\cs_new:Npn \__doc_maybe_index_aux:Nnn #1#2#3 {
+    \cs_if_exist:NTF #1
+      {
+        \__doc_trace:x{Indexing~ '#3'\space as~
+                       \tl_use:N \l__doc_idxtype_tl }
+        #1{#2}{#3}
+      }
+      {
+        \PackageError{doc}{Doc~ element~
+           '\tl_use:N \l__doc_idxtype_tl'~ unknown}%
+
+          {When~ using~ '\string\RecordIndexType'~ the~ type~ must~
+           be~ known~\MessageBreak
+           to~ the~ system,~ i.e.,~ declared~ via~
+           '\string\NewDocElement'\MessageBreak
+           before~ it~ can~ be~ used~ in~ indexing.}
+     }
+}
+\ExplSyntaxOff
+\@ifundefined{actualchar}{\def\actualchar{=}}{}
+\@ifundefined{quotechar}{\def\quotechar{!}}{}
+\@ifundefined{levelchar}{\def\levelchar{>}}{}
+\@ifundefined{encapchar}{\def\encapchar{|}}{}
+\@ifundefined{verbatimchar}{\def\verbatimchar{+}}{}
+\begingroup
+ \catcode`\|=0
+ \catcode`\\=12
+ |gdef|@SpecialIndexHelper@#1#2|@nil{%
+   |if |noexpand#1\%
+     |gdef|@gtempa{#2}%
+   |else
+     |begingroup
+       |escapechar|m at ne
+       |expandafter|gdef|expandafter|@gtempa|expandafter{|string#1#2}%
+     |endgroup
+   |fi}
+|endgroup
+\def\SortIndex#1#2{%
+  \ifdoc at noindex\else
+    \index{#1\actualchar#2}%
+  \fi
+}
+\@ifundefined{LeftBraceIndex}{\def\LeftBraceIndex{%
+   \special at index{\bgroup\actualchar
+                  \string\verb% % to fool emacs highlighting
+                  \quotechar*\verbatimchar
+                  \quotechar\bslash{\verbatimchar\string\iffalse}\string\fi}}}{}
+
+\@ifundefined{RightBraceIndex}{\def\RightBraceIndex{%
+ \special at index{\egroup\actualchar\string\iffalse{\string\fi
+           \string\verb% % to fool emacs highlighting
+           \quotechar*\verbatimchar\quotechar\bslash}\verbatimchar}}}{}
+\@ifundefined{PercentIndex}
+  {\def\PercentIndex{\it at is@a\percentchar}}{}
+\def\OldMakeindex{\def\PercentIndex{%
+    \special at index{\quotechar\percentchar\actualchar
+           \string\verb% % to fool emacs highlighting
+           \quotechar*\verbatimchar\quotechar\bslash
+           \percentchar\percentchar\verbatimchar}}}
+{\catcode`\%=12 \gdef\percentchar{%}}
+\def\it at is@a#1{\special at index{\quotechar #1\actualchar
+                          \string\verb% % to fool emacs highlighting
+                          \quotechar*\verbatimchar
+                          \quotechar\bslash\quotechar#1\verbatimchar}}
+
+\newdimen\IndexMin         \IndexMin       = 80pt
+\newcount\c at IndexColumns   \c at IndexColumns = 3
+\ifdoc at multicol
+  \RequirePackage{multicol}
+  \renewenvironment{theindex}
+    {\begin{multicols}\c at IndexColumns[\index at prologue][\IndexMin]%
+      \IndexParms \let\item\@idxitem \ignorespaces}%
+    {\end{multicols}}
+\else
+  \def\theindex{\@restonecoltrue\if at twocolumn\@restonecolfalse\fi
+    \columnseprule \z@  \columnsep 35\p@
+    \twocolumn[\index at prologue]%
+    \IndexParms \let\item\@idxitem \ignorespaces}
+  \def\endtheindex{\if at restonecol\onecolumn\else\clearpage\fi}
+\fi
+\long\def\IndexPrologue#1{\@bsphack\def\index at prologue{#1}\@esphack}
+\@ifundefined{index at prologue}
+     {\def\index at prologue{\section*{Index}%
+                 \markboth{Index}{Index}%
+                 Numbers written in italic refer to the page
+                 where the corresponding entry is described;
+                 numbers underlined refer to the
+                 \ifcodeline at index
+                   code line of the
+                 \fi
+                 definition; numbers in roman refer to the
+                 \ifcodeline at index
+                   code lines
+                 \else
+                   pages
+                 \fi
+                 where the entry is used.
+                 }}{}
+\@ifundefined{IndexParms}
+    {\def\IndexParms{%
+       \parindent \z@
+       \columnsep 15pt
+       \parskip 0pt plus 1pt
+       \rightskip 15pt
+       \mathsurround \z@
+       \parfillskip=-15pt
+        \small
+       \def\@idxitem{\par\hangindent 30pt}%
+       \def\subitem{\@idxitem\hspace*{15pt}}%
+       \def\subsubitem{\@idxitem\hspace*{25pt}}%
+       \def\indexspace{\par\vspace{10pt plus 2pt minus 3pt}}%
+      }}{}
+\def\efill{\hfill\nopagebreak}%
+\def\pfill{\unskip~%
+           \leaders\hbox to.6em{\hss .\hss}\hfill
+           \penalty500\strut\nobreak
+           \leaders\hbox to.6em{\hss .\hss}\hfil
+           ~\ignorespaces}%
+\def\*{\leavevmode\lower.8ex\hbox{$\,\widetilde{\ }\,$}}
+\@ifundefined{main}{\def\main#1{\underline{#1}}}{}
+\@ifundefined{usage}{\def\usage#1{\textit{#1}}}{}
+\@ifundefined{code}{\def\code#1{#1}}{}
+\def\PrintIndex{\@input@{\jobname.ind}%
+                \global\let\PrintIndex\@empty}
+\def\changes{\@bsphack\begingroup\@sanitize
+   \catcode`\\\z@ \catcode`\ 10 \MakePercentIgnore
+   \changes@}
+\def\changes@#1#2#3{%
+  \protected at edef\@tempa{\noexpand\glossary{#1\levelchar
+                   \ifx\saved at macroname\@empty
+                      \quotechar!%
+                      \actualchar
+                      \generalname
+                   \else
+                      \saved at indexname
+                      \actualchar
+                      \string\verb% % to fool emacs highlighting
+                      \quotechar*%
+                      \verbatimchar\saved at macroname
+                      \verbatimchar
+                   \fi
+                   :\levelchar #3}}%
+  \@tempa\endgroup\@esphack}
+\def\saved at macroname{}
+\def\saved at indexname{}
+\def\generalname{General}
+\let\RecordChanges\makeglossary
+\newdimen\GlossaryMin         \GlossaryMin       = 80pt
+\newcount\c at GlossaryColumns   \c at GlossaryColumns = 2
+\ifdoc at multicol
+  \newenvironment{theglossary}{%
+    \begin{multicols}\c at GlossaryColumns
+                     [\glossary at prologue][\GlossaryMin]%
+    \GlossaryParms \let\item\@idxitem \ignorespaces}%
+   {\end{multicols}}
+\else
+  \newenvironment{theglossary}{%
+      \@restonecoltrue\if at twocolumn\@restonecolfalse\fi
+      \columnseprule \z@  \columnsep 35\p@
+      \twocolumn[\glossary at prologue]%
+      \GlossaryParms \let\item\@idxitem \ignorespaces}
+    {\if at restonecol\onecolumn\else\clearpage\fi}
+\fi
+\long\def\GlossaryPrologue#1{\@bsphack
+                             \def\glossary at prologue{#1}%
+                             \@esphack}
+\@ifundefined{glossary at prologue}
+     {\def\glossary at prologue{\section*{{Change History}}%
+                 \markboth{{Change History}}{{Change History}}%
+                 }}{}
+\@ifundefined{GlossaryParms}{\let\GlossaryParms\IndexParms
+  \expandafter\def\expandafter\GlossaryParms\expandafter{\GlossaryParms
+     \rightskip 15pt plus 1fil
+     \parfillskip -15pt plus -1fil\relax}
+}{}
+\def\PrintChanges{\@input@{\jobname.gls}%
+                  \global\let\PrintChanges\@empty}
+\newcommand\AlsoImplementation{%
+   \long\def\MaybeStopHere##1{\@bsphack\gdef\Finale{##1%
+                  \check at checksum}%
+              \init at checksum
+              \@esphack}%
+         }
+\AlsoImplementation
+\def\OnlyDescription{\@bsphack\long\def\MaybeStopHere##1{%
+           ##1\endinput}\@esphack}
+\let\Finale\relax
+\def\StopEventually{\MaybeStopHere}
+\ifx\l at nohyphenation\undefined
+  \newlanguage\l at nohyphenation
+\fi
+\DeclareRobustCommand\meta[1]{%
+     \ensuremath\langle
+     \ifmmode \expandafter \nfss at text \fi
+     {%
+      \meta at font@select
+      \edef\meta at hyphen@restore
+        {\hyphenchar\the\font\the\hyphenchar\font}%
+      \hyphenchar\font\m at ne
+      \language\l at nohyphenation
+      #1\/%
+      \meta at hyphen@restore
+     }\ensuremath\rangle
+}
+\def\meta at font@select{\itshape}
+\def\IndexInput#1{%
+     \begingroup \macro at code
+   \frenchspacing \@vobeyspaces
+     \input{#1}\endmacrocode
+     \endgroup}
+\def\maketitle{\par
+      \begingroup \def \thefootnote {\fnsymbol {footnote}}%
+      \setcounter {footnote}\z@
+      \def\@makefnmark{\hbox to\z@{$\m at th^{\@thefnmark}$\hss}}%
+      \long\def\@makefntext##1{\parindent 1em\noindent
+            \hbox to1.8em{\hss$\m at th^{\@thefnmark}$}##1}%
+      \if at twocolumn \twocolumn [\@maketitle ]%
+      \else \newpage \global \@topnum \z@ \@maketitle \fi
+       \thispagestyle{titlepage}\@thanks \endgroup
+      \setcounter {footnote}\z@
+      \gdef\@date{\today}\gdef\@thanks{}%
+      \gdef\@author{}\gdef\@title{}}
+\@ifundefined{ps at titlepage}
+    {\let\ps at titlepage=\ps at plain}{}
+\def\MakeShortVerb{%
+  \@ifstar
+    {\def\@shortvrbdef{\verb*}\@MakeShortVerb}%
+    {\def\@shortvrbdef{\verb}\@MakeShortVerb}}
+\def\@MakeShortVerb#1{%
+  \expandafter\ifx\csname cc\string#1\endcsname\relax
+    \@shortvrbinfo{Made }{#1}\@shortvrbdef
+    \add at special{#1}%
+    \expandafter
+    \xdef\csname cc\string#1\endcsname{\the\catcode`#1}%
+    \begingroup
+      \catcode`\~\active  \lccode`\~`#1%
+      \lowercase{%
+      \global\expandafter\let
+         \csname ac\string#1\endcsname~%
+      \expandafter\gdef\expandafter~\expandafter{\@shortvrbdef~}}%
+    \endgroup
+    \global\catcode`#1\active
+  \else
+    \@shortvrbinfo\@empty{#1 already}%
+                         {\@empty\verb% % to fool emacs highlighting
+                          (*)}%
+  \fi}
+\def\DeleteShortVerb#1{%
+  \expandafter\ifx\csname cc\string#1\endcsname\relax
+    \@shortvrbinfo\@empty{#1 not}%
+                         {\@empty\verb% % to fool emacs highlighting
+                          (*)}%
+  \else
+    \@shortvrbinfo{Deleted }{#1 as}%
+                            {\@empty\verb% % to fool emacs
+                                           % highlighting
+                            (*)}%
+    \rem at special{#1}%
+    \global\catcode`#1\csname cc\string#1\endcsname
+    \global \expandafter\let \csname cc\string#1\endcsname \relax
+    \ifnum\catcode`#1=\active
+      \begingroup
+        \catcode`\~\active   \lccode`\~`#1%
+        \lowercase{%
+          \global\expandafter\let\expandafter~%
+          \csname ac\string#1\endcsname}%
+      \endgroup \fi \fi}
+\def\@shortvrbinfo#1#2#3{%
+  \PackageInfo{doc}{%
+     #1\expandafter\@gobble\string#2 a short reference
+                                          for \expandafter\string#3}}
+\def\add at special#1{%
+  \rem at special{#1}%
+  \expandafter\gdef\expandafter\dospecials\expandafter
+    {\dospecials \do #1}%
+  \expandafter\gdef\expandafter\@sanitize\expandafter
+    {\@sanitize \@makeother #1}}
+\def\rem at special#1{%
+  \def\do##1{%
+    \ifnum`#1=`##1 \else \noexpand\do\noexpand##1\fi}%
+  \xdef\dospecials{\dospecials}%
+  \begingroup
+    \def\@makeother##1{%
+      \ifnum`#1=`##1 \else \noexpand\@makeother\noexpand##1\fi}%
+    \xdef\@sanitize{\@sanitize}%
+  \endgroup}
+\def\init at checksum{\relax
+    \global\bslash at cnt\z@}
+\def\check at checksum{\relax
+  \ifnum\check at sum>\m at ne
+     \ifnum\check at sum=\z@
+       \typeout{**********************************}%
+       \typeout{* This macro file has no checksum!}%
+       \typeout{* The checksum should be \the\bslash at cnt!}%
+       \typeout{**********************************}%
+     \else
+       \ifnum\check at sum=\bslash at cnt
+         \typeout{*******************}%
+         \typeout{* Checksum passed *}%
+         \typeout{*******************}%
+       \else
+         \PackageError{doc}{Checksum not passed
+                    (\the\check at sum<>\the\bslash at cnt)}%
+          {The file currently documented seems to be wrong.^^J%
+           Try to get a correct version.}%
+       \fi
+     \fi
+  \fi
+  \global\check at sum\m at ne}
+\newcount\check at sum           \check at sum  = \m at ne
+\newcount\bslash at cnt          \bslash at cnt = \z@
+\def\CheckSum#1{\@bsphack\global\check at sum#1\relax\@esphack}
+\def\step at checksum{\global\advance\bslash at cnt\@ne}
+\def\CharacterTable{\begingroup \CharTableChanges \character at table}
+\begingroup
+  \catcode`\~=11
+  \gdef\character at table#1{\def\used~table{#1}%
+      \ifx\used~table\default~table
+           \typeout{***************************}%
+           \typeout{* Character table correct *}%
+           \typeout{***************************}%
+      \else
+         \PackageError{doc}{Character table corrupted}
+                           {\the\wrong at table}
+         \show\default~table
+         \show\used~table
+      \fi
+      \endgroup}
+  \global\let\CharTableChanges\@empty
+  \makeatother
+  \gdef\default~table
+     {Upper-case    \A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z
+      Lower-case    \a\b\c\d\e\f\g\h\i\j\k\l\m\n\o\p\q\r\s\t\u\v\w\x\y\z
+      Digits        \0\1\2\3\4\5\6\7\8\9
+      Exclamation   \!     Double quote  \"     Hash (number) \#
+      Dollar        \$     Percent       \%     Ampersand     \&
+      Acute accent  \'     Left paren    \(     Right paren   \)
+      Asterisk      \*     Plus          \+     Comma         \,
+      Minus         \-     Point         \.     Solidus       \/
+      Colon         \:     Semicolon     \;     Less than     \<
+      Equals        \=     Greater than  \>     Question mark \?
+      Commercial at \@     Left bracket  \[     Backslash     \\
+      Right bracket \]     Circumflex    \^     Underscore    \_
+      Grave accent  \`     Left brace    \{     Vertical bar  \|
+      Right brace   \}     Tilde         \~}
+\endgroup
+  \newhelp\wrong at table{Some of the ASCII characters are corrupted.^^J
+            I now \string\show\space you both tables for comparison.}
+\newif\ifcodeline at index \codeline at indexfalse
+\let\CodelineNumbered\codeline at indextrue
+\def\codeline at wrindex#1{\if at filesw
+     \begingroup
+        \set at display@protect
+        \immediate\write\@indexfile
+            {\string\indexentry{#1}%
+             {\number\c at CodelineNo}}%
+      \endgroup
+    \fi}
+\let\special at index = \@gobble
+\def\CodelineIndex{\makeindex
+                   \codeline at indextrue
+                   \let\special at index\codeline at wrindex}
+\def\PageIndex{\makeindex
+               \codeline at indexfalse
+               \let\special at index\index}
+\newcount\c at CodelineNo  \c at CodelineNo\z@
+\@ifundefined{theCodelineNo}
+  {\ifx\selectfont\undefined
+     \def\theCodelineNo{\rmfamily\scriptsize\arabic{CodelineNo}}%
+   \else
+     \def\theCodelineNo{\reset at font\scriptsize\arabic{CodelineNo}}%
+   \fi}
+  {}
+       \tolerance=1000\relax
+{ \catcode`\"=12
+  \global\mathcode`\\="705C \global\mathcode`\@="7040 }
+\@ifundefined{DocstyleParms}{}{\DocstyleParms}
+ \let\DocstyleParms\relax
+\@ifundefined{AmSTeX}
+   {\def\AmSTeX{\leavevmode\hbox{$\mathcal A\kern-.2em\lower.376ex%
+        \hbox{$\mathcal M$}\kern-.2em\mathcal S$-\TeX}}}{}
+\@ifundefined{BibTeX}
+   {\def\BibTeX{{\rmfamily B\kern-.05em%
+    \textsc{i\kern-.025em b}\kern-.08em%
+    T\kern-.1667em\lower.7ex\hbox{E}\kern-.125emX}}}{}
+\@ifundefined{SliTeX}
+   {\def\SliTeX{{\rmfamily S\kern-.06emL\kern-.18em\raise.32ex\hbox
+                {\scshape i}\kern -.03em\TeX}}}{}
+\@ifundefined{PlainTeX}{\def\PlainTeX{\textsc{Plain}\kern2pt\TeX}}{}
+\@ifundefined{Web}{\def\Web{\textsc{Web}}}{}
+\def\MakePercentIgnore{\catcode`\%9\relax}
+\def\MakePercentComment{\catcode`\%14\relax}
+\def\DocInput#1{\MakePercentIgnore\input{#1}\MakePercentComment}
+\def\GetFileInfo#1{%
+  \def\filename{#1}%
+  \def\@tempb##1 ##2 ##3\relax##4\relax{%
+    \def\filedate{##1}%
+    \def\fileversion{##2}%
+    \def\fileinfo{##3}}%
+  \edef\@tempa{\csname ver@#1\endcsname}%
+  \expandafter\@tempb\@tempa\relax? ? \relax\relax}
+
+\ifdoc at hyperref
+  \let\PrintDescribeMacro \@empty
+  \let\PrintDescribeEnv   \@empty
+  \let\PrintMacroName     \@empty
+  \let\PrintEnvName       \@empty
+  \let\SpecialUsageIndex  \@empty
+  \let\SpecialEnvIndex    \@empty
+  \expandafter\let\expandafter\doc at eoph@@k\csname doc.sty-h@@k\endcsname
+  \RequirePackage{hypdoc}
+  \expandafter\let\csname doc.sty-h@@k\endcsname\doc at eoph@@k
+  \let\PrintDescribeMacro \relax
+  \let\PrintDescribeEnv   \relax
+  \let\PrintMacroName     \relax
+  \let\PrintEnvName       \relax
+  \def\doc at providetarget{\HD at target}
+  \def\doc at handleencap#1{\encapchar hdclindex{\the\c at HD@hypercount}{#1}}
+\else
+  \let\doc at providetarget\@empty
+  \def\doc at handleencap#1{\encapchar #1}
+  \def\hdclindex#1#2{\ifx\@nil#2\@nil\else\csname #2\expandafter\endcsname\fi}
+  \def\hdpindex   #1{\ifx\@nil#1\@nil\else\csname #1\expandafter\endcsname\fi}
+\fi
+
+
+\ExplSyntaxOn
+
+\long\def\@doc at env#1#2#3{
+  \endgroup
+  \clist_map_inline:nn {#3} { \@doc at env@{#1}{#2}{##1} }
+}
+
+\ExplSyntaxOff
+\long\def\@doc at env@#1#2#3{%
+  \topsep\MacroTopsep
+  \trivlist
+    \edef\saved at macroname{\string#3}%
+    \if #1%
+      \edef\saved at indexname{\expandafter\@gobble\saved at macroname}%
+      \expandafter\ifx
+                  \csname Code#2Index\endcsname
+                  \CodeMacroIndex
+      \else
+        \record at index@type at save
+          {\saved at indexname}{#2}%
+      \fi
+    \else
+      \let\saved at indexname\saved at macroname
+    \fi
+    \def\makelabel##1{\llap{##1}}%
+    \if at inlabel
+      \let\@tempa\@empty
+      \count@\macro at cnt
+      \loop\ifnum\count@>\z@
+        \edef\@tempa{\@tempa\hbox{\strut}}\advance\count@\m at ne
+      \repeat
+      \edef\makelabel##1{\llap{\vtop to\baselineskip{\@tempa\hbox{##1}\vss}}}%
+      \advance\macro at cnt\@ne
+    \else
+      \macro at cnt\@ne
+    \fi
+    \ifdoc at noprint
+      \item
+    \else
+      \edef\@tempa{%
+        \noexpand\item[%
+        \noexpand\doc at providetarget
+        \noexpand\strut
+        \noexpand\@nameuse{Print#2Name}{\saved at macroname}]}%
+      \@tempa
+    \fi
+    \ifdoc at noindex\else
+      \global\advance\c at CodelineNo\@ne
+      \csname SpecialMain#2Index\expandafter\endcsname
+        \expandafter{\saved at macroname}\nobreak
+      \global\advance\c at CodelineNo\m at ne
+    \fi
+    \if#1\expandafter\DoNotIndex \expandafter {\saved at macroname}\fi
+    \ignorespaces}
+
+\def\doc at env#1#2[#3]{%
+  \@nameuse{doc at noprint\doc at noprintdefault}%
+  \@nameuse{doc at noindex\doc at noindexdefault}%
+  \setkeys{doc}{#3}%
+  \begingroup
+    \ifdoc at outer
+      \catcode`\\12
+    \fi
+    \MakePrivateLetters
+    \@doc at env{#1}{#2}%
+}
+
+\def\@doc at describe#1#2{%
+    \ifdoc at noprint\else
+      \marginpar{\raggedleft
+                 \strut
+                 \doc at providetarget
+                 \@nameuse{PrintDescribe#1}{#2}}%
+    \fi
+    \ifdoc at noindex\else
+      \@nameuse{Special#1Index}{#2}%
+    \fi
+  \@esphack
+  \endgroup
+  \ignorespaces}
+\def\doc at describe#1[#2]{%
+  \leavevmode\@bsphack
+    \setkeys{doc}{#2}%
+      \@doc at describe{#1}}
+\@ifundefined{temptokenb}{\newtoks\@temptokenb}{}
+\def\doc at createspecialindexes#1#2#3{%
+  \@temptokena{\space (#2)}%
+  \@temptokenb{#3:}%
+  \@nameedef{SpecialMain#1Index}##1{%
+    \noexpand\@bsphack
+  \ifdoc at toplevel
+    \noexpand\special at index{##1\noexpand\actualchar
+    {\string\ttfamily\space##1}%
+    \ifx\@nil#2\@nil\else \the\@temptokena \fi
+    \noexpand\encapchar main}%
+  \fi
+  \ifx\@nil#3\@nil\else
+    \noexpand\special at index{\the\@temptokenb\noexpand\levelchar
+      ##1\noexpand\actualchar{\string\ttfamily\space##1}%
+      \noexpand\encapchar main}%
+  \fi
+    \noexpand\@esphack}%
+  \@nameedef{Special#1Index}##1{%
+    \noexpand\@bsphack
+  \ifdoc at toplevel
+    \noexpand\doc at providetarget
+    \noexpand\index{##1\noexpand\actualchar{\string\ttfamily\space##1}%
+    \ifx\@nil#2\@nil\else \the\@temptokena \fi
+           \noexpand\doc at handleencap{usage}}%
+  \fi
+  \ifx\@nil#3\@nil\else
+    \noexpand\index{\the\@temptokenb\noexpand\levelchar
+       ##1\noexpand\actualchar{\string\ttfamily\space##1}%
+           \noexpand\doc at handleencap{usage}}%
+  \fi
+    \noexpand\@esphack}}
+\def\doc at createspecialmacrolikeindexes#1#2#3{%
+  \@temptokena{\space (#2)}%
+  \@temptokenb{#3:}%
+  \@nameedef{Code#1Index}##1##2{%
+    \noexpand\@SpecialIndexHelper@##2\noexpand\@nil
+    \noexpand\@bsphack
+  \noexpand\ifdoc at noindex\noexpand\else
+    \ifdoc at toplevel
+      \noexpand\special at index{\noexpand\@gtempa\noexpand\actualchar
+\string\verb% % to fool emacs highlighting
+\noexpand\quotechar*\noexpand\verbatimchar
+\noexpand\bslash\noexpand\@gtempa\noexpand\verbatimchar
+\ifx\@nil#2\@nil\else \the\@temptokena \fi
+\noexpand\encapchar ##1}%
+    \fi
+    \ifx\@nil#3\@nil\else
+      \noexpand\special at index{\the\@temptokenb\noexpand\levelchar
+\noexpand\@gtempa\noexpand\actualchar
+\string\verb% % to fool emacs highlighting
+\noexpand\quotechar*\noexpand\verbatimchar
+\noexpand\bslash\noexpand\@gtempa\noexpand\verbatimchar
+\noexpand\encapchar ##1}%
+    \fi
+  \noexpand\fi
+    \noexpand\@esphack}%
+  \@nameedef{SpecialMain#1Index}##1{%
+    \expandafter\noexpand\csname Code#1Index\endcsname
+        {main}{##1}}%
+  \@nameedef{Special#1Index}##1{%
+    \noexpand\@SpecialIndexHelper@##1\noexpand\@nil
+    \noexpand\@bsphack
+  \noexpand\ifdoc at noindex\noexpand\else
+    \ifdoc at toplevel
+      \noexpand\doc at providetarget
+      \noexpand\index{\noexpand\@gtempa\noexpand\actualchar
+\string\verb% % to fool emacs highlighting
+\noexpand\quotechar*\noexpand\verbatimchar
+\noexpand\bslash\noexpand\@gtempa\noexpand\verbatimchar
+\ifx\@nil#2\@nil\else \the\@temptokena \fi
+\noexpand\doc at handleencap{usage}}%
+    \fi
+    \ifx\@nil#3\@nil\else
+      \noexpand\index{\the\@temptokenb\noexpand\levelchar
+\noexpand\@gtempa\noexpand\actualchar
+\string\verb% % to fool emacs highlighting
+\noexpand\quotechar*\noexpand\verbatimchar
+\noexpand\bslash\noexpand\@gtempa\noexpand\verbatimchar
+\noexpand\doc at handleencap{usage}}%
+    \fi
+  \noexpand\fi
+    \noexpand\@esphack}}
+
+\def\doc at createdescribe#1{%
+  \@namedef{Describe#1}{%
+    \begingroup
+      \MakePrivateLetters
+      \@ifnextchar[%]
+      {\doc at describe{#1}}{\doc at describe{#1}[]}}}
+\def\doc at createenv#1#2#3{%
+  \@namedef{#3}{%
+    \@ifnextchar[%]
+    {\doc at env{#1}{#2}}{\doc at env{#1}{#2}[]}}%
+  \@namedef{end#3}{\endtrivlist}%
+}
+
+\def\@nameedef#1{\expandafter\edef\csname #1\endcsname}
+
+
+\def\doc at declareerror#1#2{%
+   \PackageError{doc}{Doc element '#1/#2' already defined?\@gobble}%
+      {There is already a definition for
+       '\string\Print#1Name',\MessageBreak
+       '\string\PrintDescribe#1'
+       or the environment '#2'.\MessageBreak
+       Maybe you are overwriting something by mistake!\MessageBreak
+       Otherwise use '\string\RenewDocElement' instead.}%
+}
+
+\def\doc at notdeclarederror#1#2{%
+   \PackageError{doc}{Doc element '#1/#2' unknown}%
+      {I expected an existing definition for
+       '\string\Print#1Name',\MessageBreak
+       '\string\PrintDescribe#1' and
+       the environment '#2' but\MessageBreak
+       not all of them are defined.\MessageBreak
+       Maybe you wanted to use
+       '\string\NewDocElement'?}%
+}
+\newcommand\NewDocElement[3][]{%
+  \@ifundefined{Print#2Name}%
+      {\@ifundefined{PrintDescribe#2}%
+           {\@ifundefined{#3}%
+               {\@ifundefined{end#3}%
+                    {\@NewDocElement{#1}}%
+                    \doc at declareerror
+               }\doc at declareerror
+           }\doc at declareerror
+      }\doc at declareerror
+  {#2}{#3}%
+}
+\newcommand\RenewDocElement[3][]{%
+  \@ifundefined{Print#2Name}\doc at notdeclarederror
+      {\@ifundefined{PrintDescribe#2}\doc at notdeclarederror
+           {\@ifundefined{#3}\doc at notdeclarederror
+               {\@ifundefined{end#3}\doc at notdeclarederror
+                    {\@NewDocElement{#1}}%
+               }%
+           }%
+      }%
+  {#2}{#3}%
+}
+\def\@NewDocElement#1#2#3{%
+  \doc at macrolikefalse
+  \doc at topleveltrue
+  \def\doc at idxtype{#3}%
+  \def\doc at idxgroup{#3s}%
+  \let\doc at printtype\@empty
+  \setkeys{doc}{#1}%
+  \ifx\doc at printtype\@empty
+    \@temptokena{}%
+  \else
+    \@temptokena\expandafter{\expandafter
+         \textnormal\expandafter{\expandafter
+         \space\expandafter
+         (\doc at printtype)}}%
+  \fi
+  \@nameedef{Print#2Name}##1{%
+     {\noexpand\MacroFont
+      \ifdoc at macrolike
+         \noexpand\string
+      \fi
+      ##1%
+      \the\@temptokena
+     }}%
+  \expandafter\let\csname PrintDescribe#2\expandafter\endcsname
+                  \csname Print#2Name\endcsname
+  \edef\doc at expr{%
+     \ifdoc at macrolike
+       \noexpand\doc at createspecialmacrolikeindexes
+     \else
+       \noexpand\doc at createspecialindexes
+     \fi
+     {#2}%
+    }%
+   \expandafter\expandafter\expandafter
+   \doc at expr
+   \expandafter\expandafter\expandafter
+     {\expandafter\doc at idxtype\expandafter}\expandafter
+     {\doc at idxgroup}%
+  \doc at createdescribe{#2}%
+    \ifdoc at macrolike
+      \doc at createenv{TT}{#2}{#3}%
+    \else
+      \doc at createenv{TF}{#2}{#3}%
+    \fi
+}
+
+
+\NewDocElement[macrolike = true ,
+                idxtype   = ,
+                idxgroup  = ,
+                printtype =
+               ]{Macro}{macro}
+
+\def\SpecialMainIndex{\SpecialMainMacroIndex}
+
+\def\SpecialUsageIndex{\SpecialMacroIndex}
+
+\def\SpecialIndex     {\CodeMacroIndex{code}}
+
+\NewDocElement[macrolike = false ,
+                idxtype   = env.  ,
+                idxgroup  = environments ,
+                printtype = \textit{env.}
+               ]{Env}{environment}
+
+
+\DeclareRobustCommand\cs[1]{\texttt{\bslash #1}}
+
+\endinput
+%%
+%% End of file `doc-v3beta.sty'.


Property changes on: trunk/Master/texmf-dist/tex/latex/base/doc-v3beta.sty
___________________________________________________________________
Added: svn:eol-style
## -0,0 +1 ##
+native
\ No newline at end of property
Modified: trunk/Master/texmf-dist/tex/latex/base/doc.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/doc.sty	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/doc.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -43,11 +43,11 @@
 %% extension .ins) which are part of the distribution.
 \NeedsTeXFormat{LaTeX2e}[1994/12/01]
  \ProvidesPackage{doc}
-  [2020/06/15 v2.1m
+  [2021/05/28 v2.1n
    Standard LaTeX documentation package (FMi)]
 %%
 %% Package `doc' to use with LaTeX 2e
-%% Copyright (C) 1989-1999 Frank Mittelbach, all rights reserved.
+%% Copyright (C) 1989-2020 Frank Mittelbach, all rights reserved.
 \@ifundefined{macro at cnt}{}{\endinput}
 \catcode`\^^A=14
 \AtBeginDocument{\catcode`\^^A=14\relax}
@@ -274,7 +274,7 @@
   \obeylines%
   \gdef\verb at eol@error{\obeylines%
     \def^^M{\verb at egroup\@latex at error{%
-           Text for \noexpand\verb command ended by end of line}\@ehc}}%
+            \noexpand\verb ended by end of line}\@ehc}}%
 \endgroup
 \def\verbatim at nolig@list{\do\`\do\<\do\>\do\,\do\'\do\-}
 \def\do at noligs#1{%

Modified: trunk/Master/texmf-dist/tex/latex/base/docstrip.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/docstrip.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/docstrip.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -45,8 +45,8 @@
 \catcode`\}=2
 \def\filename{docstrip.dtx}
 \def\fileversion{v2.6a}
-\def\filedate{2020-07-07}
-\def\docdate {2020-07-11}
+\def\filedate{2020-11-23}
+\def\docdate {2020-11-23}
 %%
 %% The docstrip program for use with TeX.
 %% Copyright (C) 1989-1991 Frank Mittelbach
@@ -54,7 +54,7 @@
 %%                         Frank Mittelbach
 %% Copyright (C) 1995 Marcin Woli\'nski
 %% Copyright (C) 1996-1997 Mark Wooding, Marcin Woli\'nski
-%% Copyright (C) 1998-2020 LaTeX3 project and the above authors
+%% Copyright (C) 1998-2021 LaTeX Project and the above authors.
 %% All rights are reserved.
 %%
 \catcode`\Z=\catcode`\%

Deleted: trunk/Master/texmf-dist/tex/latex/base/everyshi-ltx.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/everyshi-ltx.sty	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/everyshi-ltx.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,68 +0,0 @@
-%%
-%% This is file `everyshi-ltx.sty',
-%% generated with the docstrip utility.
-%%
-%% The original source files were:
-%%
-%% ltshipout.dtx  (with options: `everyshi-ltx')
-%% 
-%% 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-2020
-%% The LaTeX3 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.
-%%
-%% File: ltshipout.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team
-%%
-%%% From File: ltshipout.dtx
-\providecommand\ltshipoutversion{v1.0d}
-\providecommand\ltshipoutdate{2020/11/24}
-\ProvidesPackage{everyshi-ltx}
-   [2020/08/17 v1.0a
-    Emulation of the original everyshi package^^Jwith kernel methods]
-\protected \def \EveryShipout  {\AddToHook{shipout/before}}
-\protected \def \AtNextShipout {\AddToHookNext{shipout/before}}
-%%
-%%   In normal circumstances the above emulation is sufficient and in
-%%   all known packages (we know of) that use everyshi it either works or
-%%   the packages have been adjusted.
-%%
-%%   Code that directly manipulates box 255, however, might fail.
-%%   If that is the case look at the shipout hooks offered now as
-%%   they are normally sufficienct to avoid such minpulations (or
-%%   replace box 255 with \ShipoutBox in the code.
-%%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-\endinput
-%%
-%% End of file `everyshi-ltx.sty'.

Modified: trunk/Master/texmf-dist/tex/latex/base/exscale.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/exscale.sty	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/exscale.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/tex/latex/base/fix-cm.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/fix-cm.sty	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/fix-cm.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 \NeedsTeXFormat{LaTeX2e}
 \ProvidesPackage{fix-cm}
-          [2015/01/14 v1.1t fixes to LaTeX]
+          [2020/11/24 v1.1t fixes to LaTeX]
 %%
 
 \input{ts1enc.def}

Modified: trunk/Master/texmf-dist/tex/latex/base/fixltx2e.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/fixltx2e.sty	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/fixltx2e.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/tex/latex/base/flafter.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/flafter.sty	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/flafter.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/tex/latex/base/fleqn.clo
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/fleqn.clo	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/fleqn.clo	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/tex/latex/base/fleqn.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/fleqn.sty	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/fleqn.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/tex/latex/base/fltrace.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/fltrace.sty	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/fltrace.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -112,7 +112,7 @@
   \global \advance \@colht \@tempdima
   \ifx \@dbltoplist \@empty
   \else
-    \@latexerr{Float(s) lost}\@ehb
+    \@latex at error{Float(s) lost}\@ehb
     \let \@dbltoplist \@empty
   \fi
   \@cons \@dbltoplist \@currbox

Modified: trunk/Master/texmf-dist/tex/latex/base/fontenc.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/fontenc.sty	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/fontenc.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -43,7 +43,7 @@
 %% extension .ins) which are part of the distribution.
 %%% From File: ltoutenc.dtx
 \ProvidesPackage{fontenc}
- [2020/08/10 v2.0s
+ [2021/04/29 v2.0v
                         Standard LaTeX package]
 \def\update at uclc@with at cyrillic{%
  \expandafter\def\expandafter\@uclclist\expandafter

Modified: trunk/Master/texmf-dist/tex/latex/base/fontmath.cfg
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/fontmath.cfg	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/fontmath.cfg	2021-06-01 21:12:14 UTC (rev 59424)
@@ -8,8 +8,8 @@
 %% 
 %% This is a generated file.
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -37,8 +37,8 @@
 %% 
 %%% From File: fontdef.dtx
 \ProvidesFile{fontmath.cfg}
-           [2020/08/01 v3.0i LaTeX Kernel
-(Uncustomised math
+           [2021/01/15 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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/fontmath.ltx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -8,8 +8,8 @@
 %% 
 %% This is a generated file.
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -37,7 +37,7 @@
 %% 
 %%% From File: fontdef.dtx
 \ProvidesFile{fontmath.ltx}
-           [2020/08/01 v3.0i LaTeX Kernel
+           [2021/01/15 v3.0i LaTeX Kernel
 (Math
            font setup)]
 \typeout{=== Don't modify this file, use a .cfg file instead ===^^J}

Modified: trunk/Master/texmf-dist/tex/latex/base/fonttext.cfg
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/fonttext.cfg	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/fonttext.cfg	2021-06-01 21:12:14 UTC (rev 59424)
@@ -8,8 +8,8 @@
 %% 
 %% This is a generated file.
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -37,8 +37,8 @@
 %% 
 %%% From File: fontdef.dtx
 \ProvidesFile{fonttext.cfg}
-           [2020/08/01 v3.0i LaTeX Kernel
-(Uncustomised text
+           [2021/01/15 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	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/fonttext.ltx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -8,8 +8,8 @@
 %% 
 %% This is a generated file.
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -37,7 +37,7 @@
 %% 
 %%% From File: fontdef.dtx
 \ProvidesFile{fonttext.ltx}
-           [2020/08/01 v3.0i LaTeX Kernel
+           [2021/01/15 v3.0i LaTeX Kernel
 (Text
            font setup)]
 \typeout{=== Don't modify this file, use a .cfg file instead ===^^J}

Modified: trunk/Master/texmf-dist/tex/latex/base/graphpap.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/graphpap.sty	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/graphpap.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/tex/latex/base/hyphen.ltx
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/hyphen.ltx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/hyphen.ltx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -8,8 +8,8 @@
 %% 
 %% This is a generated file.
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.

Modified: trunk/Master/texmf-dist/tex/latex/base/idx.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/idx.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/idx.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

Modified: trunk/Master/texmf-dist/tex/latex/base/ifthen.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/ifthen.sty	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/ifthen.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -44,12 +44,12 @@
 %%
 %% File `ifthen.dtx'.
 %% Copyright (C) 1991 by Leslie Lamport
-%% Copyright (C) 1994-2001 LaTeX3 project, David Carlisle
+%% Copyright (C) 1994-2001 LaTeX project, David Carlisle
 %%                       all rights reserved.
 %%
 \NeedsTeXFormat{LaTeX2e}[1994/12/01]
 \ProvidesPackage{ifthen}
-          [2014/09/29 v1.1c Standard LaTeX ifthen package (DPC)]
+          [2020/11/24 v1.1c 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}

Modified: trunk/Master/texmf-dist/tex/latex/base/inputenc.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/inputenc.sty	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/inputenc.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -13,8 +13,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -45,7 +45,7 @@
 
 \NeedsTeXFormat{LaTeX2e}[1995/12/01]
 \ProvidesPackage{inputenc}
-   [2020/08/01 v1.3d Input encoding file]
+   [2021/02/14 v1.3d Input encoding file]
 \def\DeclareInputMath#1{%
    \@inpenc at test
    \bgroup

Modified: trunk/Master/texmf-dist/tex/latex/base/lablst.tex
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/lablst.tex	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/lablst.tex	2021-06-01 21:12:14 UTC (rev 59424)
@@ -1,7 +1,7 @@
 % \iffalse meta-comment
 %
-% Copyright (C) 1993-2020
-% The LaTeX3 Project and any individual authors listed elsewhere
+% Copyright (C) 1993-2021
+% The LaTeX Project and any individual authors listed elsewhere
 % in this file.
 %
 % This file is part of the LaTeX base system.

Modified: trunk/Master/texmf-dist/tex/latex/base/latex.ltx
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/latex.ltx	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/latex.ltx	2021-06-01 21:12:14 UTC (rev 59424)
@@ -10,11 +10,14 @@
 %% ltluatex.dtx  (with options: `2ekernel')
 %% ltexpl.dtx  (with options: `2ekernel')
 %% ltdefns.dtx  (with options: `2ekernel')
+%% ltcmd.dtx  (with options: `2ekernel')
 %% lthooks.dtx  (with options: `2ekernel')
+%% ltcmdhooks.dtx  (with options: `2ekernel')
 %% ltalloc.dtx  (with options: `2ekernel')
 %% ltcntrl.dtx  (with options: `2ekernel')
 %% lterror.dtx  (with options: `2ekernel')
 %% ltpar.dtx  (with options: `2ekernel')
+%% ltpara.dtx  (with options: `2ekernel')
 %% ltspace.dtx  (with options: `2ekernel')
 %% ltlogos.dtx  (with options: `2ekernel')
 %% ltfiles.dtx  (with options: `2ekernel')
@@ -55,8 +58,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -483,6 +486,8 @@
     \errmessage{No room for a new #3}%
   \fi}
 \def\newhelp#1#2{\newtoks#1#1\expandafter{\csname#2\endcsname}}
+\newread\@inputcheck
+\newwrite\@unused
 \newdimen\maxdimen \maxdimen=16383.99999pt % the largest legal <dimen>
 \newskip\hideskip \hideskip=-1000pt plus 1fill % negative but can grow
 \newdimen\p@ \p@=1pt % this saves macro space and time
@@ -508,6 +513,12 @@
 \finalhyphendemerits=5000
 \adjdemerits=10000
 \tracinglostchars=1
+\ifx\directlua\@undefined
+  % \tracingstacklevels=0 % added in 2021
+\else
+  \newcount\tracingstacklevels
+  % Code for \tracingstacklevels defined in ltfinal.dtx
+\fi
 \uchyph=1
 \defaulthyphenchar=`\-
 \defaultskewchar=-1
@@ -632,54 +643,25 @@
 \gdef\loggingoutput{\tracingoutput\@ne
     \showboxbreadth\maxdimen\showboxdepth\maxdimen\errorstopmode}
 \gdef\showoutput{\loggingoutput\showoverfull}
-\ifx\tracingscantokens\@undefined
-\gdef\loggingall{%
+\edef\loggingall{%
   \tracingstats\tw@
   \tracingpages\@ne
-  \tracinglostchars\@ne
+  \tracinglostchars\thr@@
   \tracingparagraphs\@ne
-  \errorcontextlines\maxdimen
-  \loggingoutput
-  \tracingmacros\tw@
-  \tracingcommands\tw@
-  \tracingrestores\@ne
-  }%
-\else
-\gdef\loggingall{%
-  \tracingstats\tw@
-  \tracingpages\@ne
-  \tracinglostchars\tw@
-  \tracingparagraphs\@ne
   \tracinggroups\@ne
   \tracingifs\@ne
   \tracingscantokens\@ne
   \tracingnesting\@ne
   \errorcontextlines\maxdimen
-  \loggingoutput
+  \ifdefined\tracingstacklevels \tracingstacklevels\maxdimen \fi
+  \noexpand \loggingoutput
   \tracingmacros\tw@
   \tracingcommands\thr@@
   \tracingrestores\@ne
   \tracingassigns\@ne
 }%
-\fi
-\gdef\tracingall{\showoverfull\loggingall}
-\ifx\tracingscantokens\@undefined
-\def\tracingnone{%
-  \tracingonline\z@
-  \tracingcommands\z@
-  \showboxdepth\m at ne
-  \showboxbreadth\m at ne
-  \tracingoutput\z@
-  \errorcontextlines\m at ne
-  \tracingrestores\z@
-  \tracingparagraphs\z@
-  \tracingmacros\z@
-  \tracinglostchars\@ne
-  \tracingpages\z@
-  \tracingstats\z@
-}%
-\else
-\def\tracingnone{%
+\def\tracingall{\showoverfull\loggingall}
+\edef\tracingnone{%
   \tracingassigns\z@
   \tracingrestores\z@
   \tracingonline\z@
@@ -688,6 +670,7 @@
   \showboxbreadth\m at ne
   \tracingoutput\z@
   \errorcontextlines\m at ne
+  \ifdefined\tracingstacklevels \tracingstacklevels\z@ \fi
   \tracingnesting\z@
   \tracingscantokens\z@
   \tracingifs\z@
@@ -698,7 +681,6 @@
   \tracingpages\z@
   \tracingstats\z@
 }%
-\fi
 \def\hideoutput{%
   \tracingoutput\z@
   \showboxbreadth\m at ne
@@ -709,9 +691,9 @@
 %%% From File: ltvers.dtx
 \def\fmtname{LaTeX2e}
 \edef\fmtversion
-   {2020-10-01}
-\def\patch at level{4}
-\edef\development at branch@name{}
+   {2021-06-01}
+\def\patch at level{0}
+\edef\development at branch@name{develop \the\year-\the\month-\the\day}
 \iffalse
 \def\reserved at a#1/#2/#3\@nil{%
   \count@\year
@@ -738,28 +720,30 @@
 \fi
   \ifnum0\ifnum\patch at level=0 \ifx\development at branch@name\@empty 1\fi\fi>0 %
     \everyjob\expandafter{\the\everyjob
-      \typeout{\fmtname \space<\fmtversion>}}
+      \typeout{\fmtname\space <\fmtversion>}}
     \immediate
     \write16{\fmtname \space<\fmtversion>}
   \else\ifnum\patch at level>0
     \everyjob\expandafter{\the\everyjob
-      \typeout{\fmtname \space<\fmtversion> patch level \patch at level}}
+      \typeout{\fmtname\space <\fmtversion> patch level \patch at level}}
     \immediate
-    \write16{\fmtname \space<\fmtversion> patch level \patch at level}
+    \write16{\fmtname\space <\fmtversion> patch level \patch at level}
   \else
     \everyjob\expandafter{\the\everyjob
-      \typeout{\fmtname \space<\fmtversion> pre-release-\number-\patch at level\space
-        \ifx\development at branch@name\@undefined  \else
-          \ifx\development at branch@name\@empty  \else
-            \space (\development at branch@name\space branch)%
+      \typeout{\fmtname\space <\fmtversion>
+               pre-release-\number-\patch at level\space
+               \ifx\development at branch@name\@undefined  \else
+                 \ifx\development at branch@name\@empty  \else
+                  \space (\development at branch@name\space branch)%
           \fi
         \fi
     }}
     \immediate
-    \write16{\fmtname \space<\fmtversion> pre-release-\number-\patch at level\space
-        \ifx\development at branch@name\@undefined  \else
-          \ifx\development at branch@name\@empty  \else
-            \space (\development at branch@name\space branch)%
+    \write16{\fmtname\space <\fmtversion>
+             pre-release-\number-\patch at level\space
+            \ifx\development at branch@name\@undefined  \else
+             \ifx\development at branch@name\@empty  \else
+               \space (\development at branch@name\space branch)%
           \fi
         \fi
     }
@@ -772,17 +756,37 @@
                 {There is an \string\EndIncludeRelease\space missing}%
   \@includeinreleasefalse
   \fi
-  \kernel at ifnextchar[%
-  {\@IncludeInRelease{#1}}
-  {\@IncludeInRelease{#1}[#1]}}
+  \ifnum0%
+      \ifx\new at moduledate\@empty\else 1\fi
+      \ifnum \expandafter\@parse at version#1//00\@nil=0 1\fi
+      =11
+    \expandafter\@firstoftwo
+  \else
+    \expandafter\@secondoftwo
+  \fi
+    {\finish at module@release{#1}}%
+    {\kernel at ifnextchar[%
+      {\@IncludeInRelease{#1}}
+      {\@IncludeInRelease{#1}[#1]}}}
+\def\finish at module@release#1#2#3{%
+  \toks@{[#1] #3}%
+  \ifnum\expandafter\@parse at version\new at moduledate//00\@nil
+       >\expandafter\@parse at version\fmtversion//00\@nil
+    \GenericInfo{}{Applying: \the\toks@}%
+  \else
+    \GenericInfo{}{Skipping: \the\toks@}%
+    \expandafter\gobble at finish@module at release
+  \fi}
+\long\def\gobble at finish@module at release#1\EndModuleRelease{%
+  \EndModuleRelease}
 \def\@IncludeInRelease#1[#2]{\@IncludeInRele at se{#2}}
 \def\@IncludeInRele at se#1#2#3{%
   \toks@{[#1] #3}%
   \expandafter\ifx\csname\string#2+\@currname+IIR\endcsname\relax
     \ifnum\expandafter\@parse at version#1//00\@nil
-          >\expandafter\@parse at version\fmtversion//00\@nil
+         >\expandafter\@parse at version\fmtversion//00\@nil
       \GenericInfo{}{Skipping: \the\toks@}%
-     \expandafter\expandafter\expandafter\@gobble at IncludeInRelease
+      \expandafter\expandafter\expandafter\@gobble at IncludeInRelease
     \else
       \GenericInfo{}{Applying: \the\toks@}%
       \@includeinreleasetrue
@@ -798,6 +802,9 @@
   \@includeinreleasefalse
 \else
   \PackageError{latexrelease}{mis-matched EndIncludeInRelease}{}%
+\fi
+\if at skipping@module
+  \expandafter\new at module@skip
 \fi}
 \long\def\@gobble at IncludeInRelease#1\EndIncludeInRelease{%
   \@includeinreleasefalse
@@ -807,7 +814,48 @@
                                    #2#3\@end at check@IncludeInRelease{%
   \ifx\@check at IncludeInRelease#2\else
     \PackageError{latexrelease}{skipped IncludeInRelease for tag \string#2}{}%
+  \fi
+  \if at skipping@module
+    \expandafter\new at module@skip
   \fi}
+\let\if at skipping@module\iffalse
+\def\@skipping at moduletrue{\let\if at skipping@module\iftrue}
+\def\@skipping at modulefalse{\let\if at skipping@module\iffalse}
+\let\new at modulename\@empty
+\let\new at moduledate\@empty
+\def\NewModuleRelease#1#2#3{%
+  \ifx\new at modulename\@empty \else
+    \@latex at error{Nested \noexpand\NewModuleRelease forbidden.}\@ehd \fi
+  \edef\new at moduledate{#1}%
+  \edef\new at modulename{#2}%
+  \GenericInfo{}{BEGIN module: \new at modulename\space (\new at moduledate)}%
+  \GenericInfo{}{ \@spaces\@spaces\@spaces\space#3\@gobble}%
+  \ifnum\sourceLaTeXdate<%
+      \expandafter\@parse at version\new at moduledate//00\@nil\relax
+    \ifnum\expandafter\@parse at version\fmtversion//00\@nil<%
+          \expandafter\@parse at version\new at moduledate//00\@nil\relax
+      \GenericInfo{}{Skipping module \new at modulename}%
+      \expandafter\expandafter
+      \expandafter\gobble at finish@module at release
+    \else
+      \GenericInfo{}{Applying module \new at modulename}
+      \@skipping at modulefalse
+    \fi
+  \else
+    \GenericInfo{}{Skipping module \new at modulename}
+    \@skipping at moduletrue
+    \expandafter\new at module@skip
+  \fi}
+\long\def\new at module@skip#1\IncludeInRelease{\IncludeInRelease}
+\def\EndModuleRelease{%
+  \ifx\new at modulename\@empty
+    \@latex at error{Extra \string\EndModuleRelease.}\@eha
+  \else
+    \GenericInfo{}{END module: \new at modulename\space (\new at moduledate)}%
+    \let\new at modulename\@empty
+    \let\new at moduledate\@empty
+    \@skipping at modulefalse
+  \fi}
 %%% From File: ltluatex.dtx
 \ifx\directlua\@undefined\else
 \ifnum\luatexversion<60 %
@@ -988,12 +1036,17 @@
   }
 \fi
 %%% From File: ltexpl.dtx
-\let\@kernel at after@enddocument\@empty
-\let\@kernel at after@enddocument at afterlastpage\@empty
-\def\@expl at sys@load at backend@@{}
-\def\@expl at push@filename@@{}
-\def\@expl at push@filename at aux@@{}
-\def\@expl at pop@filename@@{}
+\ifx\@kernel at after@enddocument\@undefined
+  \let \@kernel at after@enddocument               \@empty
+  \let \@kernel at after@enddocument at afterlastpage \@empty
+  \let \@kernel at before@begindocument \@empty
+  \let \@kernel at after@begindocument  \@empty
+\fi
+\def\reserved at a#1{\ifdefined#1\else\def#1{}\fi}
+\reserved at a\@expl at sys@load at backend@@
+\reserved at a\@expl at push@filename@@
+\reserved at a\@expl at push@filename at aux@@
+\reserved at a\@expl at pop@filename@@
 \def\@expl at finalise@setup@@{}
 \long\def\@gobble#1{}
 \long\def\@firstofone#1{#1}
@@ -1051,15 +1104,7 @@
         \errmessage{LaTeX requires expl3}%
         \batchmode \read -1 to \reserved at a
       }%
-      {%
-        \input expl3.ltx
-        \ifdefined\NewDocumentCommand
-        \else
-          \IfFileExists{xparse.ltx}
-            {\input xparse.ltx }
-            {}%
-         \fi
-      }%
+      {\input expl3.ltx }%
   }
 \ExplSyntaxOn
 \cs_gset_eq:NN \@expl at cs@to at str@@N \cs_to_str:N
@@ -1320,7 +1365,7 @@
   \count@=\escapechar
   \escapechar=`\\
   \@ifundefined{\expandafter\@gobble\string#1}{%
-    \@latex at error{The control sequence `\string#1' is undefined!%
+    \@latex at error{Command `\string#1' is undefined!%
       \MessageBreak There is nothing here to make robust}%
     \@eha
   }%
@@ -1340,7 +1385,7 @@
         \noexpand\protect\expandafter\noexpand
         \csname\expandafter\@gobble\string#1\space\endcsname}%
     }%
-    {\@latex at info{The control sequence `\string#1' is already robust}}%
+    {\@latex at info{Command `\string#1' is already robust}}%
   }%
   \escapechar=\count@
 }%
@@ -1626,12 +1671,2264 @@
     \toks@\expandafter{#1#2}%
     \xdef#1{\the\toks@}%
   \endgroup}
-%%
-%% File: lthooks.dtx (C) Copyright 2020 Frank Mittelbach,
-%%                                      Phelype Oleinik & LaTeX Team
+%%% From File: ltcmd.dtx
+\def\ltcmdversion{v1.0e}
+\def\ltcmddate{2021-05-24}
+\message{document commands,}
+\ExplSyntaxOn
+\tl_new:N \l__cmd_arg_spec_tl
+\tl_new:N \l__cmd_args_tl
+\tl_new:N \l__cmd_args_i_tl
+\tl_new:N \l__cmd_args_ii_tl
+\int_new:N \l__cmd_current_arg_int
+\bool_new:N \l__cmd_defaults_bool
+\tl_new:N \l__cmd_defaults_tl
+\bool_new:N \l__cmd_environment_bool
+\str_new:N \l__cmd_environment_str
+\bool_new:N \l__cmd_expandable_bool
+\tl_new:N \l__cmd_expandable_aux_name_tl
+\tl_set:Nn \l__cmd_expandable_aux_name_tl
+  {
+    \l__cmd_function_tl \c_space_tl
+    ( arg~ \int_use:N \l__cmd_current_arg_int )
+  }
+\int_new:N \g__cmd_grabber_int
+\tl_new:N \l__cmd_fn_tl
+\tl_new:N \l__cmd_fn_code_tl
+\tl_new:N \l__cmd_function_tl
+\bool_new:N \l__cmd_grab_expandably_bool
+\bool_new:N \l__cmd_obey_spaces_bool
+\tl_new:N \l__cmd_last_delimiters_tl
+\bool_new:N \l__cmd_long_bool
+\int_new:N \l__cmd_m_args_int
+\bool_new:N \l__cmd_prefixed_bool
+\tl_new:N \l__cmd_process_all_tl
+\tl_new:N \l__cmd_process_one_tl
+\bool_new:N \l__cmd_process_some_bool
+\tl_new:N \l__cmd_saved_args_tl
+\tl_new:N \l__cmd_signature_tl
+\bool_new:N \l__cmd_some_obey_spaces_bool
+\bool_new:N \l__cmd_some_long_bool
+\bool_new:N \l__cmd_some_short_bool
+\prop_new:N \l__cmd_tmp_prop
+\tl_new:N \l__cmd_tmpa_tl
+\tl_new:N \l__cmd_tmpb_tl
+\cs_new_eq:NN \__cmd_tmp:w ?
+\msg_redirect_module:nnn { cmd } { info } { none }
+\prop_gput:Nnn \g_msg_module_type_prop { cmd } { LaTeX }
+\cs_new_protected:Npn \__cmd_declare_cmd:Nnn
+  {
+    \bool_set_false:N \l__cmd_expandable_bool
+    \__cmd_declare_cmd_aux:Nnn
+  }
+\cs_new_protected:Npn \__cmd_declare_expandable_cmd:Nnn
+  {
+    \bool_set_true:N \l__cmd_expandable_bool
+    \__cmd_declare_cmd_aux:Nnn
+  }
+\cs_new_protected:Npn \__cmd_declare_cmd_aux:Nnn #1#2#3
+  {
+    \cs_if_exist:NTF #1
+      {
+        \msg_info:nnxx { cmd } { redefine-command }
+          { \token_to_str:N #1 } { \tl_to_str:n {#2} }
+      }
+      {
+        \bool_lazy_or:nnT
+          { \cs_if_exist_p:c { \cs_to_str:N #1 ~ code } }
+          { \cs_if_exist_p:c { \cs_to_str:N #1 ~ defaults } }
+          {
+            \msg_warning:nnx { cmd } { unsupported-let }
+              { \token_to_str:N #1 }
+          }
+        \msg_info:nnxx { cmd } { define-command }
+          { \token_to_str:N #1 } { \tl_to_str:n {#2} }
+      }
+    \bool_set_false:N \l__cmd_environment_bool
+    \__cmd_declare_cmd_internal:Nnnn #1 {#2} {#3} { }
+  }
+\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}
+    #4
+    \__cmd_break_point:n {#2}
+  }
+\cs_generate_variant:Nn \__cmd_declare_cmd_internal:Nnnn { cnx }
+\cs_new_eq:NN \__cmd_break_point:n \use_none:n
+\cs_new_protected:Npn \__cmd_declare_cmd_code:Nnn
+  {
+    \bool_if:NTF \l__cmd_grab_expandably_bool
+      { \__cmd_declare_cmd_code_expandable:Nnn }
+      { \__cmd_declare_cmd_code_aux:Nnn }
+   }
+\cs_new_protected:Npn \__cmd_declare_cmd_code_aux:Nnn #1#2#3
+  {
+    \cs_generate_from_arg_count:cNnn
+      { \l__cmd_function_tl \c_space_tl code }
+      \cs_set_protected:Npn \l__cmd_current_arg_int {#3}
+    \cs_set_protected_nopar:Npx #1
+      {
+        \bool_if:NTF \l__cmd_environment_bool
+          {
+            \__cmd_start_env:nnnnn { \exp_not:n {#2} }
+              { \l__cmd_environment_str }
+          }
+          {
+            \__cmd_start:nNNnnn { \exp_not:n {#2} }
+              \exp_not:c { \l__cmd_function_tl \c_space_tl }
+              \exp_not:c { \l__cmd_function_tl \c_space_tl code }
+          }
+          { \exp_not:o \l__cmd_signature_tl }
+          {
+            \bool_if:NT \l__cmd_defaults_bool
+              { \exp_not:o \l__cmd_defaults_tl }
+          }
+          {
+            \bool_if:NT \l__cmd_process_some_bool
+              { \exp_not:o \l__cmd_process_all_tl }
+          }
+      }
+  }
+\cs_new_protected:Npn \__cmd_declare_cmd_code_expandable:Nnn #1#2#3
+  {
+    \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 } :Npn }
+      \l__cmd_current_arg_int {#3}
+    \bool_if:NT \l__cmd_defaults_bool
+      {
+        \use:x
+          {
+            \cs_generate_from_arg_count:cNnn
+              { \l__cmd_function_tl \c_space_tl defaults }
+              \cs_set:Npn \l__cmd_current_arg_int
+              { \exp_not:o \l__cmd_defaults_tl }
+          }
+      }
+    \bool_if:NTF \l__cmd_expandable_bool
+      { \cs_set_nopar:Npx } { \cs_set_protected_nopar:Npx } #1
+      {
+        \exp_not:N \__cmd_start_expandable:nNNNNn
+          { \exp_not:n {#2} }
+          \exp_not:c { \l__cmd_function_tl \c_space_tl }
+          \exp_not:c
+            {
+              \l__cmd_function_tl \c_space_tl
+              \bool_if:NT \l__cmd_some_short_bool
+                { \bool_if:NT \l__cmd_some_long_bool { \c_space_tl } }
+            }
+          \exp_not:c { \l__cmd_function_tl \c_space_tl code }
+          \bool_if:NTF \l__cmd_defaults_bool
+            { \exp_not:c { \l__cmd_function_tl \c_space_tl defaults } }
+            { ? }
+          { \exp_not:o \l__cmd_signature_tl }
+      }
+    \bool_if:NTF \l__cmd_some_long_bool
+      {
+        \bool_if:NT \l__cmd_some_short_bool
+          {
+            \cs_set_nopar:cpx { \l__cmd_function_tl \c_space_tl \c_space_tl }
+              ##1##2 { ##1 {##2} }
+          }
+        \cs_set:cpx
+      }
+      { \cs_set_nopar:cpx }
+          { \l__cmd_function_tl \c_space_tl } ##1##2 { ##1 {##2} }
+  }
+\cs_new_protected:Npn \__cmd_declare_env:nnnn #1#2
+  {
+    \str_set:Nx \l__cmd_environment_str {#1}
+    \str_set:Nx \l__cmd_environment_str
+      { \tl_trim_spaces:o { \l__cmd_environment_str } }
+    \cs_if_exist:cTF { \l__cmd_environment_str }
+      {
+        \msg_info:nnxx { cmd } { redefine-environment }
+          { \l__cmd_environment_str } { \tl_to_str:n {#2} }
+      }
+      {
+        \msg_info:nnxx { cmd } { define-environment }
+          { \l__cmd_environment_str } { \tl_to_str:n {#2} }
+      }
+    \bool_set_false:N \l__cmd_expandable_bool
+    \bool_set_true:N \l__cmd_environment_bool
+    \exp_args:NV \__cmd_declare_env_internal:nnnn
+      \l__cmd_environment_str {#2}
+  }
+\cs_new_protected:Npn \__cmd_declare_env_internal:nnnn #1#2#3#4
+  {
+    \__cmd_declare_cmd_internal:cnxn { environment~ #1 } {#2}
+      {
+        \cs_set_nopar:Npx \exp_not:c { environment~ #1 ~end~aux }
+          {
+            \exp_not:N \exp_not:N \exp_not:c { environment~ #1~end~aux~ }
+            \exp_not:n { \exp_not:o \l__cmd_args_tl }
+          }
+        \exp_not:n {#3}
+      }
+      {
+        \cs_set_nopar:cpx { environment~ #1 ~end }
+          { \exp_not:c { environment~ #1 ~end~aux } }
+        \cs_generate_from_arg_count:cNnn
+          { environment~ #1 ~end~aux~ } \cs_set:Npn
+          \l__cmd_current_arg_int {#4}
+        \cs_set_eq:cc {#1}       { environment~ #1 }
+        \cs_set_eq:cc { end #1 } { environment~ #1 ~end }
+      }
+  }
+\cs_new_protected:Npn \__cmd_start_env:nnnnn #1#2
+  {
+    \conditionally at traceoff
+    \group_align_safe_begin:
+    \str_set:Nn \l__cmd_environment_str {#2}
+    \bool_set_true:N \l__cmd_environment_bool
+    \__cmd_start_aux:ccnnnn
+      { environment~ \l__cmd_environment_str \c_space_tl }
+      { environment~ \l__cmd_environment_str \c_space_tl code }
+      {#1}
+  }
+\cs_new_protected:Npx \__cmd_start:nNNnnn #1#2#3
+  {
+    \exp_not:c { xparse~function~is~not~expandable }
+    \exp_not:N \conditionally at traceoff
+    \exp_not:N \group_align_safe_begin:
+    \exp_not:n { \bool_set_false:N \l__cmd_environment_bool }
+    \exp_not:N \__cmd_start_aux:NNnnnn
+    #2 #3 {#1}
+  }
+\cs_new_protected:Npn \__cmd_start_aux:NNnnnn #1#2#3#4#5#6
+  {
+    \tl_clear:N \l__cmd_args_tl
+    \tl_set:Nn \l__cmd_fn_tl {#1}
+    \tl_set:Nn \l__cmd_fn_code_tl {#2}
+    \tl_set:Nn \l__cmd_defaults_tl {#5}
+    \tl_set:Nn \l__cmd_process_all_tl {#6}
+    #4 \__cmd_run_code:
+  }
+\cs_generate_variant:Nn \__cmd_start_aux:NNnnnn { cc }
+\cs_new_protected:Npn \__cmd_run_code:
+  {
+    \tl_if_empty:NF \l__cmd_defaults_tl { \__cmd_defaults: }
+    \tl_if_empty:NF \l__cmd_process_all_tl { \__cmd_args_process: }
+    \group_align_safe_end:
+    \conditionally at traceon
+    \exp_after:wN \l__cmd_fn_code_tl \l__cmd_args_tl
+  }
+\cs_new_protected:Npn \__cmd_defaults:
+  {
+    \__cmd_defaults_def:
+    \tl_set_eq:NN \l__cmd_args_i_tl \l__cmd_args_tl
+    \__cmd_defaults_aux: \__cmd_defaults_aux: \__cmd_defaults_aux:
+    \__cmd_defaults_aux: \__cmd_defaults_aux: \__cmd_defaults_aux:
+    \__cmd_defaults_aux: \__cmd_defaults_aux: \__cmd_defaults_aux:
+    \__cmd_defaults_error:w
+    \q_recursion_stop
+    \tl_set_eq:NN \l__cmd_args_tl \l__cmd_args_i_tl
+  }
+\cs_new_protected:Npn \__cmd_defaults_aux:
+  {
+    \tl_set:Nx \l__cmd_args_ii_tl
+      { \exp_after:wN \__cmd_tmp:w \l__cmd_args_i_tl }
+    \tl_if_eq:NNT \l__cmd_args_ii_tl \l__cmd_args_i_tl
+      { \use_none_delimit_by_q_recursion_stop:w }
+    \tl_set_eq:NN \l__cmd_args_i_tl \l__cmd_args_ii_tl
+  }
+\cs_new_protected:Npn \__cmd_defaults_error:w \q_recursion_stop
+  {
+    \msg_error:nnx { cmd } { loop-in-defaults }
+      { \__cmd_environment_or_command: }
+  }
+\cs_new_protected:Npn \__cmd_defaults_def:
+  {
+    \tl_clear:N \l__cmd_tmpa_tl
+    \int_zero:N \l__cmd_current_arg_int
+    \__cmd_tl_mapthread_function:NNN \l__cmd_args_tl \l__cmd_defaults_tl
+      \__cmd_defaults_def:nn
+    \cs_generate_from_arg_count:NNVo \__cmd_tmp:w \cs_set:Npn
+      \l__cmd_current_arg_int \l__cmd_tmpa_tl
+  }
+\cs_generate_variant:Nn \cs_generate_from_arg_count:NNnn { NNVo }
+\cs_new_protected:Npn \__cmd_defaults_def:nn
+  {
+    \int_incr:N \l__cmd_current_arg_int
+    \exp_args:NV \__cmd_defaults_def:nnn \l__cmd_current_arg_int
+  }
+\cs_new_protected:Npn \__cmd_defaults_def:nnn #1#2#3
+  {
+    \tl_put_right:Nx \l__cmd_tmpa_tl
+      {
+        {
+          \exp_not:N \exp_not:n
+            {
+              \tl_if_novalue:nTF {#2}
+                { \exp_not:o {#3} }
+                { \exp_not:n { ## #1 } }
+            }
+        }
+      }
+  }
+\cs_new_protected:Npn \__cmd_args_process:
+  {
+    \tl_clear:N \l__cmd_args_ii_tl
+    \__cmd_tl_mapthread_function:NNN
+      \l__cmd_args_tl
+      \l__cmd_process_all_tl
+      \__cmd_args_process_loop:nn
+    \tl_set_eq:NN \l__cmd_args_tl \l__cmd_args_ii_tl
+  }
+\cs_new_protected:Npn \__cmd_args_process_loop:nn #1#2
+  {
+    \tl_set:Nn \ProcessedArgument {#1}
+    \tl_if_novalue:nF {#1}
+      { \tl_map_function:nN {#2} \__cmd_args_process_aux:n }
+    \tl_put_right:No \l__cmd_args_ii_tl
+      { \exp_after:wN { \ProcessedArgument } }
+  }
+\cs_new_protected:Npn \__cmd_args_process_aux:n #1
+  {
+    \cs_generate_from_arg_count:NNnn \__cmd_tmp:w \cs_set:Npn
+      { \tl_count:N \l__cmd_args_tl } {#1}
+    \exp_args:NNNo \exp_after:wN \__cmd_tmp:w \l__cmd_args_tl
+      { \ProcessedArgument }
+  }
+\cs_new:Npn \__cmd_start_expandable:nNNNNn #1#2#3#4#5#6
+  {
+    \group_align_safe_begin:
+    #6 \__cmd_end_expandable:NNw #5 #4 \q__cmd #2#3
+  }
+\cs_new:Npn \__cmd_end_expandable:NNw #1#2
+  { \__cmd_end_expandable_aux:w #1#2 \prg_do_nothing: }
+\cs_new:Npn \__cmd_end_expandable_aux:w #1#2#3 \q__cmd
+  { \exp_args:No \__cmd_end_expandable_aux:nNNNN {#3} #1 #2 }
+\cs_new:Npn \__cmd_end_expandable_aux:nNNNN #1#2#3#4#5
+  {
+    \token_if_eq_charcode:NNT ? #2 { \exp_after:wN \use_iv:nnnn }
+    \__cmd_end_expandable_defaults:nnnNNn {#1} { } {#1} #2#3
+      { } { } { } { } { } { } { } { } { } { }
+      {
+        \msg_expandable_error:nnf { cmd } { loop-in-defaults }
+          { \exp_args:Nf \tl_trim_spaces:n { \token_to_str:N #4 } }
+        \use_iv:nnnn
+      }
+    \q_stop
+  }
+\cs_new:Npn \__cmd_end_expandable_defaults:nnnNNn #1#2#3#4#5#6
+  {
+    #6
+    \str_if_eq:nnTF {#1} {#2}
+      { \use_i_delimit_by_q_stop:nw { \group_align_safe_end: #5 #1 } }
+      {
+        \exp_args:No \__cmd_tl_mapthread_function:nnN
+          { #4 #1 } {#3}
+          \__cmd_end_expandable_defaults:nnw
+        \__cmd_end_expandable_defaults:nnnNNn { } {#1} {#3} #4 #5
+      }
+  }
+\cs_new:Npn \__cmd_end_expandable_defaults:nnw #1#2
+  {
+    \tl_if_novalue:nTF {#2}
+      { \exp_args:No \__cmd_end_expandable_defaults:nw {#1} }
+      { \__cmd_end_expandable_defaults:nw {#2} }
+  }
+\cs_new:Npn \__cmd_end_expandable_defaults:nw
+    #1#2 \__cmd_end_expandable_defaults:nnnNNn #3
+  { #2 \__cmd_end_expandable_defaults:nnnNNn { #3 {#1} } }
+\cs_new_protected:Npn \__cmd_normalize_arg_spec:n #1
+  {
+    \int_zero:N \l__cmd_current_arg_int
+    \tl_clear:N \l__cmd_last_delimiters_tl
+    \tl_clear:N \l__cmd_arg_spec_tl
+    \bool_set_true:N \l__cmd_grab_expandably_bool
+    \bool_set_false:N \l__cmd_obey_spaces_bool
+    \bool_set_false:N \l__cmd_long_bool
+    \bool_set_false:N \l__cmd_some_obey_spaces_bool
+    \bool_set_false:N \l__cmd_some_long_bool
+    \bool_set_false:N \l__cmd_some_short_bool
+    \__cmd_normalize_arg_spec_loop:n #1
+      \q_recursion_tail \q_recursion_tail \q_recursion_tail \q_recursion_stop
+    \int_compare:nNnT \l__cmd_current_arg_int > 9
+      {
+        \msg_error:nnxx { cmd } { too-many-arguments }
+          { \__cmd_environment_or_command: } { \tl_to_str:n {#1} }
+        \__cmd_bad_def:wn
+      }
+    \bool_if:NT \l__cmd_expandable_bool
+      {
+        \tl_if_empty:NF \l__cmd_last_delimiters_tl
+          {
+            \msg_error:nnxx { cmd } { expandable-ending-optional }
+              { \iow_char:N \\ \l__cmd_function_tl } { \tl_to_str:n {#1} }
+            \__cmd_bad_def:wn
+          }
+      }
+    \bool_if:NT \l__cmd_expandable_bool
+      { \bool_set_true:N \l__cmd_grab_expandably_bool }
+    \bool_if:NT \l__cmd_environment_bool
+      { \bool_set_false:N \l__cmd_grab_expandably_bool }
+  }
+\cs_new_protected:Npn \__cmd_normalize_arg_spec_loop:n #1
+  {
+    \quark_if_recursion_tail_stop:n {#1}
+    \int_incr:N \l__cmd_current_arg_int
+    \cs_if_exist_use:cF { __cmd_normalize_type_ \tl_to_str:n {#1} :w }
+      {
+        \bool_lazy_any:nTF
+          {
+            { \str_if_eq_p:nn {#1} { G } }
+            { \str_if_eq_p:nn {#1} { g } }
+            { \str_if_eq_p:nn {#1} { l } }
+            { \str_if_eq_p:nn {#1} { u } }
+          }
+          {
+            \msg_error:nnxx { cmd } { xparse-argument-type }
+              { \__cmd_environment_or_command: } { \tl_to_str:n {#1} }
+          }
+          {
+            \msg_error:nnxx { cmd } { unknown-argument-type }
+              { \__cmd_environment_or_command: } { \tl_to_str:n {#1} }
+          }
+        \__cmd_bad_def:wn
+      }
+  }
+\cs_set_protected:Npn \__cmd_tmp:w #1
+  {
+    \cs_new_protected:Npn \__cmd_normalize_type_d:w ##1##2
+      {
+        \quark_if_recursion_tail_stop_do:nn {##2} { \__cmd_bad_arg_spec:wn }
+        \__cmd_normalize_type_D:w {##1} {##2} {#1}
+      }
+    \cs_new_protected:Npn \__cmd_normalize_type_e:w ##1
+      {
+        \quark_if_recursion_tail_stop_do:nn {##1} { \__cmd_bad_arg_spec:wn }
+        \__cmd_normalize_type_E:w {##1} { }
+      }
+    \cs_new_protected:Npn \__cmd_normalize_type_o:w
+      { \__cmd_normalize_type_D:w [ ] {#1} }
+    \cs_new_protected:Npn \__cmd_normalize_type_O:w
+      { \__cmd_normalize_type_D:w [ ] }
+    \cs_new_protected:Npn \__cmd_normalize_type_r:w ##1##2
+      {
+        \quark_if_recursion_tail_stop_do:nn {##2} { \__cmd_bad_arg_spec:wn }
+        \__cmd_normalize_type_R:w {##1} {##2} {#1}
+      }
+    \cs_new_protected:Npn \__cmd_normalize_type_s:w
+      { \__cmd_normalize_type_t:w * }
+  }
+\exp_args:No \__cmd_tmp:w { \c_novalue_tl }
+\cs_new_protected:cpn { __cmd_normalize_type_>:w } #1#2
+  {
+    \quark_if_recursion_tail_stop_do:nn {#2} { \__cmd_bad_arg_spec:wn }
+    \bool_if:NT \l__cmd_expandable_bool
+      {
+        \msg_error:nnxx { cmd } { processor-in-expandable }
+          { \iow_char:N \\ \l__cmd_function_tl } { \tl_to_str:n {#1} }
+        \__cmd_bad_def:wn
+      }
+    \tl_put_right:Nx \l__cmd_arg_spec_tl { > { \tl_trim_spaces:n {#1} } }
+    \int_decr:N \l__cmd_current_arg_int
+    \bool_set_false:N \l__cmd_grab_expandably_bool
+    \__cmd_normalize_arg_spec_loop:n {#2}
+  }
+\cs_new_protected:cpn { __cmd_normalize_type_+:w } #1
+  {
+    \quark_if_recursion_tail_stop_do:nn {#1} { \__cmd_bad_arg_spec:wn }
+    \bool_if:NT \l__cmd_long_bool
+      {
+        \msg_error:nnxx { cmd } { two-markers }
+          { \__cmd_environment_or_command: } { + }
+        \__cmd_bad_def:wn
+      }
+    \bool_set_true:N \l__cmd_long_bool
+    \int_decr:N \l__cmd_current_arg_int
+    \__cmd_normalize_arg_spec_loop:n {#1}
+  }
+\cs_new_protected:cpn { __cmd_normalize_type_!:w } #1
+  {
+    \quark_if_recursion_tail_stop_do:nn {#1} { \__cmd_bad_arg_spec:wn }
+    \bool_if:NT \l__cmd_obey_spaces_bool
+      {
+        \msg_error:nnxx { cmd } { two-markers }
+          { \__cmd_environment_or_command: } { ! }
+        \__cmd_bad_def:wn
+      }
+    \bool_set_true:N \l__cmd_obey_spaces_bool
+    \bool_set_true:N \l__cmd_some_obey_spaces_bool
+    \int_decr:N \l__cmd_current_arg_int
+    \__cmd_normalize_arg_spec_loop:n {#1}
+  }
+\cs_new_protected:Npn \__cmd_normalize_type_D:w #1#2#3
+  {
+    \quark_if_recursion_tail_stop_do:nn {#3} { \__cmd_bad_arg_spec:wn }
+    \__cmd_single_token_check:n {#1} \__cmd_allowed_token_check:N #1
+    \__cmd_single_token_check:n {#2}
+    \__cmd_add_arg_spec:n { D #1 #2 {#3} }
+    \tl_put_right:Nn \l__cmd_last_delimiters_tl {#1}
+    \bool_set_false:N \l__cmd_grab_expandably_bool
+    \__cmd_normalize_arg_spec_loop:n
+  }
+\cs_new_protected:Npn \__cmd_normalize_type_E:w #1#2
+  {
+    \quark_if_recursion_tail_stop_do:nn {#2} { \__cmd_bad_arg_spec:wn }
+    \tl_if_blank:nT {#1} { \__cmd_bad_arg_spec:wn }
+    \tl_map_function:nN {#1} \__cmd_single_token_check:n
+    \tl_map_function:nN {#1} \__cmd_allowed_token_check:N
+    \__cmd_normalize_E_unique_check:w #1 \q_nil \q_stop
+    \int_compare:nNnT { \tl_count:n {#2} } > { \tl_count:n {#1} }
+      { \__cmd_bad_arg_spec:wn }
+    \__cmd_add_arg_spec:n { E {#1} {#2} }
+    \tl_put_right:Nn \l__cmd_last_delimiters_tl {#1}
+    \bool_set_false:N \l__cmd_grab_expandably_bool
+    \int_add:Nn \l__cmd_current_arg_int { \tl_count:n {#1} - 1 }
+    \__cmd_normalize_arg_spec_loop:n
+  }
+\cs_new_protected:Npn \__cmd_normalize_E_unique_check:w #1#2 \q_stop
+  {
+    \quark_if_nil:NF #1
+      {
+        \tl_if_in:nnT {#2} {#1} { \__cmd_bad_arg_spec:wn }
+        \__cmd_normalize_E_unique_check:w #2 \q_stop
+      }
+  }
+\cs_new_protected:Npn \__cmd_normalize_type_t:w #1
+  {
+    \quark_if_recursion_tail_stop_do:Nn #1 { \__cmd_bad_arg_spec:wn }
+    \__cmd_single_token_check:n {#1} \__cmd_allowed_token_check:N #1
+    \tl_put_right:Nx \l__cmd_arg_spec_tl
+      {
+        \bool_if:NT \l__cmd_obey_spaces_bool { ! }
+        t \exp_not:n {#1}
+      }
+    \tl_put_right:Nn \l__cmd_last_delimiters_tl {#1}
+    \bool_set_false:N \l__cmd_grab_expandably_bool
+    \bool_set_false:N \l__cmd_obey_spaces_bool
+    \bool_set_false:N \l__cmd_long_bool
+    \__cmd_normalize_arg_spec_loop:n
+  }
+\cs_new_protected:Npn \__cmd_normalize_type_m:w
+  {
+    \__cmd_delimiter_check:nnn { } { m } { \iow_char:N \{ }
+    \__cmd_add_arg_spec_mandatory:n { m }
+    \__cmd_normalize_arg_spec_loop:n
+  }
+\cs_new_protected:Npn \__cmd_normalize_type_R:w #1#2#3
+  {
+    \quark_if_recursion_tail_stop_do:nn {#3} { \__cmd_bad_arg_spec:wn }
+    \__cmd_single_token_check:n {#1} \__cmd_allowed_token_check:N #1
+    \__cmd_single_token_check:n {#2}
+    \__cmd_delimiter_check:nnn {#1} { R/r } { \tl_to_str:n {#1} }
+    \bool_set_false:N \l__cmd_grab_expandably_bool
+    \__cmd_add_arg_spec_mandatory:n { R #1 #2 {#3} }
+    \__cmd_normalize_arg_spec_loop:n
+  }
+\cs_new_protected:Npn \__cmd_normalize_type_v:w
+  {
+    \__cmd_normalize_check_gv:N v
+    \__cmd_add_arg_spec_mandatory:n { v }
+    \__cmd_normalize_arg_spec_loop:n
+  }
+\cs_new_protected:Npn \__cmd_normalize_type_b:w #1
+  {
+    \bool_if:NF \l__cmd_environment_bool
+      {
+        \msg_error:nnxx { cmd } { invalid-command-arg }
+          { \__cmd_environment_or_command: } { b }
+        \__cmd_bad_def:wn
+      }
+    \tl_clear:N \l__cmd_last_delimiters_tl
+    \__cmd_add_arg_spec:n { b }
+    \quark_if_recursion_tail_stop:n {#1}
+    \msg_error:nnxx { cmd } { arg-after-body }
+      { \__cmd_environment_or_command: }
+      { \tl_to_str:n {#1} }
+    \__cmd_bad_def:wn
+  }
+\cs_new_protected:Npn \__cmd_single_token_check:n #1
+  {
+    \tl_trim_spaces_apply:nN {#1} \tl_if_single_token:nF
+      {
+        \msg_error:nnxx { cmd } { not-single-token }
+          { \__cmd_environment_or_command: } { \tl_to_str:n {#1} }
+        \__cmd_bad_def:wn
+      }
+  }
+\cs_new_protected:Npn \__cmd_allowed_token_check:N #1
+  {
+    \token_if_eq_meaning:NNTF #1 \c_group_begin_token
+        { \use:n }
+        {
+          \token_if_eq_meaning:NNTF #1 \c_group_end_token
+            { \use:n }
+            { \use_none:n }
+        }
+      {
+        \msg_error:nnxxx { cmd } { forbidden-implicit-group-token }
+          { \__cmd_environment_or_command: } { \tl_to_str:n {#1} }
+          {
+            \token_if_eq_meaning:NNTF #1 \c_group_begin_token
+              { begin } { end }
+          }
+        \__cmd_bad_def:wn
+      }
+  }
+\cs_new_protected:Npn \__cmd_normalize_check_gv:N #1
+  {
+    \bool_if:NT \l__cmd_expandable_bool
+      {
+        \msg_error:nnxx { cmd } { invalid-expandable-argument-type }
+          { \iow_char:N \\ \l__cmd_function_tl } { \tl_to_str:n {#1} }
+        \__cmd_bad_def:wn
+      }
+    \bool_set_false:N \l__cmd_grab_expandably_bool
+  }
+\cs_new_protected:Npn \__cmd_normalize_check_lu:N #1
+  {
+    \bool_if:NT \l__cmd_expandable_bool
+      {
+        \tl_if_empty:NF \l__cmd_last_delimiters_tl
+          {
+            \msg_error:nnxx { cmd } { invalid-after-optional-expandably }
+              { \iow_char:N \\ \l__cmd_function_tl } { \tl_to_str:n {#1} }
+            \__cmd_bad_def:wn
+          }
+      }
+  }
+\cs_new_protected:Npn \__cmd_delimiter_check:nnn #1#2#3
+  {
+    \tl_map_inline:Nn \l__cmd_last_delimiters_tl
+      {
+        \tl_if_eq:nnT {##1} {#1}
+          {
+            \msg_warning:nnxx { cmd } { optional-mandatory }
+              {#2} {#3}
+          }
+      }
+  }
+\cs_new_protected:Npn \__cmd_bad_arg_spec:wn #1 \__cmd_break_point:n #2
+  {
+    \msg_error:nnxx { cmd } { bad-arg-spec }
+      { \__cmd_environment_or_command: } { \tl_to_str:n {#2} }
+  }
+\cs_new_protected:Npn \__cmd_bad_def:wn #1 \__cmd_break_point:n #2 { }
+\cs_new_protected:Npn \__cmd_add_arg_spec:n #1
+  {
+    \bool_lazy_and:nnT
+      { ! \l__cmd_long_bool }
+      { \l__cmd_some_long_bool }
+      {
+        \bool_if:NT \l__cmd_expandable_bool
+          {
+            \msg_error:nnx { cmd } { inconsistent-long }
+              { \iow_char:N \\ \l__cmd_function_tl }
+            \__cmd_bad_def:wn
+          }
+        \bool_set_false:N \l__cmd_grab_expandably_bool
+      }
+    \bool_if:NTF \l__cmd_long_bool
+      { \bool_set_true:N \l__cmd_some_long_bool }
+      { \bool_set_true:N \l__cmd_some_short_bool }
+    \tl_put_right:Nx \l__cmd_arg_spec_tl
+      {
+        \bool_if:NT \l__cmd_long_bool { + }
+        \bool_if:NT \l__cmd_obey_spaces_bool { ! }
+        \exp_not:n {#1}
+      }
+    \bool_set_false:N \l__cmd_long_bool
+    \bool_set_false:N \l__cmd_obey_spaces_bool
+  }
+\cs_new_protected:Npn \__cmd_add_arg_spec_mandatory:n #1
+  {
+    \bool_if:NT \l__cmd_some_obey_spaces_bool
+      {
+        \msg_error:nnxx { cmd } { non-trailing-obey-spaces }
+          { \__cmd_environment_or_command: } { \tl_to_str:n {#1} }
+        \__cmd_bad_def:wn
+      }
+    \tl_clear:N \l__cmd_last_delimiters_tl
+    \__cmd_add_arg_spec:n {#1}
+  }
+\cs_new_protected:Npn \__cmd_prepare_signature:n #1
+  {
+    \int_zero:N \l__cmd_current_arg_int
+    \bool_set_false:N \l__cmd_long_bool
+    \bool_set_false:N \l__cmd_obey_spaces_bool
+    \int_zero:N \l__cmd_m_args_int
+    \bool_set_false:N \l__cmd_defaults_bool
+    \tl_clear:N \l__cmd_defaults_tl
+    \tl_clear:N \l__cmd_process_all_tl
+    \tl_clear:N \l__cmd_process_one_tl
+    \bool_set_false:N \l__cmd_process_some_bool
+    \tl_clear:N \l__cmd_signature_tl
+    \__cmd_prepare_signature:N #1 \q_recursion_tail \q_recursion_stop
+    \bool_if:NF \l__cmd_expandable_bool { \__cmd_flush_m_args: }
+  }
+\cs_new_protected:Npn \__cmd_prepare_signature:N
+  {
+    \bool_set_false:N \l__cmd_prefixed_bool
+    \__cmd_prepare_signature_bypass:N
+  }
+\cs_new_protected:Npn \__cmd_prepare_signature_bypass:N #1
+  {
+    \quark_if_recursion_tail_stop:N #1
+    \use:c
+      {
+         __cmd_add
+         \bool_if:NT \l__cmd_grab_expandably_bool { _expandable }
+         _type_  \token_to_str:N #1 :w
+      }
+  }
+\cs_new_protected:cpn { __cmd_add_type_+:w }
+  {
+    \__cmd_flush_m_args:
+    \bool_set_true:N \l__cmd_long_bool
+    \bool_set_true:N \l__cmd_prefixed_bool
+    \__cmd_prepare_signature_bypass:N
+  }
+\cs_new_protected:cpn { __cmd_add_type_!:w }
+  {
+    \__cmd_flush_m_args:
+    \bool_set_true:N \l__cmd_obey_spaces_bool
+    \bool_set_true:N \l__cmd_prefixed_bool
+    \__cmd_prepare_signature_bypass:N
+  }
+\cs_new_protected:cpn { __cmd_add_type_>:w } #1
+  {
+    \__cmd_flush_m_args:
+    \bool_set_true:N \l__cmd_prefixed_bool
+    \bool_set_true:N \l__cmd_process_some_bool
+    \tl_put_left:Nn \l__cmd_process_one_tl { {#1} }
+    \__cmd_prepare_signature_bypass:N
+  }
+\cs_new_protected:Npn \__cmd_add_type_b:w
+  {
+    \__cmd_flush_m_args:
+    \__cmd_add_default:
+    \__cmd_add_grabber:N b
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_type_D:w #1#2#3
+  {
+    \__cmd_flush_m_args:
+    \__cmd_add_default:n {#3}
+    \__cmd_add_grabber:N D
+    \tl_put_right:Nn \l__cmd_signature_tl { #1 #2 }
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_type_E:w #1#2
+  {
+    \__cmd_flush_m_args:
+    \__cmd_add_default_E:nn {#1} {#2}
+    \__cmd_add_grabber:N E
+    \tl_put_right:Nn \l__cmd_signature_tl { {#1} }
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_type_m:w
+  {
+    \__cmd_add_default:
+    \bool_if:NTF \l__cmd_prefixed_bool
+      { \__cmd_add_grabber:N m }
+      { \int_incr:N \l__cmd_m_args_int }
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_type_R:w #1#2#3
+  {
+    \__cmd_flush_m_args:
+    \__cmd_add_default:n {#3}
+    \__cmd_add_grabber:N R
+    \tl_put_right:Nn \l__cmd_signature_tl { #1 #2 }
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_type_t:w #1
+  {
+    \__cmd_flush_m_args:
+    \__cmd_add_default:
+    \__cmd_add_grabber:N t
+    \tl_put_right:Nn \l__cmd_signature_tl {#1}
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_type_v:w
+  {
+    \__cmd_flush_m_args:
+    \exp_args:No \__cmd_add_default:n \c_novalue_tl
+    \__cmd_add_grabber:N v
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_flush_m_args:
+  {
+    \int_compare:nNnT \l__cmd_m_args_int > 0
+      {
+        \tl_put_right:Nx \l__cmd_signature_tl
+          { \exp_not:c { __cmd_grab_m_ \int_use:N \l__cmd_m_args_int :w } }
+        \tl_put_right:Nx \l__cmd_process_all_tl
+          { \prg_replicate:nn { \l__cmd_m_args_int } { { } } }
+      }
+    \int_zero:N \l__cmd_m_args_int
+  }
+\cs_new_protected:Npn \__cmd_add_grabber:N #1
+  {
+    \tl_put_right:Nx \l__cmd_signature_tl
+      {
+        \exp_not:c
+          {
+            __cmd_grab_ #1
+            \bool_if:NT \l__cmd_long_bool { _long }
+            \bool_if:NT \l__cmd_obey_spaces_bool { _obey_spaces }
+            :w
+          }
+      }
+    \bool_set_false:N \l__cmd_long_bool
+    \bool_set_false:N \l__cmd_obey_spaces_bool
+    \tl_put_right:Nx \l__cmd_process_all_tl
+      { { \exp_not:o \l__cmd_process_one_tl } }
+    \tl_clear:N \l__cmd_process_one_tl
+  }
+\cs_new_protected:Npn \__cmd_add_default:n #1
+  {
+    \tl_if_novalue:nTF {#1}
+      { \__cmd_add_default: }
+      {
+        \int_incr:N \l__cmd_current_arg_int
+        \bool_set_true:N \l__cmd_defaults_bool
+        \tl_put_right:Nn \l__cmd_defaults_tl { { \prg_do_nothing: #1 } }
+      }
+  }
+\cs_new_protected:Npn \__cmd_add_default:
+  {
+    \int_incr:N \l__cmd_current_arg_int
+    \tl_put_right:Nn \l__cmd_defaults_tl { \c_novalue_tl }
+  }
+\cs_new_protected:Npn \__cmd_add_default_E:nn #1#2
+  {
+    \tl_map_function:nN {#2} \__cmd_add_default:n
+    \prg_replicate:nn
+      { \tl_count:n {#1} - \tl_count:n {#2} }
+      { \__cmd_add_default: }
+  }
+\cs_new_protected:cpn { __cmd_add_expandable_type_+:w }
+  {
+    \bool_set_true:N \l__cmd_long_bool
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_expandable_type_D:w
+  { \__cmd_add_expandable_type_D_aux:NNNn D }
+\cs_new_protected:Npn \__cmd_add_expandable_type_D_aux:NNNn #1#2#3#4
+  {
+    \__cmd_add_default:n {#4}
+    \tl_if_eq:nnTF {#2} {#3}
+      { \__cmd_add_expandable_type_D_aux:NN #1 #2 }
+      { \__cmd_add_expandable_type_D_aux:NNN #1 #2 #3 }
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_expandable_type_D_aux:NNN #1#2#3
+  {
+    \bool_if:NTF \l__cmd_long_bool
+      { \cs_set:cpx }
+      { \cs_set_nopar:cpx }
+      { \l__cmd_expandable_aux_name_tl } ##1 ##2 #2 ##3 \q__cmd ##4 #3
+      { ##1 {##2} {##3} {##4} }
+    \__cmd_add_expandable_grabber:nn {#1}
+      {
+        \exp_not:c  { \l__cmd_expandable_aux_name_tl }
+        \exp_not:n { #2 #3 }
+      }
+  }
+\cs_new_protected:Npn \__cmd_add_expandable_type_D_aux:NN #1#2
+  {
+    \bool_if:NTF \l__cmd_long_bool
+      { \cs_set:cpx }
+      { \cs_set_nopar:cpx }
+      { \l__cmd_expandable_aux_name_tl } ##1 #2 ##2 #2
+      { ##1 {##2} }
+    \__cmd_add_expandable_grabber:nn { #1_alt }
+      {
+        \exp_not:c  { \l__cmd_expandable_aux_name_tl }
+        \exp_not:n {#2}
+      }
+  }
+\cs_new_protected:Npn \__cmd_add_expandable_type_E:w #1#2
+  {
+    \__cmd_add_default_E:nn {#1} {#2}
+    \tl_clear:N \l__cmd_tmpb_tl
+    \tl_map_function:nN {#1} \__cmd_add_expandable_type_E_aux:n
+    \__cmd_add_expandable_grabber:nn
+      { E \bool_if:NT \l__cmd_long_bool { _long } }
+      {
+        { \exp_not:o \l__cmd_tmpb_tl }
+        {
+          \prg_replicate:nn { \tl_count:n {#1} }
+            { { \c_novalue_tl } }
+        }
+      }
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_expandable_type_E_aux:n #1
+  {
+    \__cmd_get_grabber:NN #1 \l__cmd_tmpa_tl
+    \tl_put_right:Nx \l__cmd_tmpb_tl
+      { \exp_not:o \l__cmd_tmpa_tl \exp_not:N #1 }
+  }
+\cs_new_protected:Npn \__cmd_add_expandable_type_m:w
+  {
+    \__cmd_add_default:
+    \__cmd_add_expandable_grabber:nn
+      { m \bool_if:NT \l__cmd_long_bool { _long } } { }
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_expandable_type_R:w
+  { \__cmd_add_expandable_type_D_aux:NNNn R }
+\cs_new_protected:Npn \__cmd_add_expandable_type_t:w #1
+  {
+    \__cmd_add_default:
+    \__cmd_get_grabber:NN #1 \l__cmd_tmpa_tl
+    \__cmd_add_expandable_grabber:nn { t }
+      {
+        \exp_not:o \l__cmd_tmpa_tl
+        \exp_not:N #1
+      }
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_expandable_grabber:nn #1#2
+  {
+    \tl_put_right:Nx \l__cmd_signature_tl
+      { \exp_not:c { __cmd_expandable_grab_ #1 :w } #2 }
+  }
+\cs_new_protected:Npn \__cmd_get_grabber:NN #1#2
+  {
+    \cs_set:Npn \__cmd_tmp:w ##1 #1 {##1}
+    \exp_args:Nc \__cmd_get_grabber_auxi:NN
+      { __cmd_grabber_ \token_to_str:N #1 :w } #2
+  }
+\cs_new_protected:Npn \__cmd_get_grabber_auxi:NN #1#2
+  {
+    \cs_if_eq:NNTF \__cmd_tmp:w #1
+      { \tl_set:Nn #2 {#1} }
+      {
+        \cs_if_exist:NTF #1
+          {
+            \int_gincr:N \g__cmd_grabber_int
+            \exp_args:Nc \__cmd_get_grabber_auxi:NN
+              {
+                __cmd_grabber_
+                - \int_use:N \g__cmd_grabber_int :w
+              }
+              #2
+          }
+          { \__cmd_get_grabber_auxii:NN #1 #2 }
+      }
+  }
+\cs_new_protected:Npn \__cmd_get_grabber_auxii:NN #1#2
+  {
+    \cs_set_eq:NN #1 \__cmd_tmp:w
+    \tl_set:Nn #2 {#1}
+  }
+\cs_new_protected:Npn \__cmd_grab_b:w
+  { \__cmd_grab_b_aux:NNw \cs_set_protected_nopar:Npn \tl_trim_spaces:n }
+\cs_new_protected:Npn \__cmd_grab_b_long:w
+  { \__cmd_grab_b_aux:NNw \cs_set_protected:Npn \tl_trim_spaces:n }
+\cs_new_protected:Npn \__cmd_grab_b_obey_spaces:w
+  { \__cmd_grab_b_aux:NNw \cs_set_protected_nopar:Npn \exp_not:n }
+\cs_new_protected:Npn \__cmd_grab_b_long_obey_spaces:w
+  { \__cmd_grab_b_aux:NNw \cs_set_protected:Npn \exp_not:n }
+\cs_new_protected:Npn \__cmd_grab_b_aux:NNw #1#2#3 \__cmd_run_code:
+  {
+    \__cmd_grab_D_aux:NNnN \begin \end {#3} #1
+    \tl_put_left:Nn \l__cmd_signature_tl { \__cmd_grab_b_end:Nw #2 }
+    \tl_set_eq:NN \l__cmd_saved_args_tl \l__cmd_args_tl
+    \tl_clear:N \l__cmd_args_tl
+    \exp_args:Nc \l__cmd_fn_tl { begin ~ }
+  }
+\cs_new_protected:Npn \__cmd_grab_b_end:Nw #1#2 \__cmd_run_code:
+  {
+    \tl_set:Nx \l__cmd_args_tl
+      {
+        \exp_not:V \l__cmd_saved_args_tl
+        { \exp_after:wN #1 \l__cmd_args_tl }
+      }
+    #2
+    \__cmd_run_code:
+    \end
+  }
+\cs_new_protected:Npn \__cmd_grab_D:w #1#2#3 \__cmd_run_code:
+  {
+    \__cmd_grab_D_aux:NNnNN #1 #2 {#3} \cs_set_protected_nopar:Npn
+      \__cmd_peek_nonspace_remove:NTF
+  }
+\cs_new_protected:Npn \__cmd_grab_D_long:w #1#2#3 \__cmd_run_code:
+  {
+    \__cmd_grab_D_aux:NNnNN #1 #2 {#3} \cs_set_protected:Npn
+      \__cmd_peek_nonspace_remove:NTF
+  }
+\cs_new_protected:Npn \__cmd_grab_D_obey_spaces:w #1#2#3 \__cmd_run_code:
+  {
+    \__cmd_grab_D_aux:NNnNN #1 #2 {#3} \cs_set_protected_nopar:Npn
+      \__cmd_peek_meaning_remove:NTF
+  }
+\cs_new_protected:Npn \__cmd_grab_D_long_obey_spaces:w #1#2#3 \__cmd_run_code:
+  {
+    \__cmd_grab_D_aux:NNnNN #1 #2 {#3} \cs_set_protected:Npn
+      \__cmd_peek_meaning_remove:NTF
+  }
+\cs_new_protected:Npn \__cmd_grab_D_aux:NNnNN #1#2#3#4#5
+  {
+    \__cmd_grab_D_aux:NNnN #1#2 {#3} #4
+    #5 #1
+      { \__cmd_grab_D_call:Nw #1 }
+      { \__cmd_add_arg:o \c_novalue_tl }
+  }
+\cs_new_protected:Npn \__cmd_grab_D_aux:NNnN #1#2#3#4
+  {
+    \tl_set:Nn \l__cmd_signature_tl {#3}
+    \exp_after:wN #4 \l__cmd_fn_tl ##1 #2
+      {
+        \tl_if_in:nnTF {##1} {#1}
+          { \__cmd_grab_D_nested:NNnN #1 #2 {##1} #4 }
+          {
+            \tl_if_blank:oTF { \use_none:n ##1 }
+              { \__cmd_add_arg:o { \use_none:n ##1 } }
+              {
+                \str_if_eq:eeTF
+                  { \exp_not:o { \use_none:n ##1 } }
+                  { { \exp_not:o { \use_ii:nnn ##1 \q_nil } } }
+                  { \__cmd_add_arg:o { \use_ii:nn ##1 } }
+                  { \__cmd_add_arg:o { \use_none:n ##1 } }
+              }
+          }
+      }
+  }
+\tl_new:N \l__cmd_nesting_a_tl
+\tl_new:N \l__cmd_nesting_b_tl
+\quark_new:N \q__cmd
+\cs_new_protected:Npn \__cmd_grab_D_nested:NNnN #1#2#3#4
+  {
+    \tl_clear:N \l__cmd_nesting_a_tl
+    \tl_clear:N \l__cmd_nesting_b_tl
+    \exp_after:wN #4 \l__cmd_fn_tl ##1 #1 ##2 \q__cmd ##3 #2
+      {
+        \tl_put_right:No \l__cmd_nesting_a_tl { \use_none:n ##1 #1 }
+        \tl_put_right:No \l__cmd_nesting_b_tl { \use_i:nn #2 ##3 }
+        \tl_if_in:nnTF {##2} {#1}
+          {
+            \l__cmd_fn_tl
+              \q_nil ##2 \q__cmd \ERROR
+          }
+          {
+            \tl_put_right:Nx \l__cmd_nesting_a_tl
+              { \__cmd_grab_D_nested:w \q_nil ##2 \q_stop }
+            \tl_if_in:NnTF \l__cmd_nesting_b_tl {#1}
+              {
+                \tl_set_eq:NN \l__cmd_tmpa_tl \l__cmd_nesting_b_tl
+                \tl_clear:N \l__cmd_nesting_b_tl
+                \exp_after:wN \l__cmd_fn_tl \exp_after:wN
+                  \q_nil \l__cmd_tmpa_tl \q_nil \q__cmd \ERROR
+              }
+              {
+                \tl_put_right:No \l__cmd_nesting_a_tl
+                  \l__cmd_nesting_b_tl
+                \__cmd_add_arg:V \l__cmd_nesting_a_tl
+              }
+          }
+      }
+    \l__cmd_fn_tl #3 \q_nil \q__cmd \ERROR
+  }
+\cs_new:Npn \__cmd_grab_D_nested:w #1 \q_nil \q_stop
+  { \exp_not:o { \use_none:n #1 } }
+\cs_new_protected_nopar:Npn \__cmd_grab_D_call:Nw #1
+  {
+    \token_if_eq_catcode:NNTF + #1
+      {
+        \exp_after:wN \exp_after:wN \exp_after:wN
+          \l__cmd_fn_tl \char_generate:nn { `#1 } { 11 }
+      }
+      {
+        \__cmd_token_if_cs:NTF #1
+          {
+            \exp_after:wN \l__cmd_fn_tl
+            \cs:w \cs_to_str:N #1 ~ \cs_end:
+          }
+          {
+            \exp_after:wN \l__cmd_fn_tl
+            \token_to_str:N #1
+          }
+      }
+  }
+\cs_new_protected:Npn \__cmd_grab_E:w #1#2 \__cmd_run_code:
+  {
+    \__cmd_grab_E:nnNN {#1} {#2}
+      \cs_set_protected_nopar:Npn
+      \__cmd_peek_nonspace_remove:NTF
+  }
+\cs_new_protected:Npn \__cmd_grab_E_long:w #1#2 \__cmd_run_code:
+  {
+    \__cmd_grab_E:nnNN {#1} {#2}
+      \cs_set_protected:Npn
+      \__cmd_peek_nonspace_remove:NTF
+  }
+\cs_new_protected:Npn \__cmd_grab_E_obey_spaces:w #1#2 \__cmd_run_code:
+  {
+    \__cmd_grab_E:nnNN {#1} {#2}
+      \cs_set_protected_nopar:Npn
+      \__cmd_peek_meaning_remove:NTF
+  }
+\cs_new_protected:Npn \__cmd_grab_E_long_obey_spaces:w #1#2 \__cmd_run_code:
+  {
+    \__cmd_grab_E:nnNN {#1} {#2}
+      \cs_set_protected:Npn
+      \__cmd_peek_meaning_remove:NTF
+  }
+\cs_new_protected:Npn \__cmd_grab_E:nnNN #1#2#3#4
+  {
+    \exp_after:wN #3 \l__cmd_fn_tl ##1##2##3
+      {
+        \prop_put:Nnn \l__cmd_tmp_prop {##1} {##3}
+        \__cmd_grab_E_loop:NnN #4 { } ##2 \q_recursion_stop
+      }
+    \prop_clear:N \l__cmd_tmp_prop
+    \tl_set:Nn \l__cmd_signature_tl {#2}
+    \cs_set_protected:Npn \__cmd_grab_E_finalise:
+      {
+        \tl_map_inline:nn {#1}
+          {
+            \prop_get:NnNF \l__cmd_tmp_prop {####1} \l__cmd_tmpb_tl
+              { \tl_set_eq:NN \l__cmd_tmpb_tl \c_novalue_tl }
+            \tl_put_right:Nx \l__cmd_args_tl
+              { { \exp_not:V \l__cmd_tmpb_tl } }
+          }
+        \l__cmd_signature_tl \__cmd_run_code:
+      }
+    \__cmd_grab_E_loop:NnN #4 { } #1 \q_recursion_tail \q_recursion_stop
+  }
+\cs_new_protected:Npn \__cmd_grab_E_loop:NnN #1#2#3#4 \q_recursion_stop
+  {
+    \cs_if_eq:NNTF #3 \q_recursion_tail
+      { \__cmd_grab_E_finalise: }
+      {
+        #1 #3
+          { \l__cmd_fn_tl #3 {#2#4} }
+          { \__cmd_grab_E_loop:NnN #1 {#2#3} #4 \q_recursion_stop }
+      }
+  }
+\cs_new_protected:Npn \__cmd_grab_E_finalise: { }
+\cs_new_protected:Npn \__cmd_grab_m:w #1 \__cmd_run_code:
+  {
+    \tl_set:Nn \l__cmd_signature_tl {#1}
+    \exp_after:wN \cs_set_protected_nopar:Npn \l__cmd_fn_tl ##1
+      { \__cmd_add_arg:n {##1} }
+    \l__cmd_fn_tl
+  }
+\cs_new_protected:Npn \__cmd_grab_m_long:w #1 \__cmd_run_code:
+  {
+    \tl_set:Nn \l__cmd_signature_tl {#1}
+    \exp_after:wN \cs_set_protected:Npn \l__cmd_fn_tl ##1
+      { \__cmd_add_arg:n {##1} }
+    \l__cmd_fn_tl
+  }
+\cs_new_protected_nopar:Npn \__cmd_grab_m_aux:Nnnnnnnnn #1#2#3#4#5#6#7#8#9
+  {
+    \tl_put_right:No \l__cmd_args_tl
+      { #1 {#2} {#3} {#4} {#5} {#6} {#7} {#8} {#9} }
+    \l__cmd_signature_tl \__cmd_run_code:
+  }
+\cs_new_protected:cpn { __cmd_grab_m_1:w } #1 \__cmd_run_code:
+  {
+    \tl_set:Nn \l__cmd_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l__cmd_fn_tl \__cmd_grab_m_aux:Nnnnnnnnn
+    \l__cmd_fn_tl \use_none:nnnnnnn { } { } { } { } { } { } { }
+  }
+\cs_new_protected:cpn { __cmd_grab_m_2:w } #1 \__cmd_run_code:
+  {
+    \tl_set:Nn \l__cmd_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l__cmd_fn_tl \__cmd_grab_m_aux:Nnnnnnnnn
+    \l__cmd_fn_tl \use_none:nnnnnn { } { } { } { } { } { }
+  }
+\cs_new_protected:cpn { __cmd_grab_m_3:w } #1 \__cmd_run_code:
+  {
+    \tl_set:Nn \l__cmd_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l__cmd_fn_tl \__cmd_grab_m_aux:Nnnnnnnnn
+    \l__cmd_fn_tl \use_none:nnnnn { } { } { } { } { }
+  }
+\cs_new_protected:cpn { __cmd_grab_m_4:w } #1 \__cmd_run_code:
+  {
+    \tl_set:Nn \l__cmd_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l__cmd_fn_tl \__cmd_grab_m_aux:Nnnnnnnnn
+    \l__cmd_fn_tl \use_none:nnnn { } { } { } { }
+  }
+\cs_new_protected:cpn { __cmd_grab_m_5:w } #1 \__cmd_run_code:
+  {
+    \tl_set:Nn \l__cmd_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l__cmd_fn_tl \__cmd_grab_m_aux:Nnnnnnnnn
+    \l__cmd_fn_tl \use_none:nnn { } { } { }
+  }
+\cs_new_protected:cpn { __cmd_grab_m_6:w } #1 \__cmd_run_code:
+  {
+    \tl_set:Nn \l__cmd_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l__cmd_fn_tl \__cmd_grab_m_aux:Nnnnnnnnn
+    \l__cmd_fn_tl \use_none:nn { } { }
+  }
+\cs_new_protected:cpn { __cmd_grab_m_7:w } #1 \__cmd_run_code:
+  {
+    \tl_set:Nn \l__cmd_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l__cmd_fn_tl \__cmd_grab_m_aux:Nnnnnnnnn
+    \l__cmd_fn_tl \use_none:n { }
+  }
+\cs_new_protected:cpn { __cmd_grab_m_8:w } #1 \__cmd_run_code:
+  {
+    \tl_set:Nn \l__cmd_signature_tl {#1}
+    \exp_after:wN \cs_set_eq:NN \l__cmd_fn_tl \__cmd_grab_m_aux:Nnnnnnnnn
+    \l__cmd_fn_tl \prg_do_nothing:
+  }
+\cs_new_protected:cpx { __cmd_grab_m_9:w }
+  {
+    \exp_not:c { __cmd_grab_m_5:w }
+    \exp_not:c { __cmd_grab_m_4:w }
+  }
+\cs_new_protected:Npn \__cmd_grab_R:w #1#2#3 \__cmd_run_code:
+  { \__cmd_grab_R_aux:NNnN #1 #2 {#3} \cs_set_protected_nopar:Npn }
+\cs_new_protected:Npn \__cmd_grab_R_long:w #1#2#3 \__cmd_run_code:
+  { \__cmd_grab_R_aux:NNnN #1 #2 {#3} \cs_set_protected:Npn }
+\cs_new_protected:Npn \__cmd_grab_R_aux:NNnN #1#2#3#4
+  {
+    \__cmd_grab_D_aux:NNnN #1 #2 {#3} #4
+    \__cmd_peek_nonspace_remove:NTF #1
+      { \__cmd_grab_D_call:Nw #1 }
+      {
+        \msg_error:nnxx { cmd } { missing-required }
+          { \__cmd_environment_or_command: }
+          { \token_to_str:N #1 }
+        \__cmd_add_arg:o \c_novalue_tl
+      }
+  }
+\cs_new_protected:Npn \__cmd_grab_t:w
+  { \__cmd_grab_t_aux:NNw \__cmd_peek_nonspace_remove:NTF }
+\cs_new_protected:Npn \__cmd_grab_t_obey_spaces:w
+  { \__cmd_grab_t_aux:NNw \__cmd_peek_meaning_remove:NTF }
+\cs_new_protected:Npn \__cmd_grab_t_aux:NNw #1#2#3 \__cmd_run_code:
+  {
+    \tl_set:Nn \l__cmd_signature_tl {#3}
+    \exp_after:wN \cs_set_protected:Npn \l__cmd_fn_tl
+      {
+        #1 #2
+          { \__cmd_add_arg:n { \BooleanTrue } }
+          { \__cmd_add_arg:n { \BooleanFalse } }
+      }
+    \l__cmd_fn_tl
+  }
+\tl_new:N \l__cmd_v_arg_tl
+\cs_new_protected:Npn \__cmd_grab_v:w
+  {
+    \bool_set_false:N \l__cmd_long_bool
+    \__cmd_grab_v_aux:w
+  }
+\cs_new_protected:Npn \__cmd_grab_v_long:w
+  {
+    \bool_set_true:N \l__cmd_long_bool
+    \__cmd_grab_v_aux:w
+  }
+\cs_new_protected:Npn \__cmd_grab_v_aux:w #1 \__cmd_run_code:
+  {
+    \tl_set:Nn \l__cmd_signature_tl {#1}
+    \group_begin:
+      \tex_escapechar:D = 92 \scan_stop:
+      \tl_clear:N \l__cmd_v_arg_tl
+      \peek_remove_spaces:n
+        {
+          \peek_meaning_remove:NTF \c_group_begin_token
+            {
+              \group_align_safe_end:
+              \__cmd_grab_v_bgroup:
+            }
+            {
+              \peek_N_type:TF
+                { \__cmd_grab_v_aux_test:N }
+                { \__cmd_grab_v_aux_abort:n { } }
+            }
+        }
+  }
+\cs_new_protected:Npn \__cmd_grab_v_group_end:
+  {
+        \exp_args:NNNo
+      \group_end:
+    \tl_set:Nn \l__cmd_v_arg_tl { \l__cmd_v_arg_tl }
+  }
+\cs_new_protected:Npn \__cmd_grab_v_aux_test:N #1
+  {
+    \__cmd_grab_v_token_if_char:NTF #1
+      {
+        \__cmd_grab_v_aux_put:N #1
+        \__cmd_grab_v_aux_catcodes:
+        \__cmd_grab_v_aux_loop:N #1
+      }
+      { \__cmd_grab_v_aux_abort:n {#1} #1 }
+  }
+\cs_new_protected:Npn \__cmd_grab_v_aux_loop:N #1
+  {
+    \peek_N_type:TF
+      { \__cmd_grab_v_aux_loop:NN #1 }
+      { \__cmd_grab_v_aux_abort:n { } }
+  }
+\cs_new_protected:Npn \__cmd_grab_v_aux_loop:NN #1#2
+  {
+    \__cmd_grab_v_token_if_char:NTF #2
+      {
+        \token_if_eq_charcode:NNTF #1 #2
+          { \__cmd_grab_v_aux_loop_end: }
+          {
+            \__cmd_grab_v_aux_put:N #2
+            \__cmd_grab_v_aux_loop:N #1
+          }
+      }
+      { \__cmd_grab_v_aux_abort:n {#2} #2 }
+  }
+\cs_new_protected:Npn \__cmd_grab_v_aux_loop_end:
+  {
+    \__cmd_grab_v_group_end:
+    \__cmd_add_arg:x { \tl_tail:N \l__cmd_v_arg_tl }
+  }
+\int_new:N \l__cmd_v_nesting_int
+\cs_new_protected:Npx \__cmd_grab_v_bgroup:
+  {
+    \exp_not:N \__cmd_grab_v_aux_catcodes:
+    \exp_not:n { \int_set:Nn \l__cmd_v_nesting_int { 1 } }
+    \exp_not:N \__cmd_grab_v_aux_put:N \iow_char:N \{
+    \exp_not:N \__cmd_grab_v_bgroup_loop:
+  }
+\cs_new_protected:Npn \__cmd_grab_v_bgroup_loop:
+  {
+    \peek_N_type:TF
+      { \__cmd_grab_v_bgroup_loop:N }
+      { \__cmd_grab_v_aux_abort:n { } }
+  }
+\cs_new_protected:Npn \__cmd_grab_v_bgroup_loop:N #1
+  {
+    \__cmd_grab_v_token_if_char:NTF #1
+      {
+        \token_if_eq_charcode:NNTF \c_group_end_token #1
+          {
+            \int_decr:N \l__cmd_v_nesting_int
+            \int_compare:nNnTF \l__cmd_v_nesting_int > 0
+              {
+                \__cmd_grab_v_aux_put:N #1
+                \__cmd_grab_v_bgroup_loop:
+              }
+              { \__cmd_grab_v_aux_loop_end: }
+          }
+          {
+            \token_if_eq_charcode:NNT \c_group_begin_token #1
+              { \int_incr:N \l__cmd_v_nesting_int }
+            \__cmd_grab_v_aux_put:N #1
+            \__cmd_grab_v_bgroup_loop:
+          }
+      }
+      { \__cmd_grab_v_aux_abort:n {#1} #1 }
+  }
+\cs_new_protected:Npn \__cmd_grab_v_aux_catcodes:
+  {
+    \cs_set_eq:NN \do \char_set_catcode_other:N
+    \dospecials
+    \tex_endlinechar:D = `\^^M \scan_stop:
+    \bool_if:NTF \l__cmd_long_bool
+      { \char_set_catcode_other:n { \tex_endlinechar:D } }
+      { \char_set_catcode_parameter:n { \tex_endlinechar:D } }
+  }
+\cs_new_protected:Npn \__cmd_grab_v_aux_abort:n #1
+  {
+    \__cmd_grab_v_group_end:
+    \exp_after:wN \exp_after:wN \exp_after:wN
+      \peek_meaning_remove:NTF \char_generate:nn { \tex_endlinechar:D } { 6 }
+      {
+        \msg_error:nnxxx { cmd } { verbatim-newline }
+          { \__cmd_environment_or_command: }
+          { \tl_to_str:N \l__cmd_v_arg_tl }
+          { \tl_to_str:n {#1} }
+        \__cmd_add_arg:o \c_novalue_tl
+      }
+      {
+        \msg_error:nnxxx { cmd } { verbatim-tokenized }
+          { \__cmd_environment_or_command: }
+          { \tl_to_str:N \l__cmd_v_arg_tl }
+          { \tl_to_str:n {#1} }
+        \__cmd_add_arg:o \c_novalue_tl
+      }
+  }
+\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 }
+      }
+  }
+\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
+  {
+    \tl_put_right:Nn \l__cmd_args_tl { {#1} }
+    \l__cmd_signature_tl \__cmd_run_code:
+  }
+\cs_generate_variant:Nn \__cmd_add_arg:n { V , o , x }
+\cs_new:Npn \__cmd_expandable_grab_D:w #1 \q__cmd #2#3
+  { #2 { \__cmd_expandable_grab_D:NNNwNNn #1 \q__cmd #2 #3 } }
+\cs_set_protected:Npn \__cmd_tmp:w #1
+  {
+    \cs_new:Npn \__cmd_expandable_grab_D:NNNwNNn ##1##2##3##4 \q__cmd ##5##6##7
+      {
+        \str_if_eq:nnTF {##2} {##7}
+          {
+            \str_if_eq:onTF
+              { ##1 { } { } ##7 ##2 \q__cmd ##3 }
+              { { } {##2} { } }
+          }
+          { \use_ii:nn }
+          {
+            ##1
+              { \__cmd_expandable_grab_D:NNNwNNnnn ##1##2##3##4 \q__cmd ##5##6 }
+              \q_nil { } ##2 \ERROR \q__cmd \ERROR
+          }
+          { ##4 {#1} \q__cmd ##5 ##6 {##7} }
+      }
+  }
+\exp_args:No \__cmd_tmp:w { \c_novalue_tl }
+\cs_new:Npn \__cmd_expandable_grab_D:NNNwNNnnn #1#2#3#4 \q__cmd #5#6#7#8#9
+  {
+    \exp_args:Nof \__cmd_expandable_grab_D:nnNNNwNN
+      { \use_ii:nn #7 #2 }
+      { \__cmd_expandable_grab_D:Nw #3 \exp_stop_f: #8 #9 }
+    #1#2#3 #4 \q__cmd #5 #6
+  }
+\cs_new:Npn \__cmd_expandable_grab_D:Nw #1#2 \ERROR \ERROR { #2 #1 }
+\cs_new:Npn \__cmd_expandable_grab_D:nnNNNwNN #1#2#3#4#5#6 \q__cmd #7#8
+  {
+    \exp_args:No \tl_if_empty:oTF
+      { #3 { \use_none:nnn } #2 \q__cmd #5 #4 \q__cmd #5 }
+      {
+        \tl_if_blank:oTF { \use_none:nn #1#2 }
+          { \__cmd_put_arg_expandable:ow { \use_none:nn #1#2 } }
+          {
+            \str_if_eq:eeTF
+              { \exp_not:o { \use_none:nn #1#2 } }
+              { { \exp_not:o { \use_iii:nnnn #1#2 \q_nil } } }
+              { \__cmd_put_arg_expandable:ow { \use_iii:nnn #1#2 } }
+              { \__cmd_put_arg_expandable:ow { \use_none:nn #1#2 } }
+          }
+            #6 \q__cmd #7 #8
+      }
+      {
+        #3
+          { \__cmd_expandable_grab_D:NNNwNNnnn #3#4#5#6 \q__cmd #7 #8 }
+          \q_nil {#1} #2 \ERROR \q__cmd \ERROR
+      }
+  }
+\cs_new:Npn \__cmd_expandable_grab_D_alt:w #1 \q__cmd #2#3
+  { #2 { \__cmd_expandable_grab_D_alt:NNwNNn #1 \q__cmd #2 #3 } }
+\cs_set_protected:Npn \__cmd_tmp:w #1
+  {
+    \cs_new:Npn \__cmd_expandable_grab_D_alt:NNwNNn ##1##2##3 \q__cmd ##4##5##6
+      {
+        \str_if_eq:nnTF {##6} {##2}
+          {
+            \str_if_eq:onTF
+              { ##1 { } ##6 ##2 ##2 }
+              { { } ##2 }
+          }
+          { \use_ii:nn }
+          {
+            ##1
+              { \__cmd_expandable_grab_D_alt:NNwn ##4 ##5 ##3 \q__cmd }
+              ##6 \ERROR
+          }
+          { ##3 {#1} \q__cmd ##4 ##5 {##6} }
+      }
+  }
+\exp_args:No \__cmd_tmp:w { \c_novalue_tl }
+\cs_new:Npn \__cmd_expandable_grab_D_alt:NNwn #1#2#3 \q__cmd #4
+  {
+    \tl_if_blank:oTF { \use_none:n #4 }
+      { \__cmd_put_arg_expandable:ow { \use_none:n #4 } }
+      {
+        \str_if_eq:eeTF
+          { \exp_not:o { \use_none:n #4 } }
+          { { \exp_not:o { \use_ii:nnn #4 \q_nil } } }
+          { \__cmd_put_arg_expandable:ow { \use_ii:nn #4 } }
+          { \__cmd_put_arg_expandable:ow { \use_none:n #4 } }
+      }
+        #3 \q__cmd #1 #2
+  }
+\cs_new:Npn \__cmd_expandable_grab_E:w #1 \q__cmd #2#3
+  { \__cmd_expandable_grab_E_aux:w #1 \q__cmd #2 #3 #3 }
+\cs_new:Npn \__cmd_expandable_grab_E_long:w #1 \q__cmd #2#3
+  { \__cmd_expandable_grab_E_aux:w #1 \q__cmd #2 #3 #2 }
+\cs_new:Npn \__cmd_expandable_grab_E_aux:w #1 \q__cmd #2#3#4
+  { #2 { \__cmd_expandable_grab_E_test:nnw #1 \q__cmd #2 #3 #4 } }
+\cs_new:Npn \__cmd_expandable_grab_E_test:nnw #1#2#3 \q__cmd #4#5#6#7
+  {
+    \__cmd_expandable_grab_E_loop:nnnNNw {#7} { } { }
+      #1 \q_nil \q_nil \q_nil \q_mark #2 \q_nil
+    #3 \q__cmd #4 #5 #6
+  }
+\cs_new:Npn \__cmd_expandable_grab_E_loop:nnnNNw
+    #1#2#3#4#5#6 \q_nil #7 \q_mark #8
+  {
+    \quark_if_nil:NTF #4
+      { \__cmd_expandable_grab_E_end:nnw {#1} {#3} }
+      {
+        \tl_if_novalue:nTF {#8}
+          { \str_if_eq:onTF { #4 { } #1 #5 } {#5} }
+          { \use_ii:nn }
+            { \__cmd_expandable_grab_E_find:w { #2 #4 #5 #6 } {#3} ~ }
+            {
+              \__cmd_expandable_grab_E_loop:nnnNNw
+                {#1} { #2 #4 #5 } { #3 {#8} }
+                #6 \q_nil #7 \q_mark
+            }
+      }
+  }
+\cs_new:Npn \__cmd_expandable_grab_E_find:w #1 \q__cmd #2#3#4
+  { #4 { \__cmd_expandable_grab_E_find:nnw #1 \q__cmd #2 #3 #4 } }
+\cs_new:Npn \__cmd_expandable_grab_E_find:nnw #1#2#3 \q_nil #4 \q__cmd #5#6#7#8
+  { \__cmd_expandable_grab_E_aux:w {#1} { #2 {#8} #3 } #4 \q__cmd #5 #6 #7 }
+\cs_new:Npn \__cmd_expandable_grab_E_end:nnw #1#2#3 \q__cmd #4#5#6
+  { #3 #2 \q__cmd #4 #5 {#1} }
+\cs_new:Npn \__cmd_expandable_grab_m:w #1 \q__cmd #2#3
+  { #3 { \__cmd_expandable_grab_m_aux:wNn #1 \q__cmd #2 #3 } }
+\cs_new:Npn \__cmd_expandable_grab_m_long:w #1 \q__cmd #2#3
+  { #2 { \__cmd_expandable_grab_m_aux:wNn #1 \q__cmd #2 #3 } }
+\cs_new:Npn \__cmd_expandable_grab_m_aux:wNn #1 \q__cmd #2#3#4
+  { #1 {#4} \q__cmd #2 #3 }
+\cs_new:Npn \__cmd_expandable_grab_R:w #1 \q__cmd #2#3
+  { #2 { \__cmd_expandable_grab_R_aux:NNNwNNn #1 \q__cmd #2#3 } }
+\cs_set_protected:Npn \__cmd_tmp:w #1
+  {
+    \cs_new:Npn \__cmd_expandable_grab_R_aux:NNNwNNn ##1##2##3##4 \q__cmd ##5##6##7
+      {
+        \str_if_eq:nnTF {##7} {##2}
+          {
+            \str_if_eq:onTF
+              { ##1 { } { } ##7 ##2 \q__cmd ##3 }
+              { { } {##2} { } }
+          }
+          { \use_ii:nn }
+          {
+            ##1
+              { \__cmd_expandable_grab_D:NNNwNNnnn ##1##2##3##4 \q__cmd ##5##6 }
+              \q_nil { } ##2 \ERROR \q__cmd \ERROR
+          }
+          {
+            \msg_expandable_error:nnff { cmd } { missing-required }
+              { \exp_args:Nf \tl_trim_spaces:n { \token_to_str:N ##5 } }
+              { \tl_to_str:n {##2} }
+            ##4 {#1} \q__cmd ##5 ##6 {##7}
+          }
+      }
+  }
+\exp_args:No \__cmd_tmp:w { \c_novalue_tl }
+\cs_new:Npn \__cmd_expandable_grab_R_alt:w #1 \q__cmd #2#3
+  { #2 { \__cmd_expandable_grab_R_alt_aux:NNwNNn #1 \q__cmd #2#3 } }
+\cs_set_protected:Npn \__cmd_tmp:w #1
+  {
+    \cs_new:Npn \__cmd_expandable_grab_R_alt_aux:NNwNNn ##1##2##3 \q__cmd ##4##5##6
+      {
+        \str_if_eq:nnTF {##6} {##2}
+          {
+            \str_if_eq:onTF
+              { ##1 { } ##6 ##2 ##2 }
+              { { } ##2 }
+          }
+          { \use_ii:nn }
+          {
+            ##1
+              { \__cmd_expandable_grab_D_alt:NNwn ##4 ##5 ##3 \q__cmd }
+              ##6 \ERROR
+          }
+          {
+            \msg_expandable_error:nnff { cmd } { missing-required }
+              { \exp_args:Nf \tl_trim_spaces:n { \token_to_str:N ##4 } }
+              { \tl_to_str:n {##2} }
+            ##3 {#1} \q__cmd ##4 ##5 {##6}
+          }
+      }
+  }
+\exp_args:No \__cmd_tmp:w { \c_novalue_tl }
+\cs_new:Npn \__cmd_expandable_grab_t:w #1 \q__cmd #2#3
+  { #2 { \__cmd_expandable_grab_t_aux:NNwn #1 \q__cmd #2 #3 } }
+\cs_new:Npn \__cmd_expandable_grab_t_aux:NNwn #1#2#3 \q__cmd #4#5#6
+  {
+    \str_if_eq:onTF { #1 { } #6 #2 } {#2}
+      { #3 { \BooleanTrue } \q__cmd #4 #5 }
+      { #3 { \BooleanFalse } \q__cmd #4 #5 {#6} }
+  }
+\cs_new:Npn \__cmd_put_arg_expandable:nw #1#2 \q__cmd { #2 {#1} \q__cmd }
+\cs_generate_variant:Nn \__cmd_put_arg_expandable:nw { o }
+\cs_new_protected:Npn \__cmd_bool_reverse:N #1
+  {
+    \bool_if:NTF #1
+      { \tl_set:Nn \ProcessedArgument { \c_false_bool } }
+      { \tl_set:Nn \ProcessedArgument { \c_true_bool } }
+  }
+\seq_new:N \l__cmd_split_list_seq
+\tl_new:N \l__cmd_split_list_tl
+\cs_new_protected:Npn \__cmd_split_list:nn #1#2
+  {
+    \tl_if_single:nTF {#1}
+      {
+        \token_if_cs:NTF #1
+          { \__cmd_split_list_multi:nn {#1} {#2} }
+          { \__cmd_split_list_single:Nn #1 {#2} }
+      }
+      { \__cmd_split_list_multi:nn {#1} {#2} }
+  }
+\cs_new_protected:Npn \__cmd_split_list_multi:nn #1#2
+  {
+    \seq_set_split:Nnn \l__cmd_split_list_seq {#1} {#2}
+    \tl_clear:N \ProcessedArgument
+    \seq_map_inline:Nn \l__cmd_split_list_seq
+      { \tl_put_right:Nn \ProcessedArgument { {##1} } }
+  }
+\cs_generate_variant:Nn \__cmd_split_list_multi:nn { nV }
+\group_begin:
+\char_set_catcode_active:N \^^@
+\cs_new_protected:Npn \__cmd_split_list_single:Nn #1#2
+  {
+    \tl_set:Nn \l__cmd_split_list_tl {#2}
+    \group_begin:
+    \char_set_lccode:nn { `\^^@ } { `#1 }
+    \tex_lowercase:D
+      {
+        \group_end:
+        \tl_replace_all:Nnn \l__cmd_split_list_tl { ^^@ }
+      }   {#1}
+     \__cmd_split_list_multi:nV {#1} \l__cmd_split_list_tl
+   }
+\group_end:
+\cs_new_protected:Npn \__cmd_split_argument:nnn #1#2#3
+  {
+    \__cmd_split_list:nn {#2} {#3}
+    \exp_args:Nf \__cmd_split_argument_aux:nnnn
+      { \tl_count:N \ProcessedArgument }
+      {#1} {#2} {#3}
+  }
+\cs_new_protected:Npn \__cmd_split_argument_aux:nnnn #1#2#3#4
+  {
+    \int_compare:nNnF {#1} = { #2 + 1 }
+      {
+        \int_compare:nNnTF {#1} > { #2 + 1 }
+          {
+            \tl_set:Nx \ProcessedArgument
+              {
+                \exp_last_unbraced:NnNo
+                  \__cmd_split_argument_aux:n
+                  { #2 + 1 }
+                  \use_none_delimit_by_q_stop:w
+                  \ProcessedArgument
+                  \q_stop
+              }
+            \msg_error:nnxxx { cmd } { split-excess-tokens }
+              { \tl_to_str:n {#3} } { \int_eval:n { #2 + 1 } }
+              { \tl_to_str:n {#4} }
+          }
+          {
+            \tl_put_right:Nx \ProcessedArgument
+              {
+                \prg_replicate:nn { #2 + 1 - (#1) }
+                  { { \exp_not:V \c_novalue_tl } }
+              }
+          }
+      }
+  }
+\cs_new:Npn \__cmd_split_argument_aux:n #1
+  { \prg_replicate:nn {#1} { \__cmd_split_argument_aux:wn } }
+\cs_new:Npn \__cmd_split_argument_aux:wn #1 \use_none_delimit_by_q_stop:w #2
+  {
+    \exp_not:n { {#2} }
+    #1
+    \use_none_delimit_by_q_stop:w
+  }
+\cs_new_protected:Npn \__cmd_trim_spaces:n #1
+  { \tl_set:Nx \ProcessedArgument { \tl_trim_spaces:n {#1} } }
+\cs_new_protected:Npn \__cmd_get_arg_spec_error:N #1
+  {
+    \bool_set_false:N \l__cmd_environment_bool
+    \tl_set:Nn \l__cmd_fn_tl {#1}
+    \__cmd_get_arg_spec_error_aux:n { \cs_if_exist:NTF #1 }
+  }
+\cs_new_protected:Npn \__cmd_get_arg_spec_error:n #1
+  {
+    \bool_set_true:N \l__cmd_environment_bool
+    \str_set:Nx \l__cmd_environment_str {#1}
+    \__cmd_get_arg_spec_error_aux:n
+      { \cs_if_exist:cTF { \l__cmd_environment_str } }
+  }
+\cs_new_protected:Npn \__cmd_get_arg_spec_error_aux:n #1
+  {
+    #1
+      {
+        \msg_error:nnx { cmd } { non-xparse }
+          { \__cmd_environment_or_command: }
+      }
+      {
+        \msg_error:nnx { cmd } { unknown }
+          { \__cmd_environment_or_command: }
+      }
+  }
+\cs_new_protected:Npn \__cmd_get_arg_spec:NTF #1#2#3
+  {
+    \__kernel_cmd_if_xparse:NTF #1
+      {
+        \tl_set:Nx \ArgumentSpecification { \tl_item:Nn #1 { 2 } }
+        #2
+      }
+      {#3}
+  }
+\tl_new:N \ArgumentSpecification
+\cs_new_protected:Npn \__cmd_get_arg_spec:N #1
+  {
+    \__cmd_get_arg_spec:NTF #1 { }
+      { \__cmd_get_arg_spec_error:N #1 }
+  }
+\cs_new_protected:Npn \__cmd_get_arg_spec:n #1
+  {
+    \exp_args:Nc \__cmd_get_arg_spec:NTF
+      { environment~ \tl_to_str:n {#1} }
+      { }
+      { \__cmd_get_arg_spec_error:n {#1} }
+  }
+\cs_new_protected:Npn \__cmd_show_arg_spec:N #1
+  {
+    \__cmd_get_arg_spec:NTF #1
+      { \tl_show:N \ArgumentSpecification }
+      { \__cmd_get_arg_spec_error:N #1 }
+  }
+\cs_new_protected:Npn \__cmd_show_arg_spec:n #1
+  {
+    \exp_args:Nc \__cmd_get_arg_spec:NTF
+      { environment~ \tl_to_str:n {#1} }
+      { \tl_show:N \ArgumentSpecification }
+      { \__cmd_get_arg_spec_error:n {#1} }
+  }
+\cs_new_protected:Npn \__cmd_check_definable:nNT #1
+  { \tl_trim_spaces_apply:nN {#1} \__cmd_check_definable_aux:nN }
+\group_begin:
+  \char_set_catcode_active:n { `? }
+  \cs_new_protected:Npn \__cmd_check_definable_aux:nN #1#2
+    {
+      \group_begin:
+      \tl_if_single_token:nTF {#1}
+        {
+          \int_set:Nn \tex_escapechar:D { 92 }
+          \exp_args:Nx \tl_if_empty:nTF
+            { \exp_args:No \str_tail:n { \token_to_str:N #1 } }
+            {
+              \exp_args:Nx \char_set_lccode:nn
+                { ` \str_head:n {#1} } { `? }
+              \tex_lowercase:D { \tl_if_eq:nnTF {#1} } { ? }
+                { \group_end: \use_iii:nnn }
+                { \group_end: \use_i:nnn }
+            }
+            { \group_end: \use_iii:nnn }
+        }
+        { \group_end: \use_ii:nnn }
+      {
+        \msg_error:nnxx { cmd } { not-definable }
+          { \tl_to_str:n {#1} } { \token_to_str:N #2 }
+      }
+      {
+        \msg_error:nnxx { cmd } { not-one-token }
+          { \tl_to_str:n {#1} } { \token_to_str:N #2 }
+      }
+    }
+\group_end:
+\cs_new_protected:Npn \__cmd_token_if_cs:NTF #1
+  {
+    \group_begin:
+      \int_set:Nn \tex_escapechar:D { 92 }
+      \exp_args:Nx \tl_if_empty:nTF
+          { \exp_args:No \str_tail:n { \token_to_str:N #1 } }
+        { \group_end: \use_ii:nn }
+        { \group_end: \use_i:nn }
+  }
+\cs_new:Npn \__cmd_tl_mapthread_function:NNN #1#2#3
+  {
+    \exp_after:wN \exp_after:wN
+    \exp_after:wN \__cmd_tl_mapthread_loop:w
+    \exp_after:wN \exp_after:wN
+    \exp_after:wN #3
+    \exp_after:wN #1
+    \exp_after:wN \q_recursion_tail
+    \exp_after:wN \q_mark
+    #2
+    \q_recursion_tail
+    \q_recursion_stop
+  }
+\cs_new:Npn \__cmd_tl_mapthread_function:nnN #1#2#3
+  {
+    \__cmd_tl_mapthread_loop:w #3
+      #1 \q_recursion_tail \q_mark
+      #2 \q_recursion_tail \q_recursion_stop
+  }
+\cs_new:Npn \__cmd_tl_mapthread_loop:w #1#2#3 \q_mark #4
+  {
+    \quark_if_recursion_tail_stop:n {#2}
+    \quark_if_recursion_tail_stop:n {#4}
+    #1 {#2} {#4}
+    \__cmd_tl_mapthread_loop:w #1#3 \q_mark
+  }
+\cs_new_protected:Npn \__kernel_cmd_if_xparse:NTF #1
+  {
+    \exp_args:Nf \str_case_e:nnTF
+      {
+        \exp_args:Nf \tl_if_empty:nT { \cs_argument_spec:N #1 }
+          {
+            \exp_last_unbraced:Nf \__cmd_cmd_if_xparse_aux:w
+              { \cs_replacement_spec:N #1 } ~ \q_stop
+          }
+      }
+      {
+        { \token_to_str:N \__cmd_start:nNNnnn } { }
+        { \token_to_str:N \__cmd_start_expandable:nNNNNn } { }
+        { \token_to_str:N \__cmd_start_env:nnnnn } { }
+      }
+  }
+\cs_new:Npn \__cmd_cmd_if_xparse_aux:w #1 ~ #2 \q_stop {#1}
+\cs_new_protected:Npn \__cmd_peek_nonspace:NTF
+  { \__cmd_peek_nonspace_aux:nNNTF { } \__cmd_peek_meaning:NTF }
+\cs_new_protected:Npn \__cmd_peek_nonspace_remove:NTF
+  { \__cmd_peek_nonspace_aux:nNNTF { } \__cmd_peek_meaning_remove:NTF }
+\cs_new_protected:Npn \__cmd_peek_nonspace_aux:nNNTF #1#2#3#4#5
+  {
+    \peek_meaning_remove:NTF \c_space_token
+      { \__cmd_peek_nonspace_aux:nNNTF { #1 ~ } #2 #3 {#4} {#5} }
+      { #2 #3 { #4 } { #5 #1 } }
+  }
+\cs_new_protected:Npn \__cmd_peek_meaning:NTF
+  { \__cmd_peek_meaning_aux:NNTF \c_false_bool }
+\cs_new_protected:Npn \__cmd_peek_meaning_remove:NTF
+  { \__cmd_peek_meaning_aux:NNTF \c_true_bool }
+\cs_new_protected:Npn \__cmd_peek_meaning_aux:NNTF #1#2#3#4
+  {
+    \tl_set:Nn \l__cmd_tmpa_tl {#3}
+    \tl_set:Nn \l__cmd_tmpb_tl {#4}
+    \peek_meaning:NTF #2
+      {
+        \token_if_eq_meaning:NNTF #2 \c_group_begin_token
+          { \__cmd_peek_true_remove:Nw #1 }
+          {
+            \__cmd_token_if_cs:NTF #2
+              { \__cmd_peek_cs_check_equal:NNN #1 #2 }
+              { \__cmd_peek_true_remove:Nw #1 }
+          }
+      }
+      { \l__cmd_tmpb_tl }
+  }
+\cs_new_protected:Npn \__cmd_peek_cs_check_equal:NNN #1#2#3
+  {
+    \str_if_eq:nnTF {#2} {#3}
+      { \__cmd_peek_true_remove:Nw #1 }
+      { \l__cmd_tmpb_tl }
+    #3
+  }
+\cs_new_protected:Npn \__cmd_peek_true_remove:Nw #1
+  {
+    \bool_if:NTF #1
+      {
+        \tex_afterassignment:D \l__cmd_tmpa_tl
+        \cs_set_eq:NN \__cmd_tmp:w
+      }
+      { \l__cmd_tmpa_tl }
+  }
+\tl_const:Nn \c__cmd_ignore_def_tl
+  { \\ \\ LaTeX~will~ignore~this~entire~definition. }
+\cs_new:Npn \__cmd_environment_or_command:
+  {
+    \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 }
+        '
+      }
+  }
+\msg_new:nnnn { cmd } { arg-after-body }
+  { In~the~definition~of~#1,~b~(body)~argument~must~be~last. }
+  {
+    The~'body'~argument~type~is~followed~by~'#2'~in~the~argument~
+    specification~of~the~#1.~This~is~not~allowed.
+    \c__cmd_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { bad-arg-spec }
+  { Bad~argument~specification~'#2'~for~#1. }
+  {
+    The~argument~specification~provided~was~not~valid:~
+    one~or~more~mandatory~pieces~of~information~were~missing.
+    \c__cmd_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { command-already-defined }
+  { Command~'#1'~already~defined! }
+  {
+    You~have~used~#2~
+    with~a~command~that~already~has~a~definition. \\ \\
+    The~existing~definition~of~'#1'~will~not~be~altered.
+  }
+\msg_new:nnnn { cmd } { command-not-yet-defined }
+  { Command ~'#1'~not~yet~defined! }
+  {
+    You~have~used~#2~
+    with~a~command~that~was~never~defined.
+    \c__cmd_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { environment-already-defined }
+  { Environment~'#1'~already~defined! }
+  {
+    You~have~used~\NewDocumentEnvironment
+    with~an~environment~that~already~has~a~definition. \\ \\
+    The~existing~definition~of~'#1'~will~not~be~altered.
+  }
+\msg_new:nnnn { cmd } { environment-not-yet-defined }
+  { Environment~'#1'~not~yet~defined! }
+  {
+    You~have~used~\RenewDocumentEnvironment
+    with~an~environment~that~was~never~defined.
+    \c__cmd_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { expandable-ending-optional }
+  {
+    Argument~specification~'#2'~for~expandable~command~'#1'~
+    ends~with~optional~argument.
+  }
+  {
+    Expandable~commands~must~have~a~final~mandatory~argument~
+    (or~no~arguments~at~all).~You~cannot~have~a~terminal~optional~
+    argument~with~expandable~commands.
+  }
+\msg_new:nnnn { cmd } { inconsistent-long }
+  { Inconsistent~long~arguments~for~expandable~command~'#1'. }
+  {
+    The~arguments~for~an~expandable~command~must~not~involve~short~
+    arguments~after~long~arguments.~You~have~tried~to~mix~the~two~types.
+  }
+\msg_new:nnnn { cmd } { invalid-command-arg }
+  { Argument~type~'#2'~not~available~for~#1. }
+  {
+    The~letter~'#2'~can~only~be~used~in~environment~argument~
+    specifications,~not~for~commands.
+    \\ \\
+    LaTeX~will~ignore~this~entire~definition.
+  }
+\msg_new:nnnn { cmd } { invalid-expandable-argument-type }
+  { Argument~type~'#2'~not~available~for~expandable~command~'#1'. }
+  {
+    The~letter~'#2'~specifies~an~argument~type~which~cannot~be~used~
+    in~an~expandable~command.
+    \c__cmd_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { invalid-after-optional-expandably }
+  {
+    Argument~type~'#2'~not~available~after~optional~argument~
+    for~expandable~command~'#1'.
+  }
+  {
+    The~letter~'#2'~specifies~an~argument~type~which~cannot~be~used~
+    in~an~expandable~command~after~an~optional~argument.
+    \c__cmd_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { non-trailing-obey-spaces }
+  { Prefix~'!'~used~before~mandatory~argument~'#2'~of~#1. }
+  {
+    The~prefix~'!'~can~only~apply~to~trailing~optional~arguments.
+    \c__cmd_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { not-definable }
+  { First~argument~of~'#2'~must~be~a~command. }
+  {
+    The~first~argument~of~'#2'~should~be~the~document~command~that~will~
+    be~defined.~The~provided~argument~'#1'~is~a~character.~Perhaps~a~
+    backslash~is~missing?
+    \c__cmd_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { not-one-token }
+  { First~argument~of~'#2'~must~be~a~command. }
+  {
+    The~first~argument~of~'#2'~should~be~the~document~command~that~will~
+    be~defined.~The~provided~argument~'#1'~contains~more~than~one~
+    token.~Perhaps~a~backslash~is~missing?
+    \c__cmd_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { not-single-token }
+  {
+    Argument~delimiter~'#2'~for~the~#1~should~be~
+    a~single~non-space~token.
+  }
+  {
+    The~argument~specification~provided~was~not~valid:~in~a~place~
+    where~a~single~token~is~required,~LaTeX~found~'#2'.
+    \c__cmd_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { forbidden-implicit-group-token }
+  { Argument~delimiter~'#2'~for~the~#1~is~not~allowed. }
+  {
+    The~argument~specification~provided~was~not~valid:~the~implicit~
+    #3-group~token~'#2'~is~not~allowed~as~an~argument~delimiter.
+    \c__cmd_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { processor-in-expandable }
+  { Argument~processor~'>{#2}'~cannot~be~used~for~the~expandable~command~'#1'. }
+  {
+    The~argument~specification~for~#1~contains~a~processor~function:~
+    this~is~only~supported~for~standard~robust~commands.
+    \c__cmd_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { too-many-arguments }
+  { Too~many~arguments~in~argument~specification~'#2'~of~#1. }
+  {
+    The~argument~specification~provided~has~more~than~9~arguments.~
+    This~cannot~be~implemented.
+    \c__cmd_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { two-markers }
+  { Two~'#2'~apply~to~the~same~argument~in~argument~specification~of~#1. }
+  {
+    The~argument~specification~provided~has~two~markers~'#2'~applying~
+    to~the~same~argument;~these~are~redundant.
+  }
+\msg_new:nnnn { cmd } { unknown-argument-type }
+  { Unknown~argument~type~'#2'~for~the~#1. }
+  {
+    The~letter~'#2'~does~not~specify~a~known~argument~type.
+    \c__cmd_ignore_def_tl
+  }
+\msg_new:nnnn { cmd } { xparse-argument-type }
+  { Deprecated~argument~type~'#2'~for~the~#1~requires~xparse. }
+  {
+    The~letter~'#2'~specifies~a~known~argument~type~that~requires~
+    the~xparse~package.
+    \c__cmd_ignore_def_tl
+  }
+\msg_new:nnn { cmd } { if-boolean }
+  { Invalid~use~\iow_char:N\\IfBooleanTF~{#1} }
+\msg_new:nnnn { cmd } { loop-in-defaults }
+  { Defaults~of~#1~have~circular~dependency. }
+  {
+    The~default~values~of~two~or~more~arguments~of~the~#1~
+    depend~on~each~other~in~a~way~that~cannot~be~resolved.
+  }
+\msg_new:nnnn { cmd } { missing-required }
+  { Missing~required~argument~for~#1. }
+  {
+    The~current~#1~expects~an~argument~starting~with~'#2'.~
+    LaTeX~did~not~find~it,~and~will~insert~a~default~value~to~be~processed.
+  }
+\msg_new:nnnn { cmd } { non-xparse }
+  { \str_uppercase:n #1~not~defined~using~xparse. }
+  {
+    You~have~asked~for~the~argument~specification~for~the~#1,~
+    but~this~was~not~defined~using~xparse.
+  }
+\msg_new:nnnn { cmd } { split-excess-tokens }
+  { Too~many~'#1'~tokens~when~trying~to~split~argument. }
+  {
+    LaTeX~was~asked~to~split~the~input~'#3'~
+    at~each~occurrence~of~the~token~'#1',~up~to~a~maximum~of~#2~parts.~
+    There~were~too~many~'#1'~tokens.
+  }
+\msg_new:nnnn { cmd } { unknown }
+  { Unknown~document~#1. }
+  {
+    You~have~asked~for~the~argument~specification~for~the~#1,~
+    but~it~is~not~defined.
+  }
+\msg_new:nnnn { cmd } { verbatim-newline }
+  { Verbatim~argument~of~#1~ended~by~end~of~line. }
+  {
+    The~verbatim~argument~of~the~#1~cannot~contain~more~than~one~line,~
+    but~the~end~
+    of~the~current~line~has~been~reached.~You~may~have~forgotten~the~
+    closing~delimiter.
+    \\ \\
+    LaTeX~will~ignore~'#2'.
+  }
+\msg_new:nnnn { cmd } { verbatim-tokenized }
+  { The~verbatim~#1~cannot~be~used~inside~an~argument. }
+  {
+    The~#1~takes~a~verbatim~argument.~
+    It~may~not~appear~within~the~argument~of~another~function.~
+    It~received~an~illegal~token \tl_if_empty:nF {#3} { ~'#3' } .
+    \\ \\
+    LaTeX~will~ignore~'#2'.
+  }
+\msg_new:nnn { cmd } { define-command }
+  {
+    Defining~command~#1~
+    with~sig.~'#2'~\msg_line_context:.
+  }
+\msg_new:nnn { cmd } { define-environment }
+  {
+    Defining~environment~'#1'~
+    with~sig.~'#2'~\msg_line_context:.
+  }
+\msg_new:nnn { cmd } { redefine-command }
+  {
+    Redefining~command~#1~
+    with~sig.~'#2'~\msg_line_context:.
+  }
+\msg_new:nnn { cmd } { redefine-environment }
+  {
+    Redefining~environment~'#1'~
+    with~sig.~'#2'~\msg_line_context:.
+  }
+\msg_new:nnn { cmd } { optional-mandatory }
+  {
+    Since~the~mandatory~argument~'#1'~has~the~same~delimiter~'#2'~
+    as~a~previous~optional~argument,~it~will~not~be~possible~to~
+    omit~all~optional~arguments~when~calling~this~command.
+  }
+\msg_new:nnn { cmd } { unsupported-let }
+  {
+    The~command~'#1'~was~undefined~but~not~the~associated~commands~
+    '#1~code'~and/or~'#1~defaults'.~Maybe~you~tried~using~
+    \iow_char:N\\let.~This~may~lead~to~an~infinite~loop.
+  }
+\cs_new_eq:NN \BooleanFalse \c_false_bool
+\cs_new_eq:NN \BooleanTrue  \c_true_bool
+\cs_new_protected:Npn \NewDocumentCommand #1#2#3
+  {
+    \__cmd_check_definable:nNT {#1} \NewDocumentCommand
+      {
+        \cs_if_exist:NTF #1
+          {
+            \msg_error:nnxx { cmd } { command-already-defined }
+              { \use:nnn \token_to_str:N #1 { } }
+              { \token_to_str:N \NewDocumentCommand }
+          }
+          { \__cmd_declare_cmd:Nnn #1 {#2} {#3} }
+      }
+  }
+\cs_new_protected:Npn \RenewDocumentCommand #1#2#3
+  {
+    \__cmd_check_definable:nNT {#1} \RenewDocumentCommand
+      {
+        \cs_if_exist:NTF #1
+          { \__cmd_declare_cmd:Nnn #1 {#2} {#3} }
+          {
+            \msg_error:nnxx { cmd } { command-not-yet-defined }
+              { \use:nnn \token_to_str:N #1 { } }
+              { \token_to_str:N \RenewDocumentCommand }
+          }
+      }
+  }
+\cs_new_protected:Npn \ProvideDocumentCommand #1#2#3
+  {
+    \__cmd_check_definable:nNT {#1} \ProvideDocumentCommand
+      { \cs_if_exist:NF #1 { \__cmd_declare_cmd:Nnn #1 {#2} {#3} } }
+ }
+\cs_new_protected:Npn \DeclareDocumentCommand #1#2#3
+  {
+    \__cmd_check_definable:nNT {#1} \DeclareDocumentCommand
+      { \__cmd_declare_cmd:Nnn #1 {#2} {#3} }
+  }
+\cs_new_protected:Npn \NewDocumentEnvironment #1#2#3#4
+  {
+    \cs_if_exist:cTF {#1}
+      { \msg_error:nnx { cmd } { environment-already-defined } {#1} }
+      { \__cmd_declare_env:nnnn {#1} {#2} {#3} {#4} }
+  }
+\cs_new_protected:Npn \RenewDocumentEnvironment #1#2#3#4
+  {
+    \cs_if_exist:cTF {#1}
+      { \__cmd_declare_env:nnnn {#1} {#2} {#3} {#4} }
+      { \msg_error:nnx { cmd } { environment-not-yet-defined } {#1} }
+  }
+\cs_new_protected:Npn \ProvideDocumentEnvironment #1#2#3#4
+  { \cs_if_exist:cF {#1} { \__cmd_declare_env:nnnn {#1} {#2} {#3} {#4} } }
+\cs_new_protected:Npn \DeclareDocumentEnvironment #1#2#3#4
+  { \__cmd_declare_env:nnnn {#1} {#2} {#3} {#4} }
+\cs_new_protected:Npn \NewExpandableDocumentCommand #1#2#3
+  {
+    \__cmd_check_definable:nNT {#1} \NewExpandableDocumentCommand
+      {
+        \cs_if_exist:NTF #1
+          {
+            \msg_error:nnxx { cmd } { command-already-defined }
+              { \use:nnn \token_to_str:N #1 { } }
+              { \token_to_str:N \NewExpandableDocumentCommand }
+          }
+          { \__cmd_declare_expandable_cmd:Nnn #1 {#2} {#3} }
+      }
+  }
+\cs_new_protected:Npn \RenewExpandableDocumentCommand #1#2#3
+  {
+    \__cmd_check_definable:nNT {#1} \RenewExpandableDocumentCommand
+      {
+        \cs_if_exist:NTF #1
+          { \__cmd_declare_expandable_cmd:Nnn #1 {#2} {#3} }
+          {
+            \msg_error:nnxx { cmd } { command-not-yet-defined }
+              { \use:nnn \token_to_str:N #1 { } }
+              { \token_to_str:N \RenewExpandableDocumentCommand }
+          }
+      }
+  }
+\cs_new_protected:Npn \ProvideExpandableDocumentCommand #1#2#3
+  {
+    \__cmd_check_definable:nNT {#1} \ProvideExpandableDocumentCommand
+      {
+        \cs_if_exist:NF #1
+          { \__cmd_declare_expandable_cmd:Nnn #1 {#2} {#3} }
+      }
+ }
+\cs_new_protected:Npn \DeclareExpandableDocumentCommand #1#2#3
+  {
+    \__cmd_check_definable:nNT {#1} \DeclareExpandableDocumentCommand
+      { \__cmd_declare_expandable_cmd:Nnn #1 {#2} {#3} }
+  }
+\cs_new:Npn \IfBooleanTF #1
+  {
+    \tl_if_single:nF {#1}
+      { \prg_break:n { \use:n } }
+    \tl_if_single_token:nF #1
+      { \prg_break:n { \use:n } }
+    \token_if_eq_meaning:NNT #1 \c_true_bool
+      { \prg_break:n { \use_ii:nnn } }
+    \token_if_eq_meaning:NNT #1 \c_false_bool
+      { \prg_break:n { \use_iii:nnn } }
+    \prg_break:n { \use:n }
+    \prg_break_point:
+    {
+      \msg_expandable_error:nnn { cmd } { if-boolean } {#1}
+      \use_ii:nn
+    }
+  }
+\cs_new:Npn \IfBooleanT #1#2 { \IfBooleanTF {#1} {#2} { } }
+\cs_new:Npn \IfBooleanF #1 { \IfBooleanTF {#1} { } }
+\cs_new_eq:NN \IfNoValueF  \tl_if_novalue:nF
+\cs_new_eq:NN \IfNoValueT  \tl_if_novalue:nT
+\cs_new_eq:NN \IfNoValueTF \tl_if_novalue:nTF
+\cs_new:Npn \IfValueF { \tl_if_novalue:nT }
+\cs_new:Npn \IfValueT { \tl_if_novalue:nF }
+\cs_new:Npn \IfValueTF #1#2#3 { \tl_if_novalue:nTF {#1} {#3} {#2} }
+\tl_new:N \ProcessedArgument
+\cs_new_eq:NN \ReverseBoolean \__cmd_bool_reverse:N
+\cs_new_eq:NN \SplitArgument  \__cmd_split_argument:nnn
+\cs_new_eq:NN \SplitList      \__cmd_split_list:nn
+\cs_new_eq:NN \TrimSpaces     \__cmd_trim_spaces:n
+\cs_new_eq:NN \ProcessList \tl_map_function:nN
+\cs_new_protected:Npn \GetDocumentCommandArgSpec #1
+  {
+    \__cmd_check_definable:nNT {#1} \GetDocumentCommandArgSpec
+      { \__cmd_get_arg_spec:N #1 }
+  }
+\cs_new_eq:NN \GetDocumentEnvironmentArgSpec \__cmd_get_arg_spec:n
+\cs_new_protected:Npn \ShowDocumentCommandArgSpec #1
+  {
+    \__cmd_check_definable:nNT {#1} \ShowDocumentCommandArgSpec
+      { \__cmd_show_arg_spec:N #1 }
+  }
+\cs_new_eq:NN \ShowDocumentEnvironmentArgSpec \__cmd_show_arg_spec:n
+\ExplSyntaxOff
 %%% From File: lthooks.dtx
-\def\lthooksversion{v1.0h}
-\def\lthooksdate{2021/01/07}
+\def\lthooksversion{v1.0n}
+\def\lthooksdate{2021/05/26}
+
 \ExplSyntaxOn
 \bool_new:N \g__hook_debug_bool
 \cs_new_eq:NN \__hook_debug:n \use_none:n
@@ -1696,24 +3993,34 @@
 \cs_new_protected:Npn \__hook_tl_gclear:N #1
   { \__hook_tl_gset_eq:NN #1 \c_empty_tl }
 \cs_generate_variant:Nn \__hook_tl_gclear:N { c }
+
+
 \cs_new_protected:Npn \hook_new:n #1
   { \__hook_normalize_hook_args:Nn \__hook_new:n {#1} }
 \cs_new_protected:Npn \__hook_new:n #1
   {
-    \hook_if_exist:nTF {#1}
+    \__hook_if_declared:nTF {#1}
       { \msg_error:nnn { hooks } { exists } {#1} }
       {
+        \tl_new:c { g__hook_#1_declared_tl }
+        \__hook_make_usable:n {#1}
+      }
+  }
+\cs_new_protected:Npn \__hook_make_usable:n #1
+  {
+    \tl_if_exist:cF { __hook~#1 }
+      {
         \seq_gput_right:Nn \g__hook_all_seq {#1}
         \tl_new:c { __hook~#1 }
-        \__hook_declare:n {#1}
-        \clist_new:c {g__hook_#1_labels_clist}
+        \__hook_init_structure:n {#1}
+        \clist_new:c { g__hook_#1_labels_clist }
         \tl_new:c { g__hook_#1_reversed_tl }
         \__hook_include_legacy_code_chunk:n {#1}
-     }
+      }
   }
-\cs_new_protected:Npn \__hook_declare:n #1
+\cs_new_protected:Npn \__hook_init_structure:n #1
   {
-    \__hook_if_exist:nF {#1}
+    \__hook_if_structure_exist:nF {#1}
       {
         \prop_new:c { g__hook_#1_code_prop }
         \tl_new:c { __hook_toplevel~#1 }
@@ -1741,6 +4048,44 @@
           }
       }
   }
+\cs_new_protected:Npn \hook_disable:n #1
+  { \__hook_normalize_hook_args:Nn \__hook_disable:n {#1} }
+\cs_new_protected:Npn \__hook_disable:n #1
+  {
+    \tl_gclear_new:c { g__hook_#1_declared_tl }
+    \cs_undefine:c { __hook~#1 }
+  }
+\prg_new_conditional:Npnn \__hook_if_disabled:n #1 { p, T, F, TF }
+  {
+    \bool_lazy_and:nnTF
+        { \tl_if_exist_p:c { g__hook_#1_declared_tl } }
+        { ! \tl_if_exist_p:c { __hook~#1 } }
+      { \prg_return_true: }
+      { \prg_return_false: }
+  }
+\cs_new_protected:Npn \hook_provide:n #1
+  { \__hook_normalize_hook_args:Nn \__hook_provide:nn {#1} {   } }
+\cs_new_protected:Npn \hook_provide_reversed:n #1
+  { \__hook_normalize_hook_args:Nn \__hook_provide:nn {#1} { - } }
+\cs_new_protected:Npn \__hook_provide:nn #1 #2
+  {
+    \__hook_if_disabled:nTF {#1}
+      { \msg_warning:nnn { hooks } { provide-disabled } {#1} }
+      {
+        \__hook_if_declared:nTF {#1}
+          {
+            \str_if_eq:eeF { \tl_use:c { g__hook_#1_reversed_tl } } {#2}
+              { \msg_error:nnn { hooks } { provide-error } {#1} }
+          }
+          {
+            \tl_new:c { g__hook_#1_declared_tl }
+            \__hook_make_usable:n {#1}
+            \tl_gset:cn { g__hook_#1_reversed_tl } {#2}
+          }
+      }
+  }
+\cs_new_protected:Npn \hook_provide_pair:nn #1#2
+  { \hook_provide:n {#1} \hook_provide_reversed:n {#2} }
 \cs_new:Npn \__hook_parse_label_default:n #1
   {
     \tl_if_novalue:nTF {#1}
@@ -1779,7 +4124,7 @@
       {
         \tl_if_empty:NTF \@currname
           {
-            \msg_expandable_error:nnn { hooks } { should-not-happen }
+            \msg_expandable_error:nnn { kernel } { should-not-happen }
               { Empty~default~label. }
             \__hook_make_name:n { label-missing }
           }
@@ -1836,12 +4181,16 @@
         \__hook_if_marked_removal:nnTF {#1} {#2}
           { \__hook_unmark_removal:nn {#1} {#2} }
           {
-            \hook_if_exist:nTF {#1}
+            \__hook_if_usable:nTF {#1}
               {
                 \__hook_hook_gput_code_do:nnn {#1} {#2} {#3}
                 \__hook_update_hook_code:n {#1}
               }
-              { \__hook_try_declaring_generic_hook:nnn {#1} {#2} {#3} }
+              {
+                \__hook_if_disabled:nTF {#1}
+                  { \msg_error:nnn { hooks } { hook-disabled } {#1} }
+                  { \__hook_try_declaring_generic_hook:nnn {#1} {#2} {#3} }
+              }
           }
       }
   }
@@ -1849,7 +4198,7 @@
 \cs_new_protected:Npn \__hook_hook_gput_code_do:nnn #1 #2 #3
   {
     \__hook_debug:n{\iow_term:x{****~ Add~ to~
-                      \hook_if_exist:nF {#1} { undeclared~ }
+                      \__hook_if_usable:nF {#1} { undeclared~ }
                       hook~ #1~ (#2)
                       \on at line\space <-~ \tl_to_str:n{#3}} }
     \str_if_eq:nnTF {#2} { top-level }
@@ -1856,7 +4205,7 @@
       {
         \str_if_eq:eeTF { top-level } { \__hook_currname_or_default: }
           {
-            \__hook_declare:n {#1}
+            \__hook_init_structure:n {#1}
             \__hook_tl_gput_right:cn { __hook_toplevel~#1 } {#3}
           }
           { \msg_error:nnn { hooks } { misused-top-level } {#1} }
@@ -1872,7 +4221,7 @@
   }
 \cs_new_protected:Npn \__hook_gput_undeclared_hook:nnn #1 #2 #3
   {
-    \__hook_declare:n {#1}
+    \__hook_init_structure:n {#1}
     \__hook_hook_gput_code_do:nnn {#1} {#2} {#3}
   }
 \cs_new_protected:Npn \__hook_try_declaring_generic_hook:nnn #1
@@ -1908,7 +4257,12 @@
       {
         \prop_if_in:NnTF \c__hook_generics_prop {#1}
           {
-            \hook_if_exist:nF {#5} { \hook_new:n {#5} }
+            \__hook_if_usable:nF {#5}
+              {
+                \str_if_eq:nnT {#1} { cmd }
+                  { \__hook_try_put_cmd_hook:n {#5} }
+                \__hook_make_usable:n {#5}
+              }
             \prop_if_in:NnTF \c__hook_generics_reversed_ii_prop {#2}
               { \tl_gset:cn { g__hook_#5_reversed_tl } { - } }
               {
@@ -1948,7 +4302,7 @@
       { \__hook_strip_double_slash:w #1/#2/#3 / #4 \s__hook_mark }
   }
 \prop_const_from_keyval:Nn \c__hook_generics_prop
-  {env=,file=,package=,class=,include=}
+     {cmd=,env=,file=,package=,class=,include=}
 \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=}
@@ -1956,7 +4310,7 @@
   { \__hook_normalize_hook_args:Nnn \__hook_gremove_code:nn {#1} {#2} }
 \cs_new_protected:Npn \__hook_gremove_code:nn #1 #2
   {
-    \__hook_if_exist:nTF {#1}
+    \__hook_if_structure_exist:nTF {#1}
       {
         \str_if_eq:nnTF {#2} {*}
           {
@@ -1974,7 +4328,7 @@
                       {#1} {#2}
               }
           }
-        \hook_if_exist:nT {#1}
+        \__hook_if_usable:nT {#1}
           { \__hook_update_hook_code:n {#1} }
       }
       { \__hook_mark_removal:nn {#1} {#2} }
@@ -2009,7 +4363,7 @@
   }
 \cs_new_protected:Npn \__hook_gset_rule:nnnn #1#2#3#4
   {
-    \__hook_declare:n {#1}
+    \__hook_init_structure:n {#1}
     \__hook_rule_gclear:nnn {#1} {#2} {#4}
     \cs_if_exist_use:cTF { __hook_rule_#3_gset:nnn }
       {
@@ -2037,9 +4391,11 @@
       { \__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 } }
@@ -2055,7 +4411,7 @@
   {
     \if_int_compare:w \__hook_str_compare:nn {#1} {#2} > 0 \exp_stop_f:
       \prg_return_true:
-    \else
+    \else:
       \prg_return_false:
     \fi:
   }
@@ -2089,7 +4445,7 @@
     \__hook_debug:n{ \iow_term:x{^^JUpdate~ code~ for~ hook~
                                     '#1' \on at line :^^J} }
     \__hook_include_legacy_code_chunk:n {#1}
-    \hook_if_exist:nT {#1}
+    \__hook_if_usable:nT {#1}
       {
         \prop_if_empty:cTF {g__hook_#1_code_prop}
           {
@@ -2309,8 +4665,10 @@
   {
     \__hook_preamble_hook:n {#1}
     \__hook_log_cmd:x { ^^J ->~The~hook~'#1': }
-    \hook_if_exist:nF {#1}
-      { \__hook_log_line:x { is~not~declared! } }
+    \__hook_if_usable:nF {#1}
+      { \__hook_log_line:x { The~hook~is~not~declared. } }
+    \__hook_if_disabled:nT {#1}
+      { \__hook_log_line:x { The~hook~is~disabled. } }
     \hook_if_empty:nTF {#1}
       { #2 { The~hook~is~empty } }
       {
@@ -2324,7 +4682,7 @@
         \__hook_log_line:x
           {
             Document-level~(top-level)~code
-            \hook_if_exist:nT {#1}
+            \__hook_if_usable:nT {#1}
               { ~(executed~\__hook_if_reversed:nTF {#1} {first} {last} ) } :
           }
         \__hook_log_line_indent:x
@@ -2355,7 +4713,7 @@
         \bool_if:NT \l__hook_tmpa_bool
           { \__hook_log_line_indent:x { --- } }
         \bool_lazy_and:nnTF
-            { \hook_if_exist_p:n {#1} }
+            { \__hook_if_usable_p:n {#1} }
             { ! \hook_if_empty_p:n {#1} }
           {
             \__hook_log_line:x
@@ -2377,10 +4735,12 @@
               }
           }
           {
+            \__hook_log_line:x { Execution~order: }
             #2
               {
-                Hook~ \hook_if_exist:nTF {#1}
-                  {code~pool~empty} {not~declared}
+                \@spaces Not~set~because~the~hook~ \__hook_if_usable:nTF {#1}
+                  { code~pool~is~empty }
+                  { is~\__hook_if_disabled:nTF {#1} {disabled} {undeclared} }
               }
           }
       }
@@ -2436,10 +4796,14 @@
   { \__hook_normalize_hook_args:Nn \__hook_gput_next_code:nn {#1} }
 \cs_new_protected:Npn \__hook_gput_next_code:nn #1 #2
   {
-    \__hook_declare:n {#1}
-    \hook_if_exist:nTF {#1}
-      { \__hook_gput_next_do:nn {#1} {#2} }
-      { \__hook_try_declaring_generic_next_hook:nn {#1} {#2} }
+    \__hook_if_disabled:nTF {#1}
+      { \msg_error:nnn { hooks } { hook-disabled } {#1} }
+      {
+        \__hook_init_structure:n {#1}
+        \__hook_if_usable:nTF {#1}
+          { \__hook_gput_next_do:nn {#1} {#2} }
+          { \__hook_try_declaring_generic_next_hook:nn {#1} {#2} }
+      }
   }
 \cs_new_protected:Npn \__hook_gput_next_do:nn #1
   {
@@ -2491,12 +4855,12 @@
   {
     \__hook_if_file_hook:wTF #1 / / \s__hook_mark
       {
-        \exp_args:Ne \__hook_if_exist_use:n
+        \exp_args:Ne \__hook_if_usable_use:n
           { \exp_args:Ne \__hook_file_hook_normalize:n {#1} }
       }
-      { \__hook_if_exist_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_exist_use:n #1
+\cs_new_protected:Npn \__hook_if_usable_use:n #1
   {
     \tl_if_exist:cT { __hook~#1 }
       {
@@ -2516,9 +4880,10 @@
   }
 \cs_new_protected:Npn \__hook_use_once_store:n #1
   { \prop_gput:Nnn \g__hook_execute_immediately_prop {#1} { } }
+
 \prg_new_conditional:Npnn \hook_if_empty:n #1 { p , T , F , TF }
   {
-    \__hook_if_exist:nTF {#1}
+    \__hook_if_structure_exist:nTF {#1}
       {
         \bool_lazy_and:nnTF
             { \prop_if_empty_p:c { g__hook_#1_code_prop } }
@@ -2532,18 +4897,24 @@
       }
       { \prg_return_true: }
   }
-\prg_new_conditional:Npnn \hook_if_exist:n #1 { p , T , F , TF }
+\prg_new_conditional:Npnn \__hook_if_usable:n #1 { p , T , F , TF }
   {
     \tl_if_exist:cTF { __hook~#1 }
       { \prg_return_true: }
       { \prg_return_false: }
   }
-\prg_new_conditional:Npnn \__hook_if_exist:n #1 { p , T , F , TF }
+\prg_new_conditional:Npnn \__hook_if_structure_exist:n #1 { p , T , F , TF }
   {
     \prop_if_exist:cTF { g__hook_#1_code_prop }
       { \prg_return_true: }
       { \prg_return_false: }
   }
+\prg_new_conditional:Npnn \__hook_if_declared:n #1 { p, T, F, TF }
+  {
+    \tl_if_exist:cTF { g__hook_#1_declared_tl }
+      { \prg_return_true: }
+      { \prg_return_false: }
+  }
 \prg_new_conditional:Npnn \__hook_if_reversed:n #1 { p , T , F , TF }
   {
     \if_int_compare:w \cs:w g__hook_#1_reversed_tl \cs_end: 1 < 0 \exp_stop_f:
@@ -2552,10 +4923,12 @@
       \prg_return_false:
     \fi:
   }
+\prop_gput:Nnn \g_msg_module_type_prop { hooks } { LaTeX }
+\prop_gput:Nnn \g_msg_module_type_prop { kernel } { LaTeX }
 \msg_new:nnnn { hooks } { labels-incompatible }
   {
-    Labels~`#1'~and~`#2'~are~incompatible
-    \str_if_eq:nnF {#3} {??} { ~in~hook~`#3' } .~
+    Labels~'#1'~and~'#2'~are~incompatible
+    \str_if_eq:nnF {#3} {??} { ~in~hook~'#3' } .~
     \int_compare:nNnTF {#4} = { 1 }
       { The~ code~ for~ both~ labels~ will~ be~ dropped. }
       { You~ may~ see~ errors~ later. }
@@ -2563,14 +4936,21 @@
   { LaTeX~found~two~incompatible~labels~in~the~same~hook.~
     This~indicates~an~incompatibility~between~packages.  }
 \msg_new:nnnn { hooks } { exists }
-    { Hook~`#1'~ has~ already~ been~ declared. }
+    { Hook~'#1'~ has~ already~ been~ declared. }
     { There~ already~ exists~ a~ hook~ declaration~ with~ this~
       name.\\
       Please~ use~ a~ different~ name~ for~ your~ hook.}
+\msg_new:nnnn { hooks } { hook-disabled }
+  { Cannot~add~code~to~disabled~hook~'#1'. }
+  {
+    The~hook~'#1'~you~tried~to~add~code~to~was~previously~disabled~
+    with~\iow_char:N\\hook_disable:n~or~\iow_char:N\\DisableHook,~so~
+    it~cannot~have~code~added~to~it.
+  }
 \msg_new:nnn { hooks } { empty-label }
   {
     Empty~code~label~\msg_line_context:.~
-    Using~`\__hook_currname_or_default:'~instead.
+    Using~'\__hook_currname_or_default:'~instead.
   }
 \msg_new:nnn { hooks } { no-default-label }
   {
@@ -2578,23 +4958,23 @@
     This~command~was~ignored.
   }
 \msg_new:nnnn { hooks } { unknown-rule }
-  { Unknown~ relationship~ `#3'~
-    between~ labels~ `#2'~ and~ `#4'~
-    \str_if_eq:nnF {#1} {??} { ~in~hook~`#1' }. ~
+  { Unknown~ relationship~ '#3'~
+    between~ labels~ '#2'~ and~ '#4'~
+    \str_if_eq:nnF {#1} {??} { ~in~hook~'#1' }. ~
     Perhaps~ a~ missspelling?
   }
   {
     The~ relation~ used~ not~ known~ to~ the~ system.~ Allowed~ values~ are~
-    `before'~ or~ `<',~
-    `after'~ or~ `>',~
-    `incompatible-warning',~
-    `incompatible-error',~
-    `voids'~ or~
-    `unrelated'.
+    'before'~ or~ '<',~
+    'after'~ or~ '>',~
+    'incompatible-warning',~
+    'incompatible-error',~
+    'voids'~ or~
+    'unrelated'.
   }
 \msg_new:nnnn { hooks } { misused-top-level }
   {
-    Illegal~\iow_char:N \\AddToHook{#1}[top-level]{...}.\\
+    Illegal~use~of~\iow_char:N \\AddToHook{#1}[top-level]{...}.\\
     'top-level'~is~reserved~for~the~user's~document.
   }
   {
@@ -2605,16 +4985,10 @@
   }
 \msg_new:nnn { hooks } { set-top-level }
   {
-    You~cannot~change~the~default~label~#1~`top-level'.~Illegal \\
+    You~cannot~change~the~default~label~#1~'top-level'.~Illegal \\
     \use:nn { ~ } { ~ } \iow_char:N \\#2{#3} \\
     \msg_line_context:.
   }
-\msg_new:nnn { hooks } { ddhl-deprecated }
-  {
-    \iow_char:N \\DeclareDefaultHookLabel~is~deprecated.\\
-    Use~\iow_char:N \\SetDefaultHookLabel~instead.\\ \\
-    The~deprecated~name~will~be~removed~in~the~next~release.
-  }
 \msg_new:nnn { hooks } { extra-pop-label }
   {
     Extra~\iow_char:N \\PopDefaultHookLabel. \\
@@ -2623,16 +4997,36 @@
 \msg_new:nnn { hooks } { missing-pop-label }
   {
     Missing~\iow_char:N \\PopDefaultHookLabel. \\
-    The~label~`#1'~was~pushed~but~never~popped.~Something~is~wrong.
+    The~label~'#1'~was~pushed~but~never~popped.~Something~is~wrong.
   }
-\msg_new:nnn { hooks } { should-not-happen }
+\msg_new:nnn { kernel } { should-not-happen }
   {
-    ERROR!~This~should~not~happen.~#1 \\
+    This~should~not~happen.~#1 \\
     Please~report~at~https://github.com/latex3/latex2e.
   }
+\msg_new:nnn { hooks } { provide-disabled }
+  {
+    Cannot~ provide~ hook~ '#1'~ because~ it~ is~ disabled!
+  }
+\msg_new:nnnn { hooks } { provide-error }
+  {
+    Hook~'#1'~ already~ declared~ as~ a~
+    \__hook_if_reversed:nTF {#1} { reversed } { normal }~ hook!
+  }
+  {
+    You~ attempted~ to~ provide~ the~ hook~'#1'~ as~ a~
+    \__hook_if_reversed:nTF {#1} { normal } { reversed }~ hook,~ but~ it~
+    was~ already~ previously~ declared~ as~ a~
+    \__hook_if_reversed:nTF {#1} { reversed } { normal }~ hook.~
+    A~ redeclaration~ is~ not~ possible.
+  }
 \NewDocumentCommand \NewHook             { m }{ \hook_new:n {#1} }
 \NewDocumentCommand \NewReversedHook     { m }{ \hook_new_reversed:n {#1} }
 \NewDocumentCommand \NewMirroredHookPair { mm }{ \hook_new_pair:nn {#1}{#2} }
+\NewDocumentCommand \ProvideHook         { m }{ \hook_provide:n {#1} }
+\NewDocumentCommand \ProvideReversedHook { m }{ \hook_provide_reversed:n {#1} }
+\NewDocumentCommand \ProvideMirroredHookPair { mm }{ \hook_provide_pair:nn {#1}{#2} }
+\NewDocumentCommand \DisableHook { m }{ \hook_disable:n {#1} }
 \NewDocumentCommand \AddToHook { m o +m }
   { \hook_gput_code:nnn {#1} {#2} {#3} }
 \NewDocumentCommand \AddToHookNext { m +m }
@@ -2694,11 +5088,6 @@
       }
       { \tl_gset:Nn \g__hook_hook_curr_name_tl {#1} }
   }
-\NewDocumentCommand \DeclareDefaultHookLabel { m }
-  {
-    \msg_error:nn { hooks } { ddhl-deprecated }
-    \SetDefaultHookLabel {#1}
-  }
 \NewDocumentCommand \PushDefaultHookLabel { m }
   { \__hook_curr_name_push:n {#1} }
 \NewDocumentCommand \PopDefaultHookLabel { }
@@ -2722,9 +5111,9 @@
 \@onlypreamble\DeclareDefaultHookRule
 \NewDocumentCommand \ClearHookRule { m m m }
 { \hook_gset_rule:nnnn {#1}{#2}{unrelated}{#3} }
-\cs_new_eq:NN \IfHookExistsTF \hook_if_exist:nTF
 \cs_new_eq:NN \IfHookEmptyTF \hook_if_empty:nTF
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%5
+\cs_new_eq:NN \IfHookExistsTF \__hook_if_usable:nTF
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \cs_new_eq:NN \@expl@@@initialize at all@@
               \__hook_initialize_all:
 \cs_new_eq:NN \@expl@@@hook at curr@name at pop@@
@@ -2731,6 +5120,316 @@
               \__hook_curr_name_pop:
 \ExplSyntaxOff
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%% File: ltcmdhooks.dtx (C) Copyright 2020-2021
+%%       Frank Mittelbach, Phelype Oleinik, LaTeX Team
+%%% From File: ltcmdhooks.dtx
+\def\ltcmdhooksversion{v1.0b}
+\def\ltcmdhooksdate{2021/05/26}
+\ExplSyntaxOn
+\tl_new:N \g_hook_patch_action_list_tl
+\int_new:N \l__hook_patch_num_args_int
+\tl_new:N \l__hook_patch_prefixes_tl
+\tl_new:N \l__hook_patch_param_text_tl
+\tl_new:N \l__hook_patch_replacement_tl
+\prop_new:N \g__hook_delayed_patches_prop
+\cs_new_protected:Npn \__hook_patch_debug:x #1
+  { \__hook_debug:n { \iow_term:x { [lthooks]~#1 } } }
+\cs_generate_variant:Nn \tl_rescan:nn { nV }
+\cs_new_protected:Npn \__hook_try_put_cmd_hook:n #1
+  { \__hook_try_put_cmd_hook:w #1 / / / \s__hook_mark {#1} }
+\cs_new_protected:Npn \__hook_try_put_cmd_hook:w
+    #1 / #2 / #3 / #4 \s__hook_mark #5
+  {
+    \__hook_debug:n { \iow_term:n { ->~Adding~cmd~hook~to~'#2'~(#3): } }
+    \str_case:nnTF {#3}
+        { { before } { } { after } { } }
+      { \exp_args:Nc \__hook_patch_cmd_or_delay:Nnn {#2} {#2} {#3} }
+      { \msg_error:nnnn { hooks } { wrong-cmd-hook } {#2} {#3} }
+  }
+\cs_new_protected:Npn \__hook_patch_cmd_or_delay:Nnn #1 #2 #3
+  {
+    \__hook_debug:n { \iow_term:n { ->~Add~generic~cmd~hook~for~#2~(#3). } }
+    \__hook_debug:n
+      { \iow_term:n { !~In~the~preamble:~delaying. } }
+    \prop_gput:Nnn \g__hook_delayed_patches_prop { #2 / #3 }
+      { \__hook_cmd_try_patch:nn {#2} {#3} }
+  }
+\cs_new_protected:Npn \__hook_cmd_begindocument_code:
+  {
+    \cs_gset_eq:NN \__hook_patch_cmd_or_delay:Nnn \__hook_patch_command:Nnn
+    \prop_map_function:NN \g__hook_delayed_patches_prop { \use_ii:nn }
+    \prop_gclear:N \g__hook_delayed_patches_prop
+    \cs_undefine:N \__hook_cmd_begindocument_code:
+  }
+\g at addto@macro \@kernel at after@begindocument
+  { \__hook_cmd_begindocument_code: }
+\cs_new_protected:Npn \__hook_cmd_try_patch:nn #1 #2
+  {
+    \__hook_debug:n
+      { \iow_term:x { ->~\string\begin{document}~try~cmd / #1 / #2. } }
+    \__hook_if_declared:nTF { cmd / #1 / #2 }
+      {
+        \__hook_debug:n
+          { \iow_term:n { .->~Giving~up:~hook~already~created. } }
+      }
+      {
+        \cs_if_exist:cT {#1}
+          { \exp_args:Nc \__hook_patch_command:Nnn {#1} {#1} {#2} }
+      }
+  }
+\cs_new_protected:Npn \__hook_patch_command:Nnn #1 #2 #3
+  {
+    \__hook_patch_debug:x { analyzing~'\token_to_str:N #1' }
+    \__hook_patch_debug:x { \token_to_str:N #1 = \token_to_meaning:N #1 }
+    \__hook_patch_check:NNnn \cs_if_exist:NTF #1 { undef }
+      {
+        \__hook_patch_debug:x { ++~control~sequence~is~defined }
+        \__hook_patch_check:NNnn \token_if_macro:NTF #1 { macro }
+          {
+            \__hook_patch_debug:x { ++~control~sequence~is~a~macro }
+            \__hook_patch_check:NNnn \__hook_if_public_command:NTF #1 { expl3 }
+              {
+                \__hook_patch_debug:x { ++~macro~is~not~private }
+                \robust at command@act
+                  \g_hook_patch_action_list_tl #1
+                  \__hook_retokenize_patch:Nnn { #1 {#2} {#3} }
+              }
+          }
+      }
+  }
+\cs_new_protected:Npn \__hook_patch_check:NNnn #1 #2 #3 #4
+  {
+    #1 #2 {#4}
+      {
+        \msg_error:nnxx { hooks } { cant-patch }
+          { \token_to_str:N #2 } {#3}
+      }
+  }
+\use:x
+  {
+    \prg_new_protected_conditional:Npnn
+        \exp_not:N \__hook_if_public_command:N ##1 { TF }
+      {
+        \exp_not:N \exp_last_unbraced:Nf
+          \exp_not:N \__hook_if_public_command:w
+            { \exp_not:N \cs_to_str:N ##1 }
+          \tl_to_str:n { _ _ } \s__hook_mark
+      }
+  }
+\exp_last_unbraced:NNNNo
+\cs_new_protected:Npn \__hook_if_public_command:w
+    #1 \tl_to_str:n { _ _ } #2 \s__hook_mark
+  {
+    \tl_if_empty:nTF {#2}
+      { \prg_return_true: }
+      { \prg_return_false: }
+  }
+\tl_gset:Nn \g_hook_patch_action_list_tl
+  {
+    { \@if at DeclareRobustCommand \__hook_patch_DeclareRobustCommand:Nnn }
+    { \@if at newcommand \__hook_patch_newcommand:Nnn }
+    { \__kernel_cmd_if_xparse:NTF \__hook_cmd_patch_xparse:Nnn }
+  }
+\cs_new_protected:Npn \__hook_patch_DeclareRobustCommand:Nnn #1
+  {
+    \exp_args:Nc \@if at newcommand { \cs_to_str:N #1 ~ }
+      { \exp_args:Nc \__hook_patch_newcommand:Nnn }
+      { \exp_args:NNc \__hook_patch_expand_redefine:NNnn \c_false_bool }
+        { \cs_to_str:N #1 ~ }
+  }
+\cs_new_protected:Npn \__hook_patch_newcommand:Nnn #1
+  {
+    \exp_args:NNc \__hook_patch_expand_redefine:NNnn \c_true_bool
+      { \c_backslash_str \cs_to_str:N #1 }
+  }
+\cs_new_protected:Npn \__hook_cmd_patch_xparse:Nnn #1
+  {
+    \exp_args:NNc \__hook_patch_expand_redefine:NNnn \c_false_bool
+      { \cs_to_str:N #1 ~ code }
+  }
+\cs_new_protected:Npn \__hook_patch_expand_redefine:NNnn #1 #2 #3 #4
+  {
+    \__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
+        \bool_if:NT #1 { -1 }
+      }
+    \int_compare:nNnTF { \l__hook_patch_num_args_int } > { \c_zero_int }
+      {
+        \tl_set:Nx \l__hook_patch_param_text_tl
+          { \bool_if:NTF #1 { [####1] } {  ####1  } }
+        \tl_set:Nx \l__hook_patch_replacement_tl
+          { \bool_if:NTF #1 { [####1] } { {####1} } }
+        \int_step_inline:nnn { 2 } { \l__hook_patch_num_args_int }
+          {
+            \tl_put_right:Nn \l__hook_patch_param_text_tl    { ## ####1 }
+            \tl_put_right:Nn \l__hook_patch_replacement_tl { { ## ####1 } }
+          }
+      }
+      {
+        \tl_clear:N \l__hook_patch_param_text_tl
+        \tl_clear:N \l__hook_patch_replacement_tl
+      }
+    \group_begin:
+      \int_set:Nn \tex_escapechar:D { `\/ }
+      \use:x
+        {
+    \group_end:
+    \tl_set:Nx \exp_not:N \l__hook_patch_prefixes_tl
+      { \exp_not:N \__hook_make_prefixes:w \cs_prefix_spec:N #2 / / }
+        }
+    \use:x
+      {
+        \l__hook_patch_prefixes_tl \tex_def:D
+            \exp_not:N #2 \exp_not:V \l__hook_patch_param_text_tl
+          {
+            \str_if_eq:nnT {#4} { before }
+              { \exp_not:N \UseHook { cmd / #3 / #4 } }
+            \exp_args:No \exp_not:o
+              { \exp_after:wN #2 \l__hook_patch_replacement_tl }
+            \str_if_eq:nnT {#4} { after }
+              { \exp_not:N \UseHook { cmd / #3 / #4 } }
+          }
+      }
+  }
+\cs_new:Npn \__hook_make_prefixes:w / #1 /
+  {
+    \tl_if_empty:nF {#1}
+      {
+        \exp_not:c { tex_ \tl_trim_spaces:n {#1} :D }
+        \__hook_make_prefixes:w /
+      }
+  }
+\cs_new_protected:Npn \__hook_retokenize_patch:Nnn #1 #2 #3
+  {
+    \__hook_patch_debug:x { ..~command~can~only~be~patched~by~rescanning }
+    \str_if_eq:eeTF { \cs_argument_spec:N #1 } { }
+      { \__hook_patch_expand_redefine:NNnn \c_false_bool #1 {#2} {#3} }
+      {
+        \tl_set:Nx \l__hook_tmpa_tl
+          {
+            \int_compare:nNnTF { \char_value_catcode:n {`\@ } } = { 12 }
+              { \exp_not:N \makeatletter } { \exp_not:N \makeatother }
+          }
+        \tl_set:Nx \l__hook_tmpb_tl
+          {
+            \bool_if:NTF \l__kernel_expl_bool
+              { \ExplSyntaxOff } { \ExplSyntaxOn }
+          }
+        \use:x
+          {
+            \exp_not:N \__hook_try_patch_with_catcodes:Nnnnw
+                \exp_not:n { #1 {#2} {#3} }
+              { \prg_do_nothing: }
+              { \exp_not:V \l__hook_tmpa_tl } % @
+              { \exp_not:V \l__hook_tmpb_tl } % _:
+              {
+                \exp_not:V \l__hook_tmpa_tl   % @
+                \exp_not:V \l__hook_tmpb_tl   % _:
+              }
+          }
+              \q_recursion_tail \q_recursion_stop
+          {
+            \msg_error:nnxx { hooks } { cant-patch }
+              { \c_backslash_str #2 } { retok }
+          }
+      }
+  }
+\cs_new_protected:Npn \__hook_try_patch_with_catcodes:Nnnnw #1 #2 #3 #4
+  {
+    \quark_if_recursion_tail_stop_do:nn {#4} { \use:n }
+    \__hook_patch_debug:x { ++~trying~to~patch~by~retokenization }
+    \__hook_cmd_if_scanable:NnTF {#1} {#4}
+      {
+        \__hook_patch_debug:x { ++~macro~can~be~retokenized~cleanly }
+        \__hook_patch_debug:x { ==~retokenizing~macro~now }
+        \__hook_patch_retokenize:Nnnn #1 {#2} {#3} {#4}
+        \use_i_delimit_by_q_recursion_stop:nw \use_none:n
+      }
+      {
+        \__hook_patch_debug:x { --~macro~cannot~be~retokenized~cleanly }
+        \__hook_try_patch_with_catcodes:Nnnnw #1 {#2} {#3}
+      }
+  }
+\cs_new_eq:NN \kerneltmpDoNotUse !
+\cs_new_protected:Npn \__hook_patch_required_catcodes:
+  {
+    \char_set_catcode_escape:N \\
+    \char_set_catcode_group_begin:N \{
+    \char_set_catcode_group_end:N \}
+    \char_set_catcode_parameter:N \#
+    % \int_set:Nn \tex_endlinechar:D { -1 }
+    % \int_set:Nn \tex_newlinechar:D { -1 }
+  }
+\prg_new_protected_conditional:Npnn \__hook_cmd_if_scanable:Nn #1 #2 { TF }
+  {
+    \cs_set_eq:NN \kerneltmpDoNotUse \scan_stop:
+    \cs_set_eq:NN \__hook_tmp:w \scan_stop:
+    \use:x
+      {
+        \cs_set:Npn \__hook_tmp:w
+            ####1 \tl_to_str:n { macro: } ####2 -> ####3 \s__hook_mark
+          { ####1 \def \kerneltmpDoNotUse ####2   {####3} }
+        \tl_set:Nx \exp_not:N \l__hook_tmpa_tl
+          { \exp_not:N \__hook_tmp:w \token_to_meaning:N #1 \s__hook_mark }
+      }
+    \tl_rescan:nV { #2 \__hook_patch_required_catcodes: } \l__hook_tmpa_tl
+    \token_if_eq_meaning:NNTF #1 \kerneltmpDoNotUse
+      { \prg_return_true: }
+      { \prg_return_false: }
+  }
+\cs_new_protected:Npn \__hook_patch_retokenize:Nnnn #1 #2 #3 #4
+  {
+    \cs_set_eq:NN \kerneltmpDoNotUse \scan_stop:
+    \cs_set_eq:NN \__hook_tmp:w \scan_stop:
+    \use:x
+      {
+        \cs_set:Npn \__hook_tmp:w
+            ####1 \tl_to_str:n { macro: } ####2 -> ####3 \s__hook_mark
+          {
+            ####1 \def \kerneltmpDoNotUse ####2
+              {
+                \str_if_eq:nnT {#3} { before }
+                  { \token_to_str:N \UseHook { cmd / #2 / #3 } }
+                ####3
+                \str_if_eq:nnT {#3} { after }
+                  { \token_to_str:N \UseHook { cmd / #2 / #3 } }
+              }
+          }
+        \tl_set:Nx \exp_not:N \l__hook_tmpa_tl
+          { \exp_not:N \__hook_tmp:w \token_to_meaning:N #1 \s__hook_mark }
+      }
+    \tl_rescan:nV { #4 \__hook_patch_required_catcodes: } \l__hook_tmpa_tl
+    \cs_set_eq:NN #1 \kerneltmpDoNotUse
+  }
+\msg_new:nnnn { hooks } { wrong-cmd-hook }
+  {
+    Generic~hook~`cmd/#1/#2'~is~invalid.
+  }
+  {
+    You~tried~to~add~a~generic~hook~to~command~\iow_char:N \\#1,~but~`#2'~
+    is~an~invalid~component.~Only~`before'~or~`after'~are~allowed.
+  }
+\msg_new:nnnn { hooks } { cant-patch }
+  {
+    Generic~hooks~cannot~be~added~to~'#1'.
+  }
+  {
+    You~tried~to~add~a~hook~to~'#1',~but~LaTeX~was~unable~to~
+    patch~the~command~because~it~\__hook_unpatchable_cases:n {#2}.
+  }
+\cs_new:Npn \__hook_unpatchable_cases:n #1
+  {
+    \str_case:nn {#1}
+      {
+        { undef } { doesn't~exist }
+        { macro } { is~not~a~macro }
+        { expl3 } { is~a~private~expl3~macro }
+        { retok } { can't~be~retokenized~cleanly }
+      }
+  }
+\ExplSyntaxOff
 %%% From File: ltalloc.dtx
 \chardef\@xxxii=32
 \mathchardef\@Mi=10001
@@ -3021,6 +5720,133 @@
 \def\@setpar#1{\def\par{#1}\def\@par{#1}}
 \def\@par{\let\par\@@par\par}
 \def\@restorepar{\def\par{\@par}}
+%% File: ltpara.dtx (C) Copyright 2020-2021
+%%% From File: ltpara.dtx
+\def\ltparaversion{v1.0g}
+\def\ltparadate{2021/05/27}
+
+
+\ExplSyntaxOn
+\hook_new_pair:nn{para/before}{para/after}
+\hook_new_pair:nn{para/begin}{para/end}
+\let \@kernel at before@para at before \@empty
+\let \@kernel at before@para at begin  \@empty
+\let \@kernel at after@para at end     \@empty
+\let \@kernel at after@para at after   \@empty
+\tl_new:N \g__para_standard_everypar_tl
+\tl_gset:Nn \g__para_standard_everypar_tl {
+  \box_gset_to_last:N \g_para_indent_box
+  \group_begin:
+    \tex_par:D
+  \group_end:
+  \tex_everypar:D { \msg_error:nnnn { hooks }{ para-mode }{before}{vertical} }
+  \@kernel at before@para at before
+  \hook_use:n {para/before}
+  \group_begin:
+    \tex_everypar:D {}
+    \skip_zero:N \tex_parskip:D
+    \tex_noindent:D
+  \group_end:
+  \tex_everypar:D{\g__para_standard_everypar_tl}
+  \@kernel at before@para at begin
+  \hook_use:n {para/begin}
+  \if_mode_horizontal: \else:
+    \msg_error:nnnn { hooks }{ para-mode }{begin}{vertical} \fi:
+  \__para_handle_indent:
+}
+\tex_everypar:D{\g__para_standard_everypar_tl}
+\newtoks \everypar
+
+\tl_gput_right:Nx \g__para_standard_everypar_tl {
+    \exp_not:N \the
+    \exp_not:N \toks
+    \the \allocationnumber
+    \c_space_tl
+}
+\box_new:N \g_para_indent_box
+
+\cs_new:Npn \__para_handle_indent: {
+  \box_use_drop:N \g_para_indent_box
+}
+\cs_new:Npn \para_omit_indent: {
+  \box_gclear:N \g_para_indent_box
+}
+\cs_set_eq:NN \IndentBox \g_para_indent_box
+\cs_set_eq:NN \OmitIndent \para_omit_indent:
+\cs_new_protected:Npn \para_end: {
+  \mode_if_horizontal:TF {
+    \mode_if_inner:F {
+         \tex_unskip:D
+         \hook_use:n{para/end}
+         \@kernel at after@para at end
+         \mode_if_horizontal:TF {
+           \if_int_compare:w 0 < \tex_lastnodetype:D
+             \tex_kern:D \c_zero_dim
+           \fi:
+           \tex_par:D
+           \hook_use:n{para/after}
+           \@kernel at after@para at after
+         }
+         { \msg_error:nnnn { hooks }{ para-mode }{end}{horizontal} }
+    }
+  }
+  \tex_par:D
+}
+\cs_new:Npn \para_raw_indent: {
+  \mode_if_vertical:TF
+       {
+         \tex_everypar:D {
+           \box_gset_to_last:N \g_para_indent_box
+           \tex_everypar:D { \g__para_standard_everypar_tl }
+           \__para_handle_indent:
+           \the\everypar }
+       }
+       { \msg_error:nn { kernel }{ raw-para } }
+  \tex_indent:D
+}
+\cs_new:Npn \para_raw_noindent: {
+  \mode_if_vertical:TF
+       {
+         \tex_everypar:D {
+           \tex_everypar:D { \g__para_standard_everypar_tl }
+           \the\everypar }
+       }
+       { \msg_error:nn { kernel }{ raw-para } }
+  \tex_noindent:D
+}
+\cs_new_eq:NN \para_raw_end: \tex_par:D
+\cs_set_eq:NN \RawIndent   \para_raw_indent:
+\cs_set_eq:NN \RawNoindent \para_raw_noindent:
+\cs_set_eq:NN \RawParEnd   \para_raw_end:
+\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
+\msg_new:nnnn { hooks } { para-mode }
+  {
+    Illegal~mode~ change~ in~ hook~ 'para/#1'.\\
+    Hook~ code~ did~ not~ remain~ in~ #2~ mode.
+  }
+  {
+    Paragraph~ hooks~ cannot~ change~ the~ TeX~ mode~ without~ causing~
+    endless~ recursion.~ The~ hook~ code~ in~ 'para/#1'~ needs~ to~ stay~
+    in~ #2~ mode,~ but~ it~ didn't.~ Examine~ the~ hook~
+    code~ with~ \iow_char:N \\ShowHook~ to~ find~ the~ issue.
+  }
+\msg_new:nnnn { kernel } { raw-para }
+  {
+     Not~ in~ vertical~ mode.
+  }
+  {
+    Starting~ a~ paragraph~ with~ \iow_char:N \\RawIndent~ or~
+    \iow_char:N \\RawNoindent \\
+    (or~ \iow_char:N \\para_raw_indent:~ or~
+    \iow_char:N \\para_raw_noindent:)~ is~ only~ allowed \\
+    if~ LaTeX~ is~ in~ vertical~ mode.
+  }
+
+\ExplSyntaxOff
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%% From File: ltspace.dtx
 \message{spacing,}
 \DeclareRobustCommand\pagebreak{\@testopt{\@no at pgbk-}4}
@@ -3268,8 +6094,6 @@
   \LaTeX\kern.15em2$_{\textstyle\varepsilon}$}}
 %%% From File: ltfiles.dtx
 \message{files,}
-\newread\@inputcheck
-\newwrite\@unused
 \newwrite\@mainaux
 \newwrite\@partaux
 \newif\if at filesw \@fileswtrue
@@ -3342,8 +6166,6 @@
   \let\expandafter\noexpand\csname
        __hook env/document/begin\endcsname
   \noexpand\@empty}
-\let \@kernel at before@begindocument \@empty
-\let \@kernel at after@begindocument \@empty
 
 \@onlypreamble\document
 \let\normalsfcodes\@empty
@@ -3471,16 +6293,18 @@
   \openin\@inputcheck"#1" %
   \ifeof\@inputcheck
     \ifx\input at path\@undefined
-      \def\reserved at a{#3}%
+      \let\reserved at a\@secondoftwo
     \else
-      \def\reserved at a{\@iffileonpath{#1}{#2}{#3}}%
+      \def\reserved at a{\@iffileonpath{#1}}%
     \fi
   \else
     \closein\@inputcheck
     \edef\@filef at und{"#1" }%
-    \def\reserved at a{#2}%
+    \let\reserved at a\@firstoftwo
   \fi
-  \reserved at a}
+  \expandafter\def\expandafter\reserved at a
+    \expandafter{\reserved at a{#2}{#3}}%
+\reserved at a}
 \long\def\@iffileonpath#1{%
   \let\reserved at a\@secondoftwo
   \expandafter\@tfor\expandafter\reserved at b\expandafter
@@ -4203,7 +7027,9 @@
 \DeclareRobustCommand\usefont[4]{\fontencoding{#1}%
    \edef\f at family{#2}%
    \set at target@series{#3}%
-   \edef\f at shape{#4}\selectfont
+   \edef\f at shape{#4}%
+   \let\delayed at f@adjustment\@empty
+   \selectfont
    \ignorespaces}
 \DeclareRobustCommand\linespread[1]
    {\set at fontsize{#1}\f at size\f at baselineskip}
@@ -4869,12 +7695,14 @@
 \DeclareFontSeriesChangeRule {ulx}{?m}{ul}{}
 \DeclareFontSeriesChangeRule {ul}{?m}{ul}{}
 \DeclareFontSeriesChangeRule {x}{?m}{m}{}
-
-
+\DeclareRobustCommand\fontseries[1]{\@forced at seriesfalse
+    \expandafter\def\expandafter\delayed at f@adjustment\expandafter
+        {\delayed at f@adjustment\delayed at merge@font at series{#1}}}
+\let\delayed at f@adjustment\@empty
+\DeclareRobustCommand\fontseriesforce[1]{\@forced at seriestrue
+    \expandafter\def\expandafter\delayed at f@adjustment\expandafter
+      {\delayed at f@adjustment\edef\f at series{#1}}}
 \newif\if at forced@series
-\DeclareRobustCommand\fontseriesforce[1]{\@forced at seriestrue\edef\f at series{#1}}
-\DeclareRobustCommand\fontseries[1]{\@forced at seriesfalse\merge at font@series{#1}}
-
 \def\merge at font@series#1{%
   \expandafter\expandafter\expandafter
   \merge at font@series@
@@ -4882,13 +7710,11 @@
     {#1}%
     \@nil
 }
-
 \def\merge at font@series@#1#2#3\@nil{%
   \def\reserved at a{#3}%
   \ifx\reserved at a\@empty
     \set at target@series{#2}%
   \else
-    \maybe at load@fontshape
     \edef\reserved at a{\f at encoding /\f at family /#1/\f at shape}%
      \ifcsname \reserved at a \endcsname
        \set at target@series{#1}%
@@ -4910,7 +7736,27 @@
                     using `\reserved at b' instead}%
    \fi
 }
-\def\maybe at load@fontshape{\begingroup\try at load@fontshape\endgroup}
+\def\merge at font@series at without@substitution#1{%
+  \expandafter\expandafter\expandafter
+  \merge at font@series at without@substitution@
+    \csname series@\f at series @#1\endcsname
+    {#1}%
+    \@nil
+}
+\def\merge at font@series at without@substitution@#1#2#3\@nil{%
+  \def\reserved at a{#3}%
+  \ifx\reserved at a\@empty
+    \set at target@series{#2}%
+  \else
+    \set at target@series{#1}%
+  \fi
+}
+\let\delayed at merge@font at series\merge at font@series at without@substitution
+\def\maybe at load@fontshape{%
+  \begingroup
+    \let \typeout \@font at info
+    \try at load@fontshape
+  \endgroup}
 \def\set at target@series#1{%
     \edef\f at series{#1}%
     \series at maybe@drop at one@m\f at series\f at series
@@ -4989,8 +7835,13 @@
 \DeclareFontShapeChangeRule {sw}{sc}  {scsw}  {}
 \DeclareFontShapeChangeRule {sw}{ulc} {sw}    {}
 \DeclareFontShapeChangeRule {sw}{up} {n}      {}
-\DeclareRobustCommand\fontshape[1]{\merge at font@shape{#1}}
-\DeclareRobustCommand\fontshapeforce[1]{\edef\f at shape{#1}}
+\DeclareRobustCommand\fontshape[1]
+   {\expandafter\def\expandafter\delayed at f@adjustment\expandafter
+        {\delayed at f@adjustment\delayed at merge@font at shape{#1}}}
+\DeclareRobustCommand\fontshapeforce[1]
+   {\expandafter\def\expandafter\delayed at f@adjustment\expandafter
+        {\delayed at f@adjustment\edef\f at shape{#1}}}
+
 \def\merge at font@shape#1{%
   \expandafter\expandafter\expandafter
   \merge at font@shape@
@@ -5004,9 +7855,8 @@
   \ifx\reserved at a\@empty
     \edef\f at shape{#2}%
   \else
-    \maybe at load@fontshape
     \edef\reserved at a{\f at encoding /\f at family /\f at series/#1}%
-     \ifcsname \reserved at a\endcsname
+    \ifcsname \reserved at a\endcsname
        \edef\f at shape{#1}%
     \else
        \ifcsname \f at encoding /\f at family /\f at series/#2\endcsname
@@ -5019,6 +7869,22 @@
     \fi
   \fi
 }
+\def\merge at font@shape at without@substitution#1{%
+  \expandafter\expandafter\expandafter
+  \merge at font@shape at without@substitution@
+    \csname shape@\f at shape @#1\endcsname
+    {#1}%
+    \@nil
+}
+\def\merge at font@shape at without@substitution@#1#2#3\@nil{%
+  \def\reserved at a{#3}%
+  \ifx\reserved at a\@empty
+    \edef\f at shape{#2}%
+  \else
+    \edef\f at shape{#1}%
+  \fi
+}
+\let\delayed at merge@font at shape\merge at font@shape at without@substitution
 \protected\def\normalshape
     {\not at math@alphabet\normalshape\relax
       \fontshape\shapedefault\selectfont}%
@@ -5045,11 +7911,12 @@
           {\not at math@alphabet\sscshape\relax
            \fontshape\sscdefault\selectfont}%
 }
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 \g at addto@macro\@kernel at after@begindocument at before
               {\reinstall at nfss@defs\init at series@setup}
 %%% From File: ltfsstrc.dtx
 %% Copyright (C) 1989-97 by Frank Mittelbach and Rainer Sch\"opf.
-%% Copyright (C) 1994-97 by LaTeX3 project. All rights reserved.
+%% Copyright (C) 1994-97 by LaTeX Project. All rights reserved.
 \def\tracingfonts{%
   \@font at warning{Command \noexpand\tracingfonts
            not provided.\MessageBreak
@@ -5083,17 +7950,39 @@
          \get at external@font
    \fi\fi
 }
+
 \DeclareRobustCommand\selectfont
         {%
     \ifx\f at linespread\baselinestretch \else
       \set at fontsize\baselinestretch\f at size\f at baselineskip \fi
+    \ifx\delayed at f@adjustment\@empty
+    \else
+      \let\f at shape@saved\f at shape
+      \let\f at series@saved\f at series
+      \delayed at f@adjustment
+      \maybe at load@fontshape
+      \ifcsname \f at encoding/\f at family/\f at series/\f at shape \endcsname
+      \else
+        \let\f at shape\f at shape@saved
+        \let\f at series\f at series@saved
+        \let\delayed at merge@font at shape\merge at font@shape
+        \let\delayed at merge@font at series\merge at font@series
+        \delayed at f@adjustment
+        \let\delayed at merge@font at shape\merge at font@shape at without@substitution
+        \let\delayed at merge@font at series\merge at font@series at without@substitution
+      \fi
+      \let\delayed at f@adjustment\@empty
+    \fi
+    \@forced at seriesfalse
     \xdef\font at name{%
       \csname\curr at fontshape/\f at size\endcsname}%
     \pickup at font
     \font at name
+    \UseHook{selectfont}%
     \size at update
     \enc at update
     }
+\NewHook{selectfont}
 \def\set at fontsize#1#2#3{%
     \@defaultunits\@tempdimb#2pt\relax\@nnil
     \edef\f at size{\strip at pt\@tempdimb}%
@@ -5471,7 +8360,7 @@
                    in version \math at version}%
         \@eha
   \fi
- \else \expandafter\non at alpherr\fi
+ \else \expandafter\expandafter\expandafter\non at alpherr\fi
  \expandafter#1\ifx\math at bgroup\bgroup{#4}\else#4\fi
  }%
 }
@@ -6439,16 +9328,12 @@
         \@font at series@contexttrue
   \fi\fi\fi
 }
-
 \newif\if at font@series at context
-
 \def\DeclareEmphSequence#1{%
   \protected at edef\emfontdeclare at clist{\zap at space#1, \@empty\emforce\emreset}%
 }
 \let\emfontdeclare at clist\@empty
-
 \DeclareRobustCommand\emreset{\upshape\ulcshape}
-
 \DeclareRobustCommand\em{%
   \@nomath\em
   \ifx\emfontdeclare at clist\@empty
@@ -6519,6 +9404,7 @@
    \edef\f at family{\familydefault}%
    \edef\f at series{\seriesdefault}%
    \edef\f at shape{\shapedefault}%
+   \let\delayed at f@adjustment\@empty
    \UseHook{normalfont}%
    \@defaultfamilyhook        % hookname from 2020/02 will vanish
    \selectfont}
@@ -6542,8 +9428,8 @@
                                        %% overwrite it in fontdef.cfg
                                        %% if necessary
 \fontfamily{cmr}
-\fontseries{m}
-\fontshape{n}
+\def\f at series{m}           % \fontseries{m}
+\def\f at shape{n}            % \fontshape{n}
 \fontsize{10}{10}
 \def\@fontenc at load@list{\@elt{T1,OT1}}
 \InputIfFileExists{fonttext.cfg}
@@ -6713,6 +9599,7 @@
               there is probably something wrong with
               the class file}\@eha
 }
+%%% From File: lttextcomp.dtx
 \DeclareRobustCommand\legacyoldstylenums[1]{%
    \begingroup
     \spaceskip\fontdimen\tw@\font
@@ -6749,7 +9636,6 @@
   \egroup
 }
 \def\textcompsubstdefault{\rmsubstdefault}
-
 \def\DeclareEncodingSubset#1#2{%
   \DeclareEncodingSubset at aux{#1}#2*\DeclareEncodingSubset at aux
 }
@@ -6811,7 +9697,6 @@
       \selectfont#1%
   \egroup
 }
-
 \def\tc at fake@euro#1{%
    \leavevmode
    \@font at info{Faking \noexpand#1for font family
@@ -6824,17 +9709,17 @@
       \hbox{C}\crcr
    }%
 }
-
 \def\tc at check@symbol{\CheckEncodingSubset\UseTextSymbol{TS1}\tc at subst}
-\def\tc at check@accent#1{\CheckEncodingSubset\UseTextAccent{TS1}{\tc at swap@accent#1}}
+\def\tc at check@accent#1{\CheckEncodingSubset\UseTextAccent
+                                           {TS1}{\tc at swap@accent#1}}
 \def\tc at swap@accent#1#2{\UseTextAccent{T1}#1}
 
 \DeclareTextSymbolDefault{\textdollar}{TS1}
-\UndeclareTextCommand{\textdollar}  {OT1}         % don't use the OT1 def any longer
+\UndeclareTextCommand{\textdollar}{OT1}  % don't use the OT1 def any longer
 \DeclareTextSymbolDefault{\textsterling}{TS1}
-\UndeclareTextCommand{\textsterling}{OT1}         % don't use the OT1 def any longer
+\UndeclareTextCommand{\textsterling}{OT1}% don't use the OT1 def any longer
 \DeclareTextSymbolDefault{\textperthousand}{TS1}
-\UndeclareTextCommand{\textperthousand}{T1}       % don't use the T1 def
+\UndeclareTextCommand{\textperthousand}{T1} % don't use the T1 def
 \DeclareTextSymbolDefault{\textasteriskcentered}{TS1}
 \DeclareTextSymbolDefault{\textbullet}{TS1}
 \DeclareTextSymbolDefault{\textdaggerdbl}{TS1}
@@ -6875,22 +9760,38 @@
 \DeclareTextCommandDefault{\t}
   {\CheckEncodingSubset\UseTextAccent{TS1}{\UseTextAccent{OML}}2\t}
 \ifx\Umathcode\@undefined
-  \DeclareTextCommandDefault{\capitalacute}       {\tc at check@accent{\'}2\capitalacute}
-  \DeclareTextCommandDefault{\capitalbreve}       {\tc at check@accent{\u}2\capitalbreve}
-  \DeclareTextCommandDefault{\capitalcaron}       {\tc at check@accent{\v}2\capitalcaron}
-  \DeclareTextCommandDefault{\capitalcedilla}     {\tc at check@accent{\c}2\capitalcedilla}
-  \DeclareTextCommandDefault{\capitalcircumflex}  {\tc at check@accent{\^}2\capitalcircumflex}
-  \DeclareTextCommandDefault{\capitaldieresis}    {\tc at check@accent{\"}2\capitaldieresis}
-  \DeclareTextCommandDefault{\capitaldotaccent}   {\tc at check@accent{\.}2\capitaldotaccent}
-  \DeclareTextCommandDefault{\capitalgrave}       {\tc at check@accent{\`}2\capitalgrave}
-  \DeclareTextCommandDefault{\capitalhungarumlaut}{\tc at check@accent{\H}2\capitalhungarumlaut}
-  \DeclareTextCommandDefault{\capitalmacron}      {\tc at check@accent{\=}2\capitalmacron}
-  \DeclareTextCommandDefault{\capitalogonek}      {\tc at check@accent{\k}2\capitalogonek}
-  \DeclareTextCommandDefault{\capitalring}        {\tc at check@accent{\r}2\capitalring}
-  \DeclareTextCommandDefault{\capitaltie}         {\tc at check@accent{\t}2\capitaltie}
-  \DeclareTextCommandDefault{\capitaltilde}       {\tc at check@accent{\~}2\capitaltilde}
-  \DeclareTextCommandDefault{\newtie}             {\tc at check@accent{\t}2\newtie}
-  \DeclareTextCommandDefault{\capitalnewtie}      {\tc at check@accent{\t}2\capitalnewtie}
+  \DeclareTextCommandDefault{\capitalacute}
+                            {\tc at check@accent{\'}2\capitalacute}
+  \DeclareTextCommandDefault{\capitalbreve}
+                            {\tc at check@accent{\u}2\capitalbreve}
+  \DeclareTextCommandDefault{\capitalcaron}
+                            {\tc at check@accent{\v}2\capitalcaron}
+  \DeclareTextCommandDefault{\capitalcedilla}
+                            {\tc at check@accent{\c}2\capitalcedilla}
+  \DeclareTextCommandDefault{\capitalcircumflex}
+                            {\tc at check@accent{\^}2\capitalcircumflex}
+  \DeclareTextCommandDefault{\capitaldieresis}
+                            {\tc at check@accent{\"}2\capitaldieresis}
+  \DeclareTextCommandDefault{\capitaldotaccent}
+                            {\tc at check@accent{\.}2\capitaldotaccent}
+  \DeclareTextCommandDefault{\capitalgrave}
+                            {\tc at check@accent{\`}2\capitalgrave}
+  \DeclareTextCommandDefault{\capitalhungarumlaut}
+                            {\tc at check@accent{\H}2\capitalhungarumlaut}
+  \DeclareTextCommandDefault{\capitalmacron}
+                            {\tc at check@accent{\=}2\capitalmacron}
+  \DeclareTextCommandDefault{\capitalogonek}
+                            {\tc at check@accent{\k}2\capitalogonek}
+  \DeclareTextCommandDefault{\capitalring}
+                            {\tc at check@accent{\r}2\capitalring}
+  \DeclareTextCommandDefault{\capitaltie}
+                            {\tc at check@accent{\t}2\capitaltie}
+  \DeclareTextCommandDefault{\capitaltilde}
+                            {\tc at check@accent{\~}2\capitaltilde}
+  \DeclareTextCommandDefault{\newtie}
+                            {\tc at check@accent{\t}2\newtie}
+  \DeclareTextCommandDefault{\capitalnewtie}
+                            {\tc at check@accent{\t}2\capitalnewtie}
 \else
   \DeclareTextCommandDefault\capitalacute{\@tabacckludge'}
   \DeclareTextCommandDefault\capitalbreve{\u}
@@ -6909,86 +9810,163 @@
   \DeclareTextCommandDefault\capitaltilde{\~}
   \DeclareTextCommandDefault\newtie{\t}
 \fi
-\DeclareTextCommandDefault{\textlbrackdbl}      {\tc at check@symbol2\textlbrackdbl}
-\DeclareTextCommandDefault{\textrbrackdbl}      {\tc at check@symbol2\textrbrackdbl}
-\DeclareTextCommandDefault{\texteightoldstyle}  {\tc at check@symbol2\texteightoldstyle}
-\DeclareTextCommandDefault{\textfiveoldstyle}   {\tc at check@symbol2\textfiveoldstyle}
-\DeclareTextCommandDefault{\textfouroldstyle}   {\tc at check@symbol2\textfouroldstyle}
-\DeclareTextCommandDefault{\textnineoldstyle}   {\tc at check@symbol2\textnineoldstyle}
-\DeclareTextCommandDefault{\textoneoldstyle}    {\tc at check@symbol2\textoneoldstyle}
-\DeclareTextCommandDefault{\textsevenoldstyle}  {\tc at check@symbol2\textsevenoldstyle}
-\DeclareTextCommandDefault{\textsixoldstyle}    {\tc at check@symbol2\textsixoldstyle}
-\DeclareTextCommandDefault{\textthreeoldstyle}  {\tc at check@symbol2\textthreeoldstyle}
-\DeclareTextCommandDefault{\texttwooldstyle}    {\tc at check@symbol2\texttwooldstyle}
-\DeclareTextCommandDefault{\textzerooldstyle}   {\tc at check@symbol2\textzerooldstyle}
-\DeclareTextCommandDefault{\textacutedbl}       {\tc at check@symbol2\textacutedbl}
-\DeclareTextCommandDefault{\textasciiacute}     {\tc at check@symbol2\textasciiacute}
-\DeclareTextCommandDefault{\textasciibreve}     {\tc at check@symbol2\textasciibreve}
-\DeclareTextCommandDefault{\textasciicaron}     {\tc at check@symbol2\textasciicaron}
-\DeclareTextCommandDefault{\textasciidieresis}  {\tc at check@symbol2\textasciidieresis}
-\DeclareTextCommandDefault{\textasciigrave}     {\tc at check@symbol2\textasciigrave}
-\DeclareTextCommandDefault{\textasciimacron}    {\tc at check@symbol2\textasciimacron}
-\DeclareTextCommandDefault{\textgravedbl}       {\tc at check@symbol2\textgravedbl}
-\DeclareTextCommandDefault{\texttildelow}       {\tc at check@symbol2\texttildelow}
-\DeclareTextCommandDefault{\textbaht}           {\tc at check@symbol2\textbaht}
-\DeclareTextCommandDefault{\textbigcircle}      {\tc at check@symbol2\textbigcircle}
-\DeclareTextCommandDefault{\textborn}           {\tc at check@symbol2\textborn}
-\DeclareTextCommandDefault{\textcentoldstyle}   {\tc at check@symbol2\textcentoldstyle}
-\DeclareTextCommandDefault{\textcircledP}       {\tc at check@symbol2\textcircledP}
-\DeclareTextCommandDefault{\textcopyleft}       {\tc at check@symbol2\textcopyleft}
-\DeclareTextCommandDefault{\textdblhyphenchar}  {\tc at check@symbol2\textdblhyphenchar}
-\DeclareTextCommandDefault{\textdblhyphen}      {\tc at check@symbol2\textdblhyphen}
-\DeclareTextCommandDefault{\textdied}           {\tc at check@symbol2\textdied}
-\DeclareTextCommandDefault{\textdiscount}       {\tc at check@symbol2\textdiscount}
-\DeclareTextCommandDefault{\textdivorced}       {\tc at check@symbol2\textdivorced}
-\DeclareTextCommandDefault{\textdollaroldstyle} {\tc at check@symbol2\textdollaroldstyle}
-\DeclareTextCommandDefault{\textguarani}        {\tc at check@symbol2\textguarani}
-\DeclareTextCommandDefault{\textleaf}           {\tc at check@symbol2\textleaf}
-\DeclareTextCommandDefault{\textlquill}         {\tc at check@symbol2\textlquill}
-\DeclareTextCommandDefault{\textmarried}        {\tc at check@symbol2\textmarried}
-\DeclareTextCommandDefault{\textmho}            {\tc at check@symbol2\textmho}
-\DeclareTextCommandDefault{\textmusicalnote}    {\tc at check@symbol2\textmusicalnote}
-\DeclareTextCommandDefault{\textnaira}          {\tc at check@symbol2\textnaira}
-\DeclareTextCommandDefault{\textopenbullet}     {\tc at check@symbol2\textopenbullet}
-\DeclareTextCommandDefault{\textpeso}           {\tc at check@symbol2\textpeso}
-\DeclareTextCommandDefault{\textpilcrow}        {\tc at check@symbol2\textpilcrow}
-\DeclareTextCommandDefault{\textrecipe}         {\tc at check@symbol2\textrecipe}
-\DeclareTextCommandDefault{\textreferencemark}  {\tc at check@symbol2\textreferencemark}
-\DeclareTextCommandDefault{\textrquill}         {\tc at check@symbol2\textrquill}
-\DeclareTextCommandDefault{\textservicemark}    {\tc at check@symbol2\textservicemark}
-\DeclareTextCommandDefault{\textsurd}           {\tc at check@symbol2\textsurd}
-\DeclareTextCommandDefault{\textpertenthousand} {\tc at check@symbol2\textpertenthousand}
+\DeclareTextCommandDefault{\textlbrackdbl}
+                          {\tc at check@symbol2\textlbrackdbl}
+\DeclareTextCommandDefault{\textrbrackdbl}
+                          {\tc at check@symbol2\textrbrackdbl}
+\DeclareTextCommandDefault{\texteightoldstyle}
+                          {\tc at check@symbol2\texteightoldstyle}
+\DeclareTextCommandDefault{\textfiveoldstyle}
+                          {\tc at check@symbol2\textfiveoldstyle}
+\DeclareTextCommandDefault{\textfouroldstyle}
+                          {\tc at check@symbol2\textfouroldstyle}
+\DeclareTextCommandDefault{\textnineoldstyle}
+                          {\tc at check@symbol2\textnineoldstyle}
+\DeclareTextCommandDefault{\textoneoldstyle}
+                          {\tc at check@symbol2\textoneoldstyle}
+\DeclareTextCommandDefault{\textsevenoldstyle}
+                          {\tc at check@symbol2\textsevenoldstyle}
+\DeclareTextCommandDefault{\textsixoldstyle}
+                          {\tc at check@symbol2\textsixoldstyle}
+\DeclareTextCommandDefault{\textthreeoldstyle}
+                          {\tc at check@symbol2\textthreeoldstyle}
+\DeclareTextCommandDefault{\texttwooldstyle}
+                          {\tc at check@symbol2\texttwooldstyle}
+\DeclareTextCommandDefault{\textzerooldstyle}
+                          {\tc at check@symbol2\textzerooldstyle}
+\DeclareTextCommandDefault{\textacutedbl}
+                          {\tc at check@symbol2\textacutedbl}
+\DeclareTextCommandDefault{\textasciiacute}
+                          {\tc at check@symbol2\textasciiacute}
+\DeclareTextCommandDefault{\textasciibreve}
+                          {\tc at check@symbol2\textasciibreve}
+\DeclareTextCommandDefault{\textasciicaron}
+                          {\tc at check@symbol2\textasciicaron}
+\DeclareTextCommandDefault{\textasciidieresis}
+                          {\tc at check@symbol2\textasciidieresis}
+\DeclareTextCommandDefault{\textasciigrave}
+                          {\tc at check@symbol2\textasciigrave}
+\DeclareTextCommandDefault{\textasciimacron}
+                          {\tc at check@symbol2\textasciimacron}
+\DeclareTextCommandDefault{\textgravedbl}
+                          {\tc at check@symbol2\textgravedbl}
+\DeclareTextCommandDefault{\texttildelow}
+                          {\tc at check@symbol2\texttildelow}
+\DeclareTextCommandDefault{\textbaht}
+                          {\tc at check@symbol2\textbaht}
+\DeclareTextCommandDefault{\textbigcircle}
+                          {\tc at check@symbol2\textbigcircle}
+\DeclareTextCommandDefault{\textborn}
+                          {\tc at check@symbol2\textborn}
+\DeclareTextCommandDefault{\textcentoldstyle}
+                          {\tc at check@symbol2\textcentoldstyle}
+\DeclareTextCommandDefault{\textcircledP}
+                          {\tc at check@symbol2\textcircledP}
+\DeclareTextCommandDefault{\textcopyleft}
+                          {\tc at check@symbol2\textcopyleft}
+\DeclareTextCommandDefault{\textdblhyphenchar}
+                          {\tc at check@symbol2\textdblhyphenchar}
+\DeclareTextCommandDefault{\textdblhyphen}
+                          {\tc at check@symbol2\textdblhyphen}
+\DeclareTextCommandDefault{\textdied}
+                          {\tc at check@symbol2\textdied}
+\DeclareTextCommandDefault{\textdiscount}
+                          {\tc at check@symbol2\textdiscount}
+\DeclareTextCommandDefault{\textdivorced}
+                          {\tc at check@symbol2\textdivorced}
+\DeclareTextCommandDefault{\textdollaroldstyle}
+                          {\tc at check@symbol2\textdollaroldstyle}
+\DeclareTextCommandDefault{\textguarani}
+                          {\tc at check@symbol2\textguarani}
+\DeclareTextCommandDefault{\textleaf}
+                          {\tc at check@symbol2\textleaf}
+\DeclareTextCommandDefault{\textlquill}
+                          {\tc at check@symbol2\textlquill}
+\DeclareTextCommandDefault{\textmarried}
+                          {\tc at check@symbol2\textmarried}
+\DeclareTextCommandDefault{\textmho}
+                          {\tc at check@symbol2\textmho}
+\DeclareTextCommandDefault{\textmusicalnote}
+                          {\tc at check@symbol2\textmusicalnote}
+\DeclareTextCommandDefault{\textnaira}
+                          {\tc at check@symbol2\textnaira}
+\DeclareTextCommandDefault{\textopenbullet}
+                          {\tc at check@symbol2\textopenbullet}
+\DeclareTextCommandDefault{\textpeso}
+                          {\tc at check@symbol2\textpeso}
+\DeclareTextCommandDefault{\textpilcrow}
+                          {\tc at check@symbol2\textpilcrow}
+\DeclareTextCommandDefault{\textrecipe}
+                          {\tc at check@symbol2\textrecipe}
+\DeclareTextCommandDefault{\textreferencemark}
+                          {\tc at check@symbol2\textreferencemark}
+\DeclareTextCommandDefault{\textrquill}
+                          {\tc at check@symbol2\textrquill}
+\DeclareTextCommandDefault{\textservicemark}
+                          {\tc at check@symbol2\textservicemark}
+\DeclareTextCommandDefault{\textsurd}
+                          {\tc at check@symbol2\textsurd}
+\DeclareTextCommandDefault{\textpertenthousand}
+                          {\tc at check@symbol2\textpertenthousand}
 \UndeclareTextCommand{\textpertenthousand}{T1}
-\DeclareTextCommandDefault{\textlangle}         {\tc at check@symbol3\textlangle}
-\DeclareTextCommandDefault{\textrangle}         {\tc at check@symbol3\textrangle}
-\DeclareTextCommandDefault{\textcolonmonetary}  {\tc at check@symbol4\textcolonmonetary}
-\DeclareTextCommandDefault{\textdong}           {\tc at check@symbol4\textdong}
-\DeclareTextCommandDefault{\textdownarrow}      {\tc at check@symbol4\textdownarrow}
-\DeclareTextCommandDefault{\textleftarrow}      {\tc at check@symbol4\textleftarrow}
-\DeclareTextCommandDefault{\textlira}           {\tc at check@symbol4\textlira}
-\DeclareTextCommandDefault{\textrightarrow}     {\tc at check@symbol4\textrightarrow}
-\DeclareTextCommandDefault{\textuparrow}        {\tc at check@symbol4\textuparrow}
-\DeclareTextCommandDefault{\textwon}            {\tc at check@symbol4\textwon}
-\DeclareTextCommandDefault{\textestimated}      {\tc at check@symbol5\textestimated}
-\DeclareTextCommandDefault{\textnumero}         {\tc at check@symbol5\textnumero}
-\DeclareTextCommandDefault{\textflorin}         {\tc at check@symbol6\textflorin}
-\DeclareTextCommandDefault{\textcurrency}       {\tc at check@symbol6\textcurrency}
-\DeclareTextCommandDefault{\textfractionsolidus}{\tc at check@symbol7\textfractionsolidus}
-\DeclareTextCommandDefault{\textohm}            {\tc at check@symbol7\textohm}
-\DeclareTextCommandDefault{\textmu}             {\tc at check@symbol7\textmu}
-\DeclareTextCommandDefault{\textminus}          {\tc at check@symbol7\textminus}
-\DeclareTextCommandDefault{\textblank}          {\tc at check@symbol{8}\textblank}
-\DeclareTextCommandDefault{\textinterrobangdown}{\tc at check@symbol{8}\textinterrobangdown}
-\DeclareTextCommandDefault{\textinterrobang}    {\tc at check@symbol{8}\textinterrobang}
+\DeclareTextCommandDefault{\textlangle}
+                          {\tc at check@symbol3\textlangle}
+\DeclareTextCommandDefault{\textrangle}
+                          {\tc at check@symbol3\textrangle}
+\DeclareTextCommandDefault{\textcolonmonetary}
+                          {\tc at check@symbol4\textcolonmonetary}
+\DeclareTextCommandDefault{\textdong}
+                          {\tc at check@symbol4\textdong}
+\DeclareTextCommandDefault{\textdownarrow}
+                          {\tc at check@symbol4\textdownarrow}
+\DeclareTextCommandDefault{\textleftarrow}
+                          {\tc at check@symbol4\textleftarrow}
+\DeclareTextCommandDefault{\textlira}
+                          {\tc at check@symbol4\textlira}
+\DeclareTextCommandDefault{\textrightarrow}
+                          {\tc at check@symbol4\textrightarrow}
+\DeclareTextCommandDefault{\textuparrow}
+                          {\tc at check@symbol4\textuparrow}
+\DeclareTextCommandDefault{\textwon}
+                          {\tc at check@symbol4\textwon}
+\DeclareTextCommandDefault{\textestimated}
+                          {\tc at check@symbol5\textestimated}
+\DeclareTextCommandDefault{\textnumero}
+                          {\tc at check@symbol5\textnumero}
+\DeclareTextCommandDefault{\textflorin}
+                          {\tc at check@symbol6\textflorin}
+\DeclareTextCommandDefault{\textcurrency}
+                          {\tc at check@symbol6\textcurrency}
+\DeclareTextCommandDefault{\textfractionsolidus}
+                          {\tc at check@symbol7\textfractionsolidus}
+\DeclareTextCommandDefault{\textohm}
+                          {\tc at check@symbol7\textohm}
+\DeclareTextCommandDefault{\textmu}
+                          {\tc at check@symbol7\textmu}
+\DeclareTextCommandDefault{\textminus}
+                          {\tc at check@symbol7\textminus}
+\DeclareTextCommandDefault{\textblank}
+                          {\tc at check@symbol{8}\textblank}
+\DeclareTextCommandDefault{\textinterrobangdown}
+                          {\tc at check@symbol{8}\textinterrobangdown}
+\DeclareTextCommandDefault{\textinterrobang}
+                          {\tc at check@symbol{8}\textinterrobang}
 \DeclareTextCommandDefault{\texteuro}
-            {\CheckEncodingSubset\UseTextSymbol{TS1}\tc at fake@euro{8}\texteuro}
-\DeclareTextCommandDefault{\textcelsius}{\tc at check@symbol{9}\textcelsius}
-\DeclareTextCommandDefault{\textonesuperior}{\tc at check@symbol{9}\textonesuperior}
-\DeclareTextCommandDefault{\textthreequartersemdash}{\tc at check@symbol{9}\textthreequartersemdash}
-\DeclareTextCommandDefault{\textthreesuperior}{\tc at check@symbol{9}\textthreesuperior}
-\DeclareTextCommandDefault{\texttwelveudash}{\tc at check@symbol{9}\texttwelveudash}
-\DeclareTextCommandDefault{\texttwosuperior}{\tc at check@symbol{9}\texttwosuperior}
-\DeclareTextCommandDefault{\textbardbl}{\tc at check@symbol{9}\textbardbl}
+  {\CheckEncodingSubset\UseTextSymbol{TS1}\tc at fake@euro{8}\texteuro}
+\DeclareTextCommandDefault{\textcelsius}
+                          {\tc at check@symbol{9}\textcelsius}
+\DeclareTextCommandDefault{\textonesuperior}
+                          {\tc at check@symbol{9}\textonesuperior}
+\DeclareTextCommandDefault{\textthreequartersemdash}
+                          {\tc at check@symbol{9}\textthreequartersemdash}
+\DeclareTextCommandDefault{\textthreesuperior}
+                          {\tc at check@symbol{9}\textthreesuperior}
+\DeclareTextCommandDefault{\texttwelveudash}
+                          {\tc at check@symbol{9}\texttwelveudash}
+\DeclareTextCommandDefault{\texttwosuperior}
+                          {\tc at check@symbol{9}\texttwosuperior}
+\DeclareTextCommandDefault{\textbardbl}
+                          {\tc at check@symbol{9}\textbardbl}
 
 \ifx \Umathcode\@undefined  \else
 \DeclareTextCommand{\textzerooldstyle} \UnicodeEncodingName{\oldstylenums{0}}
@@ -7001,12 +9979,12 @@
 \DeclareTextCommand{\textsevenoldstyle}\UnicodeEncodingName{\oldstylenums{7}}
 \DeclareTextCommand{\texteightoldstyle}\UnicodeEncodingName{\oldstylenums{8}}
 \DeclareTextCommand{\textnineoldstyle} \UnicodeEncodingName{\oldstylenums{9}}
-\DeclareTextSymbol{\textpilcrow}       \UnicodeEncodingName{"00B6}
-\DeclareTextSymbol{\textborn}          \UnicodeEncodingName{"002A}
-\DeclareTextSymbol{\textdied}          \UnicodeEncodingName{"2020}
-\DeclareTextSymbol{\textlbrackdbl}     \UnicodeEncodingName{"27E6}
-\DeclareTextSymbol{\textrbrackdbl}     \UnicodeEncodingName{"27E7}
-\DeclareTextSymbol{\textguarani}       \UnicodeEncodingName{"20B2}
+\DeclareTextSymbol{\textpilcrow}        \UnicodeEncodingName{"00B6}
+\DeclareTextSymbol{\textborn}           \UnicodeEncodingName{"002A}
+\DeclareTextSymbol{\textdied}           \UnicodeEncodingName{"2020}
+\DeclareTextSymbol{\textlbrackdbl}      \UnicodeEncodingName{"27E6}
+\DeclareTextSymbol{\textrbrackdbl}      \UnicodeEncodingName{"27E7}
+\DeclareTextSymbol{\textguarani}        \UnicodeEncodingName{"20B2}
 \DeclareTextSymbol{\textdollaroldstyle}{TS1}{138}
 \DeclareTextSymbol{\textcentoldstyle}  {TS1}{139}
 \fi               % --- END of Unicode engines specials
@@ -7038,31 +10016,32 @@
 \DeclareEncodingSubset{TS1}{lmss}    {1}
 \DeclareEncodingSubset{TS1}{lmssq}   {1}
 \DeclareEncodingSubset{TS1}{lmvtt}   {1}
-\DeclareEncodingSubset{TS1}{lmtt}    {1} % missing TM, SM, pertenthousand for some reason
+\DeclareEncodingSubset{TS1}{lmtt}    {1} % missing TM, SM and
+                                         % pertenthousand for some reason
 \DeclareEncodingSubset{TS1}{ptmx}    {2}
 \DeclareEncodingSubset{TS1}{ptmj}    {2}
 \DeclareEncodingSubset{TS1}{ul8}     {2}
-\DeclareEncodingSubset{TS1}{bch}     {5}  % tofu for blank, ohm
-\DeclareEncodingSubset{TS1}{futj}    {5}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{futs}    {5}  % tofu for blank, ohm
-\DeclareEncodingSubset{TS1}{futx}    {5}  % probably (currently broken distrib)
-\DeclareEncodingSubset{TS1}{pag}     {5}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{pbk}     {5}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{pcr}     {5}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{phv}     {5}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{pnc}     {5}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{pplj}    {5}  % tofu for blank
-\DeclareEncodingSubset{TS1}{pplx}    {5}  % tofu for blank
-\DeclareEncodingSubset{TS1}{ppl}     {5}  % tofu for blank interrobang/down
-\DeclareEncodingSubset{TS1}{ptm}     {5}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{pzc}     {5}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{ul9}     {5}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{dayroms} {6}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{dayrom}  {6}  % tofu for blank, interrobang/down, ohm
-\DeclareEncodingSubset{TS1}{augie}   {8}  % really only missing euro
-\DeclareEncodingSubset{TS1}{put}     {8}
-\DeclareEncodingSubset{TS1}{uag}     {8}  % probably (currently broken distrib)
-\DeclareEncodingSubset{TS1}{ugq}     {8}
+\DeclareEncodingSubset{TS1}{bch} {5} % tofu for blank, ohm
+\DeclareEncodingSubset{TS1}{futj}{5} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{futs}{5} % tofu for blank, ohm
+\DeclareEncodingSubset{TS1}{futx}{5} % probably (currently broken distrib)
+\DeclareEncodingSubset{TS1}{pag} {5} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{pbk} {5} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{pcr} {5} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{phv} {5} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{pnc} {5} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{pplj}{5} % tofu for blank
+\DeclareEncodingSubset{TS1}{pplx}{5} % tofu for blank
+\DeclareEncodingSubset{TS1}{ppl} {5} % tofu for blank interrobang/down
+\DeclareEncodingSubset{TS1}{ptm} {5} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{pzc} {5} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{ul9} {5} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{dayroms}{6} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{dayrom} {6} % tofu for blank, interrobang/down, ohm
+\DeclareEncodingSubset{TS1}{augie}{8} % really only missing euro
+\DeclareEncodingSubset{TS1}{put}  {8}
+\DeclareEncodingSubset{TS1}{uag}  {8} % probably (currently broken distrib)
+\DeclareEncodingSubset{TS1}{ugq}  {8}
 \DeclareEncodingSubset{TS1}{zi4}     {9}
 \DeclareEncodingSubset{TS1}{hls}     {5}
 \DeclareEncodingSubset{TS1}{hlst}    {5}
@@ -7073,11 +10052,11 @@
 \DeclareEncodingSubset{TS1}{hlcn}    {8}
 \DeclareEncodingSubset{TS1}{hlcw}    {8}
 \DeclareEncodingSubset{TS1}{hlcf}    {8}
-\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}{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}{Alegreya-*}               {2}
 \DeclareEncodingSubset{TS1}{AlegreyaSans-*}           {2}
 \DeclareEncodingSubset{TS1}{DejaVuSans-TLF}           {2}
@@ -7185,7 +10164,7 @@
 \DeclareEncodingSubset{TS1}{erewhon-*}                {7}
 \DeclareEncodingSubset{TS1}{ComicNeue-TLF}            {7}
 \DeclareEncodingSubset{TS1}{ComicNeueAngular-TLF}     {7}
-\DeclareEncodingSubset{TS1}{Forum-LF}                 {7}  % the superiors are missing
+\DeclareEncodingSubset{TS1}{Forum-LF}      {7}  % the superiors are missing
 \DeclareEncodingSubset{TS1}{Cochineal-*}              {8}
 \DeclareEncodingSubset{TS1}{AlgolRevived-TLF}         {9}
 \def\UseLegacyTextSymbols{%
@@ -7279,6 +10258,7 @@
 \@ignorefalse
 \let\ignorespacesafterend\@ignoretrue
 \def\enddocument{%
+   \@kernel at before@enddocument
    \UseOneTimeHook{enddocument}%
    \@kernel at after@enddocument
    \@checkend{document}%
@@ -7328,6 +10308,7 @@
      \fi
    \fi
 }
+\def\@kernel at before@enddocument{\par}
 \def\@testdef #1#2#3{%
   \def\reserved at a{#3}\expandafter \ifx \csname #1@#2\endcsname
  \reserved at a  \else \@tempswatrue \fi}
@@ -7772,7 +10753,7 @@
 }
 \let\@eqnsel=\relax
 \def\nonumber{\global\@eqnswfalse}
-\def\@eqncr{%
+\protected\def\@eqncr{%
    {\ifnum0=`}\fi
    \@ifstar{%
       \global\@eqpen\@M\@yeqncr
@@ -7794,7 +10775,7 @@
      \reserved at a \if at eqnsw\@eqnnum\stepcounter{equation}\fi
      \global\@eqnswtrue\global\@eqcnt\z@\cr}
 \let\@seqncr=\@eqncr
-\@namedef{eqnarray*}{\def\@eqncr{\nonumber\@seqncr}\eqnarray}
+\@namedef{eqnarray*}{\protected\def\@eqncr{\nonumber\@seqncr}\eqnarray}
 \@namedef{endeqnarray*}{\nonumber\endeqnarray}
 \def\lefteqn#1{\rlap{$\displaystyle #1$}}
 \DeclareRobustCommand{\ensuremath}{%
@@ -8096,13 +11077,13 @@
     \mb at b
     \kern\z@}}
 \let\set at color\relax
-\let\color at begingroup\relax
-\let\color at endgroup\relax
-\let\color at setgroup\relax
-\let\normalcolor\relax
-\let\color at hbox\relax
-\let\color at vbox\relax
-\let\color at endbox\relax
+\let\color at begingroup\begingroup
+\def\color at endgroup{\endgraf\endgroup}
+\def\color at setgroup{\color at begingroup}        % changed further in color package
+\let\normalcolor\relax                        % remains untouched; only changed in a color package
+\def\color at hbox{\hbox\bgroup\color at begingroup}
+\def\color at vbox{\vbox\bgroup\color at begingroup}
+\def\color at endbox{\color at endgroup\egroup}
 \def\newsavebox#1{\@ifdefinable{#1}{\newbox#1}}
 \DeclareRobustCommand\savebox[1]{%
   \@ifnextchar(%)
@@ -8299,6 +11280,7 @@
     \color at begingroup
       \@makefntext{%
         \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
+    \par
     \color at endgroup}}
 \newif\if at pboxsw
 \DeclareRobustCommand\rule{\@ifnextchar[\@rule{\@rule[\z@]}}%
@@ -8402,7 +11384,7 @@
 \def\@addfield{\global\setbox\@curline\hbox{\unhbox
      \@curline\unhbox\@curfield}}
 \def\@ifatmargin{\ifdim \wd\@curline =\z@}
-\def\@tabcr{\@stopline \@ifstar{\penalty \@M \@xtabcr}\@xtabcr}
+\protected\def\@tabcr{\@stopline \@ifstar{\penalty \@M \@xtabcr}\@xtabcr}
 \def\@xtabcr{\@ifnextchar[\@itabcr{\@startline\ignorespaces}}
 \def\@itabcr[#1]{\@vspace at calcify{#1}\@startline\ignorespaces}
 \def\tabbing{\lineskip \z at skip\let\>\@rtab\let\<\@ltab\let\=\@settab
@@ -8520,7 +11502,7 @@
     \lineskip\z at skip\baselineskip\z at skip
     \ifhmode \@preamerr\z@ \@@par\fi
     \@preamble}
-\def\@arraycr{%
+\protected\def\@arraycr{%
   ${\ifnum0=`}\fi\@ifstar\@xarraycr\@xarraycr}
 \def\@xarraycr{\@ifnextchar[\@argarraycr{\ifnum0=`{\fi}${}\cr}}
 \def\@argarraycr[#1]{%
@@ -8527,7 +11509,7 @@
   \ifnum0=`{\fi}${}\ifdim #1>\z@ \@xargarraycr{#1}\else
    \@yargarraycr{#1}\fi}
 \let\tabularnewline\relax
-\def\@tabularcr{%
+\protected\def\@tabularcr{%
   {\ifnum0=`}\fi\@ifstar\@xtabularcr\@xtabularcr}
 \def\@xtabularcr{\@ifnextchar[\@argtabularcr{\ifnum0=`{\fi}\cr}}
 \def\@argtabularcr[#1]{%
@@ -8761,7 +11743,7 @@
     \let\\\@stackcr
     \@ishortstack}
 \def\@ishortstack#1{\ialign{\mb at l {##}\unskip\mb at r\cr #1\crcr}\egroup}
-\def\@stackcr{\@ifstar\@ixstackcr\@ixstackcr}
+\protected\def\@stackcr{\@ifstar\@ixstackcr\@ixstackcr}
 \def\@ixstackcr{\@ifnextchar[\@istackcr{\cr\ignorespaces}}
 \def\@istackcr[#1]{\cr\noalign{\@vspace at calcify{#1}}\ignorespaces}
 \newif\if at negarg
@@ -9535,7 +12517,7 @@
         \hsize\marginparwidth
         \@parboxrestore
         \@marginparreset
-        #2%
+        #2\par
         \@minipagefalse
         \outer at nobreak
         }%
@@ -9599,6 +12581,7 @@
     \color at begingroup
       \@makefntext{%
         \rule\z@\footnotesep\ignorespaces#1\@finalstrut\strutbox}%
+    \par
     \color at endgroup}}%
 \def\footnotemark{%
    \@ifnextchar[\@xfootnotemark
@@ -9629,6 +12612,12 @@
   \@footnotetext}
 \def\@mpfn{footnote}
 \def\thempfn{\thefootnote}
+\def\footref#1{%
+  \begingroup
+    \unrestored at protected@xdef\@thefnmark{\ref{#1}}%
+  \endgroup
+  \@footnotemark
+}
 %%% From File: ltidxglo.dtx
 \message{index,}
 \def\makeindex{%
@@ -9710,8 +12699,7 @@
       \@ifundefined{b@\@citeb}{\G at refundefinedtrue
           \@latex at warning{Citation `\@citeb' undefined}}{}}%
   \else
-    \@latex at error{Cannot be used in preamble}\@eha
-    % \AtBeginDocument{\nocite{#1}}
+    \AddToHook{begindocument/end}[kernel]{\nocite{#1}}%
   \fi
   \@esphack}
 \expandafter\let\csname b@*\endcsname\@empty
@@ -9783,6 +12771,7 @@
 \let\@declaredoptions\@empty
 \let\@classoptionslist\relax
 \@onlypreamble\@classoptionslist
+\let\@raw at classoptionslist\relax
 \let\@unusedoptionlist\@empty
 \@onlypreamble\@unusedoptionlist
 \let\CurrentOption\@empty
@@ -9936,7 +12925,11 @@
     \zap at space#2 \@empty}%
   \expandafter\let
     \csname opt@#3.#1\expandafter\endcsname
-    \csname opt@\reserved at a\endcsname}
+    \csname opt@\reserved at a\endcsname
+    \@ifundefined{@raw at opt@#3.#1}%
+      {\expandafter\gdef\csname @raw at opt@#3.#1\endcsname{#2}}%
+      {\expandafter\g at addto@macro\csname @raw at opt@#3.#1\endcsname{,#2}}%
+}
 \@onlypreamble\@pass at ptions
 \def\PassOptionsToPackage{\@pass at ptions\@pkgextension}
 \def\PassOptionsToClass{\@pass at ptions\@clsextension}
@@ -9955,11 +12948,12 @@
 \@onlypreamble\DeclareOption
 \@onlypreamble\@declareoption
 \@onlypreamble\@defdefault at ds
+\def\@remove at eq@value#1=#2\@nil{#1}
 \def\OptionNotUsed{%
   \ifx\@currext\@clsextension
     \xdef\@unusedoptionlist{%
       \ifx\@unusedoptionlist\@empty\else\@unusedoptionlist,\fi
-      \CurrentOption}%
+      \expandafter\@remove at eq@value\CurrentOption=\@nil}%
   \fi}
 \@onlypreamble\OptionNotUsed
 \def\ProcessOptions{%
@@ -9982,14 +12976,15 @@
 \@onlypreamble\@process at ptions
 \def\@xprocess at ptions{%
   \ifx\@currext\@clsextension\else
+   \ifx\@classoptionslist\relax\else
     \@for\CurrentOption:=\@classoptionslist\do{%
       \ifx\CurrentOption\@empty\else
-        \@expandtwoargs\in@{,\CurrentOption,}{,\@declaredoptions,}%
-        \ifin@
+        \@ifundefined{ds@\CurrentOption}{}{%
           \@use at ption
           \expandafter\let\csname ds@\CurrentOption\endcsname\@empty
-        \fi
+        }%
       \fi}%
+    \fi
   \fi
   \@process at pti@ns}
 \@onlypreamble\@xprocess at ptions
@@ -10010,7 +13005,8 @@
 \def\@options{\ProcessOptions*}
 \@onlypreamble\@options
 \def\@use at ption{%
-  \@expandtwoargs\@removeelement\CurrentOption
+  \@expandtwoargs\@removeelement
+     {\expandafter\@remove at eq@value\CurrentOption=\@nil}%
   \@unusedoptionlist\@unusedoptionlist
   \csname ds@\CurrentOption\endcsname}
 \@onlypreamble\@use at ption
@@ -10108,6 +13104,7 @@
   \ifx#1\@clsextension
     \ifx\@classoptionslist\relax
       \xdef\@classoptionslist{\zap at space#2 \@empty}%
+      \gdef\@raw at classoptionslist{#2}%
       \def\reserved at a{%
         \@onefilewithoptions#3[{#2}][{#4}]#1%
         \@documentclasshook}%
@@ -10369,14 +13366,12 @@
       \let\write\@gobbletwo%
       \let\closeout\@gobble%
     \else%
-      \edef\reserved at a{#1}%
-      \edef\reserved at a{\detokenize\expandafter{\reserved at a}}%
       \edef\reserved at b{\detokenize\expandafter{\jobname}}%
-      \ifx\reserved at a\reserved at b%
+      \ifx\@curr at file\reserved at b%
         \@fileswtrue%
       \else%
         \edef\reserved at b{\reserved at b\detokenize{.tex}}%
-        \ifx\reserved at a\reserved at b
+        \ifx\@curr at file\reserved at b
           \@fileswtrue%
         \fi%
       \fi%
@@ -10422,7 +13417,8 @@
       \ifx\relax##1\relax%
       \else%
           \@latex at warning{Writing text `##1' before %
-             \string\end{\@currenvir}\MessageBreak as last line of \@curr at file}%
+            \string\end{\@currenvir}\MessageBreak
+            as last line of \@curr at file}%
         \immediate\write\reserved at c{##1}%
       \fi%
       \ifx\relax##2\relax%
@@ -10646,12 +13642,9 @@
     \expandafter\@secondoftwo
   \fi
 }
-%%
-%% File: ltfilehook.dtx (C) Copyright 2020 Frank Mittelbach,
-%%                                         Phelype Oleinik & LaTeX Team
 %%% From File: ltfilehook.dtx
-\providecommand\ltfilehookversion{v1.0e}
-\providecommand\ltfilehookdate{2021/01/07}
+\providecommand\ltfilehookversion{v1.0k}
+\providecommand\ltfilehookdate{2021/05/25}
 \ExplSyntaxOn
 \tl_new:N \CurrentFile
 \tl_new:N \CurrentFilePath
@@ -10689,7 +13682,8 @@
 \cs_new:Npn \__filehook_drop_extension_aux:nnn #1 #2 #3
    { \tl_if_empty:nF {#1} { #1 / } #2 }
 \tl_new:N \l__filehook_internal_tl
-\seq_new:N \g__filehook_input_file_seq
+\seq_if_exist:NF \g__filehook_input_file_seq
+  { \seq_new:N \g__filehook_input_file_seq }
 \cs_new_protected:Npn \__filehook_file_push:
   {
     \seq_gpush:Nx \g__filehook_input_file_seq
@@ -10703,7 +13697,7 @@
     \seq_gpop:NNTF \g__filehook_input_file_seq \l__filehook_internal_tl
       { \exp_after:wN \__filehook_file_pop_assign:nnnn \l__filehook_internal_tl }
       {
-        \msg_error:nnn { hooks } { should-not-happen }
+        \msg_error:nnn { kernel } { should-not-happen }
           { Tried~to~pop~from~an~empty~file~name~stack. }
       }
   }
@@ -10756,7 +13750,8 @@
           @file-subst@
           \__filehook_subst_file_normalize:Nn \use_ii_iii:nnn {#1}
         }
-        { \__filehook_subst_file_normalize:Nn \__filehook_file_name_compose:nnn {#2} }
+        { \__filehook_subst_file_normalize:Nn \__filehook_file_name_compose:nnn
+                                      {#2} }
     \group_end:
   }
 \cs_new_protected:Npn \__filehook_subst_remove:n #1
@@ -10789,6 +13784,8 @@
 \def\set at curr@file#1{%
   \begingroup
     \escapechar\m at ne
+    \let\protect\string
+    \edef~{\string~}%
     \expandafter\def\csname\expandafter\endcsname
       \expandafter{\csname\endcsname}%
     \@expl@@@filehook at if@no at extension@@nTF{#1}%
@@ -10911,7 +13908,7 @@
 \cs_new_eq:NN \@expl@@@filehook at drop@extension@@N
               \__filehook_drop_extension:N
 \cs_new_eq:NN \@expl@@@filehook at file@push@@
-               \__filehook_file_push:
+              \__filehook_file_push:
 \cs_new_eq:NN \@expl@@@filehook at file@pop@@
               \__filehook_file_pop:
 \cs_new_eq:NN \@expl@@@filehook at file@pop at assign@@nnnn
@@ -10920,11 +13917,12 @@
 \declare at file@substitution{atveryend.sty}{atveryend-ltx.sty}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%
-%% File: ltshipout.dtx (C) Copyright 2020 Frank Mittelbach, LaTeX Team
+%% Copyright (C) 2020-2021
+%%               Frank Mittelbach, LaTeX Team
 %%
 %%% From File: ltshipout.dtx
-\providecommand\ltshipoutversion{v1.0d}
-\providecommand\ltshipoutdate{2020/11/24}
+\providecommand\ltshipoutversion{v1.0i}
+\providecommand\ltshipoutdate{2021/03/17}
 \ExplSyntaxOn
 \bool_new:N \g__shipout_debug_bool
 \cs_new_eq:NN \__shipout_debug:n  \use_none:n
@@ -10945,6 +13943,27 @@
   }
 \box_new:N  \l_shipout_box
 \cs_set_eq:NN \ShipoutBox \l_shipout_box
+\box_new:N  \l__shipout_raw_box
+\sys_if_engine_luatex:TF
+  {
+    \newluafunction \__shipout_finalize_box:
+    \exp_args:Nx \everyjob {
+      \exp_not:V \everyjob
+      \exp_not:N \lua_now:n {
+        luatexbase.create_callback('pre_shipout_filter', 'list')
+        local~call, getbox, setbox = luatexbase.call_callback, tex.getbox, tex.setbox~
+        lua.get_functions_table()[\the \__shipout_finalize_box:] = function()
+          local~result = call('pre_shipout_filter', getbox(\the \l_shipout_box))
+          if~not (result == true) then~
+            setbox(\the \l_shipout_box, result~or~nil)
+          end~
+        end
+      }
+    }
+    \protected \luadef \__shipout_finalize_box: \the \__shipout_finalize_box:
+  } {
+    \cs_set_eq:NN \__shipout_finalize_box: \scan_stop:
+  }
 \cs_set_protected:Npn \__shipout_execute: {
   \tl_set:Nx \l__shipout_group_level_tl
      { \int_value:w \tex_currentgrouplevel:D }
@@ -10956,26 +13975,43 @@
 \cs_new:Npn \__shipout_execute_test_level: {
   \int_compare:nNnT
      \l__shipout_group_level_tl < \tex_currentgrouplevel:D
-     \tex_aftergroup:D
-  \__shipout_execute_cont:
+     \tex_aftergroup:D \__shipout_execute_cont:
 }
 \cs_new:Npn \__shipout_execute_cont: {
-  \box_if_empty:NTF \l_shipout_box
-    { \PackageWarning{ltshipout}{Ignoring~ void~ shipout~ box} }
+  \__shipout_execute_main_cont:Nnnn
+     \l_shipout_box
+     { \hook_use:n {shipout/before} }
+     { \hook_if_empty:nF {shipout/foreground}
+         { \__shipout_add_foreground_picture:n
+             { \hook_use:n {shipout/foreground} } }
+       \bool_lazy_and:nnF
+         { \hook_if_empty_p:n {shipout/background} }
+         { \tl_if_empty_p:N \@kernel at before@shipout at background }
+         { \__shipout_add_background_picture:n
+           { \@kernel at before@shipout at background
+             \hook_use:n {shipout/background}
+             \@kernel at after@shipout at background }
+         }
+     }
+     { \hook_use:n {shipout/after} }
+}
+\cs_new:Npn \__shipout_execute_main_cont:Nnnn #1#2#3#4 {
+  \box_if_empty:NTF #1
+    { \@latex at warning{Ignoring~ void~ shipout~ box} }
     {
-      \bool_gset_false:N \g__shipout_discard_bool
+                                              % \DiscardShipoutBox on doc-level
       \cs_set_eq:NN \__shipout_saved_protect: \protect
       \set at typeset@protect
-      \__shipout_get_box_size:N \l_shipout_box
-      \hook_use:n {shipout/before}
+      \__shipout_get_box_size:N #1
+      #2
       \int_gincr:N \g_shipout_totalpages_int
       \bool_if:NTF \g__shipout_discard_bool
-        { \PackageInfo{ltshipout}{Completed~ page~ discarded}
+        { \@latex at info@no at line{Completed~ page~ discarded}
           \bool_gset_false:N \g__shipout_discard_bool
           \tex_deadcycles:D \c_zero_int
         }
-        { \box_if_empty:NTF \l_shipout_box
-            { \PackageWarning{ltshipout}{
+        { \box_if_empty:NTF #1
+            { \@latex at warning{
                 Shipout~ box~ was~ voided~ by~ hook,\MessageBreak
                 ignoring~ shipout~ box  }
             }
@@ -10985,33 +14021,54 @@
                 \typeout{Absolute~ page~ =~ \int_use:N \g_shipout_readonly_int
                          \space (target:~ \@abspage at last)}
               }
-              \__shipout_get_box_size:N \l_shipout_box
-              \hook_if_empty:nF {shipout/foreground}
-                   { \__shipout_add_foreground_picture:n
-                     { \hook_use:n {shipout/foreground} } }
-              \hook_if_empty:nF {shipout/background}
-                   { \__shipout_add_background_picture:n
-                     { \@kernel at before@shipout at background
-                       \hook_use:n {shipout/background} } }
-              \__shipout_execute_firstpage_hook:
+              \__shipout_get_box_size:N #1
+              \__shipout_run_firstpage_hook:
+              #3
+              \__shipout_add_firstpage_specials:
               \int_compare:nNnT \@abspage at last = \g_shipout_readonly_int
-                { \hook_if_empty:nF {shipout/lastpage}
+                { \bool_lazy_and:nnF
+                    { \hook_if_empty_p:n {shipout/lastpage} }
+                    { \tl_if_empty_p:N \@kernel at after@shipout at lastpage }
                     { \__shipout_debug:n { \typeout{Executing~ lastpage~ hook~
-                          on~ page~ \int_use:N \g_shipout_readonly_int }        }
-                      \__shipout_add_foreground_box:n { \UseHook{shipout/lastpage}
-                                                  \@kernel at after@shipout at lastpage }
+                          on~ page~ \int_use:N \g_shipout_readonly_int } }
+                      \__shipout_add_foreground_box:n
+                          { \UseHook{shipout/lastpage}
+                            \@kernel at after@shipout at lastpage }
                     }
                     \bool_gset_true:N \g__shipout_lastpage_handled_bool
                 }
+              \__shipout_finalize_box:
               \cs_set_eq:NN \protect \exp_not:N
               \tex_shipout:D \box_use:N \l_shipout_box
+              \__shipout_drop_firstpage_specials:
+              \set at typeset@protect
+              #4
             }
         }
       \cs_set_eq:NN \protect \__shipout_saved_protect:
     }
 }
+\cs_set_protected:Npn \__shipout_execute_raw: {
+  \tl_set:Nx \l__shipout_group_level_tl
+     { \int_value:w \tex_currentgrouplevel:D }
+  \tex_afterassignment:D \__shipout_execute_test_level_raw:
+  \tex_setbox:D \l__shipout_raw_box
+}
+\cs_new:Npn \__shipout_execute_test_level_raw: {
+  \int_compare:nNnT
+     \l__shipout_group_level_tl < \tex_currentgrouplevel:D
+     \tex_aftergroup:D \__shipout_execute_nohooks_cont:
+}
+\cs_new:Npn \__shipout_execute_nohooks_cont: {
+  \__shipout_execute_main_cont:Nnnn \l__shipout_raw_box
+     {} { \__shipout_debug:n{ \typeout{Doing~ raw~ shipout~ ...} }
+          \box_set_eq:NN \l_shipout_box \l__shipout_raw_box } {}
+}
+
+\cs_gset_eq:NN \RawShipout \__shipout_execute_raw:
 \cs_new_eq:NN  \__shipout_saved_protect: \protect
 \hook_new:n{shipout/before}
+\hook_new:n{shipout/after}
 \hook_new:n{shipout/foreground}
 \hook_new:n{shipout/background}
 \hook_new:n{shipout/firstpage}
@@ -11018,10 +14075,17 @@
 \hook_new:n{shipout/lastpage}
 \let\@kernel at after@shipout at lastpage\@empty
 \let\@kernel at before@shipout at background\@empty
-\cs_new:Npn \__shipout_execute_firstpage_hook: {
-  \hook_if_empty:nF {shipout/firstpage}
-       { \__shipout_add_background_box:n { \UseHook{shipout/firstpage} } }
-  \cs_gset_eq:NN \__shipout_execute_firstpage_hook: \prg_do_nothing:
+\let\@kernel at after@shipout at background\@empty
+\cs_new:Npn \__shipout_run_firstpage_hook: {
+  \hook_if_empty:nTF {shipout/firstpage}
+       {
+         \cs_gset_eq:NN \__shipout_add_firstpage_specials:  \prg_do_nothing:
+         \cs_gset_eq:NN \__shipout_drop_firstpage_specials: \prg_do_nothing:
+       }
+       {
+         \hbox_set:Nn \l__shipout_firstpage_box { \UseHook{shipout/firstpage} }
+       }
+  \cs_gset_eq:NN \__shipout_run_firstpage_hook: \prg_do_nothing:
   \cs_gset:Npn \__shipout_add_firstpage_material:Nn ##1 ##2 {
     \@latex at warning{
         First~ page~ is~ already~ shipped~ out,~ ignoring\MessageBreak
@@ -11028,6 +14092,18 @@
         \string##1 }
   }
 }
+\cs_new:Npn \__shipout_add_firstpage_specials: {
+  \box_set_eq:NN \l__shipout_raw_box \l_shipout_box
+  \__shipout_add_background_box:n { \hbox_unpack_drop:N \l__shipout_firstpage_box }
+  \cs_gset_eq:NN \__shipout_add_firstpage_specials: \prg_do_nothing:
+}
+\cs_new:Npn \__shipout_drop_firstpage_specials: {
+    \box_set_eq:NN \l_shipout_box \l__shipout_raw_box
+    \cs_gset_eq:NN \__shipout_drop_firstpage_specials:  \prg_do_nothing:
+  }
+
+\box_new:N \l__shipout_firstpage_box
+
 \bool_new:N \g__shipout_lastpage_handled_bool
 \cs_new:Npn \__shipout_add_firstpage_material:Nn #1#2 {
    \AddToHook{shipout/firstpage}{#2}
@@ -11036,8 +14112,8 @@
   \dim_set:Nn \l_shipout_box_ht_dim { \box_ht:N #1 }
   \dim_set:Nn \l_shipout_box_dp_dim { \box_dp:N #1 }
   \dim_set:Nn \l_shipout_box_wd_dim { \box_wd:N #1 }
-  \dim_set:Nn \l_shipout_box_ht_plus_dp_dim { \l_shipout_box_ht_dim +
-                                         \l_shipout_box_dp_dim }
+  \dim_set:Nn \l_shipout_box_ht_plus_dp_dim
+      { \l_shipout_box_ht_dim + \l_shipout_box_dp_dim }
 }
 \dim_new:N \l_shipout_box_ht_dim
 \dim_new:N \l_shipout_box_dp_dim
@@ -11243,7 +14319,8 @@
   {\ifnum\@abspage at last<\maxdimen
      \xdef\PreviousTotalPages{\@abspage at last}\fi}
 \cs_new_eq:NN \DiscardShipoutBox \shipout_discard:
-\cs_set_protected:Npn \AtBeginDvi {\__shipout_add_firstpage_material:Nn \AtBeginDvi}
+\cs_set_protected:Npn \AtBeginDvi
+                      {\__shipout_add_firstpage_material:Nn \AtBeginDvi}
 \cs_new_eq:NN \DebugShipoutsOn  \shipout_debug_on:
 \cs_new_eq:NN \DebugShipoutsOff \shipout_debug_off:
 \cs_set_eq:NN \@expl@@@shipout at add@firstpage at material@@Nn
@@ -11268,7 +14345,6 @@
       and you can safely remove it.\MessageBreak
       Found on}}
 \declare at file@substitution{atbegshi.sty}{atbegshi-ltx.sty}
-\declare at file@substitution{everyshi.sty}{everyshi-ltx.sty}
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %%% From File: ltoutput.dtx
 \expandafter\let\csname ver at autoout1.sty\endcsname\fmtversion
@@ -11451,7 +14527,7 @@
   \global \advance \@colht \@tempdima
   \ifx \@dbltoplist \@empty
   \else
-    \@latexerr{Float(s) lost}\@ehb
+    \@latex at error{Float(s) lost}\@ehb
     \let \@dbltoplist \@empty
   \fi
   \@cons \@dbltoplist \@currbox
@@ -11564,7 +14640,7 @@
        \global \@colroom \@colht
        \ifx \@currlist\@empty
        \else
-          \@latexerr{Float(s) lost}\@ehb
+          \@latex at error{Float(s) lost}\@ehb
           \global \let \@currlist \@empty
        \fi
        \@makefcolumn\@deferlist
@@ -12135,9 +15211,9 @@
 \gdef\@enlargepage#1#2{%
    \@tempskipa#2\relax
    \ifdim \@tempskipa>.5\maxdimen
-     \@latexerr{Suggested\space extra\space height\space
-                (\the\@tempskipa)\space dangerously\space
-                large}\@eha
+     \@latex at error{Suggested\space extra\space height\space
+                   (\the\@tempskipa)\space dangerously\space
+                   large}\@eha
    \else
      \ifdim \vsize<.5\maxdimen
        \@bsphack
@@ -12144,8 +15220,8 @@
          \insert\@kludgeins{#1\vskip-\@tempskipa}%
        \@esphack
      \else
-       \@latexerr{Page\space height\space already\space
-                  too\space large}\@eha
+       \@latex at error{Page\space height\space already\space
+                     too\space large}\@eha
      \fi
    \fi
 }
@@ -12357,6 +15433,33 @@
   \countdef\xe at alloc@intercharclass=257
   \xe at alloc@intercharclass=\z@
 \fi
+\ifx\directlua\@undefined
+\else
+  \expanded{%
+    \everyjob{\the\everyjob
+    \noexpand%\directlua
+    \directlua{%
+      local function trace_stack_levels (input_ptr)
+        local tracingstacklevels = tex.count.tracingstacklevels
+        if tex.tracingmacros > 0 or input_ptr < tracingstacklevels then
+          if tracingstacklevels > 0 then
+            if input_ptr < tracingstacklevels then
+              return "\string\n\string~" .. string.rep(".",input_ptr)
+            else
+              return "\string~\string~"
+            end
+          else
+            return "\string\n"
+          end
+        else
+          return ""
+        end
+      end
+      luatexbase.add_to_callback('input_level_string',
+        trace_stack_levels,'tracingstacklevels')
+    }%
+  }}%
+\fi
 \unitlength = 1pt
 \fboxsep = 3pt
 \fboxrule = .4pt
@@ -12449,6 +15552,22 @@
    \errmessage{}
 \def\font at submax{0pt}
 \fi
+\ifx \pdfgentounicode \@undefined \else
+  \ifnum 0=0%
+    \ifdefined\pdftexversion
+      \ifnum \pdftexversion=140 \ifnum\pdftexrevision<22 1\fi\fi
+    \fi
+    \relax
+    \input glyphtounicode
+  \else
+    \begingroup
+      \everyeof{\noexpand}\endlinechar-1
+      \edef\x{\endgroup
+        \everyjob{\the\everyjob\@@input glyphtounicode }%
+    }\x
+  \fi
+  \pdfgentounicode=1
+\fi
 \ifnum0%
   \ifx\Umathcode\@undefined\else 1\fi
   \ifx\mubyte\@undefined\else 1\fi

Modified: trunk/Master/texmf-dist/tex/latex/base/latex209.def
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/latex209.def	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/latex209.def	2021-06-01 21:12:14 UTC (rev 59424)
@@ -15,8 +15,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -44,7 +44,7 @@
 %% and covered by LPPL is defined by the unpacking scripts (with
 %% extension .ins) which are part of the distribution.
 \NeedsTeXFormat{LaTeX2e}
-\ProvidesFile{latex209.def}[2020/08/21 v0.55 Standard LaTeX file]
+\ProvidesFile{latex209.def}[2020/11/26 v0.55 Standard LaTeX file]
 \if at compatibility
   \expandafter\endinput
 \else

Modified: trunk/Master/texmf-dist/tex/latex/base/latexrelease.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/base/latexrelease.sty	2021-06-01 21:08:14 UTC (rev 59423)
+++ trunk/Master/texmf-dist/tex/latex/base/latexrelease.sty	2021-06-01 21:12:14 UTC (rev 59424)
@@ -12,11 +12,14 @@
 %% ltluatex.dtx  (with options: `latexrelease')
 %% ltexpl.dtx  (with options: `latexrelease')
 %% ltdefns.dtx  (with options: `latexrelease')
+%% ltcmd.dtx  (with options: `latexrelease')
 %% lthooks.dtx  (with options: `latexrelease')
+%% ltcmdhooks.dtx  (with options: `latexrelease')
 %% ltalloc.dtx  (with options: `latexrelease')
 %% ltcntrl.dtx  (with options: `latexrelease')
 %% lterror.dtx  (with options: `latexrelease')
 %% ltpar.dtx  (with options: `latexrelease')
+%% ltpara.dtx  (with options: `latexrelease')
 %% ltspace.dtx  (with options: `latexrelease')
 %% ltlogos.dtx  (with options: `latexrelease')
 %% ltfiles.dtx  (with options: `latexrelease')
@@ -51,6 +54,7 @@
 %% ltoutput.dtx  (with options: `latexrelease')
 %% ltfsscmp.dtx  (with options: `latexrelease')
 %% ltfinal.dtx  (with options: `latexrelease')
+%% latexrelease.dtx  (with options: `latexrelease-finish')
 %% 
 %% This is a generated file.
 %% 
@@ -59,8 +63,8 @@
 %% (but please observe conditions on bug reports sent to that address!)
 %% 
 %% 
-%% Copyright (C) 1993-2020
-%% The LaTeX3 Project and any individual authors listed elsewhere
+%% Copyright (C) 1993-2021
+%% The LaTeX Project and any individual authors listed elsewhere
 %% in this file.
 %% 
 %% This file was generated from file(s) of the LaTeX base system.
@@ -283,7 +287,7 @@
 }
 %%% From File: ltvers.dtx
 \edef\latexreleaseversion
-   {2020-10-01}
+   {2021-06-01}
 \newif\if at includeinrelease
 \@includeinreleasefalse
 \def\IncludeInRelease#1{%
@@ -292,17 +296,37 @@
                 {There is an \string\EndIncludeRelease\space missing}%
   \@includeinreleasefalse
   \fi
-  \kernel at ifnextchar[%
-  {\@IncludeInRelease{#1}}
-  {\@IncludeInRelease{#1}[#1]}}
+  \ifnum0%
+      \ifx\new at moduledate\@empty\else 1\fi
+      \ifnum \expandafter\@parse at version#1//00\@nil=0 1\fi
+      =11
+    \expandafter\@firstoftwo
+  \else
+    \expandafter\@secondoftwo
+  \fi
+    {\finish at module@release{#1}}%
+    {\kernel at ifnextchar[%
+      {\@IncludeInRelease{#1}}
+      {\@IncludeInRelease{#1}[#1]}}}
+\def\finish at module@release#1#2#3{%
+  \toks@{[#1] #3}%
+  \ifnum\expandafter\@parse at version\new at moduledate//00\@nil
+       >\expandafter\@parse at version\fmtversion//00\@nil
+    \GenericInfo{}{Applying: \the\toks@}%
+  \else
+    \GenericInfo{}{Skipping: \the\toks@}%
+    \expandafter\gobble at finish@module at release
+  \fi}
+\long\def\gobble at finish@module at release#1\EndModuleRelease{%
+  \EndModuleRelease}
 \def\@IncludeInRelease#1[#2]{\@IncludeInRele at se{#2}}
 \def\@IncludeInRele at se#1#2#3{%
   \toks@{[#1] #3}%
   \expandafter\ifx\csname\string#2+\@currname+IIR\endcsname\relax
     \ifnum\expandafter\@parse at version#1//00\@nil
-          >\expandafter\@parse at version\fmtversion//00\@nil
+         >\expandafter\@parse at version\fmtversion//00\@nil
       \GenericInfo{}{Skipping: \the\toks@}%
-     \expandafter\expandafter\expandafter\@gobble at IncludeInRelease
+      \expandafter\expandafter\expandafter\@gobble at IncludeInRelease
     \else
       \GenericInfo{}{Applying: \the\toks@}%
       \@includeinreleasetrue
@@ -318,6 +342,9 @@
   \@includeinreleasefalse
 \else
   \PackageError{latexrelease}{mis-matched EndIncludeInRelease}{}%
+\fi
+\if at skipping@module
+  \expandafter\new at module@skip
 \fi}
 \long\def\@gobble at IncludeInRelease#1\EndIncludeInRelease{%
   \@includeinreleasefalse
@@ -327,11 +354,55 @@
                                    #2#3\@end at check@IncludeInRelease{%
   \ifx\@check at IncludeInRelease#2\else
     \PackageError{latexrelease}{skipped IncludeInRelease for tag \string#2}{}%
+  \fi
+  \if at skipping@module
+    \expandafter\new at module@skip
   \fi}
+\let\if at skipping@module\iffalse
+\def\@skipping at moduletrue{\let\if at skipping@module\iftrue}
+\def\@skipping at modulefalse{\let\if at skipping@module\iffalse}
+\let\new at modulename\@empty
+\let\new at moduledate\@empty
+\def\NewModuleRelease#1#2#3{%
+  \ifx\new at modulename\@empty \else
+    \@latex at error{Nested \noexpand\NewModuleRelease forbidden.}\@ehd \fi
+  \edef\new at moduledate{#1}%
+  \edef\new at modulename{#2}%
+  \GenericInfo{}{BEGIN module: \new at modulename\space (\new at moduledate)}%
+  \GenericInfo{}{ \@spaces\@spaces\@spaces\space#3\@gobble}%
+  \ifnum\sourceLaTeXdate<%
+      \expandafter\@parse at version\new at moduledate//00\@nil\relax
+    \ifnum\expandafter\@parse at version\fmtversion//00\@nil<%
+          \expandafter\@parse at version\new at moduledate//00\@nil\relax
+      \GenericInfo{}{Skipping module \new at modulename}%
+      \expandafter\expandafter
+      \expandafter\gobble at finish@module at release
+    \else
+      \GenericInfo{}{Applying module \new at modulename}
+      \@skipping at modulefalse
+    \fi
+  \else
+    \GenericInfo{}{Skipping module \new at modulename}
+    \@skipping at moduletrue
+    \expandafter\new at module@skip
+  \fi}
+\long\def\new at module@skip#1\IncludeInRelease{\IncludeInRelease}
+\def\EndModuleRelease{%
+  \ifx\new at modulename\@empty
+    \@latex at error{Extra \string\EndModuleRelease.}\@eha
+  \else
+    \GenericInfo{}{END module: \new at modulename\space (\new at moduledate)}%
+    \let\new at modulename\@empty
+    \let\new at moduledate\@empty
+    \@skipping at modulefalse
+  \fi}
 \ProvidesPackage{latexrelease}
-          [2018/05/08 v1.0k LaTeX release emulation and tests
+          [2021/04/29 v1.0n LaTeX release emulation and tests
               (including releases up to \latexreleaseversion)]
 \NeedsTeXFormat{LaTeX2e}[1996/06/01]
+\@ifundefined{sourceLaTeXdate}{%
+  \edef\sourceLaTeXdate{%
+    \expandafter\@parse at version\fmtversion//00\@nil}}{}%
 \DeclareOption*{%
   \def\@IncludeInRelease#1[#2]{\@IncludeInRele at se{#1}}%
   \let\requestedpatchdate\CurrentOption}
@@ -382,6 +453,76 @@
 \fi
 \let\fmtversion\requestedpatchdate
 \let\currentLaTeXdate\requestedLaTeXdate
+\csname ExplSyntaxOn\endcsname
+\csname ExplSyntaxOff\endcsname
+\begingroup
+  \endlinechar=-1
+  \catcode95=11 % _
+  \catcode58=11 % :
+  \catcode126=10 % ~
+  \catcode32=09 % <space>
+  \xdef\latexrelease at postexpl{\unexpanded{%
+\cs_gset_protected:Npn \__latexrelease_declare_command:w
+  { \@star at or@long \__latexrelease_declare_command:Nw }
+\cs_gset_protected:Npn \__latexrelease_declare_command:Nw #1
+  { \cs_if_exist:NTF #1 { \renew at command } { \new at command } #1 }
+\cs_gset_protected:Npn \__latexrelease_e at alloc:NnnnnN #1 #2 #3 #4 #5 #6
+  {
+    \cs_if_free:NTF #6
+      { \use:n }
+      {
+        \exp_after:wN \__latexrelease_e at alloc:N
+          \token_to_meaning:N #6 \scan_stop: {#2} #6
+      }
+        { \__latexrelease_e at alloc #1 {#2} {#3} {#4} {#5} #6 }
+  }
+\cs_gset_protected:Npn \__latexrelease_e at alloc:N #1
+  {
+    \if_int_compare:w 0 < 0
+        \if_int_compare:w 10 < 9#1 ~ 1 \fi:
+        \if_charcode:w " #1 1 \fi: \exp_stop_f:
+      \tex_afterassignment:D \__latexrelease_e at alloc:w
+      \@tempcnta #1
+      \use_i:nnn
+    \fi:
+    \use:n
+      {
+        \if_meaning:w \scan_stop: #1
+          \exp_after:wN \use_iv:nnnn
+        \fi:
+        \__latexrelease_e at alloc:N
+      }
+  }
+\cs_gset_protected:Npn \__latexrelease_e at alloc:w #1 \scan_stop: #2 #3
+  {
+    #2 \__latexrelease_tmp:w = \@tempcnta
+    \token_if_eq_meaning:NNTF #3 \__latexrelease_tmp:w
+      { \int_set_eq:NN \allocationnumber \@tempcnta  \use_none:n }
+      { \cs_set_eq:NN #3 \tex_undefined:D            \use:n      }
+  }
+\tl_clear_new:N \l__latexrelease_restores_tl
+\cs_gset:Npn \__latexrelease_tmp:w #1 #2
+  {
+    \quark_if_recursion_tail_stop_do:Nn #1
+      { \cs_undefine:N \__latexrelease_tmp:w }
+    \tl_put_right:Nn \l__latexrelease_restores_tl {#1}
+    \cs_set_eq:cN { __latexrelease_ \cs_to_str:N #1 } #1
+    \cs_set_eq:NN #1 #2
+    \__latexrelease_tmp:w
+  }
+\__latexrelease_tmp:w
+  \__kernel_chk_if_free_cs:N \use_none:n
+  \e at alloc \__latexrelease_e at alloc:NnnnnN
+  \__kernel_msg_error:nnx \use_none:nnn
+  \msg_new:nnnn \msg_gset:nnnn
+  \NewDocumentCommand \DeclareDocumentCommand
+  \newcommand \__latexrelease_declare_command:w
+  \__kernel_msg_error:nnn  \use_none:nnn  % needed while redirect for kernel msgs doesn't work
+  \q_recursion_tail \q_recursion_tail
+  \q_recursion_stop
+\msg_redirect_name:nnn { hooks } { exists } { none }
+  }}%
+\endgroup
 %%% From File: ltdirchk.dtx
 \ifx\directlua\undefined\else
 \IncludeInRelease{2015/10/01}{\luatexluafunction}
@@ -679,6 +820,45 @@
   \global\chardef#1\allocationnumber
   \wlog{\string#1=\string\insert\the\allocationnumber}}
 \EndIncludeInRelease
+\IncludeInRelease{2021/06/01}{\tracingstacklevels}%
+                 {tracingstacklevels}%
+\ifx\directlua\@undefined
+  % \tracingstacklevels=0 % added in 2021
+\else
+  \newcount\tracingstacklevels
+  % Code for \tracingstacklevels defined in ltfinal.dtx
+\fi
+\EndIncludeInRelease
+
+\IncludeInRelease{0000/00/00}{\tracingstacklevels}%
+                 {tracingstacklevels}%
+\ifx\directlua\@undefined
+\else
+  \let\tracingstacklevels\@undefined
+\fi
+\EndIncludeInRelease
+\IncludeInRelease{2021/06/01}{\loggingall}
+                 {\tracingstacklevels and \tracinglostchars=3}%
+\edef\loggingall{%
+  \tracingstats\tw@
+  \tracingpages\@ne
+  \tracinglostchars\thr@@
+  \tracingparagraphs\@ne
+  \tracinggroups\@ne
+  \tracingifs\@ne
+  \tracingscantokens\@ne
+  \tracingnesting\@ne
+  \errorcontextlines\maxdimen
+  \ifdefined\tracingstacklevels \tracingstacklevels\maxdimen \fi
+  \noexpand \loggingoutput
+  \tracingmacros\tw@
+  \tracingcommands\thr@@
+  \tracingrestores\@ne
+  \tracingassigns\@ne
+}%
+\def\tracingall{\showoverfull\loggingall}
+\EndIncludeInRelease
+
 \IncludeInRelease{2015/01/01}{\loggingall}{etex tracing}%
 \ifx\tracingscantokens\@undefined
 \gdef\loggingall{%
@@ -712,6 +892,7 @@
 \fi
 \gdef\tracingall{\showoverfull\loggingall}
 \EndIncludeInRelease
+
 \IncludeInRelease{0000/00/00}{\loggingall}{etex tracing}%
 \gdef\loggingall{\tracingcommands\tw@\tracingstats\tw@
   \tracingpages\@ne\tracinglostchars\@ne
@@ -721,6 +902,30 @@
 \EndIncludeInRelease
 \IncludeInRelease{2015/01/01}{\tracingnone}%
                              {turn off etex tracing}%
+\edef\tracingnone{%
+  \tracingassigns\z@
+  \tracingrestores\z@
+  \tracingonline\z@
+  \tracingcommands\z@
+  \showboxdepth\m at ne
+  \showboxbreadth\m at ne
+  \tracingoutput\z@
+  \errorcontextlines\m at ne
+  \ifdefined\tracingstacklevels \tracingstacklevels\z@ \fi
+  \tracingnesting\z@
+  \tracingscantokens\z@
+  \tracingifs\z@
+  \tracinggroups\z@
+  \tracingparagraphs\z@
+  \tracingmacros\z@
+  \tracinglostchars\@ne
+  \tracingpages\z@
+  \tracingstats\z@
+}%
+\EndIncludeInRelease
+
+\IncludeInRelease{2015/01/01}{\tracingnone}%
+                             {turn off etex tracing}%
 \ifx\tracingscantokens\@undefined
 \def\tracingnone{%
   \tracingonline\z@
@@ -757,6 +962,14 @@
   \tracingstats\z@
 }%
 \fi
+\EndIncludeInRelease
+
+\IncludeInRelease{0000/00/00}{\tracingnone}%
+                             {turn off etex tracing}%
+\let\tracingnone\@undefined
+\EndIncludeInRelease
+\IncludeInRelease{2015/01/01}{\hideoutput}%
+                             {hide output from tracing}%
 \def\hideoutput{%
   \tracingoutput\z@
   \showboxbreadth\m at ne
@@ -764,9 +977,9 @@
   \tracingonline\m at ne
 }%
 \EndIncludeInRelease
-\IncludeInRelease{0000/00/00}{\tracingnone}%
-                             {turn off etex tracing}%
-\let\tracingnone\@undefined
+
+\IncludeInRelease{0000/00/00}{\hideoutput}%
+                             {hide output from tracing}%
 \let\hideoutput\@undefined
 \EndIncludeInRelease
 \ifx\directlua\@undefined\else
@@ -980,21 +1193,28 @@
 \fi
 %%% From File: ltexpl.dtx
 \IncludeInRelease{2020/10/01}%
-  {kernel at enddocument hooks}{Define kernel enddocument Hooks}%
-\let\@kernel at after@enddocument\@empty
-\let\@kernel at after@enddocument at afterlastpage\@empty
+  {kernel at enddocument hooks}{Define several kernel hooks}
+\ifx\@kernel at after@enddocument\@undefined
+  \let \@kernel at after@enddocument               \@empty
+  \let \@kernel at after@enddocument at afterlastpage \@empty
+  \let \@kernel at before@begindocument \@empty
+  \let \@kernel at after@begindocument  \@empty
+\fi
 \EndIncludeInRelease
 \IncludeInRelease{0000/00/00}%
-  {kernel at enddocument hooks}{Define kernel enddocument Hooks}%
+  {kernel at enddocument hooks}{Define several kernel hooks}
 \let\@kernel at after@enddocument\@undefined
 \let\@kernel at after@enddocument at afterlastpage\@undefined
+\let\@kernel at before@begindocument\@undefined
+\let\@kernel at after@begindocument\@undefined
 \EndIncludeInRelease
 \IncludeInRelease{2020/10/01}%
             {\@expl at sys@load at backend@@}{Roll forward support}%
-\def\@expl at sys@load at backend@@{}
-\def\@expl at push@filename@@{}
-\def\@expl at push@filename at aux@@{}
-\def\@expl at pop@filename@@{}
+\def\reserved at a#1{\ifdefined#1\else\def#1{}\fi}
+\reserved at a\@expl at sys@load at backend@@
+\reserved at a\@expl at push@filename@@
+\reserved at a\@expl at push@filename at aux@@
+\reserved at a\@expl at pop@filename@@
 \EndIncludeInRelease
 \IncludeInRelease{2020/10/01}%
                  {expl3}{Pre-load expl3}%
@@ -1034,17 +1254,9 @@
            --- I'm giving up!\MessageBreak\MessageBreak
            Note that manually loading the expl3 package\MessageBreak
            from your distribution is not enough}%
-        \@@end  % die
+        \batchmode \read -1 to \reserved at a
       }%
-      {%
-        \input expl3.ltx
-        \ifdefined\NewDocumentCommand
-        \else
-          \IfFileExists{xparse.ltx}
-            {\input xparse.ltx }
-            {}%
-         \fi
-      }%
+      {\input expl3.ltx }%
   }
 \EndIncludeInRelease
 
@@ -1068,14 +1280,6 @@
   }%
 \input{expl3.ltx}
 \EndIncludeInRelease
-\IncludeInRelease{2020/10/01}%
-                 {\NewDocumentCommand}{Emergency loading xparse}%
-
-\ifdefined\NewDocumentCommand \else
-  \RequirePackage{xparse}
-\fi
-
-\EndIncludeInRelease
 \IncludeInRelease{2020/10/01}{\@expl at cs@to at str@@N}%
         {expl3 macros added for the 2020-10-01 release}%
 \ExplSyntaxOn
@@ -1122,7 +1326,7 @@
   \count@=\escapechar
   \escapechar=`\\
   \@ifundefined{\expandafter\@gobble\string#1}{%
-    \@latex at error{The control sequence `\string#1' is undefined!%
+    \@latex at error{Command `\string#1' is undefined!%
       \MessageBreak There is nothing here to make robust}%
     \@eha
   }%
@@ -1142,7 +1346,7 @@
         \noexpand\protect\expandafter\noexpand
         \csname\expandafter\@gobble\string#1\space\endcsname}%
     }%
-    {\@latex at info{The control sequence `\string#1' is already robust}}%
+    {\@latex at info{Command `\string#1' is already robust}}%
   }%
   \escapechar=\count@
 }%
@@ -1576,15 +1780,2281 @@
 \kernel at make@fragile\underbar
 
 \EndIncludeInRelease
-%%
-%% File: lthooks.dtx (C) Copyright 2020 Frank Mittelbach,
-%%                                      Phelype Oleinik & LaTeX Team
+%%% From File: ltcmd.dtx
+\def\ltcmdversion{v1.0e}
+\def\ltcmddate{2021-05-24}
+\edef\@latexrelease at catcode@null{\the\catcode`\^^@ }
+\catcode`\^^@=12
+\ExplSyntaxOn
+\NewModuleRelease{2020/10/01}{ltcmd}
+                 {Document~command~parser}%
+\tl_new:N \l__cmd_arg_spec_tl
+\tl_new:N \l__cmd_args_tl
+\tl_new:N \l__cmd_args_i_tl
+\tl_new:N \l__cmd_args_ii_tl
+\int_new:N \l__cmd_current_arg_int
+\bool_new:N \l__cmd_defaults_bool
+\tl_new:N \l__cmd_defaults_tl
+\bool_new:N \l__cmd_environment_bool
+\str_new:N \l__cmd_environment_str
+\bool_new:N \l__cmd_expandable_bool
+\tl_new:N \l__cmd_expandable_aux_name_tl
+\tl_set:Nn \l__cmd_expandable_aux_name_tl
+  {
+    \l__cmd_function_tl \c_space_tl
+    ( arg~ \int_use:N \l__cmd_current_arg_int )
+  }
+\int_new:N \g__cmd_grabber_int
+\tl_new:N \l__cmd_fn_tl
+\tl_new:N \l__cmd_fn_code_tl
+\tl_new:N \l__cmd_function_tl
+\bool_new:N \l__cmd_grab_expandably_bool
+\bool_new:N \l__cmd_obey_spaces_bool
+\tl_new:N \l__cmd_last_delimiters_tl
+\bool_new:N \l__cmd_long_bool
+\int_new:N \l__cmd_m_args_int
+\bool_new:N \l__cmd_prefixed_bool
+\tl_new:N \l__cmd_process_all_tl
+\tl_new:N \l__cmd_process_one_tl
+\bool_new:N \l__cmd_process_some_bool
+\tl_new:N \l__cmd_saved_args_tl
+\tl_new:N \l__cmd_signature_tl
+\bool_new:N \l__cmd_some_obey_spaces_bool
+\bool_new:N \l__cmd_some_long_bool
+\bool_new:N \l__cmd_some_short_bool
+\prop_new:N \l__cmd_tmp_prop
+\tl_new:N \l__cmd_tmpa_tl
+\tl_new:N \l__cmd_tmpb_tl
+\cs_new_eq:NN \__cmd_tmp:w ?
+\msg_redirect_module:nnn { cmd } { info } { none }
+\prop_gput:Nnn \g_msg_module_type_prop { cmd } { LaTeX }
+\cs_new_protected:Npn \__cmd_declare_cmd:Nnn
+  {
+    \bool_set_false:N \l__cmd_expandable_bool
+    \__cmd_declare_cmd_aux:Nnn
+  }
+\cs_new_protected:Npn \__cmd_declare_expandable_cmd:Nnn
+  {
+    \bool_set_true:N \l__cmd_expandable_bool
+    \__cmd_declare_cmd_aux:Nnn
+  }
+\cs_new_protected:Npn \__cmd_declare_cmd_aux:Nnn #1#2#3
+  {
+    \cs_if_exist:NTF #1
+      {
+        \msg_info:nnxx { cmd } { redefine-command }
+          { \token_to_str:N #1 } { \tl_to_str:n {#2} }
+      }
+      {
+        \bool_lazy_or:nnT
+          { \cs_if_exist_p:c { \cs_to_str:N #1 ~ code } }
+          { \cs_if_exist_p:c { \cs_to_str:N #1 ~ defaults } }
+          {
+            \msg_warning:nnx { cmd } { unsupported-let }
+              { \token_to_str:N #1 }
+          }
+        \msg_info:nnxx { cmd } { define-command }
+          { \token_to_str:N #1 } { \tl_to_str:n {#2} }
+      }
+    \bool_set_false:N \l__cmd_environment_bool
+    \__cmd_declare_cmd_internal:Nnnn #1 {#2} {#3} { }
+  }
+\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}
+    #4
+    \__cmd_break_point:n {#2}
+  }
+\cs_generate_variant:Nn \__cmd_declare_cmd_internal:Nnnn { cnx }
+\cs_new_eq:NN \__cmd_break_point:n \use_none:n
+\cs_new_protected:Npn \__cmd_declare_cmd_code:Nnn
+  {
+    \bool_if:NTF \l__cmd_grab_expandably_bool
+      { \__cmd_declare_cmd_code_expandable:Nnn }
+      { \__cmd_declare_cmd_code_aux:Nnn }
+   }
+\cs_new_protected:Npn \__cmd_declare_cmd_code_aux:Nnn #1#2#3
+  {
+    \cs_generate_from_arg_count:cNnn
+      { \l__cmd_function_tl \c_space_tl code }
+      \cs_set_protected:Npn \l__cmd_current_arg_int {#3}
+    \cs_set_protected_nopar:Npx #1
+      {
+        \bool_if:NTF \l__cmd_environment_bool
+          {
+            \__cmd_start_env:nnnnn { \exp_not:n {#2} }
+              { \l__cmd_environment_str }
+          }
+          {
+            \__cmd_start:nNNnnn { \exp_not:n {#2} }
+              \exp_not:c { \l__cmd_function_tl \c_space_tl }
+              \exp_not:c { \l__cmd_function_tl \c_space_tl code }
+          }
+          { \exp_not:o \l__cmd_signature_tl }
+          {
+            \bool_if:NT \l__cmd_defaults_bool
+              { \exp_not:o \l__cmd_defaults_tl }
+          }
+          {
+            \bool_if:NT \l__cmd_process_some_bool
+              { \exp_not:o \l__cmd_process_all_tl }
+          }
+      }
+  }
+\cs_new_protected:Npn \__cmd_declare_cmd_code_expandable:Nnn #1#2#3
+  {
+    \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 } :Npn }
+      \l__cmd_current_arg_int {#3}
+    \bool_if:NT \l__cmd_defaults_bool
+      {
+        \use:x
+          {
+            \cs_generate_from_arg_count:cNnn
+              { \l__cmd_function_tl \c_space_tl defaults }
+              \cs_set:Npn \l__cmd_current_arg_int
+              { \exp_not:o \l__cmd_defaults_tl }
+          }
+      }
+    \bool_if:NTF \l__cmd_expandable_bool
+      { \cs_set_nopar:Npx } { \cs_set_protected_nopar:Npx } #1
+      {
+        \exp_not:N \__cmd_start_expandable:nNNNNn
+          { \exp_not:n {#2} }
+          \exp_not:c { \l__cmd_function_tl \c_space_tl }
+          \exp_not:c
+            {
+              \l__cmd_function_tl \c_space_tl
+              \bool_if:NT \l__cmd_some_short_bool
+                { \bool_if:NT \l__cmd_some_long_bool { \c_space_tl } }
+            }
+          \exp_not:c { \l__cmd_function_tl \c_space_tl code }
+          \bool_if:NTF \l__cmd_defaults_bool
+            { \exp_not:c { \l__cmd_function_tl \c_space_tl defaults } }
+            { ? }
+          { \exp_not:o \l__cmd_signature_tl }
+      }
+    \bool_if:NTF \l__cmd_some_long_bool
+      {
+        \bool_if:NT \l__cmd_some_short_bool
+          {
+            \cs_set_nopar:cpx { \l__cmd_function_tl \c_space_tl \c_space_tl }
+              ##1##2 { ##1 {##2} }
+          }
+        \cs_set:cpx
+      }
+      { \cs_set_nopar:cpx }
+          { \l__cmd_function_tl \c_space_tl } ##1##2 { ##1 {##2} }
+  }
+\cs_new_protected:Npn \__cmd_declare_env:nnnn #1#2
+  {
+    \str_set:Nx \l__cmd_environment_str {#1}
+    \str_set:Nx \l__cmd_environment_str
+      { \tl_trim_spaces:o { \l__cmd_environment_str } }
+    \cs_if_exist:cTF { \l__cmd_environment_str }
+      {
+        \msg_info:nnxx { cmd } { redefine-environment }
+          { \l__cmd_environment_str } { \tl_to_str:n {#2} }
+      }
+      {
+        \msg_info:nnxx { cmd } { define-environment }
+          { \l__cmd_environment_str } { \tl_to_str:n {#2} }
+      }
+    \bool_set_false:N \l__cmd_expandable_bool
+    \bool_set_true:N \l__cmd_environment_bool
+    \exp_args:NV \__cmd_declare_env_internal:nnnn
+      \l__cmd_environment_str {#2}
+  }
+\cs_new_protected:Npn \__cmd_declare_env_internal:nnnn #1#2#3#4
+  {
+    \__cmd_declare_cmd_internal:cnxn { environment~ #1 } {#2}
+      {
+        \cs_set_nopar:Npx \exp_not:c { environment~ #1 ~end~aux }
+          {
+            \exp_not:N \exp_not:N \exp_not:c { environment~ #1~end~aux~ }
+            \exp_not:n { \exp_not:o \l__cmd_args_tl }
+          }
+        \exp_not:n {#3}
+      }
+      {
+        \cs_set_nopar:cpx { environment~ #1 ~end }
+          { \exp_not:c { environment~ #1 ~end~aux } }
+        \cs_generate_from_arg_count:cNnn
+          { environment~ #1 ~end~aux~ } \cs_set:Npn
+          \l__cmd_current_arg_int {#4}
+        \cs_set_eq:cc {#1}       { environment~ #1 }
+        \cs_set_eq:cc { end #1 } { environment~ #1 ~end }
+      }
+  }
+\cs_new_protected:Npn \__cmd_start_env:nnnnn #1#2
+  {
+    \conditionally at traceoff
+    \group_align_safe_begin:
+    \str_set:Nn \l__cmd_environment_str {#2}
+    \bool_set_true:N \l__cmd_environment_bool
+    \__cmd_start_aux:ccnnnn
+      { environment~ \l__cmd_environment_str \c_space_tl }
+      { environment~ \l__cmd_environment_str \c_space_tl code }
+      {#1}
+  }
+\cs_new_protected:Npx \__cmd_start:nNNnnn #1#2#3
+  {
+    \exp_not:c { xparse~function~is~not~expandable }
+    \exp_not:N \conditionally at traceoff
+    \exp_not:N \group_align_safe_begin:
+    \exp_not:n { \bool_set_false:N \l__cmd_environment_bool }
+    \exp_not:N \__cmd_start_aux:NNnnnn
+    #2 #3 {#1}
+  }
+\cs_new_protected:Npn \__cmd_start_aux:NNnnnn #1#2#3#4#5#6
+  {
+    \tl_clear:N \l__cmd_args_tl
+    \tl_set:Nn \l__cmd_fn_tl {#1}
+    \tl_set:Nn \l__cmd_fn_code_tl {#2}
+    \tl_set:Nn \l__cmd_defaults_tl {#5}
+    \tl_set:Nn \l__cmd_process_all_tl {#6}
+    #4 \__cmd_run_code:
+  }
+\cs_generate_variant:Nn \__cmd_start_aux:NNnnnn { cc }
+\cs_new_protected:Npn \__cmd_run_code:
+  {
+    \tl_if_empty:NF \l__cmd_defaults_tl { \__cmd_defaults: }
+    \tl_if_empty:NF \l__cmd_process_all_tl { \__cmd_args_process: }
+    \group_align_safe_end:
+    \conditionally at traceon
+    \exp_after:wN \l__cmd_fn_code_tl \l__cmd_args_tl
+  }
+\cs_new_protected:Npn \__cmd_defaults:
+  {
+    \__cmd_defaults_def:
+    \tl_set_eq:NN \l__cmd_args_i_tl \l__cmd_args_tl
+    \__cmd_defaults_aux: \__cmd_defaults_aux: \__cmd_defaults_aux:
+    \__cmd_defaults_aux: \__cmd_defaults_aux: \__cmd_defaults_aux:
+    \__cmd_defaults_aux: \__cmd_defaults_aux: \__cmd_defaults_aux:
+    \__cmd_defaults_error:w
+    \q_recursion_stop
+    \tl_set_eq:NN \l__cmd_args_tl \l__cmd_args_i_tl
+  }
+\cs_new_protected:Npn \__cmd_defaults_aux:
+  {
+    \tl_set:Nx \l__cmd_args_ii_tl
+      { \exp_after:wN \__cmd_tmp:w \l__cmd_args_i_tl }
+    \tl_if_eq:NNT \l__cmd_args_ii_tl \l__cmd_args_i_tl
+      { \use_none_delimit_by_q_recursion_stop:w }
+    \tl_set_eq:NN \l__cmd_args_i_tl \l__cmd_args_ii_tl
+  }
+\cs_new_protected:Npn \__cmd_defaults_error:w \q_recursion_stop
+  {
+    \msg_error:nnx { cmd } { loop-in-defaults }
+      { \__cmd_environment_or_command: }
+  }
+\cs_new_protected:Npn \__cmd_defaults_def:
+  {
+    \tl_clear:N \l__cmd_tmpa_tl
+    \int_zero:N \l__cmd_current_arg_int
+    \__cmd_tl_mapthread_function:NNN \l__cmd_args_tl \l__cmd_defaults_tl
+      \__cmd_defaults_def:nn
+    \cs_generate_from_arg_count:NNVo \__cmd_tmp:w \cs_set:Npn
+      \l__cmd_current_arg_int \l__cmd_tmpa_tl
+  }
+\cs_generate_variant:Nn \cs_generate_from_arg_count:NNnn { NNVo }
+\cs_new_protected:Npn \__cmd_defaults_def:nn
+  {
+    \int_incr:N \l__cmd_current_arg_int
+    \exp_args:NV \__cmd_defaults_def:nnn \l__cmd_current_arg_int
+  }
+\cs_new_protected:Npn \__cmd_defaults_def:nnn #1#2#3
+  {
+    \tl_put_right:Nx \l__cmd_tmpa_tl
+      {
+        {
+          \exp_not:N \exp_not:n
+            {
+              \tl_if_novalue:nTF {#2}
+                { \exp_not:o {#3} }
+                { \exp_not:n { ## #1 } }
+            }
+        }
+      }
+  }
+\cs_new_protected:Npn \__cmd_args_process:
+  {
+    \tl_clear:N \l__cmd_args_ii_tl
+    \__cmd_tl_mapthread_function:NNN
+      \l__cmd_args_tl
+      \l__cmd_process_all_tl
+      \__cmd_args_process_loop:nn
+    \tl_set_eq:NN \l__cmd_args_tl \l__cmd_args_ii_tl
+  }
+\cs_new_protected:Npn \__cmd_args_process_loop:nn #1#2
+  {
+    \tl_set:Nn \ProcessedArgument {#1}
+    \tl_if_novalue:nF {#1}
+      { \tl_map_function:nN {#2} \__cmd_args_process_aux:n }
+    \tl_put_right:No \l__cmd_args_ii_tl
+      { \exp_after:wN { \ProcessedArgument } }
+  }
+\cs_new_protected:Npn \__cmd_args_process_aux:n #1
+  {
+    \cs_generate_from_arg_count:NNnn \__cmd_tmp:w \cs_set:Npn
+      { \tl_count:N \l__cmd_args_tl } {#1}
+    \exp_args:NNNo \exp_after:wN \__cmd_tmp:w \l__cmd_args_tl
+      { \ProcessedArgument }
+  }
+\cs_new:Npn \__cmd_start_expandable:nNNNNn #1#2#3#4#5#6
+  {
+    \group_align_safe_begin:
+    #6 \__cmd_end_expandable:NNw #5 #4 \q__cmd #2#3
+  }
+\cs_new:Npn \__cmd_end_expandable:NNw #1#2
+  { \__cmd_end_expandable_aux:w #1#2 \prg_do_nothing: }
+\cs_new:Npn \__cmd_end_expandable_aux:w #1#2#3 \q__cmd
+  { \exp_args:No \__cmd_end_expandable_aux:nNNNN {#3} #1 #2 }
+\cs_new:Npn \__cmd_end_expandable_aux:nNNNN #1#2#3#4#5
+  {
+    \token_if_eq_charcode:NNT ? #2 { \exp_after:wN \use_iv:nnnn }
+    \__cmd_end_expandable_defaults:nnnNNn {#1} { } {#1} #2#3
+      { } { } { } { } { } { } { } { } { } { }
+      {
+        \msg_expandable_error:nnf { cmd } { loop-in-defaults }
+          { \exp_args:Nf \tl_trim_spaces:n { \token_to_str:N #4 } }
+        \use_iv:nnnn
+      }
+    \q_stop
+  }
+\cs_new:Npn \__cmd_end_expandable_defaults:nnnNNn #1#2#3#4#5#6
+  {
+    #6
+    \str_if_eq:nnTF {#1} {#2}
+      { \use_i_delimit_by_q_stop:nw { \group_align_safe_end: #5 #1 } }
+      {
+        \exp_args:No \__cmd_tl_mapthread_function:nnN
+          { #4 #1 } {#3}
+          \__cmd_end_expandable_defaults:nnw
+        \__cmd_end_expandable_defaults:nnnNNn { } {#1} {#3} #4 #5
+      }
+  }
+\cs_new:Npn \__cmd_end_expandable_defaults:nnw #1#2
+  {
+    \tl_if_novalue:nTF {#2}
+      { \exp_args:No \__cmd_end_expandable_defaults:nw {#1} }
+      { \__cmd_end_expandable_defaults:nw {#2} }
+  }
+\cs_new:Npn \__cmd_end_expandable_defaults:nw
+    #1#2 \__cmd_end_expandable_defaults:nnnNNn #3
+  { #2 \__cmd_end_expandable_defaults:nnnNNn { #3 {#1} } }
+\cs_new_protected:Npn \__cmd_normalize_arg_spec:n #1
+  {
+    \int_zero:N \l__cmd_current_arg_int
+    \tl_clear:N \l__cmd_last_delimiters_tl
+    \tl_clear:N \l__cmd_arg_spec_tl
+    \bool_set_true:N \l__cmd_grab_expandably_bool
+    \bool_set_false:N \l__cmd_obey_spaces_bool
+    \bool_set_false:N \l__cmd_long_bool
+    \bool_set_false:N \l__cmd_some_obey_spaces_bool
+    \bool_set_false:N \l__cmd_some_long_bool
+    \bool_set_false:N \l__cmd_some_short_bool
+    \__cmd_normalize_arg_spec_loop:n #1
+      \q_recursion_tail \q_recursion_tail \q_recursion_tail \q_recursion_stop
+    \int_compare:nNnT \l__cmd_current_arg_int > 9
+      {
+        \msg_error:nnxx { cmd } { too-many-arguments }
+          { \__cmd_environment_or_command: } { \tl_to_str:n {#1} }
+        \__cmd_bad_def:wn
+      }
+    \bool_if:NT \l__cmd_expandable_bool
+      {
+        \tl_if_empty:NF \l__cmd_last_delimiters_tl
+          {
+            \msg_error:nnxx { cmd } { expandable-ending-optional }
+              { \iow_char:N \\ \l__cmd_function_tl } { \tl_to_str:n {#1} }
+            \__cmd_bad_def:wn
+          }
+      }
+    \bool_if:NT \l__cmd_expandable_bool
+      { \bool_set_true:N \l__cmd_grab_expandably_bool }
+    \bool_if:NT \l__cmd_environment_bool
+      { \bool_set_false:N \l__cmd_grab_expandably_bool }
+  }
+\cs_new_protected:Npn \__cmd_normalize_arg_spec_loop:n #1
+  {
+    \quark_if_recursion_tail_stop:n {#1}
+    \int_incr:N \l__cmd_current_arg_int
+    \cs_if_exist_use:cF { __cmd_normalize_type_ \tl_to_str:n {#1} :w }
+      {
+        \bool_lazy_any:nTF
+          {
+            { \str_if_eq_p:nn {#1} { G } }
+            { \str_if_eq_p:nn {#1} { g } }
+            { \str_if_eq_p:nn {#1} { l } }
+            { \str_if_eq_p:nn {#1} { u } }
+          }
+          {
+            \msg_error:nnxx { cmd } { xparse-argument-type }
+              { \__cmd_environment_or_command: } { \tl_to_str:n {#1} }
+          }
+          {
+            \msg_error:nnxx { cmd } { unknown-argument-type }
+              { \__cmd_environment_or_command: } { \tl_to_str:n {#1} }
+          }
+        \__cmd_bad_def:wn
+      }
+  }
+\cs_set_protected:Npn \__cmd_tmp:w #1
+  {
+    \cs_new_protected:Npn \__cmd_normalize_type_d:w ##1##2
+      {
+        \quark_if_recursion_tail_stop_do:nn {##2} { \__cmd_bad_arg_spec:wn }
+        \__cmd_normalize_type_D:w {##1} {##2} {#1}
+      }
+    \cs_new_protected:Npn \__cmd_normalize_type_e:w ##1
+      {
+        \quark_if_recursion_tail_stop_do:nn {##1} { \__cmd_bad_arg_spec:wn }
+        \__cmd_normalize_type_E:w {##1} { }
+      }
+    \cs_new_protected:Npn \__cmd_normalize_type_o:w
+      { \__cmd_normalize_type_D:w [ ] {#1} }
+    \cs_new_protected:Npn \__cmd_normalize_type_O:w
+      { \__cmd_normalize_type_D:w [ ] }
+    \cs_new_protected:Npn \__cmd_normalize_type_r:w ##1##2
+      {
+        \quark_if_recursion_tail_stop_do:nn {##2} { \__cmd_bad_arg_spec:wn }
+        \__cmd_normalize_type_R:w {##1} {##2} {#1}
+      }
+    \cs_new_protected:Npn \__cmd_normalize_type_s:w
+      { \__cmd_normalize_type_t:w * }
+  }
+\exp_args:No \__cmd_tmp:w { \c_novalue_tl }
+\cs_new_protected:cpn { __cmd_normalize_type_>:w } #1#2
+  {
+    \quark_if_recursion_tail_stop_do:nn {#2} { \__cmd_bad_arg_spec:wn }
+    \bool_if:NT \l__cmd_expandable_bool
+      {
+        \msg_error:nnxx { cmd } { processor-in-expandable }
+          { \iow_char:N \\ \l__cmd_function_tl } { \tl_to_str:n {#1} }
+        \__cmd_bad_def:wn
+      }
+    \tl_put_right:Nx \l__cmd_arg_spec_tl { > { \tl_trim_spaces:n {#1} } }
+    \int_decr:N \l__cmd_current_arg_int
+    \bool_set_false:N \l__cmd_grab_expandably_bool
+    \__cmd_normalize_arg_spec_loop:n {#2}
+  }
+\cs_new_protected:cpn { __cmd_normalize_type_+:w } #1
+  {
+    \quark_if_recursion_tail_stop_do:nn {#1} { \__cmd_bad_arg_spec:wn }
+    \bool_if:NT \l__cmd_long_bool
+      {
+        \msg_error:nnxx { cmd } { two-markers }
+          { \__cmd_environment_or_command: } { + }
+        \__cmd_bad_def:wn
+      }
+    \bool_set_true:N \l__cmd_long_bool
+    \int_decr:N \l__cmd_current_arg_int
+    \__cmd_normalize_arg_spec_loop:n {#1}
+  }
+\cs_new_protected:cpn { __cmd_normalize_type_!:w } #1
+  {
+    \quark_if_recursion_tail_stop_do:nn {#1} { \__cmd_bad_arg_spec:wn }
+    \bool_if:NT \l__cmd_obey_spaces_bool
+      {
+        \msg_error:nnxx { cmd } { two-markers }
+          { \__cmd_environment_or_command: } { ! }
+        \__cmd_bad_def:wn
+      }
+    \bool_set_true:N \l__cmd_obey_spaces_bool
+    \bool_set_true:N \l__cmd_some_obey_spaces_bool
+    \int_decr:N \l__cmd_current_arg_int
+    \__cmd_normalize_arg_spec_loop:n {#1}
+  }
+\cs_new_protected:Npn \__cmd_normalize_type_D:w #1#2#3
+  {
+    \quark_if_recursion_tail_stop_do:nn {#3} { \__cmd_bad_arg_spec:wn }
+    \__cmd_single_token_check:n {#1} \__cmd_allowed_token_check:N #1
+    \__cmd_single_token_check:n {#2}
+    \__cmd_add_arg_spec:n { D #1 #2 {#3} }
+    \tl_put_right:Nn \l__cmd_last_delimiters_tl {#1}
+    \bool_set_false:N \l__cmd_grab_expandably_bool
+    \__cmd_normalize_arg_spec_loop:n
+  }
+\cs_new_protected:Npn \__cmd_normalize_type_E:w #1#2
+  {
+    \quark_if_recursion_tail_stop_do:nn {#2} { \__cmd_bad_arg_spec:wn }
+    \tl_if_blank:nT {#1} { \__cmd_bad_arg_spec:wn }
+    \tl_map_function:nN {#1} \__cmd_single_token_check:n
+    \tl_map_function:nN {#1} \__cmd_allowed_token_check:N
+    \__cmd_normalize_E_unique_check:w #1 \q_nil \q_stop
+    \int_compare:nNnT { \tl_count:n {#2} } > { \tl_count:n {#1} }
+      { \__cmd_bad_arg_spec:wn }
+    \__cmd_add_arg_spec:n { E {#1} {#2} }
+    \tl_put_right:Nn \l__cmd_last_delimiters_tl {#1}
+    \bool_set_false:N \l__cmd_grab_expandably_bool
+    \int_add:Nn \l__cmd_current_arg_int { \tl_count:n {#1} - 1 }
+    \__cmd_normalize_arg_spec_loop:n
+  }
+\cs_new_protected:Npn \__cmd_normalize_E_unique_check:w #1#2 \q_stop
+  {
+    \quark_if_nil:NF #1
+      {
+        \tl_if_in:nnT {#2} {#1} { \__cmd_bad_arg_spec:wn }
+        \__cmd_normalize_E_unique_check:w #2 \q_stop
+      }
+  }
+\cs_new_protected:Npn \__cmd_normalize_type_t:w #1
+  {
+    \quark_if_recursion_tail_stop_do:Nn #1 { \__cmd_bad_arg_spec:wn }
+    \__cmd_single_token_check:n {#1} \__cmd_allowed_token_check:N #1
+    \tl_put_right:Nx \l__cmd_arg_spec_tl
+      {
+        \bool_if:NT \l__cmd_obey_spaces_bool { ! }
+        t \exp_not:n {#1}
+      }
+    \tl_put_right:Nn \l__cmd_last_delimiters_tl {#1}
+    \bool_set_false:N \l__cmd_grab_expandably_bool
+    \bool_set_false:N \l__cmd_obey_spaces_bool
+    \bool_set_false:N \l__cmd_long_bool
+    \__cmd_normalize_arg_spec_loop:n
+  }
+\cs_new_protected:Npn \__cmd_normalize_type_m:w
+  {
+    \__cmd_delimiter_check:nnn { } { m } { \iow_char:N \{ }
+    \__cmd_add_arg_spec_mandatory:n { m }
+    \__cmd_normalize_arg_spec_loop:n
+  }
+\cs_new_protected:Npn \__cmd_normalize_type_R:w #1#2#3
+  {
+    \quark_if_recursion_tail_stop_do:nn {#3} { \__cmd_bad_arg_spec:wn }
+    \__cmd_single_token_check:n {#1} \__cmd_allowed_token_check:N #1
+    \__cmd_single_token_check:n {#2}
+    \__cmd_delimiter_check:nnn {#1} { R/r } { \tl_to_str:n {#1} }
+    \bool_set_false:N \l__cmd_grab_expandably_bool
+    \__cmd_add_arg_spec_mandatory:n { R #1 #2 {#3} }
+    \__cmd_normalize_arg_spec_loop:n
+  }
+\cs_new_protected:Npn \__cmd_normalize_type_v:w
+  {
+    \__cmd_normalize_check_gv:N v
+    \__cmd_add_arg_spec_mandatory:n { v }
+    \__cmd_normalize_arg_spec_loop:n
+  }
+\cs_new_protected:Npn \__cmd_normalize_type_b:w #1
+  {
+    \bool_if:NF \l__cmd_environment_bool
+      {
+        \msg_error:nnxx { cmd } { invalid-command-arg }
+          { \__cmd_environment_or_command: } { b }
+        \__cmd_bad_def:wn
+      }
+    \tl_clear:N \l__cmd_last_delimiters_tl
+    \__cmd_add_arg_spec:n { b }
+    \quark_if_recursion_tail_stop:n {#1}
+    \msg_error:nnxx { cmd } { arg-after-body }
+      { \__cmd_environment_or_command: }
+      { \tl_to_str:n {#1} }
+    \__cmd_bad_def:wn
+  }
+\cs_new_protected:Npn \__cmd_single_token_check:n #1
+  {
+    \tl_trim_spaces_apply:nN {#1} \tl_if_single_token:nF
+      {
+        \msg_error:nnxx { cmd } { not-single-token }
+          { \__cmd_environment_or_command: } { \tl_to_str:n {#1} }
+        \__cmd_bad_def:wn
+      }
+  }
+\cs_new_protected:Npn \__cmd_allowed_token_check:N #1
+  {
+    \token_if_eq_meaning:NNTF #1 \c_group_begin_token
+        { \use:n }
+        {
+          \token_if_eq_meaning:NNTF #1 \c_group_end_token
+            { \use:n }
+            { \use_none:n }
+        }
+      {
+        \msg_error:nnxxx { cmd } { forbidden-implicit-group-token }
+          { \__cmd_environment_or_command: } { \tl_to_str:n {#1} }
+          {
+            \token_if_eq_meaning:NNTF #1 \c_group_begin_token
+              { begin } { end }
+          }
+        \__cmd_bad_def:wn
+      }
+  }
+\cs_new_protected:Npn \__cmd_normalize_check_gv:N #1
+  {
+    \bool_if:NT \l__cmd_expandable_bool
+      {
+        \msg_error:nnxx { cmd } { invalid-expandable-argument-type }
+          { \iow_char:N \\ \l__cmd_function_tl } { \tl_to_str:n {#1} }
+        \__cmd_bad_def:wn
+      }
+    \bool_set_false:N \l__cmd_grab_expandably_bool
+  }
+\cs_new_protected:Npn \__cmd_normalize_check_lu:N #1
+  {
+    \bool_if:NT \l__cmd_expandable_bool
+      {
+        \tl_if_empty:NF \l__cmd_last_delimiters_tl
+          {
+            \msg_error:nnxx { cmd } { invalid-after-optional-expandably }
+              { \iow_char:N \\ \l__cmd_function_tl } { \tl_to_str:n {#1} }
+            \__cmd_bad_def:wn
+          }
+      }
+  }
+\cs_new_protected:Npn \__cmd_delimiter_check:nnn #1#2#3
+  {
+    \tl_map_inline:Nn \l__cmd_last_delimiters_tl
+      {
+        \tl_if_eq:nnT {##1} {#1}
+          {
+            \msg_warning:nnxx { cmd } { optional-mandatory }
+              {#2} {#3}
+          }
+      }
+  }
+\cs_new_protected:Npn \__cmd_bad_arg_spec:wn #1 \__cmd_break_point:n #2
+  {
+    \msg_error:nnxx { cmd } { bad-arg-spec }
+      { \__cmd_environment_or_command: } { \tl_to_str:n {#2} }
+  }
+\cs_new_protected:Npn \__cmd_bad_def:wn #1 \__cmd_break_point:n #2 { }
+\cs_new_protected:Npn \__cmd_add_arg_spec:n #1
+  {
+    \bool_lazy_and:nnT
+      { ! \l__cmd_long_bool }
+      { \l__cmd_some_long_bool }
+      {
+        \bool_if:NT \l__cmd_expandable_bool
+          {
+            \msg_error:nnx { cmd } { inconsistent-long }
+              { \iow_char:N \\ \l__cmd_function_tl }
+            \__cmd_bad_def:wn
+          }
+        \bool_set_false:N \l__cmd_grab_expandably_bool
+      }
+    \bool_if:NTF \l__cmd_long_bool
+      { \bool_set_true:N \l__cmd_some_long_bool }
+      { \bool_set_true:N \l__cmd_some_short_bool }
+    \tl_put_right:Nx \l__cmd_arg_spec_tl
+      {
+        \bool_if:NT \l__cmd_long_bool { + }
+        \bool_if:NT \l__cmd_obey_spaces_bool { ! }
+        \exp_not:n {#1}
+      }
+    \bool_set_false:N \l__cmd_long_bool
+    \bool_set_false:N \l__cmd_obey_spaces_bool
+  }
+\cs_new_protected:Npn \__cmd_add_arg_spec_mandatory:n #1
+  {
+    \bool_if:NT \l__cmd_some_obey_spaces_bool
+      {
+        \msg_error:nnxx { cmd } { non-trailing-obey-spaces }
+          { \__cmd_environment_or_command: } { \tl_to_str:n {#1} }
+        \__cmd_bad_def:wn
+      }
+    \tl_clear:N \l__cmd_last_delimiters_tl
+    \__cmd_add_arg_spec:n {#1}
+  }
+\cs_new_protected:Npn \__cmd_prepare_signature:n #1
+  {
+    \int_zero:N \l__cmd_current_arg_int
+    \bool_set_false:N \l__cmd_long_bool
+    \bool_set_false:N \l__cmd_obey_spaces_bool
+    \int_zero:N \l__cmd_m_args_int
+    \bool_set_false:N \l__cmd_defaults_bool
+    \tl_clear:N \l__cmd_defaults_tl
+    \tl_clear:N \l__cmd_process_all_tl
+    \tl_clear:N \l__cmd_process_one_tl
+    \bool_set_false:N \l__cmd_process_some_bool
+    \tl_clear:N \l__cmd_signature_tl
+    \__cmd_prepare_signature:N #1 \q_recursion_tail \q_recursion_stop
+    \bool_if:NF \l__cmd_expandable_bool { \__cmd_flush_m_args: }
+  }
+\cs_new_protected:Npn \__cmd_prepare_signature:N
+  {
+    \bool_set_false:N \l__cmd_prefixed_bool
+    \__cmd_prepare_signature_bypass:N
+  }
+\cs_new_protected:Npn \__cmd_prepare_signature_bypass:N #1
+  {
+    \quark_if_recursion_tail_stop:N #1
+    \use:c
+      {
+         __cmd_add
+         \bool_if:NT \l__cmd_grab_expandably_bool { _expandable }
+         _type_  \token_to_str:N #1 :w
+      }
+  }
+\cs_new_protected:cpn { __cmd_add_type_+:w }
+  {
+    \__cmd_flush_m_args:
+    \bool_set_true:N \l__cmd_long_bool
+    \bool_set_true:N \l__cmd_prefixed_bool
+    \__cmd_prepare_signature_bypass:N
+  }
+\cs_new_protected:cpn { __cmd_add_type_!:w }
+  {
+    \__cmd_flush_m_args:
+    \bool_set_true:N \l__cmd_obey_spaces_bool
+    \bool_set_true:N \l__cmd_prefixed_bool
+    \__cmd_prepare_signature_bypass:N
+  }
+\cs_new_protected:cpn { __cmd_add_type_>:w } #1
+  {
+    \__cmd_flush_m_args:
+    \bool_set_true:N \l__cmd_prefixed_bool
+    \bool_set_true:N \l__cmd_process_some_bool
+    \tl_put_left:Nn \l__cmd_process_one_tl { {#1} }
+    \__cmd_prepare_signature_bypass:N
+  }
+\cs_new_protected:Npn \__cmd_add_type_b:w
+  {
+    \__cmd_flush_m_args:
+    \__cmd_add_default:
+    \__cmd_add_grabber:N b
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_type_D:w #1#2#3
+  {
+    \__cmd_flush_m_args:
+    \__cmd_add_default:n {#3}
+    \__cmd_add_grabber:N D
+    \tl_put_right:Nn \l__cmd_signature_tl { #1 #2 }
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_type_E:w #1#2
+  {
+    \__cmd_flush_m_args:
+    \__cmd_add_default_E:nn {#1} {#2}
+    \__cmd_add_grabber:N E
+    \tl_put_right:Nn \l__cmd_signature_tl { {#1} }
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_type_m:w
+  {
+    \__cmd_add_default:
+    \bool_if:NTF \l__cmd_prefixed_bool
+      { \__cmd_add_grabber:N m }
+      { \int_incr:N \l__cmd_m_args_int }
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_type_R:w #1#2#3
+  {
+    \__cmd_flush_m_args:
+    \__cmd_add_default:n {#3}
+    \__cmd_add_grabber:N R
+    \tl_put_right:Nn \l__cmd_signature_tl { #1 #2 }
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_type_t:w #1
+  {
+    \__cmd_flush_m_args:
+    \__cmd_add_default:
+    \__cmd_add_grabber:N t
+    \tl_put_right:Nn \l__cmd_signature_tl {#1}
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_type_v:w
+  {
+    \__cmd_flush_m_args:
+    \exp_args:No \__cmd_add_default:n \c_novalue_tl
+    \__cmd_add_grabber:N v
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_flush_m_args:
+  {
+    \int_compare:nNnT \l__cmd_m_args_int > 0
+      {
+        \tl_put_right:Nx \l__cmd_signature_tl
+          { \exp_not:c { __cmd_grab_m_ \int_use:N \l__cmd_m_args_int :w } }
+        \tl_put_right:Nx \l__cmd_process_all_tl
+          { \prg_replicate:nn { \l__cmd_m_args_int } { { } } }
+      }
+    \int_zero:N \l__cmd_m_args_int
+  }
+\cs_new_protected:Npn \__cmd_add_grabber:N #1
+  {
+    \tl_put_right:Nx \l__cmd_signature_tl
+      {
+        \exp_not:c
+          {
+            __cmd_grab_ #1
+            \bool_if:NT \l__cmd_long_bool { _long }
+            \bool_if:NT \l__cmd_obey_spaces_bool { _obey_spaces }
+            :w
+          }
+      }
+    \bool_set_false:N \l__cmd_long_bool
+    \bool_set_false:N \l__cmd_obey_spaces_bool
+    \tl_put_right:Nx \l__cmd_process_all_tl
+      { { \exp_not:o \l__cmd_process_one_tl } }
+    \tl_clear:N \l__cmd_process_one_tl
+  }
+\cs_new_protected:Npn \__cmd_add_default:n #1
+  {
+    \tl_if_novalue:nTF {#1}
+      { \__cmd_add_default: }
+      {
+        \int_incr:N \l__cmd_current_arg_int
+        \bool_set_true:N \l__cmd_defaults_bool
+        \tl_put_right:Nn \l__cmd_defaults_tl { { \prg_do_nothing: #1 } }
+      }
+  }
+\cs_new_protected:Npn \__cmd_add_default:
+  {
+    \int_incr:N \l__cmd_current_arg_int
+    \tl_put_right:Nn \l__cmd_defaults_tl { \c_novalue_tl }
+  }
+\cs_new_protected:Npn \__cmd_add_default_E:nn #1#2
+  {
+    \tl_map_function:nN {#2} \__cmd_add_default:n
+    \prg_replicate:nn
+      { \tl_count:n {#1} - \tl_count:n {#2} }
+      { \__cmd_add_default: }
+  }
+\cs_new_protected:cpn { __cmd_add_expandable_type_+:w }
+  {
+    \bool_set_true:N \l__cmd_long_bool
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_expandable_type_D:w
+  { \__cmd_add_expandable_type_D_aux:NNNn D }
+\cs_new_protected:Npn \__cmd_add_expandable_type_D_aux:NNNn #1#2#3#4
+  {
+    \__cmd_add_default:n {#4}
+    \tl_if_eq:nnTF {#2} {#3}
+      { \__cmd_add_expandable_type_D_aux:NN #1 #2 }
+      { \__cmd_add_expandable_type_D_aux:NNN #1 #2 #3 }
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_expandable_type_D_aux:NNN #1#2#3
+  {
+    \bool_if:NTF \l__cmd_long_bool
+      { \cs_set:cpx }
+      { \cs_set_nopar:cpx }
+      { \l__cmd_expandable_aux_name_tl } ##1 ##2 #2 ##3 \q__cmd ##4 #3
+      { ##1 {##2} {##3} {##4} }
+    \__cmd_add_expandable_grabber:nn {#1}
+      {
+        \exp_not:c  { \l__cmd_expandable_aux_name_tl }
+        \exp_not:n { #2 #3 }
+      }
+  }
+\cs_new_protected:Npn \__cmd_add_expandable_type_D_aux:NN #1#2
+  {
+    \bool_if:NTF \l__cmd_long_bool
+      { \cs_set:cpx }
+      { \cs_set_nopar:cpx }
+      { \l__cmd_expandable_aux_name_tl } ##1 #2 ##2 #2
+      { ##1 {##2} }
+    \__cmd_add_expandable_grabber:nn { #1_alt }
+      {
+        \exp_not:c  { \l__cmd_expandable_aux_name_tl }
+        \exp_not:n {#2}
+      }
+  }
+\cs_new_protected:Npn \__cmd_add_expandable_type_E:w #1#2
+  {
+    \__cmd_add_default_E:nn {#1} {#2}
+    \tl_clear:N \l__cmd_tmpb_tl
+    \tl_map_function:nN {#1} \__cmd_add_expandable_type_E_aux:n
+    \__cmd_add_expandable_grabber:nn
+      { E \bool_if:NT \l__cmd_long_bool { _long } }
+      {
+        { \exp_not:o \l__cmd_tmpb_tl }
+        {
+          \prg_replicate:nn { \tl_count:n {#1} }
+            { { \c_novalue_tl } }
+        }
+      }
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_expandable_type_E_aux:n #1
+  {
+    \__cmd_get_grabber:NN #1 \l__cmd_tmpa_tl
+    \tl_put_right:Nx \l__cmd_tmpb_tl
+      { \exp_not:o \l__cmd_tmpa_tl \exp_not:N #1 }
+  }
+\cs_new_protected:Npn \__cmd_add_expandable_type_m:w
+  {
+    \__cmd_add_default:
+    \__cmd_add_expandable_grabber:nn
+      { m \bool_if:NT \l__cmd_long_bool { _long } } { }
+    \__cmd_prepare_signature:N
+  }
+\cs_new_protected:Npn \__cmd_add_expandable_type_R:w
+  { \__cmd_add_expandable_type_D_aux:NNNn R }
+\cs_new_protected:Npn \__cmd_add_expandable_type_t:w #1
+  {
+    \__cmd_add_default:
+    \__cmd_get_grabber:NN #1 \l__cmd_tmpa_tl
+    \__cmd_add_expandable_grabber:nn { t }
+      {
+        \exp_not:o \l__cmd_tmpa_tl
+        \exp_not:N #1
+      }
+    \__cmd_prepare_signature:N
+  }

@@ Diff output truncated at 1234567 characters. @@


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