summaryrefslogtreecommitdiff
path: root/macros/latex-dev
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-05-05 03:02:17 +0000
committerNorbert Preining <norbert@preining.info>2021-05-05 03:02:17 +0000
commit75db33dc347ec9cfbaa2f3ec538a2697351f571b (patch)
tree0ea6d721f8478ed9ae95c93330c94aa8fcfd30b8 /macros/latex-dev
parent342f2e1be699f5ec70b5b1c35d9cd59798d37304 (diff)
CTAN sync 202105050302
Diffstat (limited to 'macros/latex-dev')
-rw-r--r--macros/latex-dev/base/README.md2
-rw-r--r--macros/latex-dev/base/alltt.pdfbin214708 -> 214710 bytes
-rw-r--r--macros/latex-dev/base/cfgguide.pdfbin242885 -> 242886 bytes
-rw-r--r--macros/latex-dev/base/changes.txt130
-rw-r--r--macros/latex-dev/base/classes.pdfbin550002 -> 550002 bytes
-rw-r--r--macros/latex-dev/base/clsguide.pdfbin402778 -> 402779 bytes
-rw-r--r--macros/latex-dev/base/cmfonts.pdfbin292316 -> 292317 bytes
-rw-r--r--macros/latex-dev/base/cyrguide.pdfbin239679 -> 239681 bytes
-rw-r--r--macros/latex-dev/base/doc.pdfbin676705 -> 676545 bytes
-rw-r--r--macros/latex-dev/base/docstrip.pdfbin503365 -> 503349 bytes
-rw-r--r--macros/latex-dev/base/encguide.pdfbin1316471 -> 1316472 bytes
-rw-r--r--macros/latex-dev/base/exscale.pdfbin212291 -> 212307 bytes
-rw-r--r--macros/latex-dev/base/fix-cm.pdfbin287671 -> 287672 bytes
-rw-r--r--macros/latex-dev/base/fntguide.pdfbin493933 -> 493957 bytes
-rw-r--r--macros/latex-dev/base/fntguide.tex9
-rw-r--r--macros/latex-dev/base/format.ins9
-rw-r--r--macros/latex-dev/base/graphpap.pdfbin169321 -> 169323 bytes
-rw-r--r--macros/latex-dev/base/ifthen.pdfbin220414 -> 220417 bytes
-rw-r--r--macros/latex-dev/base/inputenc.pdfbin318168 -> 318168 bytes
-rw-r--r--macros/latex-dev/base/latexchanges.pdfbin468044 -> 468043 bytes
-rw-r--r--macros/latex-dev/base/latexrelease.dtx329
-rw-r--r--macros/latex-dev/base/latexrelease.ins7
-rw-r--r--macros/latex-dev/base/latexrelease.pdfbin271510 -> 290495 bytes
-rw-r--r--macros/latex-dev/base/latexsym.pdfbin208358 -> 208359 bytes
-rw-r--r--macros/latex-dev/base/lb2.err7
-rw-r--r--macros/latex-dev/base/lb2.pdfbin252153 -> 252154 bytes
-rw-r--r--macros/latex-dev/base/letter.dtx4
-rw-r--r--macros/latex-dev/base/letter.pdfbin328965 -> 328853 bytes
-rw-r--r--macros/latex-dev/base/lgc2.err7
-rw-r--r--macros/latex-dev/base/lgc2.pdfbin215090 -> 215091 bytes
-rw-r--r--macros/latex-dev/base/lppl.pdfbin132372 -> 132373 bytes
-rw-r--r--macros/latex-dev/base/ltbibl.dtx2
-rw-r--r--macros/latex-dev/base/ltboxes.dtx4
-rw-r--r--macros/latex-dev/base/ltclass.dtx91
-rw-r--r--macros/latex-dev/base/ltcmd.dtx68
-rw-r--r--macros/latex-dev/base/ltcmdhooks-code.pdfbin0 -> 686990 bytes
-rw-r--r--macros/latex-dev/base/ltcmdhooks-code.tex4
-rw-r--r--macros/latex-dev/base/ltcmdhooks-doc.pdfbin0 -> 477922 bytes
-rw-r--r--macros/latex-dev/base/ltcmdhooks-doc.tex6
-rw-r--r--macros/latex-dev/base/ltcmdhooks.dtx1093
-rw-r--r--macros/latex-dev/base/ltdefns.dtx5
-rw-r--r--macros/latex-dev/base/ltexpl.dtx37
-rw-r--r--macros/latex-dev/base/ltfilehook-code.pdfbin785603 -> 784738 bytes
-rw-r--r--macros/latex-dev/base/ltfilehook-doc.pdfbin544026 -> 543890 bytes
-rw-r--r--macros/latex-dev/base/ltfilehook.dtx24
-rw-r--r--macros/latex-dev/base/ltfiles.dtx145
-rw-r--r--macros/latex-dev/base/ltfinal.dtx73
-rw-r--r--macros/latex-dev/base/ltfloat.dtx24
-rw-r--r--macros/latex-dev/base/ltfssaxes.dtx15
-rw-r--r--macros/latex-dev/base/ltfssbas.dtx28
-rw-r--r--macros/latex-dev/base/ltfssini.dtx58
-rw-r--r--macros/latex-dev/base/ltfsstrc.dtx16
-rw-r--r--macros/latex-dev/base/lthooks-code.pdfbin968601 -> 1002696 bytes
-rw-r--r--macros/latex-dev/base/lthooks-doc.pdfbin656622 -> 676691 bytes
-rw-r--r--macros/latex-dev/base/lthooks.dtx1186
-rw-r--r--macros/latex-dev/base/ltluatex.dtx6
-rw-r--r--macros/latex-dev/base/ltluatex.pdfbin325172 -> 325289 bytes
-rw-r--r--macros/latex-dev/base/ltmath.dtx8
-rw-r--r--macros/latex-dev/base/ltmiscen.dtx2
-rw-r--r--macros/latex-dev/base/ltnews.pdfbin1055081 -> 1068601 bytes
-rw-r--r--macros/latex-dev/base/ltnews.tex5
-rw-r--r--macros/latex-dev/base/ltnews01.pdfbin161517 -> 161518 bytes
-rw-r--r--macros/latex-dev/base/ltnews02.pdfbin150465 -> 150466 bytes
-rw-r--r--macros/latex-dev/base/ltnews03.pdfbin150492 -> 150493 bytes
-rw-r--r--macros/latex-dev/base/ltnews04.pdfbin143685 -> 143686 bytes
-rw-r--r--macros/latex-dev/base/ltnews05.pdfbin174489 -> 174488 bytes
-rw-r--r--macros/latex-dev/base/ltnews06.pdfbin142908 -> 142909 bytes
-rw-r--r--macros/latex-dev/base/ltnews07.pdfbin138043 -> 138044 bytes
-rw-r--r--macros/latex-dev/base/ltnews08.pdfbin155052 -> 155055 bytes
-rw-r--r--macros/latex-dev/base/ltnews09.pdfbin129031 -> 129032 bytes
-rw-r--r--macros/latex-dev/base/ltnews10.pdfbin159312 -> 159313 bytes
-rw-r--r--macros/latex-dev/base/ltnews11.pdfbin111954 -> 111955 bytes
-rw-r--r--macros/latex-dev/base/ltnews12.pdfbin147585 -> 147587 bytes
-rw-r--r--macros/latex-dev/base/ltnews12.tex3
-rw-r--r--macros/latex-dev/base/ltnews13.pdfbin173322 -> 173323 bytes
-rw-r--r--macros/latex-dev/base/ltnews14.pdfbin161405 -> 161405 bytes
-rw-r--r--macros/latex-dev/base/ltnews15.pdfbin130445 -> 130447 bytes
-rw-r--r--macros/latex-dev/base/ltnews16.pdfbin146533 -> 146533 bytes
-rw-r--r--macros/latex-dev/base/ltnews17.pdfbin166366 -> 166368 bytes
-rw-r--r--macros/latex-dev/base/ltnews18.pdfbin38030 -> 38031 bytes
-rw-r--r--macros/latex-dev/base/ltnews19.pdfbin245818 -> 245818 bytes
-rw-r--r--macros/latex-dev/base/ltnews20.pdfbin297069 -> 297070 bytes
-rw-r--r--macros/latex-dev/base/ltnews21.pdfbin244859 -> 244869 bytes
-rw-r--r--macros/latex-dev/base/ltnews22.pdfbin318402 -> 318399 bytes
-rw-r--r--macros/latex-dev/base/ltnews23.pdfbin287124 -> 287125 bytes
-rw-r--r--macros/latex-dev/base/ltnews24.pdfbin265212 -> 265211 bytes
-rw-r--r--macros/latex-dev/base/ltnews25.pdfbin205161 -> 205162 bytes
-rw-r--r--macros/latex-dev/base/ltnews26.pdfbin379734 -> 379735 bytes
-rw-r--r--macros/latex-dev/base/ltnews27.pdfbin252432 -> 252432 bytes
-rw-r--r--macros/latex-dev/base/ltnews28.pdfbin387986 -> 387987 bytes
-rw-r--r--macros/latex-dev/base/ltnews29.pdfbin454807 -> 454808 bytes
-rw-r--r--macros/latex-dev/base/ltnews30.pdfbin511854 -> 511855 bytes
-rw-r--r--macros/latex-dev/base/ltnews31.pdfbin526312 -> 526312 bytes
-rw-r--r--macros/latex-dev/base/ltnews32.pdfbin546168 -> 546162 bytes
-rw-r--r--macros/latex-dev/base/ltnews32.tex2
-rw-r--r--macros/latex-dev/base/ltnews33.pdfbin518997 -> 539851 bytes
-rw-r--r--macros/latex-dev/base/ltnews33.tex333
-rw-r--r--macros/latex-dev/base/ltoutenc.dtx15
-rw-r--r--macros/latex-dev/base/ltpar.dtx16
-rw-r--r--macros/latex-dev/base/ltpara-code.pdfbin614825 -> 655726 bytes
-rw-r--r--macros/latex-dev/base/ltpara-doc.pdfbin490887 -> 557225 bytes
-rw-r--r--macros/latex-dev/base/ltpara.dtx381
-rw-r--r--macros/latex-dev/base/ltpictur.dtx5
-rw-r--r--macros/latex-dev/base/ltplain.dtx210
-rw-r--r--macros/latex-dev/base/ltshipout-code.pdfbin810735 -> 811021 bytes
-rw-r--r--macros/latex-dev/base/ltshipout-doc.pdfbin562262 -> 562571 bytes
-rw-r--r--macros/latex-dev/base/ltshipout.dtx8
-rw-r--r--macros/latex-dev/base/lttab.dtx10
-rw-r--r--macros/latex-dev/base/lttextcomp.dtx69
-rw-r--r--macros/latex-dev/base/ltvers.dtx121
-rw-r--r--macros/latex-dev/base/ltx3info.pdfbin219353 -> 219354 bytes
-rw-r--r--macros/latex-dev/base/ltxdoc.pdfbin238576 -> 238577 bytes
-rw-r--r--macros/latex-dev/base/makeindx.pdfbin173683 -> 173682 bytes
-rw-r--r--macros/latex-dev/base/manual.pdfbin160519 -> 160521 bytes
-rw-r--r--macros/latex-dev/base/modguide.pdfbin243601 -> 243601 bytes
-rw-r--r--macros/latex-dev/base/nfssfont.pdfbin218781 -> 218782 bytes
-rw-r--r--macros/latex-dev/base/proc.pdfbin233994 -> 233995 bytes
-rw-r--r--macros/latex-dev/base/slides.pdfbin374049 -> 374051 bytes
-rw-r--r--macros/latex-dev/base/slifonts.pdfbin234006 -> 234008 bytes
-rw-r--r--macros/latex-dev/base/source2e.pdfbin4757868 -> 4959329 bytes
-rw-r--r--macros/latex-dev/base/source2e.tex6
-rw-r--r--macros/latex-dev/base/syntonly.pdfbin197456 -> 197297 bytes
-rw-r--r--macros/latex-dev/base/tlc2.err5
-rw-r--r--macros/latex-dev/base/tlc2.pdfbin289514 -> 289245 bytes
-rw-r--r--macros/latex-dev/base/tulm.pdfbin170529 -> 170529 bytes
-rw-r--r--macros/latex-dev/base/usrguide.pdfbin430996 -> 430996 bytes
-rw-r--r--macros/latex-dev/base/usrguide3.pdfbin325379 -> 325299 bytes
-rw-r--r--macros/latex-dev/base/usrguide3.tex18
-rw-r--r--macros/latex-dev/base/utf8ienc.pdfbin361507 -> 361356 bytes
-rw-r--r--macros/latex-dev/base/webcomp.err7
-rw-r--r--macros/latex-dev/base/webcomp.pdfbin146199 -> 146200 bytes
-rw-r--r--macros/latex-dev/required/graphics/README.md4
-rw-r--r--macros/latex-dev/required/graphics/changes.txt21
-rw-r--r--macros/latex-dev/required/graphics/color.dtx4
-rw-r--r--macros/latex-dev/required/graphics/color.pdfbin200892 -> 215002 bytes
-rw-r--r--macros/latex-dev/required/graphics/drivers.dtx4
-rw-r--r--macros/latex-dev/required/graphics/drivers.pdfbin263761 -> 286309 bytes
-rw-r--r--macros/latex-dev/required/graphics/epsfig.dtx4
-rw-r--r--macros/latex-dev/required/graphics/epsfig.pdfbin154479 -> 167686 bytes
-rw-r--r--macros/latex-dev/required/graphics/graphics-2017-06-25.sty2
-rw-r--r--macros/latex-dev/required/graphics/graphics.dtx19
-rw-r--r--macros/latex-dev/required/graphics/graphics.pdfbin286071 -> 310676 bytes
-rw-r--r--macros/latex-dev/required/graphics/graphicx.dtx11
-rw-r--r--macros/latex-dev/required/graphics/graphicx.pdfbin231066 -> 247910 bytes
-rw-r--r--macros/latex-dev/required/graphics/grfguide.pdfbin310275 -> 330071 bytes
-rw-r--r--macros/latex-dev/required/graphics/grfguide.tex38
-rw-r--r--macros/latex-dev/required/graphics/keyval.dtx4
-rw-r--r--macros/latex-dev/required/graphics/keyval.pdfbin222527 -> 239654 bytes
-rw-r--r--macros/latex-dev/required/graphics/lscape.dtx4
-rw-r--r--macros/latex-dev/required/graphics/lscape.pdfbin150615 -> 163584 bytes
-rw-r--r--macros/latex-dev/required/graphics/rotating.dtx8
-rw-r--r--macros/latex-dev/required/graphics/rotating.pdfbin245612 -> 269434 bytes
-rw-r--r--macros/latex-dev/required/graphics/rotex.pdfbin162269 -> 172231 bytes
-rw-r--r--macros/latex-dev/required/graphics/trig.dtx6
-rw-r--r--macros/latex-dev/required/graphics/trig.pdfbin191692 -> 207299 bytes
-rw-r--r--macros/latex-dev/required/tools/README.md2
-rw-r--r--macros/latex-dev/required/tools/afterpage.pdfbin205343 -> 205344 bytes
-rw-r--r--macros/latex-dev/required/tools/array.dtx5
-rw-r--r--macros/latex-dev/required/tools/array.pdfbin516397 -> 516484 bytes
-rw-r--r--macros/latex-dev/required/tools/bm.dtx67
-rw-r--r--macros/latex-dev/required/tools/bm.pdfbin328028 -> 331424 bytes
-rw-r--r--macros/latex-dev/required/tools/calc.pdfbin370412 -> 370414 bytes
-rw-r--r--macros/latex-dev/required/tools/changes.txt36
-rw-r--r--macros/latex-dev/required/tools/dcolumn.pdfbin220688 -> 220689 bytes
-rw-r--r--macros/latex-dev/required/tools/delarray.pdfbin198646 -> 198647 bytes
-rw-r--r--macros/latex-dev/required/tools/enumerate.pdfbin215355 -> 215355 bytes
-rw-r--r--macros/latex-dev/required/tools/fileerr.pdfbin195249 -> 195098 bytes
-rw-r--r--macros/latex-dev/required/tools/fontsmpl.pdfbin154032 -> 154034 bytes
-rw-r--r--macros/latex-dev/required/tools/ftnright.pdfbin369962 -> 369809 bytes
-rw-r--r--macros/latex-dev/required/tools/hhline.pdfbin189538 -> 189538 bytes
-rw-r--r--macros/latex-dev/required/tools/indentfirst.pdfbin157801 -> 157803 bytes
-rw-r--r--macros/latex-dev/required/tools/layout.dtx14
-rw-r--r--macros/latex-dev/required/tools/layout.pdfbin267872 -> 267761 bytes
-rw-r--r--macros/latex-dev/required/tools/longtable.dtx28
-rw-r--r--macros/latex-dev/required/tools/longtable.pdfbin381665 -> 382012 bytes
-rw-r--r--macros/latex-dev/required/tools/multicol.pdfbin516297 -> 516282 bytes
-rw-r--r--macros/latex-dev/required/tools/rawfonts.pdfbin146533 -> 146534 bytes
-rw-r--r--macros/latex-dev/required/tools/shellesc.pdfbin183519 -> 183532 bytes
-rw-r--r--macros/latex-dev/required/tools/showkeys.pdfbin260623 -> 260624 bytes
-rw-r--r--macros/latex-dev/required/tools/somedefs.pdfbin175168 -> 175169 bytes
-rw-r--r--macros/latex-dev/required/tools/tabularx.pdfbin278038 -> 278041 bytes
-rw-r--r--macros/latex-dev/required/tools/theorem.pdfbin351478 -> 351310 bytes
-rw-r--r--macros/latex-dev/required/tools/tools-overview.pdfbin73673 -> 73674 bytes
-rw-r--r--macros/latex-dev/required/tools/trace.dtx30
-rw-r--r--macros/latex-dev/required/tools/trace.pdfbin229686 -> 229713 bytes
-rw-r--r--macros/latex-dev/required/tools/varioref.pdfbin383481 -> 383483 bytes
-rw-r--r--macros/latex-dev/required/tools/verbatim.pdfbin330814 -> 330815 bytes
-rw-r--r--macros/latex-dev/required/tools/xr.pdfbin177595 -> 177595 bytes
-rw-r--r--macros/latex-dev/required/tools/xspace.pdfbin256896 -> 256897 bytes
189 files changed, 3995 insertions, 929 deletions
diff --git a/macros/latex-dev/base/README.md b/macros/latex-dev/base/README.md
index 8087411acb..4997754b3c 100644
--- a/macros/latex-dev/base/README.md
+++ b/macros/latex-dev/base/README.md
@@ -1,7 +1,7 @@
The LaTeX kernel
================
-Release 2021-05-01 pre-release 2
+Release 2021-06-01 pre-release 3
Overview
--------
diff --git a/macros/latex-dev/base/alltt.pdf b/macros/latex-dev/base/alltt.pdf
index de9abedb7c..b763b6bda8 100644
--- a/macros/latex-dev/base/alltt.pdf
+++ b/macros/latex-dev/base/alltt.pdf
Binary files differ
diff --git a/macros/latex-dev/base/cfgguide.pdf b/macros/latex-dev/base/cfgguide.pdf
index d5c5c2ee72..dea65fdbf8 100644
--- a/macros/latex-dev/base/cfgguide.pdf
+++ b/macros/latex-dev/base/cfgguide.pdf
Binary files differ
diff --git a/macros/latex-dev/base/changes.txt b/macros/latex-dev/base/changes.txt
index e9d856a364..75e7d04a2f 100644
--- a/macros/latex-dev/base/changes.txt
+++ b/macros/latex-dev/base/changes.txt
@@ -6,6 +6,134 @@ completeness or accuracy and it contains some references to files that
are not part of the distribution.
================================================================================
+2021-04-29 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+
+ * lthooks.dtx (subsection{\LaTeXe{} package interface commands}):
+ Add \ProvideHook and related commands.
+
+2021-04-29 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+
+ * lthooks.dtx, ltfilehook.dtx:
+ Switch to kernel (not package) errors.
+
+
+2021-04-29 Marcel Krüger <Marcel.Krueger@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@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@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@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@latex-project.org>
+
+ * ltfilehook.dtx:
+ Ensure that ~ expands to the character ~ in file names.
+
+2021-04-18 Phelype Oleinik <phelype.oleinik@latex-project.org>
+
+ * ltplain.dtx:
+ Add support for \tracingstacklevels and \tracinglostchars=3.
+
+2021-04-16 Phelype Oleinik <phelype.oleinik@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@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@latex-project.org>
+
+ * ltclass.dtx:
+ Do not rollback expl3 file stack management (gh/504).
+
+2021-03-26 Frank Mittelbach <Frank.Mittelbach@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@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@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@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@latex-project.org>
+
+ * ltclass.dtx:
+ Fix overwrite check for files with UTF-8 (gh/415).
+
2021-02-25 Marcel Krüger <Marcel.Krueger@latex-project.org>
* ltfinal.dtx:
@@ -19,7 +147,7 @@ are not part of the distribution.
to OT1, T1 and TU encoding (gh/404)
* doc-v3beta.sty: File added, currently for internal documentation
- to be replaced in a later release.
+ only; to be replaced in a later release.
2021-02-18 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
diff --git a/macros/latex-dev/base/classes.pdf b/macros/latex-dev/base/classes.pdf
index 01527318fe..cf7d562b56 100644
--- a/macros/latex-dev/base/classes.pdf
+++ b/macros/latex-dev/base/classes.pdf
Binary files differ
diff --git a/macros/latex-dev/base/clsguide.pdf b/macros/latex-dev/base/clsguide.pdf
index c4c4cad12d..d41d2f7dc7 100644
--- a/macros/latex-dev/base/clsguide.pdf
+++ b/macros/latex-dev/base/clsguide.pdf
Binary files differ
diff --git a/macros/latex-dev/base/cmfonts.pdf b/macros/latex-dev/base/cmfonts.pdf
index 9a9131d46c..65eada2d18 100644
--- a/macros/latex-dev/base/cmfonts.pdf
+++ b/macros/latex-dev/base/cmfonts.pdf
Binary files differ
diff --git a/macros/latex-dev/base/cyrguide.pdf b/macros/latex-dev/base/cyrguide.pdf
index 38b01ca8d0..b81d5740dd 100644
--- a/macros/latex-dev/base/cyrguide.pdf
+++ b/macros/latex-dev/base/cyrguide.pdf
Binary files differ
diff --git a/macros/latex-dev/base/doc.pdf b/macros/latex-dev/base/doc.pdf
index 2914d862ff..b4b752d02f 100644
--- a/macros/latex-dev/base/doc.pdf
+++ b/macros/latex-dev/base/doc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/docstrip.pdf b/macros/latex-dev/base/docstrip.pdf
index bcbaf41e21..1f93adfd24 100644
--- a/macros/latex-dev/base/docstrip.pdf
+++ b/macros/latex-dev/base/docstrip.pdf
Binary files differ
diff --git a/macros/latex-dev/base/encguide.pdf b/macros/latex-dev/base/encguide.pdf
index 367f5f7c41..2682e5e3a1 100644
--- a/macros/latex-dev/base/encguide.pdf
+++ b/macros/latex-dev/base/encguide.pdf
Binary files differ
diff --git a/macros/latex-dev/base/exscale.pdf b/macros/latex-dev/base/exscale.pdf
index fb19614ee8..c15633e2c5 100644
--- a/macros/latex-dev/base/exscale.pdf
+++ b/macros/latex-dev/base/exscale.pdf
Binary files differ
diff --git a/macros/latex-dev/base/fix-cm.pdf b/macros/latex-dev/base/fix-cm.pdf
index 00ac759011..d8149b7da8 100644
--- a/macros/latex-dev/base/fix-cm.pdf
+++ b/macros/latex-dev/base/fix-cm.pdf
Binary files differ
diff --git a/macros/latex-dev/base/fntguide.pdf b/macros/latex-dev/base/fntguide.pdf
index 48e00dbf08..c498f9f449 100644
--- a/macros/latex-dev/base/fntguide.pdf
+++ b/macros/latex-dev/base/fntguide.pdf
Binary files differ
diff --git a/macros/latex-dev/base/fntguide.tex b/macros/latex-dev/base/fntguide.tex
index 6e20cc253f..a4b872a261 100644
--- a/macros/latex-dev/base/fntguide.tex
+++ b/macros/latex-dev/base/fntguide.tex
@@ -37,12 +37,12 @@
\title{\LaTeXe{} font selection}
-\author{\copyright~Copyright 1995--2020, \LaTeX\ 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 @@ A less common value for font shape is:
\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:
diff --git a/macros/latex-dev/base/format.ins b/macros/latex-dev/base/format.ins
index 9c90555b9f..eece2f57ef 100644
--- a/macros/latex-dev/base/format.ins
+++ b/macros/latex-dev/base/format.ins
@@ -166,12 +166,14 @@ the system are in the document `cfgguide.tex'.
% we have the extensions as soon as possible.
\from{ltexpl.dtx}{2ekernel} % expl3-based extensions
\from{ltdefns.dtx}{2ekernel}
- \from{ltcmd.dtx}{2ekernel} % Used to be xparse
+ \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}
@@ -240,11 +242,6 @@ the system are in the document `cfgguide.tex'.
\generate{\file{structuredlog.sty}{\from{ltfilehook.dtx}{structuredlog}}}
-% hook managed para
-
-\generate{\file{ltpara.ltx}{\from{ltpara.dtx}{2ekernel}}}
-
-
% luatex support (TeX part)
\generate{\file{ltluatex.tex}{\from{ltluatex.dtx}{tex,plain}}}
diff --git a/macros/latex-dev/base/graphpap.pdf b/macros/latex-dev/base/graphpap.pdf
index 21ed3df036..df0b482d62 100644
--- a/macros/latex-dev/base/graphpap.pdf
+++ b/macros/latex-dev/base/graphpap.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ifthen.pdf b/macros/latex-dev/base/ifthen.pdf
index 777c2602e9..a756833b7e 100644
--- a/macros/latex-dev/base/ifthen.pdf
+++ b/macros/latex-dev/base/ifthen.pdf
Binary files differ
diff --git a/macros/latex-dev/base/inputenc.pdf b/macros/latex-dev/base/inputenc.pdf
index 92bf387168..ca53fac3a5 100644
--- a/macros/latex-dev/base/inputenc.pdf
+++ b/macros/latex-dev/base/inputenc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/latexchanges.pdf b/macros/latex-dev/base/latexchanges.pdf
index 5c361e6139..3e4f2aaa9d 100644
--- a/macros/latex-dev/base/latexchanges.pdf
+++ b/macros/latex-dev/base/latexchanges.pdf
Binary files differ
diff --git a/macros/latex-dev/base/latexrelease.dtx b/macros/latex-dev/base/latexrelease.dtx
index cfcac4b397..7d2290f4d8 100644
--- a/macros/latex-dev/base/latexrelease.dtx
+++ b/macros/latex-dev/base/latexrelease.dtx
@@ -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}
- [2021/01/23 v1.0l 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 \LaTeX Project}
+% \author{The \LaTeX{} Project}
% \date{\filedate}
% \MaintainedByLaTeXTeam{latex}
% \maketitle
@@ -364,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
@@ -387,27 +482,34 @@
\NeedsTeXFormat{LaTeX2e}[1996/06/01]
% \end{macrocode}
%
-% \section{Setup}
+% \subsection{Setup}
%
% \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|:
+% 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}
-\edef\sourceLaTeXdate{%
- \expandafter\@parse@version\fmtversion//00\@nil}
+\@ifundefined{sourceLaTeXdate}{%
+ \edef\sourceLaTeXdate{%
+ \expandafter\@parse@version\fmtversion//00\@nil}}{}%
% \end{macrocode}
% \end{macro}
%
% \begin{macro}{\IncludeInRelease}
% \begin{macro}{\EndIncludeInRelease}
-% \begin{macrocode}
-% \end{macrocode}
+% 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, github 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@se{#1}}%
@@ -494,16 +596,213 @@ of this package available from CTAN}
% \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@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@or@long \@@_declare_command:Nw }
+\cs_gset_protected:Npn \@@_declare_command:Nw #1
+ { \cs_if_exist:NTF #1 { \renew@command } { \new@command } #1 }
+% \end{macrocode}
+%
+% Then define a version of \cs{e@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@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@alloc:NnnnnN #1 #2 #3 #4 #5 #6
+ {
+ \cs_if_free:NTF #6
+ { \use:n }
+ {
+ \exp_after:wN \@@_e@alloc:N
+ \token_to_meaning:N #6 \scan_stop: {#2} #6
+ }
+ { \@@_e@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@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@alloc:w
+ \@tempcnta #1
+ \use_i:nnn
+ \fi:
+ \use:n
+ {
+ \if_meaning:w \scan_stop: #1
+ \exp_after:wN \use_iv:nnnn
+ \fi:
+ \@@_e@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@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@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@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@alloc \@@_e@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}
diff --git a/macros/latex-dev/base/latexrelease.ins b/macros/latex-dev/base/latexrelease.ins
index b4d0aef567..0b65114a2f 100644
--- a/macros/latex-dev/base/latexrelease.ins
+++ b/macros/latex-dev/base/latexrelease.ins
@@ -94,13 +94,15 @@ extension .ins) which are part of the distribution.
\from{ltexpl.dtx} {latexrelease}% empty
\from{ltdefns.dtx} {latexrelease}%
\from{ltcmd.dtx} {latexrelease}%
- \from{lthooks.dtx} {latexrelease}% empty % L3 layer module
+ \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}%
@@ -133,6 +135,7 @@ extension .ins) which are part of the distribution.
\from{ltoutput.dtx} {latexrelease}%
\from{ltfsscmp.dtx} {latexrelease}% only in latexrelease!
\from{ltfinal.dtx} {latexrelease}%
+ \from{latexrelease.dtx}{latexrelease-finish}%
}
diff --git a/macros/latex-dev/base/latexrelease.pdf b/macros/latex-dev/base/latexrelease.pdf
index f91d690fb6..cdce0fb74f 100644
--- a/macros/latex-dev/base/latexrelease.pdf
+++ b/macros/latex-dev/base/latexrelease.pdf
Binary files differ
diff --git a/macros/latex-dev/base/latexsym.pdf b/macros/latex-dev/base/latexsym.pdf
index 54b92b46ca..5fb4a09541 100644
--- a/macros/latex-dev/base/latexsym.pdf
+++ b/macros/latex-dev/base/latexsym.pdf
Binary files differ
diff --git a/macros/latex-dev/base/lb2.err b/macros/latex-dev/base/lb2.err
index 47dc4010c2..767cc86a05 100644
--- a/macros/latex-dev/base/lb2.err
+++ b/macros/latex-dev/base/lb2.err
@@ -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]
diff --git a/macros/latex-dev/base/lb2.pdf b/macros/latex-dev/base/lb2.pdf
index f6d24713c4..6cc60fec76 100644
--- a/macros/latex-dev/base/lb2.pdf
+++ b/macros/latex-dev/base/lb2.pdf
Binary files differ
diff --git a/macros/latex-dev/base/letter.dtx b/macros/latex-dev/base/letter.dtx
index 3c7fe56ba1..6beee81735 100644
--- a/macros/latex-dev/base/letter.dtx
+++ b/macros/latex-dev/base/letter.dtx
@@ -45,7 +45,7 @@
%<*driver>
\ProvidesFile{letter.drv}
%</driver>
- [2021/01/07 v1.3c
+ [2021/03/05 v1.3c
%<+letter> Standard LaTeX document class]
% \end{macrocode}
%
@@ -1034,7 +1034,7 @@
% \texttt{extletter.cls},\\
% \texttt{frletter.cls},
% \texttt{hletter.cls},
-% \texttt{scrlttr2.cls},
+% \texttt{scrlttr2.cls} (change rejected),
% \texttt{lettre.cls},
% \texttt{beletter.cls},\\
% \texttt{brief.cls} and perhaps others.
diff --git a/macros/latex-dev/base/letter.pdf b/macros/latex-dev/base/letter.pdf
index 0280c54380..2431b6d81f 100644
--- a/macros/latex-dev/base/letter.pdf
+++ b/macros/latex-dev/base/letter.pdf
Binary files differ
diff --git a/macros/latex-dev/base/lgc2.err b/macros/latex-dev/base/lgc2.err
index e9a1de4ea5..cbee8d6f35 100644
--- a/macros/latex-dev/base/lgc2.err
+++ b/macros/latex-dev/base/lgc2.err
@@ -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]
diff --git a/macros/latex-dev/base/lgc2.pdf b/macros/latex-dev/base/lgc2.pdf
index e285c6f20d..2a58b0470e 100644
--- a/macros/latex-dev/base/lgc2.pdf
+++ b/macros/latex-dev/base/lgc2.pdf
Binary files differ
diff --git a/macros/latex-dev/base/lppl.pdf b/macros/latex-dev/base/lppl.pdf
index 37035109f3..dfccc5d5eb 100644
--- a/macros/latex-dev/base/lppl.pdf
+++ b/macros/latex-dev/base/lppl.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltbibl.dtx b/macros/latex-dev/base/ltbibl.dtx
index 0319342dd4..cda0fa160a 100644
--- a/macros/latex-dev/base/ltbibl.dtx
+++ b/macros/latex-dev/base/ltbibl.dtx
@@ -329,7 +329,7 @@
% \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2021/05/01}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease> {\nocite}{Allow nocite in preamble}%
\def\nocite#1{\@bsphack
% \end{macrocode}
diff --git a/macros/latex-dev/base/ltboxes.dtx b/macros/latex-dev/base/ltboxes.dtx
index 8281b4b712..8499d3ab8b 100644
--- a/macros/latex-dev/base/ltboxes.dtx
+++ b/macros/latex-dev/base/ltboxes.dtx
@@ -464,7 +464,7 @@
% \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2021/05/01}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease> {\color@begingroup}{color group settings}%
\let\color@begingroup\begingroup
\def\color@endgroup{\endgraf\endgroup}
@@ -1140,7 +1140,7 @@
% \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2021/05/01}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease> {\@mpfootnotetext}{footnotetext tagging}%
\long\def\@mpfootnotetext#1{%
\global\setbox\@mpfootins\vbox{%
diff --git a/macros/latex-dev/base/ltclass.dtx b/macros/latex-dev/base/ltclass.dtx
index 26667cbeb1..06b0e1cf43 100644
--- a/macros/latex-dev/base/ltclass.dtx
+++ b/macros/latex-dev/base/ltclass.dtx
@@ -33,7 +33,7 @@
%<*driver>
% \fi
\ProvidesFile{ltclass.dtx}
- [2021/02/18 v1.3x LaTeX Kernel (Class & Package Interface)]
+ [2021/03/27 v1.4a LaTeX Kernel (Class & Package Interface)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{ltclass.dtx}
@@ -640,14 +640,38 @@
%<latexrelease> \@expl@push@filename@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@push@filename@@ and \@expl@push@filename@aux@@}%
+%<latexrelease>\ifnum\sourceLaTeXdate<20200202\relax
+%<latexrelease> \GenericInfo{}{Defining 00-00-00\string\@pushfilename.}
%<latexrelease>\def\@pushfilename{%
%<latexrelease> \xdef\@currnamestack{%
%<latexrelease> {\@currname}%
%<latexrelease> {\@currext}%
%<latexrelease> {\the\catcode`\@}%
%<latexrelease> \@currnamestack}}
+%<latexrelease>\else
+%<latexrelease> \GenericInfo{}{Defining 2020-02-02\string\@pushfilename.}
+%<latexrelease>\def\@pushfilename{%
+%<latexrelease> \@expl@push@filename@@
+%<latexrelease> \xdef\@currnamestack{%
+%<latexrelease> {\@currname}%
+%<latexrelease> {\@currext}%
+%<latexrelease> {\the\catcode`\@}%
+%<latexrelease> \@currnamestack}%
+%<latexrelease> \@expl@push@filename@aux@@}
+%<latexrelease>\fi
%<latexrelease>\EndIncludeInRelease
\@onlypreamble\@pushfilename
% \end{macrocode}
@@ -676,9 +700,21 @@
%<latexrelease> \@expl@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@push@filename@@ and \@expl@push@filename@aux@@}%
+%<latexrelease>\ifnum\sourceLaTeXdate<20200202\relax
+%<latexrelease> \GenericInfo{}{Defining 00-00-00\string\@popfilename.}
%<latexrelease>\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil}
+%<latexrelease>\else
+%<latexrelease> \GenericInfo{}{Defining 2020-02-02\string\@popfilename.}
+%<latexrelease>\def\@popfilename{\expandafter\@p@pfilename\@currnamestack\@nil
+%<latexrelease> \@expl@pop@filename@@}
+%<latexrelease>\fi
%<latexrelease>\EndIncludeInRelease
\@onlypreamble\@popfilename
% \end{macrocode}
@@ -1172,7 +1208,7 @@
% \changes{v1.3x}{2021/02/18}{save raw option lists (gh/85)}
% \begin{macrocode}
%</2ekernel>
-%<latexrelease>\IncludeInRelease{2021/05/01}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease> {\@pass@ptions}{Raw option lists}%
%<*2ekernel|latexrelease>
\def\@pass@ptions#1#2#3{%
@@ -1283,7 +1319,7 @@
% unused options. Otherwise, in a package file do nothing.
% \begin{macrocode}
%</2ekernel>
-%<latexrelease>\IncludeInRelease{2021/05/01}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease> {\OptionNotUsed}{filter unused option list}%
%<*2ekernel|latexrelease>
\def\@remove@eq@value#1=#2\@nil{#1}
@@ -1378,19 +1414,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@ptions}{safer @xprocess@ptions}%
+%<*2ekernel|latexrelease>
\def\@xprocess@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@ption
\expandafter\let\csname ds@\CurrentOption\endcsname\@empty
- \fi
+ }%
\fi}%
+ \fi
\fi
\@process@pti@ns}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease> {\@xprocess@ptions}{safer @xprocess@ptions}%
+%<latexrelease>\let\@remove@eq@value\@undefined
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<latexrelease>\def\@xprocess@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@ption
+%<latexrelease> \expandafter\let\csname ds@\CurrentOption\endcsname\@empty
+%<latexrelease> \fi
+%<latexrelease> \fi}%
+%<latexrelease> \fi
+%<latexrelease> \@process@pti@ns}
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+% \end{macrocode}
+%
+% \begin{macrocode}
\@onlypreamble\@xprocess@ptions
% \end{macrocode}
%
@@ -1472,7 +1539,7 @@
% \changes{v1.3x}{2021/02/18}{filter out =value from unused option list (gh/85)}
% \begin{macrocode}
%</2ekernel>
-%<latexrelease>\IncludeInRelease{2021/05/01}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease> {\@use@ption}{filter unused option list}%
%<*2ekernel|latexrelease>
\def\@use@ption{%
@@ -1954,7 +2021,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
@@ -2669,15 +2736,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@a{#1}%
- \edef\reserved@a{\detokenize\expandafter{\reserved@a}}%
\edef\reserved@b{\detokenize\expandafter{\jobname}}%
- \ifx\reserved@a\reserved@b%
+ \ifx\@curr@file\reserved@b%
\@fileswtrue%
\else%
\edef\reserved@b{\reserved@b\detokenize{.tex}}%
- \ifx\reserved@a\reserved@b
+ \ifx\@curr@file\reserved@b
\@fileswtrue%
\fi%
\fi%
diff --git a/macros/latex-dev/base/ltcmd.dtx b/macros/latex-dev/base/ltcmd.dtx
index 26ce75224f..fee555586d 100644
--- a/macros/latex-dev/base/ltcmd.dtx
+++ b/macros/latex-dev/base/ltcmd.dtx
@@ -34,14 +34,15 @@
%%% From File: ltcmd.dtx
%
% \begin{macrocode}
-\def\ltcmdversion{v1.0a}
-\def\ltcmddate{2021/01/21}
+\def\ltcmdversion{v1.0d}
+\def\ltcmddate{2021-04-19}
% \end{macrocode}
%
%<*driver>
% \fi
\ProvidesFile{ltcmd.dtx}
- [2020-11-20 v1.0 LaTeX Kernel (Document commands)]
+ [\ltcmddate\space \ltcmdversion\space
+ LaTeX Kernel (Document commands)]
% \iffalse
\documentclass{l3doc}
\GetFileInfo{ltcmd.dtx}
@@ -57,7 +58,7 @@
%
% \section{Creating document commands}
%
-% \changes{v1.0}{2020-11-20}{Initial version derived from \texttt{xparse.dtx}}
+% \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
@@ -78,6 +79,7 @@
%</2ekernel>
% \end{macrocode}
%
+% \changes{v1.0b}{2021/03/18}{Use \cs{NewModuleRelease}.}
% \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:
@@ -85,12 +87,9 @@
%<*2ekernel|latexrelease>
%<latexrelease>\edef\@latexrelease@catcode@null{\the\catcode`\^^@ }
%<latexrelease>\catcode`\^^@=12
-%<latexrelease>\IncludeInRelease{2021/05/01}%
-%<latexrelease> {\NewDocumentCommand}{Document commands}%
-% \end{macrocode}
-%
-% \begin{macrocode}
\ExplSyntaxOn
+%<latexrelease>\NewModuleRelease{2020/10/01}{ltcmd}
+%<latexrelease> {Document~command~parser}%
% \end{macrocode}
%
% \subsection{Variables and constants}
@@ -3196,7 +3195,7 @@
% \begin{macrocode}
\cs_new_protected:Npn \@@_get_arg_spec:NTF #1#2#3
{
- \@@_cmd_if_xparse:NTF #1
+ \__kernel_cmd_if_xparse:NTF #1
{
\tl_set:Nx \ArgumentSpecification { \tl_item:Nn #1 { 2 } }
#2
@@ -3374,15 +3373,22 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\@@_cmd_if_xparse:NTF}
+% \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).
+%
+% 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 \@@_cmd_if_xparse:NTF #1
+\cs_new_protected:Npn \__kernel_cmd_if_xparse:NTF #1
{
\exp_args:Nf \str_case_e:nnTF
{
@@ -4008,29 +4014,15 @@
% \end{macrocode}
%
% \begin{macrocode}
-\ExplSyntaxOff
-% \end{macrocode}
-%
-% \begin{macrocode}
-%</2ekernel|latexrelease>
-%<latexrelease>\EndIncludeInRelease
-%<latexrelease>\catcode`\^^@=\@latexrelease@catcode@null\relax
-%<latexrelease>
-%<latexrelease>\IncludeInRelease{2020/10/01}%
-%<latexrelease> {\NewDocumentCommand}{Document commands}%
-%<latexrelease>\@ifundefined{NewDocumentCommand}
-%<latexrelease> {%
-%<latexrelease> \IfFileExists{xparse.ltx}
-%<latexrelease> {\input xparse.ltx }
-%<latexrelease> {\@latex@error{LaTeX requires xparse}\@ehd}%
-%<latexrelease> }
-%<latexrelease> {}
-%<latexrelease>\EndIncludeInRelease
%<latexrelease>
-%<latexrelease>\IncludeInRelease{0000/00/00}%
-%<latexrelease> {\NewDocumentCommand}{Document commands}%
+%<latexrelease>\IncludeInRelease{0000/00/00}{ltcmd}%
+%<latexrelease> {Document~command~parser}%
%<latexrelease>
-%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\EndModuleRelease
+\ExplSyntaxOff
+%<latexrelease>\@ifundefined{ExplSyntaxOff}{}{\latexrelease@postexpl}
+%<latexrelease>\catcode`\^^@=\@latexrelease@catcode@null\relax
+%</2ekernel|latexrelease>
% \end{macrocode}
%
% We need to stop DocStrip treating |@@| in a special way at this point.
diff --git a/macros/latex-dev/base/ltcmdhooks-code.pdf b/macros/latex-dev/base/ltcmdhooks-code.pdf
new file mode 100644
index 0000000000..ccc055e33b
--- /dev/null
+++ b/macros/latex-dev/base/ltcmdhooks-code.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltcmdhooks-code.tex b/macros/latex-dev/base/ltcmdhooks-code.tex
new file mode 100644
index 0000000000..e54dcf10d8
--- /dev/null
+++ b/macros/latex-dev/base/ltcmdhooks-code.tex
@@ -0,0 +1,4 @@
+% this will typeset documentation + code
+
+\AtBeginDocument{\AlsoImplementation}
+\input{ltcmdhooks.dtx}
diff --git a/macros/latex-dev/base/ltcmdhooks-doc.pdf b/macros/latex-dev/base/ltcmdhooks-doc.pdf
new file mode 100644
index 0000000000..86cc6e3e96
--- /dev/null
+++ b/macros/latex-dev/base/ltcmdhooks-doc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltcmdhooks-doc.tex b/macros/latex-dev/base/ltcmdhooks-doc.tex
new file mode 100644
index 0000000000..1efae5f229
--- /dev/null
+++ b/macros/latex-dev/base/ltcmdhooks-doc.tex
@@ -0,0 +1,6 @@
+% this will typeset only documentation but not the code
+
+\AtBeginDocument{\OnlyDescription
+ \let\tableofcontents\relax
+ }
+\input{ltcmdhooks.dtx}
diff --git a/macros/latex-dev/base/ltcmdhooks.dtx b/macros/latex-dev/base/ltcmdhooks.dtx
new file mode 100644
index 0000000000..cc67f5eaa7
--- /dev/null
+++ b/macros/latex-dev/base/ltcmdhooks.dtx
@@ -0,0 +1,1093 @@
+% \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.0a}
+\def\ltcmdhooksdate{2021/04/30}
+%
+%
+%
+%<*driver>
+\documentclass{l3doc}
+%\usepackage{ltcmdhooks}
+\makeatletter
+\providecommand\footref[1]{%
+ \begingroup
+ \unrestored@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}
+%
+% \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@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} }
+ { \__kernel_msg_error:nnn { 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@addto@macro \@kernel@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@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@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}
+ {
+ \__kernel_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@DeclareRobustCommand \@@_patch_DeclareRobustCommand:Nnn }
+ { \@if@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@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@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@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}
+ {
+ \__kernel_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}
+\__kernel_msg_new:nnnn { hooks } { wrong-cmd-hook }
+ {
+ Command~hook~`cmd/#1/#2'~invalid.\\
+ The~hook~should~be~`cmd/#1/before'~or~`cmd/#1/after'.
+ }
+ {
+ You~tried~to~add~a~hook~to~command~\iow_char:N \\#1,~but~`#2'~
+ is~an~invalid~position.~Only~`before'~or~`after'~are~allowed.
+ }
+\__kernel_msg_new:nnnn { hooks } { cant-patch }
+ {
+ Command~`#1'~cannot~have~hooks~because~it~
+ \@@_unpatchable_cases:n {#2} .
+ }
+ {
+ You~tried~to~add~a~hook~to~`#1',~but~LaTeX~was~not~able~to~
+ add~the~hook~to~that~command~because~`#1'~
+ \@@_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
+%
diff --git a/macros/latex-dev/base/ltdefns.dtx b/macros/latex-dev/base/ltdefns.dtx
index ab9d4d0da1..7236083dfa 100644
--- a/macros/latex-dev/base/ltdefns.dtx
+++ b/macros/latex-dev/base/ltdefns.dtx
@@ -32,7 +32,7 @@
%<*driver>
% \fi
\ProvidesFile{ltdefns.dtx}
- [2021/01/15 v1.5o LaTeX Kernel (definition commands)]
+ [2021/04/19 v1.5o LaTeX Kernel (definition commands)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{ltdefns.dtx}
@@ -2419,7 +2419,8 @@
%
%
% \begin{macro}{\g@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}
diff --git a/macros/latex-dev/base/ltexpl.dtx b/macros/latex-dev/base/ltexpl.dtx
index a9be1b0521..6d7ec3ff60 100644
--- a/macros/latex-dev/base/ltexpl.dtx
+++ b/macros/latex-dev/base/ltexpl.dtx
@@ -33,7 +33,7 @@
%<*driver>
% \fi
\ProvidesFile{ltexpl.dtx}
- [2021/01/24 v1.3a LaTeX Kernel (expl3-dependent code)]
+ [2021/04/20 v1.3c LaTeX Kernel (expl3-dependent code)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{ltexpl.dtx}
@@ -82,21 +82,46 @@
% \begin{macrocode}
%<*2ekernel|latexrelease>
%<latexrelease>\IncludeInRelease{2020/10/01}%
-%<latexrelease> {kernel@enddocument hooks}{Define kernel enddocument Hooks}%
-\let\@kernel@after@enddocument\@empty
-\let\@kernel@after@enddocument@afterlastpage\@empty
+%<latexrelease> {kernel@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@after@enddocument\@undefined
+ \let \@kernel@after@enddocument \@empty
+ \let \@kernel@after@enddocument@afterlastpage \@empty
+% \end{macrocode}
+%
+% \begin{macro}{\@kernel@before@begindocument,\@kernel@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@before@begindocument \@empty
+ \let \@kernel@after@begindocument \@empty
+\fi
%<latexrelease>\EndIncludeInRelease
% \end{macrocode}
%
% \begin{macrocode}
%<latexrelease>\IncludeInRelease{0000/00/00}%
-%<latexrelease> {kernel@enddocument hooks}{Define kernel enddocument Hooks}%
+%<latexrelease> {kernel@enddocument hooks}{Define several kernel hooks}
%<latexrelease>\let\@kernel@after@enddocument\@undefined
%<latexrelease>\let\@kernel@after@enddocument@afterlastpage\@undefined
-%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\let\@kernel@before@begindocument\@undefined
+%<latexrelease>\let\@kernel@after@begindocument\@undefined
%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
% \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
diff --git a/macros/latex-dev/base/ltfilehook-code.pdf b/macros/latex-dev/base/ltfilehook-code.pdf
index 27c4d70486..ef767fa207 100644
--- a/macros/latex-dev/base/ltfilehook-code.pdf
+++ b/macros/latex-dev/base/ltfilehook-code.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltfilehook-doc.pdf b/macros/latex-dev/base/ltfilehook-doc.pdf
index 2ee786f0c9..28e0f8a5f2 100644
--- a/macros/latex-dev/base/ltfilehook-doc.pdf
+++ b/macros/latex-dev/base/ltfilehook-doc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltfilehook.dtx b/macros/latex-dev/base/ltfilehook.dtx
index 85c758ae60..e9309c41f7 100644
--- a/macros/latex-dev/base/ltfilehook.dtx
+++ b/macros/latex-dev/base/ltfilehook.dtx
@@ -31,8 +31,8 @@
%%% From File: ltfilehook.dtx
%
% \begin{macrocode}
-\providecommand\ltfilehookversion{v1.0g}
-\providecommand\ltfilehookdate{2021/02/08}
+\providecommand\ltfilehookversion{v1.0j}
+\providecommand\ltfilehookdate{2021/04/29}
% \end{macrocode}
%
%<*driver>
@@ -585,9 +585,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
@@ -601,7 +605,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 }
+ \__kernel_msg_error:nnn { hooks } { should-not-happen }
{ Tried~to~pop~from~an~empty~file~name~stack. }
}
}
@@ -1031,15 +1035,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{2021/05/01}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease> {\set@curr@file}{Setting current file name}%
\def\set@curr@file#1{%
\begingroup
\escapechar\m@ne
\let\protect\string
+ \edef~{\string~}%
\expandafter\def\csname\expandafter\endcsname
\expandafter{\csname\endcsname}%
% \end{macrocode}
@@ -1078,6 +1085,7 @@
%
% \begin{macrocode}
%<latexrelease>\IncludeInRelease{2020/10/01}%
+%<latexrelease> {\set@curr@file}{Setting current file name}%
%<latexrelease>\def\set@curr@file#1{%
%<latexrelease> \begingroup
%<latexrelease> \escapechar\m@ne
@@ -1529,7 +1537,7 @@
%
% \begin{macrocode}
\cs_new_eq:NN \@expl@@@filehook@file@push@@
- \__filehook_file_push:
+ \__filehook_file_push:
% \end{macrocode}
%
% \begin{macrocode}
@@ -1720,8 +1728,8 @@
% \Finale
%
%
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\endinput
-%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
diff --git a/macros/latex-dev/base/ltfiles.dtx b/macros/latex-dev/base/ltfiles.dtx
index b27f910587..bcaac58220 100644
--- a/macros/latex-dev/base/ltfiles.dtx
+++ b/macros/latex-dev/base/ltfiles.dtx
@@ -32,7 +32,7 @@
%<*driver>
% \fi
\ProvidesFile{ltfiles.dtx}
- [2021/01/15 v1.2j LaTeX Kernel (File Handling)]
+ [2021/04/17 v1.2m LaTeX Kernel (File Handling)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{ltfiles.dtx}
@@ -195,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}
@@ -470,9 +457,14 @@
% \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@before@begindocument} and
+% \cs{@kernel@after@begindocument} init earlier so that other modules can
+% write to the hooks}
% \begin{macrocode}
-\let \@kernel@before@begindocument \@empty
-\let \@kernel@after@begindocument \@empty
+%\let \@kernel@before@begindocument \@empty
+%\let \@kernel@after@begindocument \@empty
% \end{macrocode}
%
% \end{macro}
@@ -1072,30 +1064,114 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macrocode}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease> {\quote@name}{Quote file names}%
+%<latexrelease>
+%<latexrelease>\let\quote@name\@undefined
+%<latexrelease>\let\quote@@name\@undefined
+%<latexrelease>\let\unquote@name\@undefined
+%<latexrelease>
+%<latexrelease>\long\def \IfFileExists#1#2#3{%
+%<latexrelease> \openin\@inputcheck#1 %
+%<latexrelease> \ifeof\@inputcheck
+%<latexrelease> \ifx\input@path\@undefined
+%<latexrelease> \def\reserved@a{#3}%
+%<latexrelease> \else
+%<latexrelease> \def\reserved@a{\@iffileonpath{#1}{#2}{#3}}%
+%<latexrelease> \fi
+%<latexrelease> \else
+%<latexrelease> \closein\@inputcheck
+%<latexrelease> \edef\@filef@und{#1 }%
+%<latexrelease> \def\reserved@a{#2}%
+%<latexrelease> \fi
+%<latexrelease> \reserved@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@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@path\@undefined
- \def\reserved@a{#3}%
+ \let\reserved@a\@secondoftwo
\else
- \def\reserved@a{\@iffileonpath{#1}{#2}{#3}}%
+ \def\reserved@a{\@iffileonpath{#1}}%
\fi
\else
\closein\@inputcheck
\edef\@filef@und{"#1" }%
- \def\reserved@a{#2}%
+ \let\reserved@a\@firstoftwo
\fi
- \reserved@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@a
+ \expandafter{\reserved@a{#2}{#3}}%
+\reserved@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@path\@undefined
+%<latexrelease> \def\reserved@a{#3}%
+%<latexrelease> \else
+%<latexrelease> \def\reserved@a{\@iffileonpath{#1}{#2}{#3}}%
+%<latexrelease> \fi
+%<latexrelease> \else
+%<latexrelease> \closein\@inputcheck
+%<latexrelease> \edef\@filef@und{"#1" }%
+%<latexrelease> \def\reserved@a{#2}%
+%<latexrelease> \fi
+%<latexrelease> \reserved@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@path| is defined,
% look in all the directories specified in |\input@path|.
@@ -1109,6 +1185,10 @@
% \changes{v1.2d}{2019/10/26}{quote on openin}%
% \changes{v1.2f}{2019/11/11}{make \cs{@filef@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@a\@secondoftwo
\expandafter\@tfor\expandafter\reserved@b\expandafter
@@ -1128,28 +1208,7 @@
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
-%<latexrelease> {\quote@name}{Quote file names}%
-%<latexrelease>
-%<latexrelease>\let\quote@name\@undefined
-%<latexrelease>\let\quote@@name\@undefined
-%<latexrelease>\let\unquote@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@path\@undefined
-%<latexrelease> \def\reserved@a{#3}%
-%<latexrelease> \else
-%<latexrelease> \def\reserved@a{\@iffileonpath{#1}{#2}{#3}}%
-%<latexrelease> \fi
-%<latexrelease> \else
-%<latexrelease> \closein\@inputcheck
-%<latexrelease> \edef\@filef@und{#1 }%
-%<latexrelease> \def\reserved@a{#2}%
-%<latexrelease> \fi
-%<latexrelease> \reserved@a}
+%<latexrelease> {\quote@name}{Quote file names}
%<latexrelease>
%<latexrelease>\long\def\@iffileonpath#1{%
%<latexrelease> \let\reserved@a\@secondoftwo
diff --git a/macros/latex-dev/base/ltfinal.dtx b/macros/latex-dev/base/ltfinal.dtx
index d6fa6e8a7b..19f82934aa 100644
--- a/macros/latex-dev/base/ltfinal.dtx
+++ b/macros/latex-dev/base/ltfinal.dtx
@@ -33,7 +33,7 @@
%<*driver>
% \fi
\ProvidesFile{ltfinal.dtx}
- [2021/02/25 v2.2m LaTeX Kernel (Final Settings)]
+ [2021/04/18 v2.2o LaTeX Kernel (Final Settings)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{ltfinal.dtx}
@@ -242,7 +242,73 @@
% \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}
@@ -574,7 +640,7 @@
% \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2021/05/01}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease> {\pdfgentounicode}{Preload glyphtounicode}%
\ifx \pdfgentounicode \@undefined \else
%<*2ekernel>
@@ -1194,7 +1260,6 @@
% {Load first aid file if existing}
% \begin{macrocode}
\@input{latex2e-first-aid-for-external-files.ltx}
-\@input{ltpara.ltx}
% \end{macrocode}
%
%
diff --git a/macros/latex-dev/base/ltfloat.dtx b/macros/latex-dev/base/ltfloat.dtx
index f2324118a0..ed25db3ed1 100644
--- a/macros/latex-dev/base/ltfloat.dtx
+++ b/macros/latex-dev/base/ltfloat.dtx
@@ -31,7 +31,7 @@
%
%<*driver>
% \fi
-\ProvidesFile{ltfloat.dtx}[2021/02/10 v1.2f LaTeX Kernel (Floats)]
+\ProvidesFile{ltfloat.dtx}[2021/03/03 v1.2f LaTeX Kernel (Floats)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{ltfloat.dtx}
@@ -1008,7 +1008,7 @@
% \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2021/05/01}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease> {\@savemarbox}{Explicit par for marginpar}%
\long\def \@savemarbox #1#2{%
\global\setbox #1%
@@ -1513,7 +1513,7 @@
% \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2021/05/01}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease> {\@footnotetext}{footnotetext tagging}%
\long\def\@footnotetext#1{\insert\footins{%
\reset@font\footnotesize
@@ -1633,7 +1633,7 @@
% \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2021/05/01}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease> {\footref}{Add footref}%
\def\footref#1{%
\begingroup
@@ -1644,14 +1644,16 @@
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
% \end{macrocode}
-% We don't remove it when rolling back.
+% 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
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease> {\footref}{Add footref}%
+%<latexrelease>
+%<latexrelease> % \let\footref\@undefined
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
%<*2ekernel>
% \end{macrocode}
% \end{macro}
diff --git a/macros/latex-dev/base/ltfssaxes.dtx b/macros/latex-dev/base/ltfssaxes.dtx
index e0c0787455..86c84b111f 100644
--- a/macros/latex-dev/base/ltfssaxes.dtx
+++ b/macros/latex-dev/base/ltfssaxes.dtx
@@ -35,7 +35,7 @@
%
%
\ProvidesFile{ltfssaxes.dtx}
- [2021/01/15 v1.0h LaTeX Kernel (NFSS Axes handing)]
+ [2021/03/18 v1.0i LaTeX Kernel (NFSS Axes handing)]
% \iffalse
\documentclass{ltxdoc}
\begin{document}
@@ -699,7 +699,7 @@
%
% \begin{macrocode}
%<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2021/05/01}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease> {\fontseries}{delay fontseries update}%
% \end{macrocode}
%
@@ -772,11 +772,12 @@
%<latexrelease>
% \end{macrocode}
% For a roll forward we may have to define \cs{if@forced@series}
-% but this needs doing in a somewhat roundabout way.
+% 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>\ifx\@forced@seriestrue\@undefined \else
-%<latexrelease> \expandafter\newif\csname if@forced@series\endcsname
-%<latexrelease>\fi
+%<latexrelease>\expandafter\newif\csname if@forced@series\endcsname
%<latexrelease>
%<latexrelease>\EndIncludeInRelease
% \end{macrocode}
@@ -1328,7 +1329,7 @@
%
% \begin{macrocode}
%<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2021/05/01}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease> {\fontshape}{Font shape change}%
% \end{macrocode}
%
diff --git a/macros/latex-dev/base/ltfssbas.dtx b/macros/latex-dev/base/ltfssbas.dtx
index 6d575fc9d0..df265d0b0f 100644
--- a/macros/latex-dev/base/ltfssbas.dtx
+++ b/macros/latex-dev/base/ltfssbas.dtx
@@ -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@family{#2}%
\set@target@series{#3}%
- \edef\f@shape{#4}\selectfont
+ \edef\f@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@f@adjustment}.
+% \changes{v3.2i}{2021/04/26}{Unconditionally switch to the requested
+% font face (gh/444)}
+% \begin{macrocode}
+ \let\delayed@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@family{#2}%
+%<latexrelease> \set@target@series{#3}%
+%<latexrelease> \edef\f@shape{#4}\selectfont
+%<latexrelease> \ignorespaces}
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease> {\usefont}{Drop m in usefont}%
%<latexrelease>
diff --git a/macros/latex-dev/base/ltfssini.dtx b/macros/latex-dev/base/ltfssini.dtx
index 361adac9c3..b06fc161b0 100644
--- a/macros/latex-dev/base/ltfssini.dtx
+++ b/macros/latex-dev/base/ltfssini.dtx
@@ -36,7 +36,7 @@
%
%
\ProvidesFile{ltfssini.dtx}
- [2021/01/15 v3.2f LaTeX Kernel (NFSS Initialisation)]
+ [2021/04/26 v3.2h LaTeX Kernel (NFSS Initialisation)]
% \iffalse
\documentclass{ltxdoc}
\begin{document}
@@ -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@family@series@update{tt}\ttdefault
%<latexrelease> \@ttfamilyhook
%<latexrelease> \selectfont}
+%<latexrelease>\let\@rmfamilyhook\@empty
+%<latexrelease>\let\@sffamilyhook\@empty
+%<latexrelease>\let\@ttfamilyhook\@empty
%<latexrelease>
% \end{macrocode}
%
@@ -1765,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}
@@ -1778,6 +1783,15 @@
\edef\f@series{\seriesdefault}%
\edef\f@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@f@adjustment}.
+% \changes{v3.2h}{2021/04/26}{Unconditionally switch to the requested
+% font face (gh/444)}
+% \begin{macrocode}
+ \let\delayed@f@adjustment\@empty
+% \end{macrocode}
%
% \changes{v3.2b}{2020/08/21}{Integration of new hook management interface}
% \begin{macrocode}
@@ -1789,18 +1803,54 @@
\@defaultfamilyhook % hookname from 2020/02 will vanish
\selectfont}
% \end{macrocode}
-%
+%
% \begin{macrocode}
\let\reset@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@family{\familydefault}%
+%<latexrelease> \edef\f@series{\seriesdefault}%
+%<latexrelease> \edef\f@shape{\shapedefault}%
+%<latexrelease> \UseHook{normalfont}%
+%<latexrelease> \@defaultfamilyhook % hookname from 2020/02 will vanish
+%<latexrelease> \selectfont}
+%<latexrelease>
+%<latexrelease>\let\reset@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@family{\familydefault}%
+%<latexrelease> \edef\f@series{\seriesdefault}%
+%<latexrelease> \edef\f@shape{\shapedefault}%
+%<latexrelease> \@defaultfamilyhook
+%<latexrelease> \selectfont}
+%<latexrelease>
+%<latexrelease>\let\reset@font\normalfont
+%<latexrelease>
+%<latexrelease>\let\@defaultfamilyhook\@empty
+%<latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease> {\normalfont}{Add hook to \normalfont}%
%<latexrelease>
diff --git a/macros/latex-dev/base/ltfsstrc.dtx b/macros/latex-dev/base/ltfsstrc.dtx
index 961abafc8a..c6aec105ba 100644
--- a/macros/latex-dev/base/ltfsstrc.dtx
+++ b/macros/latex-dev/base/ltfsstrc.dtx
@@ -32,12 +32,12 @@
%% Copyright (C) 1989-97 by Frank Mittelbach and Rainer Sch\"opf.
%% Copyright (C) 1994-97 by LaTeX Project. All rights reserved.
%
-%<package>\NeedsTeXFormat{LaTeX2e}[2021/05/01]
+%<package>\NeedsTeXFormat{LaTeX2e}[2021/06/01]
%<package>\ProvidesPackage{tracefnt}
%<package> [2020/12/22 v3.0n Standard LaTeX package (font tracing)]
% \fi
% \ProvidesFile{ltfsstrc.dtx}
-% [2020/12/22 v3.0n LaTeX Kernel (NFSS tracing)]
+% [2021/04/26 v3.0o LaTeX Kernel (NFSS tracing)]
%
% \iffalse
%<+checkmem>\CHECKMEM
@@ -423,7 +423,7 @@
% \begin{macrocode}
%<*2ekernel|latexrelease|package>
-%<latexrelease>\IncludeInRelease{2021/05/01}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease> {\selectfont}{Add hook to \selectfont}%
% \end{macrocode}
%
@@ -525,6 +525,14 @@
\let\delayed@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@series}.
+% \changes{v3.0o}{2021/04/26}{Unset the forced series boolean when reaching
+% \cs{selectfont} (gh/444)}
+% \begin{macrocode}
+ \@forced@seriesfalse
+% \end{macrocode}
% Then we generate the internal name of the font
% by concatenating {\em family}, {\em series},
% {\em shape}, and current {\em size},
@@ -610,7 +618,7 @@
% 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/05/01}%
+%<package>\IncludeInRelease{2021/06/01}%
%<package> {\selectfont}{Add hook to \selectfont}%
%<package>\EndIncludeInRelease
% \end{macrocode}
diff --git a/macros/latex-dev/base/lthooks-code.pdf b/macros/latex-dev/base/lthooks-code.pdf
index d47079374c..b50be3475f 100644
--- a/macros/latex-dev/base/lthooks-code.pdf
+++ b/macros/latex-dev/base/lthooks-code.pdf
Binary files differ
diff --git a/macros/latex-dev/base/lthooks-doc.pdf b/macros/latex-dev/base/lthooks-doc.pdf
index 2bca7b9184..369fa25069 100644
--- a/macros/latex-dev/base/lthooks-doc.pdf
+++ b/macros/latex-dev/base/lthooks-doc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/lthooks.dtx b/macros/latex-dev/base/lthooks.dtx
index 803914b4a7..45d6a78aba 100644
--- a/macros/latex-dev/base/lthooks.dtx
+++ b/macros/latex-dev/base/lthooks.dtx
@@ -31,8 +31,8 @@
%%% From File: lthooks.dtx
%
% \begin{macrocode}
-\def\lthooksversion{v1.0h}
-\def\lthooksdate{2021/01/15}
+\def\lthooksversion{v1.0m}
+\def\lthooksdate{2021/04/29}
% \end{macrocode}
%
%<*driver>
@@ -67,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}}
+%
+% \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}}
%
-% \newcommand\hook[1]{\texttt{#1}}
%
%
% \title{The \texttt{lthooks} package\thanks{This package has version
@@ -122,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}
@@ -176,6 +180,62 @@
% \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}
@@ -201,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
@@ -212,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}
%
%
@@ -264,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.
@@ -299,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
@@ -359,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
@@ -370,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.
%
@@ -425,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.
@@ -435,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}
@@ -651,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
@@ -664,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}
@@ -676,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.
%
@@ -684,30 +753,7 @@
% 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}
%
@@ -822,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}
@@ -859,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}
@@ -971,28 +1064,6 @@
% 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}
@@ -1262,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@before@\meta{hookname}} or
-% \cs{@kernel@after@\meta{hookname}}. For example, in
+% convention: \cs{@kernel@before@\meta{hook}} or
+% \cs{@kernel@after@\meta{hook}}. For example, in
% \cs{enddocument} you find
%\begin{verbatim}
% \UseHook{enddocument}%
@@ -1412,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
@@ -1455,6 +1526,38 @@
% \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}
@@ -1554,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.
%
@@ -1621,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
@@ -1630,14 +1735,6 @@
% \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}
%
@@ -1706,27 +1803,19 @@
% \section{The Implementation}
%
%
-% \subsection{Loading further extensions}
-%
% \begin{macrocode}
%<@@=hook>
% \end{macrocode}
%
-%
-% 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.
+% \changes{v1.0i}{2021/03/18}
+% {Use \cs{NewModuleRelease}.}
% \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}
@@ -1856,8 +1945,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 }
@@ -1949,25 +2039,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.
@@ -1976,54 +2071,194 @@
% 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,
% 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.
+%
+% 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}
-% The \cs{hook_new:n} declaration declare a new hook and expects
+% \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}
+ \@@_if_declared:nTF {#1}
+ { \__kernel_msg_error:nnn { hooks } { exists } {#1} }
+ {
+ \tl_new:c { g_@@_#1_declared_tl }
+ \@@_make_usable:n {#1}
+ }
+ }
+% \end{macrocode}
+% \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}
- \hook_if_exist:nTF {#1}
- { \msg_error:nnn { hooks } { exists } {#1} }
+\cs_new_protected:Npn \@@_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.
+% 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}
@@ -2034,12 +2269,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
@@ -2061,23 +2296,30 @@
%
% \begin{macrocode}
\@@_include_legacy_code_chunk:n {#1}
- }
+ }
}
% \end{macrocode}
% \end{macro}
%
%
%
-% \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 }
@@ -2109,6 +2351,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}
@@ -2159,6 +2404,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}
+ { \__kernel_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}
+ { \__kernel_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}
@@ -2193,7 +2572,7 @@
{
\tl_if_empty:nTF {#1}
{
- \msg_expandable_error:nn { hooks } { empty-label }
+ \__kernel_msg_expandable_error:nn { hooks } { empty-label }
\@@_currname_or_default:
}
{
@@ -2230,7 +2609,7 @@
{
\tl_if_empty:NTF \@currname
{
- \msg_expandable_error:nnn { hooks } { should-not-happen }
+ \__kernel_msg_expandable_error:nnn { hooks } { should-not-happen }
{ Empty~default~label. }
\@@_make_name:n { label-missing }
}
@@ -2247,10 +2626,10 @@
% 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
{
@@ -2310,6 +2689,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}
%
@@ -2319,6 +2701,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}
@@ -2342,7 +2727,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}=
@@ -2363,10 +2748,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}
+ { \__kernel_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}
%
@@ -2378,7 +2770,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@line\space <-~ \tl_to_str:n{#3}} }
% \end{macrocode}
@@ -2386,9 +2778,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 }
{
@@ -2396,12 +2788,12 @@
{
% \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} }
+ { \__kernel_msg_error:nnn { hooks } { misused-top-level } {#1} }
}
{
\prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl
@@ -2423,14 +2815,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.
@@ -2457,13 +2850,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
@@ -2481,12 +2875,24 @@
}
{ \@@_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}
{ #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 }
{
@@ -2495,31 +2901,70 @@
{
\prop_if_in:NnTF \c_@@_generics_prop {#1}
{
- \hook_if_exist:nF {#5} { \hook_new:n {#5} }
+ \@@_if_usable:nF {#5}
+ {
+% \end{macrocode}
+% 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}
-% 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.
+%
+% 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 } { - } }
{
\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}
@@ -2528,7 +2973,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
@@ -2594,14 +3039,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}
%
@@ -2628,11 +3075,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
@@ -2640,9 +3087,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} {*}
{
@@ -2655,7 +3102,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
@@ -2679,7 +3126,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}
@@ -2774,10 +3221,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}
@@ -2798,14 +3245,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
{
@@ -2813,14 +3258,14 @@
{#1} {#2} {#3} {#4}
}
% \end{macrocode}
-%
+%
% \begin{macrocode}
\cs_new_protected:Npn \@@_gset_rule:nnnn #1#2#3#4
{
% \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}
@@ -2834,7 +3279,7 @@
{#1} {#2} {#4}
\@@_update_hook_code:n {#1}
}
- { \msg_error:nnnnnn { hooks } { unknown-rule }
+ { \__kernel_msg_error:nnnnnn { hooks } { unknown-rule }
{#1} {#2} {#3} {#4} }
}
% \end{macrocode}
@@ -2938,7 +3383,7 @@
{
\if_int_compare:w \@@_str_compare:nn {#1} {#2} > 0 \exp_stop_f:
\prg_return_true:
- \else
+ \else:
\prg_return_false:
\fi:
}
@@ -3038,13 +3483,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}
{
@@ -3097,7 +3542,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 }
@@ -3161,7 +3606,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
@@ -3302,7 +3747,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{====================}
@@ -3442,7 +3887,7 @@
\cs_new_protected:cpn { @@_apply_rule_xE:nnn } #1#2#3
{
\@@_debug:n { \@@_msg_pair_found:nnn {#1} {#2} {#3} }
- \msg_error:nnnnnn { hooks } { labels-incompatible }
+ \__kernel_msg_error:nnnnnn { hooks } { labels-incompatible }
{#1} {#2} {#3} { 1 }
\use:c { @@_apply_rule_->:nnn } {#1} {#2} {#3}
\use:c { @@_apply_rule_<-:nnn } {#1} {#2} {#3}
@@ -3450,7 +3895,7 @@
\cs_new_protected:cpn { @@_apply_rule_xW:nnn } #1#2#3
{
\@@_debug:n { \@@_msg_pair_found:nnn {#1} {#2} {#3} }
- \msg_warning:nnnnnn { hooks } { labels-incompatible }
+ \__kernel_msg_warning:nnnnnn { hooks } { labels-incompatible }
{#1} {#2} {#3} { 0 }
}
% \end{macrocode}
@@ -3573,15 +4018,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 } }
{
@@ -3599,7 +4049,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
@@ -3650,7 +4100,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
@@ -3672,10 +4122,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} }
}
}
}
@@ -3767,25 +4219,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}
+ { \__kernel_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
@@ -3814,7 +4278,11 @@
{ \cs_gset_eq:cN { @@_next~#1 } \c_empty_tl }
% \end{macrocode}
% \end{macro}
-% \end{macro}
+%
+%
+%
+%
+%
%
% \subsection{Using the hook}
%
@@ -3841,7 +4309,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.
@@ -3878,7 +4346,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,
@@ -3888,7 +4356,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
@@ -3897,16 +4365,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 }
{
@@ -3929,7 +4403,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
{
@@ -3953,9 +4426,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
@@ -3965,19 +4439,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 } }
@@ -3994,8 +4468,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
@@ -4003,7 +4478,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: }
@@ -4012,13 +4487,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: }
@@ -4026,6 +4503,22 @@
}
% \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.
@@ -4045,10 +4538,10 @@
% \subsection{Messages}
%
% \begin{macrocode}
-\msg_new:nnnn { hooks } { labels-incompatible }
+\__kernel_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,23 +4551,34 @@
% \end{macrocode}
%
% \begin{macrocode}
-\msg_new:nnnn { hooks } { exists }
- { Hook~`#1'~ has~ already~ been~ declared. }
+\__kernel_msg_new:nnnn { hooks } { exists }
+ { 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}
+\__kernel_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 }
+\__kernel_msg_new:nnn { hooks } { empty-label }
{
Empty~code~label~\msg_line_context:.~
- Using~`\@@_currname_or_default:'~instead.
+ Using~'\@@_currname_or_default:'~instead.
}
% \end{macrocode}
%
% \begin{macrocode}
-\msg_new:nnn { hooks } { no-default-label }
+\__kernel_msg_new:nnn { hooks } { no-default-label }
{
Missing~(empty)~default~label~\msg_line_context:. \\
This~command~was~ignored.
@@ -4082,25 +4586,25 @@
% \end{macrocode}
%
% \begin{macrocode}
-\msg_new:nnnn { hooks } { unknown-rule }
- { Unknown~ relationship~ `#3'~
- between~ labels~ `#2'~ and~ `#4'~
- \str_if_eq:nnF {#1} {??} { ~in~hook~`#1' }. ~
+\__kernel_msg_new:nnnn { hooks } { unknown-rule }
+ { 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}
%
% \begin{macrocode}
-\msg_new:nnnn { hooks } { misused-top-level }
+\__kernel_msg_new:nnnn { hooks } { misused-top-level }
{
Illegal~\iow_char:N \\AddToHook{#1}[top-level]{...}.\\
'top-level'~is~reserved~for~the~user's~document.
@@ -4114,16 +4618,16 @@
% \end{macrocode}
%
% \begin{macrocode}
-\msg_new:nnn { hooks } { set-top-level }
+\__kernel_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:.
}
% \end{macrocode}
%
% \begin{macrocode}
-\msg_new:nnn { hooks } { ddhl-deprecated }
+\__kernel_msg_new:nnn { hooks } { ddhl-deprecated }
{
\iow_char:N \\DeclareDefaultHookLabel~is~deprecated.\\
Use~\iow_char:N \\SetDefaultHookLabel~instead.\\ \\
@@ -4132,26 +4636,55 @@
% \end{macrocode}
%
% \begin{macrocode}
-\msg_new:nnn { hooks } { extra-pop-label }
+\__kernel_msg_new:nnn { hooks } { extra-pop-label }
{
Extra~\iow_char:N \\PopDefaultHookLabel. \\
This~command~will~be~ignored.
}
-\msg_new:nnn { hooks } { missing-pop-label }
+\__kernel_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 }
+\__kernel_msg_new:nnn { hooks } { should-not-happen }
{
ERROR!~This~should~not~happen.~#1 \\
Please~report~at~https://github.com/latex3/latex2e.
}
% \end{macrocode}
%
+%
+%
+% \begin{macrocode}
+\__kernel_msg_new:nnn { hooks } { provide-disabled }
+ {
+ Can't~ provide~ hook~ '#1'~ because~ it~ is~ disabled!
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\__kernel_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}
%
%
@@ -4165,6 +4698,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}
@@ -4194,6 +4765,10 @@
% \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:}
@@ -4217,8 +4792,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:
@@ -4234,9 +4812,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,
@@ -4248,11 +4829,11 @@
\cs_new_protected:Npn \@@_curr_name_push_aux:n #1
{
\tl_if_blank:nTF {#1}
- { \msg_error:nn { hooks } { no-default-label } }
+ { \__kernel_msg_error:nn { hooks } { no-default-label } }
{
\str_if_eq:nnTF {#1} { top-level }
{
- \msg_error:nnnnn { hooks } { set-top-level }
+ \__kernel_msg_error:nnnnn { hooks } { set-top-level }
{ to } { PushDefaultHookLabel } {#1}
}
{
@@ -4270,12 +4851,12 @@
{
\seq_gpop:NNTF \g_@@_name_stack_seq \l_@@_return_tl
{ \tl_gset_eq:NN \g_@@_hook_curr_name_tl \l_@@_return_tl }
- { \msg_error:nn { hooks } { extra-pop-label } }
+ { \__kernel_msg_error:nn { hooks } { extra-pop-label } }
}
% \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}
@@ -4285,7 +4866,7 @@
{
\seq_gpop:NNT \g_@@_name_stack_seq \l_@@_return_tl
{
- \msg_error:nnx { hooks } { missing-pop-label }
+ \__kernel_msg_error:nnx { hooks } { missing-pop-label }
{ \g_@@_hook_curr_name_tl }
\tl_gset_eq:NN \g_@@_hook_curr_name_tl \l_@@_return_tl
\@@_end_document_label_check:
@@ -4303,7 +4884,7 @@
{
\seq_if_empty:NTF \g_@@_name_stack_seq
{
- \msg_error:nnnnn { hooks } { set-top-level }
+ \__kernel_msg_error:nnnnn { hooks } { set-top-level }
{ for } { SetDefaultHookLabel } {#1}
}
{ \exp_args:Nx \@@_set_default_label:n { \@@_make_name:n {#1} } }
@@ -4312,14 +4893,14 @@
{
\str_if_eq:nnTF {#1} { top-level }
{
- \msg_error:nnnnn { hooks } { set-top-level }
+ \__kernel_msg_error:nnnnn { hooks } { set-top-level }
{ to } { SetDefaultHookLabel } {#1}
}
{ \tl_gset:Nn \g_@@_hook_curr_name_tl {#1} }
}
\NewDocumentCommand \DeclareDefaultHookLabel { m }
{
- \msg_error:nn { hooks } { ddhl-deprecated }
+ \__kernel_msg_error:nn { hooks } { ddhl-deprecated }
\SetDefaultHookLabel {#1}
}
% \end{macrocode}
@@ -4414,7 +4995,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} }
@@ -4422,19 +5003,33 @@
% \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}
%
@@ -4463,12 +5058,6 @@
% \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
@@ -4476,14 +5065,15 @@
% \changes{v1.0d}{2020/10/04}{Definition \cs{AddToHookNext} was supposed
% 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>
-%<latexrelease>\def\NewHook#1{}
-%<latexrelease>\def\NewReversedHook#1{}
-%<latexrelease>\def\NewMirroredHookPair#1#2{}
+%<latexrelease>\def \DisableHook #1{}
%<latexrelease>
%<latexrelease>\long\def\AddToHookNext#1#2{}
%<latexrelease>
@@ -4511,7 +5101,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}
%
%
diff --git a/macros/latex-dev/base/ltluatex.dtx b/macros/latex-dev/base/ltluatex.dtx
index e3fa9f9343..3b9a337731 100644
--- a/macros/latex-dev/base/ltluatex.dtx
+++ b/macros/latex-dev/base/ltluatex.dtx
@@ -28,7 +28,7 @@
\ProvidesFile{ltluatex.dtx}
%</driver>
%<*tex>
-[2021/01/15 v1.1s
+[2021/04/18 v1.1t
%</tex>
%<plain> LuaTeX support for plain TeX (core)
%<*tex>
@@ -1412,6 +1412,7 @@ local callbacktypes = callbacktypes or {
% \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,
@@ -1419,6 +1420,7 @@ local callbacktypes = callbacktypes or {
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}
@@ -1477,7 +1479,7 @@ end
% 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.
diff --git a/macros/latex-dev/base/ltluatex.pdf b/macros/latex-dev/base/ltluatex.pdf
index 120ea02dcb..3b803f3383 100644
--- a/macros/latex-dev/base/ltluatex.pdf
+++ b/macros/latex-dev/base/ltluatex.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltmath.dtx b/macros/latex-dev/base/ltmath.dtx
index ca90e1980d..aadb96fb02 100644
--- a/macros/latex-dev/base/ltmath.dtx
+++ b/macros/latex-dev/base/ltmath.dtx
@@ -38,7 +38,7 @@
%<*driver>
% \fi
\ProvidesFile{ltmath.dtx}
- [2020/12/05 v1.2h LaTeX Kernel (Math Setup)]
+ [2021/04/20 v1.2i LaTeX Kernel (Math Setup)]
% \iffalse
%</driver>
%
@@ -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}
diff --git a/macros/latex-dev/base/ltmiscen.dtx b/macros/latex-dev/base/ltmiscen.dtx
index 939bd51a2d..8bae3f9bfa 100644
--- a/macros/latex-dev/base/ltmiscen.dtx
+++ b/macros/latex-dev/base/ltmiscen.dtx
@@ -400,7 +400,7 @@
% \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2021/05/01}%
+%<latexrelease>\IncludeInRelease{2021/06/01}%
%<latexrelease> {\@kernel@before@enddocument}{kernel before hook}%
\def\@kernel@before@enddocument{\par}
%</2ekernel|latexrelease>
diff --git a/macros/latex-dev/base/ltnews.pdf b/macros/latex-dev/base/ltnews.pdf
index ed24b7b485..02b805b97d 100644
--- a/macros/latex-dev/base/ltnews.pdf
+++ b/macros/latex-dev/base/ltnews.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews.tex b/macros/latex-dev/base/ltnews.tex
index 87982065d2..fa44de670c 100644
--- a/macros/latex-dev/base/ltnews.tex
+++ b/macros/latex-dev/base/ltnews.tex
@@ -177,6 +177,11 @@
\egroup
}
+\ExplSyntaxOn
+\newcommand \acro [1]
+ { \textsc { \text_lowercase:n {#1} } }
+\ExplSyntaxOff
+
\makeatother
diff --git a/macros/latex-dev/base/ltnews01.pdf b/macros/latex-dev/base/ltnews01.pdf
index 02a6c7a776..0f16508cc2 100644
--- a/macros/latex-dev/base/ltnews01.pdf
+++ b/macros/latex-dev/base/ltnews01.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews02.pdf b/macros/latex-dev/base/ltnews02.pdf
index a9a388e900..718558863a 100644
--- a/macros/latex-dev/base/ltnews02.pdf
+++ b/macros/latex-dev/base/ltnews02.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews03.pdf b/macros/latex-dev/base/ltnews03.pdf
index 256c443b84..be857e7ee4 100644
--- a/macros/latex-dev/base/ltnews03.pdf
+++ b/macros/latex-dev/base/ltnews03.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews04.pdf b/macros/latex-dev/base/ltnews04.pdf
index 6f9651308c..005348dff7 100644
--- a/macros/latex-dev/base/ltnews04.pdf
+++ b/macros/latex-dev/base/ltnews04.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews05.pdf b/macros/latex-dev/base/ltnews05.pdf
index 01a5d7a1f8..7008d76f68 100644
--- a/macros/latex-dev/base/ltnews05.pdf
+++ b/macros/latex-dev/base/ltnews05.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews06.pdf b/macros/latex-dev/base/ltnews06.pdf
index 1c504ac583..538c9768f3 100644
--- a/macros/latex-dev/base/ltnews06.pdf
+++ b/macros/latex-dev/base/ltnews06.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews07.pdf b/macros/latex-dev/base/ltnews07.pdf
index 654abf8b13..d6b706b906 100644
--- a/macros/latex-dev/base/ltnews07.pdf
+++ b/macros/latex-dev/base/ltnews07.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews08.pdf b/macros/latex-dev/base/ltnews08.pdf
index a672d94340..9931ddee80 100644
--- a/macros/latex-dev/base/ltnews08.pdf
+++ b/macros/latex-dev/base/ltnews08.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews09.pdf b/macros/latex-dev/base/ltnews09.pdf
index c6e93c9496..616c594eb8 100644
--- a/macros/latex-dev/base/ltnews09.pdf
+++ b/macros/latex-dev/base/ltnews09.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews10.pdf b/macros/latex-dev/base/ltnews10.pdf
index 7eba03fb13..7e0f03f1cc 100644
--- a/macros/latex-dev/base/ltnews10.pdf
+++ b/macros/latex-dev/base/ltnews10.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews11.pdf b/macros/latex-dev/base/ltnews11.pdf
index 3e4489ebce..6ef42aca9f 100644
--- a/macros/latex-dev/base/ltnews11.pdf
+++ b/macros/latex-dev/base/ltnews11.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews12.pdf b/macros/latex-dev/base/ltnews12.pdf
index 15ecabb663..3ea3f11d6a 100644
--- a/macros/latex-dev/base/ltnews12.pdf
+++ b/macros/latex-dev/base/ltnews12.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews12.tex b/macros/latex-dev/base/ltnews12.tex
index 8815c232ec..7e3a73f508 100644
--- a/macros/latex-dev/base/ltnews12.tex
+++ b/macros/latex-dev/base/ltnews12.tex
@@ -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}
diff --git a/macros/latex-dev/base/ltnews13.pdf b/macros/latex-dev/base/ltnews13.pdf
index c1731bc652..a94411b8c2 100644
--- a/macros/latex-dev/base/ltnews13.pdf
+++ b/macros/latex-dev/base/ltnews13.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews14.pdf b/macros/latex-dev/base/ltnews14.pdf
index 28c3a8adbd..79be2aab4d 100644
--- a/macros/latex-dev/base/ltnews14.pdf
+++ b/macros/latex-dev/base/ltnews14.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews15.pdf b/macros/latex-dev/base/ltnews15.pdf
index 7e0bed9caa..aa4ef31e3e 100644
--- a/macros/latex-dev/base/ltnews15.pdf
+++ b/macros/latex-dev/base/ltnews15.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews16.pdf b/macros/latex-dev/base/ltnews16.pdf
index e8020df9f0..a11d785c60 100644
--- a/macros/latex-dev/base/ltnews16.pdf
+++ b/macros/latex-dev/base/ltnews16.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews17.pdf b/macros/latex-dev/base/ltnews17.pdf
index 6b267b1406..b25ec2b3b4 100644
--- a/macros/latex-dev/base/ltnews17.pdf
+++ b/macros/latex-dev/base/ltnews17.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews18.pdf b/macros/latex-dev/base/ltnews18.pdf
index d84aeeba0f..7e926718fb 100644
--- a/macros/latex-dev/base/ltnews18.pdf
+++ b/macros/latex-dev/base/ltnews18.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews19.pdf b/macros/latex-dev/base/ltnews19.pdf
index ad22c7254d..96f3be4711 100644
--- a/macros/latex-dev/base/ltnews19.pdf
+++ b/macros/latex-dev/base/ltnews19.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews20.pdf b/macros/latex-dev/base/ltnews20.pdf
index 5eb13810e9..5b2ed0ee07 100644
--- a/macros/latex-dev/base/ltnews20.pdf
+++ b/macros/latex-dev/base/ltnews20.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews21.pdf b/macros/latex-dev/base/ltnews21.pdf
index c40d64c9f2..e8dfbc7c0f 100644
--- a/macros/latex-dev/base/ltnews21.pdf
+++ b/macros/latex-dev/base/ltnews21.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews22.pdf b/macros/latex-dev/base/ltnews22.pdf
index bf670e208d..240c83b6c6 100644
--- a/macros/latex-dev/base/ltnews22.pdf
+++ b/macros/latex-dev/base/ltnews22.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews23.pdf b/macros/latex-dev/base/ltnews23.pdf
index f485261a67..9807ac1a7a 100644
--- a/macros/latex-dev/base/ltnews23.pdf
+++ b/macros/latex-dev/base/ltnews23.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews24.pdf b/macros/latex-dev/base/ltnews24.pdf
index 513e3d8779..0aa98e091e 100644
--- a/macros/latex-dev/base/ltnews24.pdf
+++ b/macros/latex-dev/base/ltnews24.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews25.pdf b/macros/latex-dev/base/ltnews25.pdf
index 085e5958bc..3393251fb8 100644
--- a/macros/latex-dev/base/ltnews25.pdf
+++ b/macros/latex-dev/base/ltnews25.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews26.pdf b/macros/latex-dev/base/ltnews26.pdf
index ce1f355dbf..b6da2cc18d 100644
--- a/macros/latex-dev/base/ltnews26.pdf
+++ b/macros/latex-dev/base/ltnews26.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews27.pdf b/macros/latex-dev/base/ltnews27.pdf
index 6cf574b621..d3f0ab919f 100644
--- a/macros/latex-dev/base/ltnews27.pdf
+++ b/macros/latex-dev/base/ltnews27.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews28.pdf b/macros/latex-dev/base/ltnews28.pdf
index 2d0c517c1c..d6670e6a43 100644
--- a/macros/latex-dev/base/ltnews28.pdf
+++ b/macros/latex-dev/base/ltnews28.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews29.pdf b/macros/latex-dev/base/ltnews29.pdf
index feefff5b52..60644a30e4 100644
--- a/macros/latex-dev/base/ltnews29.pdf
+++ b/macros/latex-dev/base/ltnews29.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews30.pdf b/macros/latex-dev/base/ltnews30.pdf
index d55fccc019..87651bc456 100644
--- a/macros/latex-dev/base/ltnews30.pdf
+++ b/macros/latex-dev/base/ltnews30.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews31.pdf b/macros/latex-dev/base/ltnews31.pdf
index fa449938c0..f50f366566 100644
--- a/macros/latex-dev/base/ltnews31.pdf
+++ b/macros/latex-dev/base/ltnews31.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews32.pdf b/macros/latex-dev/base/ltnews32.pdf
index 901c02a46e..51c980520e 100644
--- a/macros/latex-dev/base/ltnews32.pdf
+++ b/macros/latex-dev/base/ltnews32.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews32.tex b/macros/latex-dev/base/ltnews32.tex
index 2f1db6c560..c56537a203 100644
--- a/macros/latex-dev/base/ltnews32.tex
+++ b/macros/latex-dev/base/ltnews32.tex
@@ -278,7 +278,7 @@ expressions (as used by the \cs{glueexpr} primitive although all uses
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.
diff --git a/macros/latex-dev/base/ltnews33.pdf b/macros/latex-dev/base/ltnews33.pdf
index 548bb7c4da..486fd7b9ab 100644
--- a/macros/latex-dev/base/ltnews33.pdf
+++ b/macros/latex-dev/base/ltnews33.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltnews33.tex b/macros/latex-dev/base/ltnews33.tex
index 922740a7ed..7f23e9d853 100644
--- a/macros/latex-dev/base/ltnews33.tex
+++ b/macros/latex-dev/base/ltnews33.tex
@@ -40,6 +40,8 @@
\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}}
@@ -71,7 +73,7 @@
\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#2}%
+ \href{https://www.latex-project.org/cgi-bin/ltxbugs2html?pr=#1\%2F\getfirstgithubissue#2 \relax}%
{gnats issue #1/#2}%
)}%
\par}
@@ -87,8 +89,8 @@
\providecommand\tubcommand[1]{}
\tubcommand{\input{tubltmac}}
-\publicationmonth{May}
-\publicationyear{2021}
+\publicationmonth{June}
+\publicationyear{2021 --- Draft Version}
\publicationissue{33}
@@ -107,7 +109,14 @@
\section{Introduction}
-\emph{to be written}
+The focus of the June 2020 release is to provide further important
+building blocks for producing reliable tagged PDF output in the future
+(see \cite{33:blueprint}), they are discussed in the next two
+sections. In addition we included a number of smaller enhancement and
+fixes that are outlined on the next pages. As usual, more detail can
+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}.
@@ -115,11 +124,11 @@
\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 (see
-\cite{33:blueprint}), we have extended the paragraph processing of
-\LaTeX{} so that the kernel gains control both at the start and the
-end of each paragraph. This is done in a manner that is (or should
-be) transparent to packages and user documents.
+processing, in particular when producing tagged PDF output, we have
+extended the paragraph processing of \LaTeX{} so that the kernel gains
+control both at the start and the end of each paragraph. This is done
+in a manner that is (or should be) transparent to packages and user
+documents.
Beside the internal control points for exclusive use of the \LaTeX{}
kernel we also implemented four public hooks that can be used by
@@ -131,9 +140,38 @@ packages.
The documentation of the hooks together with a few examples is
provided in \file{ltpara-doc.pdf} and for those who want to study the
-(quite interesting) code is found in \file{ltpara-code.pdf}. At
-some point in the future it will get fully merged into the \LaTeX{}
-kernel and will then appear in \file{source2e.pdf}.
+(quite interesting) code is found in
+\file{ltpara-code.pdf}. Additionally it is included as part of the
+full kernel documentation in \file{source2e.pdf}.
+
+
+
+\section{Extending the hook concept to commands}
+
+Up to now the hook management covered hooks for a few core areas, such
+as hooks for the \cs{shipout} process or those in the \env{document}
+environment, as well as generic hooks for file loading (helpful for
+patching) and for arbitrary environments (executed by \cs{begin} and
+\cs{end}).
+
+This has now been extended to add \hook{/before} and \hook{/after}
+hooks to any (document-level) command---in theory at that is. In
+practice the new generic \hook{cmd} hooks, especially the
+\hook{cmd/.../after} hooks may fail with commands that are too complex
+to be automatically patched and break them if the hook is filled with
+code. The restrictions are documented in \texttt{ltcmdhooks-doc.pdf}.
+
+However, given that these hooks are mainly meant for package
+developers to provide a better interoperability between different
+packages and between packages and the \LaTeX{} kernel, these
+restrictions are of minor importance: for commands where the mechanism
+can't be applied, one is in the same situation as before and for all
+others there will be a noticeable improvement. This is especially
+important for our big project providing accessible and tagged PDF
+output~\cite{33:blueprint}, because for this we will eventually have
+to patch many third-party packages and this is only feasible, if it can
+be done in controlled and standardized ways.
+
@@ -145,7 +183,7 @@ The command \cs{labelitemfont} was in fact already introduced 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 at the same time make it easier
-to adjust its layout if necessary. What could happen in the past was the the
+to adjust its layout if necessary. What could happen in the past was the
\env{itemize} labels, e.g., the \textbullet{}, would sometimes react to
surrounding font changes and could suddenly change shape, for example
to \textit{\textbullet}.
@@ -174,7 +212,7 @@ you the buggy old behavior back.
\subsection{A note on file names with spaces, dots or UTF-8 characters}
-In one of the the recent \LaTeX{} releases we improved the interface
+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 on Windows but also elsewhere), UTF-8 characters
outside the \acro{ascii} range as well as names with several dots in
@@ -228,7 +266,7 @@ it always starts out in vertical mode.
\subsection{Allow extra space between name and address in \pkg{letter} class}
-The \cs{opening} command in the the \pkg{letter} class expects the
+The \cs{opening} command in the \pkg{letter} class expects the
name and address to be separated by \verb=\\= but it didn't allow to
use an optional argument at this point to add some extra space after
the name. The coding has now been slightly altered to allow for this.
@@ -236,8 +274,11 @@ the name. The coding has now been slightly altered to allow for this.
\githubissue{427}
-\subsection{Add a Lua callback to \pkg{ltshipout} to provide
- a uniform location for applying custom attributes}
+\subsection[Add a Lua callback to \pkg{ltshipout} to provide
+ a uniform location for applying custom attributes]
+ {Add a Lua callback to \pkg{ltshipout} to provide
+ a uniform
+ \mbox\quad location for applying custom attributes}
Just before shipping out a page, a new \LuaTeX{} callback
\texttt{pre\_shipout\_filter} is now called to allow final
@@ -248,7 +289,8 @@ elements at shipout. An example for this is the \pkg{luacolor}
package which could insert the color commands using this callback.
-\subsection{Improved copy\&paste support for \pdfTeX{} documents}
+
+\subsection{Improved copy\,\&\,paste support for \pdfTeX{} documents}
When compiling with \pdfTeX{}, additional information is added to the
PDF file to improve copying from and searching in text. This especially
@@ -274,7 +316,7 @@ slightly different and uses the standard hook management.
\subsection{Delay change of font series and shape to \cs{selectfont} call}
With the NFSS extensions introduced in 2020 the font series and shape
-settings be be influenced by changes to the font family. The setting
+settings can be influenced by changes to the font family. The setting
is therefore delayed until \cs{selectfont} is executed to avoid
unnecessary or incorrect substitutions that may otherwise happen due
to the order of declarations.
@@ -314,8 +356,10 @@ With the new behavior it accesses \verb|sqrt {2}.tex|.
\githubissue{481}
-\subsection{Additional support for Unicode characters from the
- Latin Extended Additional block}
+\subsection[Additional support for Unicode characters from the
+ Latin Extended Additional block]
+ {Additional support for Unicode characters from the Latin\\
+ \mbox\quad Extended Additional block}
\LaTeX\ is quite capable of typesetting characters such as
\enquote{\d{m}}, but until now it lacked the Unicode mappings for some
@@ -327,6 +371,7 @@ entered directly instead of resorting to \verb=\d{m}= and so forth.
\githubissue{484}
+
\subsection{Always have color groups set up}
To use color in \LaTeX{} certain constructs, especially boxes, need an
@@ -350,6 +395,10 @@ each. At the end of a paragraph this is done inside the \cs{par}
command, but the way \cs{marginpar} was coded, \LaTeX{} ended the
marginal note without ever explicitly calling \cs{par}. This has now
been changed.
+
+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 a \cs{par} in the document.
%
\githubissue{489}
@@ -361,7 +410,7 @@ It is sometimes necessary to reference the same footnote several
times, i.e., produce several footnote marks with the same number or
symbol. This is now always possible by placing a \cs{label} into the
\cs{footnote} and reference it with the command \cs{footref}
-elsewhere. This way marks refering to footnotes anywhere on the page
+elsewhere. This way marks referring to footnotes anywhere on the page
(including those in \texttt{minipage}s) can be generated. In the past
this command was only available with certain classes or when loading
the \pkg{footmisc} package.
@@ -370,7 +419,10 @@ the \pkg{footmisc} package.
-\subsection{Providing the raw option list of packages or documentclass to key/value handlers}
+\subsection[Providing the raw option list of packages or documentclass
+ to key/value handlers]
+ {Providing the raw option list of packages or documentclass\\
+ \mbox\quad to key/value handlers}
\LaTeXe{} has always normalized space in option lists so\\
\verb|\documentclass[ a4paper , 12pt ]{article}|\\
@@ -379,25 +431,25 @@ processed the intended options \texttt{a4paper} and \texttt{12pt}.
Unfortunately the mechanism used was designed for the simple option
names of the standard option processing. Many classes and packages
now use extended \emph{keyval} processing, however this white space
-normalisation makes this difficult:
+normalization makes this difficult:
\verb|[bb=1 2 3 4]|
which might be expected to pass a bounding box of four numbers is
-normalised to \texttt{bb=1234} and
+normalized to \texttt{bb=1234} and
\verb|[bb={1 2 3 4}]|\\
which might be expected to quote the spaces results in low level \TeX{}
parsing errors.
For compatibility reasons, the standard option processing has not been
-changed however the original un-normalised package and class option lists
+changed however the original un-normalized package and class option lists
are now saved. They are not used in the standard processing, however
extended package option systems may use these \enquote{raw} option list
macros if they are defined.
The one change affecting the standard processing is that the low level
error mentioned above is now avoided as values (any tokens to the
-right of an = sign) are removed from consideration from the \enquote{unused
-option list}. In this release \texttt{clip=true} and
+right of an = sign) are removed from consideration from the
+\enquote{unused option list}. In this release \texttt{clip=true} and
\texttt{clip=false} both contribute \texttt{clip} to the list of
options that have been used.
%
@@ -425,9 +477,11 @@ up.
-\subsection{Provide more ``dashes'' in encodings \texttt{OT1}, \texttt{T1} and \texttt{TU}}
+\subsection{Provide more ``dashes'' in encodings \texttt{OT1},
+ \texttt{T1} and \texttt{TU}}
-When pasting in text from external sources one sometimes encounters the Unicode characters
+When pasting in text from external sources one sometimes encounters
+the Unicode characters
%
\texttt{"2011} (non-breaking hyphen),
\texttt{"2012} (figure dash) and
@@ -451,31 +505,165 @@ and \cs{texthorizontalbar}, respectively.
-\subsection{\ldots}
+\subsection{\env{filecontents} with \acro{utf-8} characters in file name}
+
+Since a few releases back, the \env{filecontents} environment allows writing a
+file with \acro{utf-8} characters in its name. However there was a bug that
+would not allow \emph{over}writing a file with \acro{utf-8} characters in the
+name. This has been fixed and now \env{filecontents} allows any characters in
+the file name.
+%
+\githubissue{415}
+
+
+
+\subsection{Extending \pkg{latexrelease} to declare an entire module}
+
+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}, so that it is possible to roll back to a date where
+such module didn't exist yet, or roll forward from an older release and have the
+hook management system by loading the \pkg{latexrelease} package.
-\emph{to be written}
+However 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 that would result in errors, as usual with commands defined with
+\cs{newcommand} or in the case of \pkg{lthooks}, \cs{cs\_new:Npn}.
+
+To solve this issue, now completely new modules can be defined in
+\pkg{latexrelease} using \cs{NewModuleRelease}
+and then when rolling back or forward it will know if the code
+of the module has to be read or completely ignored. More details can be
+found in the \pkg{latexrelease} documentation (\verb|texdoc latexrelease|).
%
-\githubissue{xxx}
+\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 because the management of the \cs{ExplSyntaxOn/Off} status
+for packages cannot be removed by the rollback without messing up catcodes after
+an \pkg{expl3}-based package is loaded. This has been fixed and now rollback is
+more careful not to leave \pkg{ExplSyntaxOn} after a package ends.
+%
+\githubissue{504}
+
+
+
+\subsection[Add \cs{tracingstacklevels}
+ and \cs{tracinglostchars}\texttt{=3} to \cs{tracingall}]
+ {Add \cs{tracingstacklevels}
+ and \cs{tracinglostchars}\texttt{=3}\\
+ \mbox\quad to \cs{tracingall}}
+
+In July 2020 David Jones suggested an extension to \TeX{} engines, that
+added the possibility to set \cs{tracinglostchars}\texttt{=3} to have an
+error in case some character is missing from a font. In previous years,
+the warning for a missing character would be silently printed to the
+\texttt{.log} file (if $\cs{tracinglostchars}>0$) and to the terminal
+(if ${}>1$). This extension was added for \TL{} and \MiKTeX{} (except
+in Knuth's \TeX, of course) and now with $\cs{tracinglostchars}>2$ you
+get an error on a missing glyph.
+
+Later, in January 2021, Petr Olšák suggested yet another extension, a
+new primitive parameter \cs{tracingstacklevels} that, when positive (and
+when \cs{tracingmacros} is also positive), will print a visual
+indication of the macro nesting level in \TeX's tracing information.
+
+Both these changes were incorporated to \LaTeX's debugging macros
+\cs{tracingall} and \cs{tracingnone}, so when you use them, the new
+extensions are automatically activated/deactivated if your \TeX{}
+distributions has a recent enough engine. An example document
+demonstrating these parameters is available in the linked GitHub issue.
+%
+\githubissue{524}
+
+
+\subsection{Make \cs{\textbackslash} generally robust}
+
+In 2018 most \LaTeX{} user-level commands were made robust including
+\cs{\textbackslash}. However, \cs{\textbackslash} is redefined in
+various environments and not all cases were caught, in particular its use as row
+delimiter in \env{tablular} structures. This has now been corrected and
+\cs{\textbackslash} should be robust in all standard
+circumstances. Doing that also fixed one anomaly present in the past:
+in a tabular preamble of the form
+\begin{quote}
+ \verb={l=\texttt{\string>}\verb={raggedright}p{10cm}r}= % stupid class
+\end{quote}
+a \cs{\textbackslash} in the second column would have the definition
+used by \cs{raggedright} and would not indicate the (premature) end of
+the \env{tabular}, e.g.,
+\begin{quote}
+ \verb=a & b1 \\ b2 & c \\=
+\end{quote}
+would be a single row in that \env{tabular}. However, writing
+\begin{quote}
+ \verb=a & \\ b2 & c \\=
+\end{quote}
+would give you two rows: due to the scanning process the
+\cs{\textbackslash} directly following the \verb=&= still had
+the \enquote{end the row} meaning and not the \enquote{start a new
+ line in the second column} meaning.
+
+With \cs{\textbackslash} now robust, the scanning after \verb=&= ends
+when the command is seen and the second column is started and so now
+both lines above consistently produce a single \env{tabular} row.
+
+As before, you can use \cs{raggedright} \cs{arraybackslash} in the
+\env{tabular} preamble to ensure that \cs{\textbackslash} is always
+interpreted as a row separator when used in the column or you could
+use \cs{tabularnewline} to explicitly ask for a new row even when
+\cs{\textbackslash} has a different meaning in the current column.
+%
+\githubissue{548}
\section{Changes to packages in the \pkg{graphics} category}
-\subsection{\ldots}
+\subsection{Removed spurious warning for generic graphics rules}
+
+A previous release mistakenly caused a warning to appear when loading a graphics
+file with an unknown extension through a generic graphics rule. The warning
+would incorrectly say that the file was not found, whereas the file would be
+included correctly. The warning now doesn't show up in that case.
%
-\githubissue{xxx}
+\githubissue{516}
+
+
+\subsection{Fixed loading \texttt{gzip}ped PostScript graphics files}
+
+A previous release mistakenly changed the file searching mechanism and
+compressed graphics files would raise an error when being loaded with
+\cs{includegraphics}. This has been fixed and now \texttt{gzip}ped graphics
+load correctly.
+%
+\githubissue{519}
+
+
\section{Changes to packages in the \pkg{tools} category}
-\subsection{\pkg{layout}: Support Japanese as a language option}
-The package now recognizes \texttt{japanese} as a language option.
+\subsection{\pkg{layout}: Support extra language options}
+The package now recognizes \texttt{japanese} and \texttt{romanian} as
+language options.
%
-\githubissue{353}
+\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}
Minor update to \pkg{longtable} to fix bugs reported. Notably the
@@ -484,21 +672,53 @@ that 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}{3512}
+\gnatsissue{tools}{2914 3396 3512}
+\githubissue{133 183 464}
+
+
+\subsection[\pkg{trace}: Add \cs{tracingstacklevels}
+ and \cs{tracinglostchars}\texttt{=3} to \cs{traceon}]
+ {\pkg{trace}: Add \cs{tracingstacklevels} and\\
+ \mbox\quad \cs{tracinglostchars}\texttt{=3} to \cs{traceon}}
+
+The enhancement mentioned earlier was also added to the \pkg{trace} package.
+%
+\iffalse
+The \cs{tracingstacklevels} and \cs{tracinglostchars} extensions
+mentioned earlier for \cs{tracingall} were also added for
+\cs{traceon} in the \pkg{trace} package, so if you're using that you
+can also benefit from these new debugging tools.
+\fi
+%
+%
+\githubissue{524}
+\subsection{\pkg{bm}: Better support for commands with optional arguments}
+Some uses of optional arguments that were supported by \cs{bm} stopped
+being supported (in 2004) when \cs{kernel@ifnextchar} was used
+internally by the format instead of \cs{@ifnextchar}. This update
+handles both versions of this command and restores the original
+behaviour.
+
+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}
-\subsection{\ldots}
+%\subsection{\pkg{amsmath}: Make \cs{\textbackslash} generally robust}
+The fix for issue 548 was also applied in \pkg{amsmath}, see above.
%
-\githubissue{xxx}
+\githubissue{548}
-\medskip
+%\medskip
+
\begin{thebibliography}{9}
\fontsize{9.3}{11.3}\selectfont
@@ -507,31 +727,16 @@ existing documents, a rollback to \pkg{longtable 4.13}
\emph{\LaTeX{} Tagged PDF — A blueprint for a large project}.\\
\url{https://latex-project.org/publications/indexbyyear/2020/}
-\end{thebibliography}
-
-
-
-\end{document}
-
-
-\endinput % needed for ltnews processing
-
-\bibitem{32:ltnews31} \LaTeX{} Project Team:
- \emph{\LaTeXe{} news 31}.\\
- \url{https://latex-project.org/news/latex2e-news/ltnews31.pdf}
-
-\bibitem{32:site-doc}
+\bibitem{33:source2e}
\emph{\LaTeX{} documentation on the \LaTeX{} Project Website}.\\
\url{https://latex-project.org/help/documentation/}
-\bibitem{32:issue-tracker}
- \emph{\LaTeX{} issue tracker}.
- \url{https://github.com/latex3/latex2e/issues/}
+\bibitem{33:ltnews32} \LaTeX{} Project Team:
+ \emph{\LaTeXe{} news 32}.\\
+ \url{https://latex-project.org/news/latex2e-news/ltnews32.pdf}
+
+\end{thebibliography}
-\bibitem{32:babel}
- Javier Bezos and Johannes Braams.
- \emph{Babel---Localization and internationalization}.\\
- \url{https://www.ctan.org/pkg/babel}
-
+\end{document}
diff --git a/macros/latex-dev/base/ltoutenc.dtx b/macros/latex-dev/base/ltoutenc.dtx
index 73146428c0..eb2ecd1e53 100644
--- a/macros/latex-dev/base/ltoutenc.dtx
+++ b/macros/latex-dev/base/ltoutenc.dtx
@@ -37,14 +37,14 @@
%<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> [2021/02/19 v2.0u
+%<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]
%
%<*driver>
% \fi
\ProvidesFile{ltoutenc.dtx}
- [2021/02/19 v2.0u LaTeX Kernel (font encodings)]
+ [2021/04/29 v2.0v LaTeX Kernel (font encodings)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{ltoutenc.dtx}
@@ -3468,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}
diff --git a/macros/latex-dev/base/ltpar.dtx b/macros/latex-dev/base/ltpar.dtx
index f4f3d5e63f..969954be0a 100644
--- a/macros/latex-dev/base/ltpar.dtx
+++ b/macros/latex-dev/base/ltpar.dtx
@@ -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,9 +67,11 @@
% |\par| and |\everypar| when ever their function needs to be
% changed for a long time.
%
-% \StopEventually{}
-%
-% \subsection{Implementation}
+% 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.
%
%
% There are two situations in which |\par| may be changed:
@@ -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.
diff --git a/macros/latex-dev/base/ltpara-code.pdf b/macros/latex-dev/base/ltpara-code.pdf
index cee442360d..8984f1ccb5 100644
--- a/macros/latex-dev/base/ltpara-code.pdf
+++ b/macros/latex-dev/base/ltpara-code.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltpara-doc.pdf b/macros/latex-dev/base/ltpara-doc.pdf
index a264538a99..c8bff05546 100644
--- a/macros/latex-dev/base/ltpara-doc.pdf
+++ b/macros/latex-dev/base/ltpara-doc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltpara.dtx b/macros/latex-dev/base/ltpara.dtx
index 1a3df95a6e..ad503b68e2 100644
--- a/macros/latex-dev/base/ltpara.dtx
+++ b/macros/latex-dev/base/ltpara.dtx
@@ -11,11 +11,11 @@
% https://www.latex-project.org/lppl.txt
%
%
-%%% From File: lthooks.dtx
+%%% From File: ltpara.dtx
%
% \begin{macrocode}
-\def\ltparaversion{v1.0d}
-\def\ltparadate{2021/02/18}
+\def\ltparaversion{v1.0f}
+\def\ltparadate{2021/04/16}
% \end{macrocode}
%<*driver>
\documentclass{l3doc}
@@ -302,13 +302,14 @@
% \cs{noindent}).
%
% The indentation box to be typeset is available to the hook as
-% \cs{IndentationBox} and its automatic placement (after the hook is
-% executed) can be prevented through \cs{SuppressIndentationBox}.
+% \cs{IndentBox} and its automatic placement (after the hook is
+% executed) can be prevented through \cs{OmitIndent}.
+% More precisely \cs{OmitIndent} voids the box.
%
-% If not suppressed, then the indentation is typeset directly
+% The indentation box is then typeset directly
% after the hook execution by something equivalent to
-% \cs{box}\cs{IndentationBox} followed by the current content of
-% the token register \cs{everypar} as it is available to the
+% \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
@@ -375,7 +376,7 @@
% \item[\cs{@kernel@before@para@before}]
% For future extensions, not currently used by the kernel.
%
-
+%
% \item[\cs{@kernel@after@para@after}]
% For future extensions, not currently used by the kernel.
%
@@ -437,26 +438,67 @@
% Spring release!
% \end{quote}
%
-% \begin{function}{\SuppressIndentationBox,\para_suppress_indentation:}
+% \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_suppress_indentation:}.
+% The \pkg{expl3} name for the function is \cs{para_omit_indent:}.
% \end{function}
%
-% \begin{variable}{\IndentationBox,\g_para_indentation_box}
+% \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{SuppressIndentationBox} command was
+% 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_indentation_box}.
+% 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}
@@ -574,21 +616,70 @@
% 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}
-%<*2ekernel>
+%<@@=para>
% \end{macrocode}
%
+%
% \begin{macrocode}
-%<@@=para>
+%<*2ekernel|latexrelease>
\ExplSyntaxOn
+%<latexrelease>\NewModuleRelease{2021/06/01}{ltpara}
+%<latexrelease> {Paragraph~handling~and~hooks}
% \end{macrocode}
-
-
+%
%
%
% \subsection{Providing hooks for paragraphs}
@@ -641,10 +732,10 @@
\tl_gset:Nn \g_@@_standard_everypar_tl {
% \end{macrocode}
% First we remove the indentation box and store it in
-% \cs{g_para_indentation_box}. If there was none because the paragraph
+% \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_indentation_box
+ \box_gset_to_last:N \g_para_indent_box
% \end{macrocode}
%
% This will make the newly started horizontal list empty, so if we
@@ -683,13 +774,6 @@
% case there are nested paragraphs coming up.
% \begin{macrocode}
\tex_everypar:D{\g_@@_standard_everypar_tl}
-% \showthe\tex_everypar:D
-% \end{macrocode}
-% Then we set up \cs{@@_handle_indent:} to reinsert the indentation
-% box later. This can be undone via \cs{SuppressIndentationBox}
-% inside the hook(s).
-% \begin{macrocode}
- \cs_set_eq:NN \@@_handle_indent: \@@_add_indentation_box:
% \end{macrocode}
%
% This is followed by executing the kernel and the public hook. The
@@ -710,7 +794,7 @@
% we add that later, and indirectly.
% \begin{macrocode}
\@@_handle_indent:
-% \the \everypar % <--- done differently
+% \the \everypar % <--- done differently below
}
% \end{macrocode}
% \end{macro}
@@ -782,40 +866,38 @@
% \end{macro}
%
%
-% \begin{macro}{\g_para_indentation_box}
+% \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_indentation_box
+\box_new:N \g_para_indent_box
% \end{macrocode}
% \end{macro}
-% \begin{macro}{\@@_handle_indent:,\@@_add_indentation_box:}
-% Adding (typesetting) the indent box is straight forward, the
-% default action for is \cs{@@_handle_indent:} is
-% \cs{@@_add_indentation_box:}.
+% \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 \@@_add_indentation_box: {
- \box_use_drop:N \g_para_indentation_box
+\cs_new:Npn \@@_handle_indent: {
+ \box_use_drop:N \g_para_indent_box
}
-\cs_new_eq:NN \@@_handle_indent: \@@_add_indentation_box:
% \end{macrocode}
-% The declaration \cs{para_suppress_indentation:} (or
-% \cs{SuppressIndentationBox}) changes that to do nothing.
+% The declaration \cs{para_omit_indent:} (or
+% \cs{OmitIndent}) changes that to do nothing.
% \begin{macrocode}
-\cs_new:Npn \para_suppress_indentation: {
- \cs_set_eq:NN \@@_handle_indent: \prg_do_nothing:
+\cs_new:Npn \para_omit_indent: {
+ \box_gclear:N \g_para_indent_box
}
% \end{macrocode}
% \end{macro}
%
%
-% \begin{macro}{\IndentationBox,\SuppressIndentationBox}
+% \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 \IndentationBox \g_para_indentation_box
-\cs_set_eq:NN \SuppressIndentationBox \para_suppress_indentation:
+\cs_set_eq:NN \IndentBox \g_para_indent_box
+\cs_set_eq:NN \OmitIndent \para_omit_indent:
% \end{macrocode}
% \end{macro}
%
@@ -979,6 +1061,67 @@
% \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 }
+ }
+ { \__kernel_msg_error:nn {para}{raw} }
+ \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 }
+ }
+ { \__kernel_msg_error:nn {para}{raw} }
+ \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}
%<@@=>
@@ -1010,7 +1153,10 @@
%
% \subsection{The error messages}
%
-% Well, one really, first argument is the hook name second the mode
+% 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}
\__kernel_msg_new:nnnn {para} {mode}
@@ -1026,72 +1172,43 @@
}
% \end{macrocode}
%
+% And here is one used in the \enquote{raw} commands when they are
+% used outside of vertical mode.
% \begin{macrocode}
-\ExplSyntaxOff
-% \end{macrocode}
-%
-% \subsection{Kernel corrections}
-%
-% These corrections/changes are already part of the 2021/05
-% release, i.e., but for testing with older releases they have been
-% included here for now. So this section will vanish soon.
-%
-%
-% Marginpar boxes are missing a final internal \cs{par}.
-% \begin{macrocode}
-\IfFormatAtLeastTF{2021/05/01}{}
-{
-\long\def \@savemarbox #1#2{%
- \global\setbox #1%
- \color@vbox
- \vtop{%
- \hsize\marginparwidth
- \@parboxrestore
- \@marginparreset
- #2\par % <-- needed
- \@minipagefalse
- \outer@nobreak
- }%
- \color@endbox
-}
+\__kernel_msg_new:nnnn {para} {raw}
+ {
+ Paragraph started while not in vertical mode.
+ }
+ {
+ Starting a paragraph with \RawIndent or \RawNoindent
+ (or \para_raw_indent: or \para_raw_noindent:) is only
+ allowed if LaTeX is in vertical mode.
+ }
% \end{macrocode}
-%
-% Two sample definitions for the kernel hooks to help a bit with
-% tracing.
+
+
% \begin{macrocode}
-\newcounter{paracnt}
-\def\@kernel@before@para@begin{%
- \stepcounter{paracnt}%
- \typeout{PARA: \arabic{paracnt} start
- (\@currenvir\space level\on@line)}%
-}
-\def\@kernel@after@para@end {%
- \typeout{PARA: \arabic{paracnt} end \space\space
- (\@currenvir\space level\on@line)}%
- \addtocounter{paracnt}{-1}%
-}
-% \end{macrocode}
-%
%
-% The next lines belong in the kernel and just make sure that we
-% avoid the these days unnecessary optimization that \TeX{} doesn't
-% call on \cs{par} if a vertical box ends in hmode. Instead \TeX{}
-% directly calls the par builder in that case :-(.
-% \begin{macrocode}
-\let\color@begingroup\begingroup
-\def\color@endgroup{\endgraf\endgroup}
-\def\color@setgroup{\color@begingroup} % \def\color@setgroup{\color@begingroup\set@color}
-\def\color@hbox{\hbox\bgroup\color@begingroup}
-\def\color@vbox{\vbox\bgroup\color@begingroup}
-\def\color@endbox{\color@endgroup\egroup}
-}
+%<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}
%
%
%
-% \begin{macrocode}
-%<*2ekernel>
-% \end{macrocode}
%
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -1099,61 +1216,3 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
-%%%% unused as hok was dropped
-
-% \subsubsection{Put the first word of each paragraph in an \cs{fbox} and append
-% a \P{} sign at the end of the paragraph}
-%
-% We make the assumption that the first word ends in a space so
-% that we can grab it easily (which
-% is of course not quite right). So here is the code for that.
-%\begin{verbatim}
-% \def\firstwordboxed#1 {\fbox{#1} }
-%\end{verbatim}
-% Installing that is then just a matter of putting it into the right
-% hook. Since we don't want to box the indentation (or what comes
-% from \cs{everypar} we shouldn't use \hook{para/begin} but
-% \hook{para/textbegin}.
-% Adding the \P{} is equally simple.
-%\begin{verbatim}
-% \AddToHook{para/textbegin}{\firstwordboxed}
-% \AddToHook{para/end}{\P}
-%\end{verbatim}
-% While this will work more or less flawless (if you accept that it
-% will pick up any punctuation after the first word), it will fail
-% in at least two cases.
-% \begin{itemize}
-% \item Single word paragraphs ending with \cs{par} instead of an
-% empty line will blow up because the \cs{par} will be picked up as
-% part of the argument and error as our \cs{firstwordboxed} doesn't
-% accept a \cs{par} not being long. That is actually good, because
-% picking it up would be worse: it would get ignored inside
-% \cs{fbox} and so the paragraph would be combined with the next
-% (or worse).
-%
-% \item The second problem is, of course, that sticking it into
-% every \hook{para/textbegin} means it get applied to places like
-% \cs{section} which is not really what you want. So some more
-% elaborate mechanism would be necessary---a task for another rainy
-% day.
-% \end{itemize}
-%
-% There is one other point to note here. The \cs{firstwordboxed} is
-% expected to scan ahead. So can that kind of code be placed into a
-% hook? The answer is a kind of yes and no.
-
-% Hooks can receive code from different places, but obviously only
-% one chunk of code can do some scanning ahead, the one that comes
-% last. Any hook code in a different position would see any
-% following code from later chunks as part of the scanning which
-% may or may not be a problem. In fact, even in our simple example,
-% the argument picked up by \cs{firstwordboxed} isn't really the
-% first word of the paragraph. It is that but in front of it there
-% is also the code responsible for running
-% \verb=\AddTohookNext{para/textbegin}=. As long as this is not
-% doing anything harmful it doesn't hurt in this case, but it
-% clearly shows that this example is not as simple as it
-% claims to be and on the whole we have to conclude that hooks
-% aren't really meant to do such scanning or at least not without a
-% lot of precaution.
-%
diff --git a/macros/latex-dev/base/ltpictur.dtx b/macros/latex-dev/base/ltpictur.dtx
index b958d43760..ae8b58995d 100644
--- a/macros/latex-dev/base/ltpictur.dtx
+++ b/macros/latex-dev/base/ltpictur.dtx
@@ -32,7 +32,7 @@
%<*driver>
% \fi
\ProvidesFile{ltpictur.dtx}
- [2020/12/05 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}
diff --git a/macros/latex-dev/base/ltplain.dtx b/macros/latex-dev/base/ltplain.dtx
index fa53cc17ec..e0fbcecf1b 100644
--- a/macros/latex-dev/base/ltplain.dtx
+++ b/macros/latex-dev/base/ltplain.dtx
@@ -32,7 +32,7 @@
%<*driver>
% \fi
\ProvidesFile{ltplain.dtx}
- [2020/11/26 v2.3d LaTeX Kernel (Plain TeX)]
+ [2021/04/18 v2.3f LaTeX Kernel (Plain TeX)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{ltplain.dtx}
@@ -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
@@ -1482,42 +1535,68 @@
% \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}{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
- \tracingparagraphs\@ne
- \errorcontextlines\maxdimen
- \loggingoutput
- \tracingmacros\tw@
- \tracingcommands\tw@
- \tracingrestores\@ne
- }%
-\else
-\gdef\loggingall{%
- \tracingstats\tw@
- \tracingpages\@ne
- \tracinglostchars\tw@
+ \tracinglostchars\thr@@
\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@ne
- \showboxbreadth\m@ne
- \tracingoutput\z@
- \errorcontextlines\m@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@ne
\tracingoutput\z@
\errorcontextlines\m@ne
+ \ifdefined\tracingstacklevels \tracingstacklevels\z@ \fi
\tracingnesting\z@
\tracingscantokens\z@
\tracingifs\z@
@@ -1573,30 +1638,77 @@
\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@ne
+%<latexrelease> \showboxbreadth\m@ne
+%<latexrelease> \tracingoutput\z@
+%<latexrelease> \errorcontextlines\m@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@ne
+%<latexrelease> \showboxbreadth\m@ne
+%<latexrelease> \tracingoutput\z@
+%<latexrelease> \errorcontextlines\m@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@ne
\showboxdepth\m@ne
\tracingonline\m@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.
%
diff --git a/macros/latex-dev/base/ltshipout-code.pdf b/macros/latex-dev/base/ltshipout-code.pdf
index f234cc2d02..828e444c2f 100644
--- a/macros/latex-dev/base/ltshipout-code.pdf
+++ b/macros/latex-dev/base/ltshipout-code.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltshipout-doc.pdf b/macros/latex-dev/base/ltshipout-doc.pdf
index 6592e23b4e..4c8457428f 100644
--- a/macros/latex-dev/base/ltshipout-doc.pdf
+++ b/macros/latex-dev/base/ltshipout-doc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltshipout.dtx b/macros/latex-dev/base/ltshipout.dtx
index 565f35f529..f773cd23da 100644
--- a/macros/latex-dev/base/ltshipout.dtx
+++ b/macros/latex-dev/base/ltshipout.dtx
@@ -33,7 +33,7 @@
%
% \begin{macrocode}
\providecommand\ltshipoutversion{v1.0i}
-\providecommand\ltshipoutdate{2021/01/25}
+\providecommand\ltshipoutdate{2021/03/17}
% \end{macrocode}
%
%<*driver>
@@ -144,6 +144,12 @@
% 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.
diff --git a/macros/latex-dev/base/lttab.dtx b/macros/latex-dev/base/lttab.dtx
index a964b36575..48627f40a3 100644
--- a/macros/latex-dev/base/lttab.dtx
+++ b/macros/latex-dev/base/lttab.dtx
@@ -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}
diff --git a/macros/latex-dev/base/lttextcomp.dtx b/macros/latex-dev/base/lttextcomp.dtx
index d840f0448b..1efc36d563 100644
--- a/macros/latex-dev/base/lttextcomp.dtx
+++ b/macros/latex-dev/base/lttextcomp.dtx
@@ -36,7 +36,7 @@
%
%
\ProvidesFile{lttextcomp.dtx}
- [2021/01/20 v1.0d LaTeX Kernel (text companion symbols)]
+ [2021/04/16 v1.0f LaTeX Kernel (text companion symbols)]
% \iffalse
\documentclass{ltxdoc}
\begin{document}
@@ -70,20 +70,23 @@
%
% \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
% 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}
@@ -157,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@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}
@@ -1300,9 +1265,19 @@
% 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@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
@@ -1493,9 +1468,7 @@
%<latexrelease>\let\textlegacyperiodcentered\@undefined
%<latexrelease>\let\textlegacysection\@undefined
%<latexrelease>
-%<latexrelease>\EndIncludeInRelease
-%<*2ekernel>
-%</2ekernel>
+%<latexrelease>\EndModuleRelease
% \end{macrocode}
%
%
diff --git a/macros/latex-dev/base/ltvers.dtx b/macros/latex-dev/base/ltvers.dtx
index 26eaee9890..fe50d75a8f 100644
--- a/macros/latex-dev/base/ltvers.dtx
+++ b/macros/latex-dev/base/ltvers.dtx
@@ -33,7 +33,7 @@
%<*driver>
% \fi
\ProvidesFile{ltvers.dtx}
- [2021/01/15 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>
- {2021-05-01}
+ {2021-06-01}
%</2ekernel|latexrelease>
%<*2ekernel>
-\def\patch@level{-2}
+\def\patch@level{-3}
% \end{macrocode}
%
% \begin{macro}{\development@branch@name}
@@ -214,6 +214,11 @@
% \end{macrocode}
%
% \begin{macro}{\IncludeInRelease}
+% \begin{macro}{\EndIncludeInRelease}
+% \begin{macro}{\@IncludeInRelease}
+% \begin{macro}{\@IncludeInRele@se}
+% \begin{macro}{\@gobble@IncludeInRelease}
+% \begin{macro}{\@check@IncludeInRelease}
% \changes{v1.0w}{2015/02/21}
% {set \cs{@currname} empty here (in case \cs{IncludeInRelease} input early)}
% \begin{macrocode}
@@ -224,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>
@@ -237,9 +243,29 @@
{There is an \string\EndIncludeRelease\space missing}%
\@includeinreleasefalse
\fi
- \kernel@ifnextchar[%
- {\@IncludeInRelease{#1}}
- {\@IncludeInRelease{#1}[#1]}}
+ \ifnum0%
+ \ifx\new@moduledate\@empty\else 1\fi
+ \ifnum \expandafter\@parse@version#1//00\@nil=0 1\fi
+ =11
+ \expandafter\@firstoftwo
+ \else
+ \expandafter\@secondoftwo
+ \fi
+ {\finish@module@release{#1}}%
+ {\kernel@ifnextchar[%
+ {\@IncludeInRelease{#1}}
+ {\@IncludeInRelease{#1}[#1]}}}
+\def\finish@module@release#1#2#3{%
+ \toks@{[#1] #3}%
+ \ifnum\expandafter\@parse@version\new@moduledate//00\@nil
+ >\expandafter\@parse@version\fmtversion//00\@nil
+ \GenericInfo{}{Applying: \the\toks@}%
+ \else
+ \GenericInfo{}{Skipping: \the\toks@}%
+ \expandafter\gobble@finish@module@release
+ \fi}
+\long\def\gobble@finish@module@release#1\EndModuleRelease{%
+ \EndModuleRelease}
% \end{macrocode}
%
% If a specific date has not been specified in |latexrelease|
@@ -261,9 +287,9 @@
% only really needed for rolling forward. So maybe one day \dots
% \begin{macrocode}
\ifnum\expandafter\@parse@version#1//00\@nil
- >\expandafter\@parse@version\fmtversion//00\@nil
+ >\expandafter\@parse@version\fmtversion//00\@nil
\GenericInfo{}{Skipping: \the\toks@}%
- \expandafter\expandafter\expandafter\@gobble@IncludeInRelease
+ \expandafter\expandafter\expandafter\@gobble@IncludeInRelease
\else
\GenericInfo{}{Applying: \the\toks@}%
\@includeinreleasetrue
@@ -282,6 +308,9 @@
\@includeinreleasefalse
\else
\PackageError{latexrelease}{mis-matched EndIncludeInRelease}{}%
+\fi
+\if@skipping@module
+ \expandafter\new@module@skip
\fi}
% \end{macrocode}
%
@@ -296,13 +325,87 @@
#2#3\@end@check@IncludeInRelease{%
\ifx\@check@IncludeInRelease#2\else
\PackageError{latexrelease}{skipped IncludeInRelease for tag \string#2}{}%
+ \fi
+ \if@skipping@module
+ \expandafter\new@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@skipping@module}
+% \begin{macro}{\NewModuleRelease}
+% \begin{macro}{\EndModuleRelease}
+% \begin{macro}{\new@module@skip}
+% \begin{macro}{\new@modulename}
+% \begin{macro}{\new@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}
-%</2ekernel|latexrelease>
+\let\if@skipping@module\iffalse
+\def\@skipping@moduletrue{\let\if@skipping@module\iftrue}
+\def\@skipping@modulefalse{\let\if@skipping@module\iffalse}
+\let\new@modulename\@empty
+\let\new@moduledate\@empty
+\def\NewModuleRelease#1#2#3{%
+ \ifx\new@modulename\@empty \else
+ \@latex@error{Nested \noexpand\NewModuleRelease forbidden.}\@ehd \fi
+ \edef\new@moduledate{#1}%
+ \edef\new@modulename{#2}%
+ \GenericInfo{}{BEGIN module: \new@modulename\space (\new@moduledate)}%
+ \GenericInfo{}{ \@spaces\@spaces\@spaces\space#3\@gobble}%
+ \ifnum\sourceLaTeXdate<%
+ \expandafter\@parse@version\new@moduledate//00\@nil\relax
+ \ifnum\expandafter\@parse@version\fmtversion//00\@nil<%
+ \expandafter\@parse@version\new@moduledate//00\@nil\relax
+ \GenericInfo{}{Skipping module \new@modulename}%
+ \expandafter\expandafter
+ \expandafter\gobble@finish@module@release
+ \else
+ \GenericInfo{}{Applying module \new@modulename}
+ \@skipping@modulefalse
+ \fi
+ \else
+ \GenericInfo{}{Skipping module \new@modulename}
+ \@skipping@moduletrue
+ \expandafter\new@module@skip
+ \fi}
+\long\def\new@module@skip#1\IncludeInRelease{\IncludeInRelease}
+\def\EndModuleRelease{%
+ \ifx\new@modulename\@empty
+ \@latex@error{Extra \string\EndModuleRelease.}\@eha
+ \else
+ \GenericInfo{}{END module: \new@modulename\space (\new@moduledate)}%
+ \let\new@modulename\@empty
+ \let\new@moduledate\@empty
+ \@skipping@modulefalse
+ \fi}
% \end{macrocode}
% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</2ekernel|latexrelease>
+% \end{macrocode}
+%
% \Finale
%
\endinput
diff --git a/macros/latex-dev/base/ltx3info.pdf b/macros/latex-dev/base/ltx3info.pdf
index 98075fb822..2788cb0a36 100644
--- a/macros/latex-dev/base/ltx3info.pdf
+++ b/macros/latex-dev/base/ltx3info.pdf
Binary files differ
diff --git a/macros/latex-dev/base/ltxdoc.pdf b/macros/latex-dev/base/ltxdoc.pdf
index 5b9dc2b119..aa2a071366 100644
--- a/macros/latex-dev/base/ltxdoc.pdf
+++ b/macros/latex-dev/base/ltxdoc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/makeindx.pdf b/macros/latex-dev/base/makeindx.pdf
index a0b1e589aa..42d3a434e9 100644
--- a/macros/latex-dev/base/makeindx.pdf
+++ b/macros/latex-dev/base/makeindx.pdf
Binary files differ
diff --git a/macros/latex-dev/base/manual.pdf b/macros/latex-dev/base/manual.pdf
index d6c5c7c6f3..cb9024f559 100644
--- a/macros/latex-dev/base/manual.pdf
+++ b/macros/latex-dev/base/manual.pdf
Binary files differ
diff --git a/macros/latex-dev/base/modguide.pdf b/macros/latex-dev/base/modguide.pdf
index 86e0031dca..0edb139e19 100644
--- a/macros/latex-dev/base/modguide.pdf
+++ b/macros/latex-dev/base/modguide.pdf
Binary files differ
diff --git a/macros/latex-dev/base/nfssfont.pdf b/macros/latex-dev/base/nfssfont.pdf
index bdbd184b27..8e6a4987f3 100644
--- a/macros/latex-dev/base/nfssfont.pdf
+++ b/macros/latex-dev/base/nfssfont.pdf
Binary files differ
diff --git a/macros/latex-dev/base/proc.pdf b/macros/latex-dev/base/proc.pdf
index f3813139e4..b0d4032019 100644
--- a/macros/latex-dev/base/proc.pdf
+++ b/macros/latex-dev/base/proc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/slides.pdf b/macros/latex-dev/base/slides.pdf
index 28983111b2..3116ccc852 100644
--- a/macros/latex-dev/base/slides.pdf
+++ b/macros/latex-dev/base/slides.pdf
Binary files differ
diff --git a/macros/latex-dev/base/slifonts.pdf b/macros/latex-dev/base/slifonts.pdf
index 24115796a7..faa2053db2 100644
--- a/macros/latex-dev/base/slifonts.pdf
+++ b/macros/latex-dev/base/slifonts.pdf
Binary files differ
diff --git a/macros/latex-dev/base/source2e.pdf b/macros/latex-dev/base/source2e.pdf
index 181f2b6bf6..fbc7f5ac41 100644
--- a/macros/latex-dev/base/source2e.pdf
+++ b/macros/latex-dev/base/source2e.pdf
Binary files differ
diff --git a/macros/latex-dev/base/source2e.tex b/macros/latex-dev/base/source2e.tex
index 28a516b9e9..abe8c1aac2 100644
--- a/macros/latex-dev/base/source2e.tex
+++ b/macros/latex-dev/base/source2e.tex
@@ -248,10 +248,12 @@ page_precedence "rnaA"
\DocInclude{ltdefns} % Initial definitions.
- \DocInclude{ltcmd} % Document command creation
+ \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.
@@ -260,6 +262,8 @@ page_precedence "rnaA"
\DocInclude{ltpar} % Paragraphs.
+ \DocInclude{ltpara} % Paragraph hooks (L3 module)
+
\DocInclude{ltspace} % Spacing, line and page breaking.
\DocInclude{ltlogos} % Logos.
diff --git a/macros/latex-dev/base/syntonly.pdf b/macros/latex-dev/base/syntonly.pdf
index f3cc919750..2156a292b9 100644
--- a/macros/latex-dev/base/syntonly.pdf
+++ b/macros/latex-dev/base/syntonly.pdf
Binary files differ
diff --git a/macros/latex-dev/base/tlc2.err b/macros/latex-dev/base/tlc2.err
index 7f4e2817c8..a361d1673a 100644
--- a/macros/latex-dev/base/tlc2.err
+++ b/macros/latex-dev/base/tlc2.err
@@ -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]
diff --git a/macros/latex-dev/base/tlc2.pdf b/macros/latex-dev/base/tlc2.pdf
index a37da64384..dd55f4b589 100644
--- a/macros/latex-dev/base/tlc2.pdf
+++ b/macros/latex-dev/base/tlc2.pdf
Binary files differ
diff --git a/macros/latex-dev/base/tulm.pdf b/macros/latex-dev/base/tulm.pdf
index 4eac541e92..34f1ca3ce0 100644
--- a/macros/latex-dev/base/tulm.pdf
+++ b/macros/latex-dev/base/tulm.pdf
Binary files differ
diff --git a/macros/latex-dev/base/usrguide.pdf b/macros/latex-dev/base/usrguide.pdf
index 92e5852045..80d5bc6a1e 100644
--- a/macros/latex-dev/base/usrguide.pdf
+++ b/macros/latex-dev/base/usrguide.pdf
Binary files differ
diff --git a/macros/latex-dev/base/usrguide3.pdf b/macros/latex-dev/base/usrguide3.pdf
index a6e9571db4..3e2c599b39 100644
--- a/macros/latex-dev/base/usrguide3.pdf
+++ b/macros/latex-dev/base/usrguide3.pdf
Binary files differ
diff --git a/macros/latex-dev/base/usrguide3.tex b/macros/latex-dev/base/usrguide3.tex
index b14e753ea1..c378ac8592 100644
--- a/macros/latex-dev/base/usrguide3.tex
+++ b/macros/latex-dev/base/usrguide3.tex
@@ -33,10 +33,10 @@
\usepackage[T1]{fontenc} % needed for \textbackslash in tt
\title{New \LaTeX\ methods for authors (starting 2020)}
-\author{\copyright~Copyright 2020, \LaTeX\ Project Team.\\
+\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 @@ the nature of the argument received.
\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 @@ analogue \cs{ifblank}.
\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 @@ names which are accessible outside of code blocks.
\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
diff --git a/macros/latex-dev/base/utf8ienc.pdf b/macros/latex-dev/base/utf8ienc.pdf
index 207600f959..625decf88d 100644
--- a/macros/latex-dev/base/utf8ienc.pdf
+++ b/macros/latex-dev/base/utf8ienc.pdf
Binary files differ
diff --git a/macros/latex-dev/base/webcomp.err b/macros/latex-dev/base/webcomp.err
index 269636f9fb..6a62e258c5 100644
--- a/macros/latex-dev/base/webcomp.err
+++ b/macros/latex-dev/base/webcomp.err
@@ -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]
diff --git a/macros/latex-dev/base/webcomp.pdf b/macros/latex-dev/base/webcomp.pdf
index 51a3b66f36..7267cc5344 100644
--- a/macros/latex-dev/base/webcomp.pdf
+++ b/macros/latex-dev/base/webcomp.pdf
Binary files differ
diff --git a/macros/latex-dev/required/graphics/README.md b/macros/latex-dev/required/graphics/README.md
index 8fb13bb141..b9d06376c6 100644
--- a/macros/latex-dev/required/graphics/README.md
+++ b/macros/latex-dev/required/graphics/README.md
@@ -1,7 +1,7 @@
The LaTeX `graphics` bundle
===========================
-Release 2021-05-01 pre-release 0
+Release 2021-06-01 pre-release 1
Overview
--------
@@ -61,4 +61,4 @@ of the package.
-----
-<p>Copyright (C) 1993-2020 The LaTeX Project <br />
+<p>Copyright (C) 1993-2021 The LaTeX Project <br />
diff --git a/macros/latex-dev/required/graphics/changes.txt b/macros/latex-dev/required/graphics/changes.txt
index adf9fe8fc7..980d2b33e4 100644
--- a/macros/latex-dev/required/graphics/changes.txt
+++ b/macros/latex-dev/required/graphics/changes.txt
@@ -4,10 +4,31 @@ completeness or accuracy and it contains some references to files that
are not part of the distribution.
=======================================================================
+2021-03-04 Phelype Oleinik <phelype.oleinik@latex-project.org>
+
+ * graphics.dtx: fix loading gzipped .(e)ps graphics files.
+
+2021-03-05 David Carlisle <David.Carlisle@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@latex-project.org>
+
+ * graphics.dtx: Avoid warning when loading a file using a generic rule (gh/516).
+
================================================================================
All changes above are only part of the development branch for the next release.
================================================================================
+2020-12-05 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+
+ * graphics.dtx: fix missing default in quiet key.
+
+
#########################
# 2020-10-01 Release
#########################
diff --git a/macros/latex-dev/required/graphics/color.dtx b/macros/latex-dev/required/graphics/color.dtx
index cdc2dbe5fe..2dfbb238da 100644
--- a/macros/latex-dev/required/graphics/color.dtx
+++ b/macros/latex-dev/required/graphics/color.dtx
@@ -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
diff --git a/macros/latex-dev/required/graphics/color.pdf b/macros/latex-dev/required/graphics/color.pdf
index 40cda1f1af..b4d0a03cd8 100644
--- a/macros/latex-dev/required/graphics/color.pdf
+++ b/macros/latex-dev/required/graphics/color.pdf
Binary files differ
diff --git a/macros/latex-dev/required/graphics/drivers.dtx b/macros/latex-dev/required/graphics/drivers.dtx
index 9bf32f78a1..6704ad11c6 100644
--- a/macros/latex-dev/required/graphics/drivers.dtx
+++ b/macros/latex-dev/required/graphics/drivers.dtx
@@ -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
diff --git a/macros/latex-dev/required/graphics/drivers.pdf b/macros/latex-dev/required/graphics/drivers.pdf
index aef45cddc8..617f4f8ec3 100644
--- a/macros/latex-dev/required/graphics/drivers.pdf
+++ b/macros/latex-dev/required/graphics/drivers.pdf
Binary files differ
diff --git a/macros/latex-dev/required/graphics/epsfig.dtx b/macros/latex-dev/required/graphics/epsfig.dtx
index 8e883bd8df..a34aa6842e 100644
--- a/macros/latex-dev/required/graphics/epsfig.dtx
+++ b/macros/latex-dev/required/graphics/epsfig.dtx
@@ -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
diff --git a/macros/latex-dev/required/graphics/epsfig.pdf b/macros/latex-dev/required/graphics/epsfig.pdf
index 2a38f559fe..7cdd87b5d0 100644
--- a/macros/latex-dev/required/graphics/epsfig.pdf
+++ b/macros/latex-dev/required/graphics/epsfig.pdf
Binary files differ
diff --git a/macros/latex-dev/required/graphics/graphics-2017-06-25.sty b/macros/latex-dev/required/graphics/graphics-2017-06-25.sty
index 5cfa5df450..154867d99a 100644
--- a/macros/latex-dev/required/graphics/graphics-2017-06-25.sty
+++ b/macros/latex-dev/required/graphics/graphics-2017-06-25.sty
@@ -12,7 +12,7 @@
%%
%%
%% graphics.dtx Copyright (C) 1994 David Carlisle Sebastian Rahtz
-%% Copyright (C) 1995--2017 David Carlisle, LaTeX3 Project
+%% Copyright (C) 1995--2017 David Carlisle, LaTeX Project
%%
%% This file is part of the Standard LaTeX `Graphics Bundle'.
%% It may be distributed under the terms of the LaTeX Project Public
diff --git a/macros/latex-dev/required/graphics/graphics.dtx b/macros/latex-dev/required/graphics/graphics.dtx
index 51ef9a4ee3..0c5c9e88ec 100644
--- a/macros/latex-dev/required/graphics/graphics.dtx
+++ b/macros/latex-dev/required/graphics/graphics.dtx
@@ -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@ext\relax
\let\filename@ext\Gin@gzext
\else
- \edef\Gin@ext{\Gin@ext\Gin@sepdefault\Gin@gzext}%
+% \end{macrocode}
+% \changes{v1.4d}{2021/03/04}
+% {\cs{filename@ext} instead of \cs{Gin@ext} when
+% checking for \texttt{gzip}ped graphics file.}
+% \begin{macrocode}
+ \edef\filename@ext{\filename@ext\Gin@sepdefault\Gin@gzext}%
\fi
\fi
\ifx\filename@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@ext\relax 1%
\else \@ifundefined{Gin@rule@\Gin@ext}{1}{0}%
\fi >0
- \let\Gin@ext\relax
+ \let\Gin@extsaved\Gin@ext
\let\Gin@savedbase\filename@base
\let\Gin@savedext\filename@ext
+ \let\Gin@ext\relax
\edef\filename@base{\filename@base\Gin@sepdefault\filename@ext}%
\let\filename@ext\relax
\@for\Gin@temp:=\Gin@extensions\do{%
@@ -1164,6 +1174,7 @@
% Restore if no file found using the known extensions.
% \begin{macrocode}
\ifx\Gin@ext\relax
+ \let\Gin@ext\Gin@extsaved
\let\filename@base\Gin@savedbase
\let\filename@ext\Gin@savedext
\fi
diff --git a/macros/latex-dev/required/graphics/graphics.pdf b/macros/latex-dev/required/graphics/graphics.pdf
index 09c3ac0792..7dea8f5a99 100644
--- a/macros/latex-dev/required/graphics/graphics.pdf
+++ b/macros/latex-dev/required/graphics/graphics.pdf
Binary files differ
diff --git a/macros/latex-dev/required/graphics/graphicx.dtx b/macros/latex-dev/required/graphics/graphicx.dtx
index b10c67c794..a2fc17e393 100644
--- a/macros/latex-dev/required/graphics/graphicx.dtx
+++ b/macros/latex-dev/required/graphics/graphicx.dtx
@@ -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@key{Gin}{quiet}{%
+\define@key{Gin}{quiet}[]{%
\let\Gin@log\@gobble
}
% \end{macrocode}
diff --git a/macros/latex-dev/required/graphics/graphicx.pdf b/macros/latex-dev/required/graphics/graphicx.pdf
index f359d1d9b6..56d9451077 100644
--- a/macros/latex-dev/required/graphics/graphicx.pdf
+++ b/macros/latex-dev/required/graphics/graphicx.pdf
Binary files differ
diff --git a/macros/latex-dev/required/graphics/grfguide.pdf b/macros/latex-dev/required/graphics/grfguide.pdf
index 0a7258803d..c6a4b2a5ca 100644
--- a/macros/latex-dev/required/graphics/grfguide.pdf
+++ b/macros/latex-dev/required/graphics/grfguide.pdf
Binary files differ
diff --git a/macros/latex-dev/required/graphics/grfguide.tex b/macros/latex-dev/required/graphics/grfguide.tex
index 8df07c5a6a..3b679ea382 100644
--- a/macros/latex-dev/required/graphics/grfguide.tex
+++ b/macros/latex-dev/required/graphics/grfguide.tex
@@ -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 @@ stroke
\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,28 +766,12 @@ This would declare a default rule, such that all unknown extensions
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.
-
-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.
+\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.
\subsection{Global setting of keys}
diff --git a/macros/latex-dev/required/graphics/keyval.dtx b/macros/latex-dev/required/graphics/keyval.dtx
index dd1f542832..58664b8f03 100644
--- a/macros/latex-dev/required/graphics/keyval.dtx
+++ b/macros/latex-dev/required/graphics/keyval.dtx
@@ -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
diff --git a/macros/latex-dev/required/graphics/keyval.pdf b/macros/latex-dev/required/graphics/keyval.pdf
index 0472ef6179..41cbbcb3f8 100644
--- a/macros/latex-dev/required/graphics/keyval.pdf
+++ b/macros/latex-dev/required/graphics/keyval.pdf
Binary files differ
diff --git a/macros/latex-dev/required/graphics/lscape.dtx b/macros/latex-dev/required/graphics/lscape.dtx
index ac5c16d7c2..969c94ae7a 100644
--- a/macros/latex-dev/required/graphics/lscape.dtx
+++ b/macros/latex-dev/required/graphics/lscape.dtx
@@ -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
diff --git a/macros/latex-dev/required/graphics/lscape.pdf b/macros/latex-dev/required/graphics/lscape.pdf
index dd09581a15..4caf895c6b 100644
--- a/macros/latex-dev/required/graphics/lscape.pdf
+++ b/macros/latex-dev/required/graphics/lscape.pdf
Binary files differ
diff --git a/macros/latex-dev/required/graphics/rotating.dtx b/macros/latex-dev/required/graphics/rotating.dtx
index 535f115594..c6db1273a4 100644
--- a/macros/latex-dev/required/graphics/rotating.dtx
+++ b/macros/latex-dev/required/graphics/rotating.dtx
@@ -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
diff --git a/macros/latex-dev/required/graphics/rotating.pdf b/macros/latex-dev/required/graphics/rotating.pdf
index 7a6f10d5c2..b57235b7fe 100644
--- a/macros/latex-dev/required/graphics/rotating.pdf
+++ b/macros/latex-dev/required/graphics/rotating.pdf
Binary files differ
diff --git a/macros/latex-dev/required/graphics/rotex.pdf b/macros/latex-dev/required/graphics/rotex.pdf
index 3d79c5c925..9659ba3101 100644
--- a/macros/latex-dev/required/graphics/rotex.pdf
+++ b/macros/latex-dev/required/graphics/rotex.pdf
Binary files differ
diff --git a/macros/latex-dev/required/graphics/trig.dtx b/macros/latex-dev/required/graphics/trig.dtx
index 67f6c6a970..83e774ff20 100644
--- a/macros/latex-dev/required/graphics/trig.dtx
+++ b/macros/latex-dev/required/graphics/trig.dtx
@@ -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
diff --git a/macros/latex-dev/required/graphics/trig.pdf b/macros/latex-dev/required/graphics/trig.pdf
index 968fe6e864..5c1f68dffc 100644
--- a/macros/latex-dev/required/graphics/trig.pdf
+++ b/macros/latex-dev/required/graphics/trig.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/README.md b/macros/latex-dev/required/tools/README.md
index 3ea0557c49..5ff7b0d1e0 100644
--- a/macros/latex-dev/required/tools/README.md
+++ b/macros/latex-dev/required/tools/README.md
@@ -1,7 +1,7 @@
The LaTeX `tools` bundle
========================
-Release 2021-05-01 pre-release 1
+Release 2021-06-01 pre-release 2
Overview
--------
diff --git a/macros/latex-dev/required/tools/afterpage.pdf b/macros/latex-dev/required/tools/afterpage.pdf
index 88b0ebd7bc..918b9bbe27 100644
--- a/macros/latex-dev/required/tools/afterpage.pdf
+++ b/macros/latex-dev/required/tools/afterpage.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/array.dtx b/macros/latex-dev/required/tools/array.dtx
index 1ca08036d9..84376a486b 100644
--- a/macros/latex-dev/required/tools/array.dtx
+++ b/macros/latex-dev/required/tools/array.dtx
@@ -33,7 +33,7 @@
%<+package>\DeclareCurrentRelease{}{2020-10-01}
%<+package>
%<+package>\ProvidesPackage{array}
-%<+package> [2021/02/10 v2.5d Tabular extension package (FMi)]
+%<+package> [2021/04/20 v2.5e Tabular extension package (FMi)]
%
% \fi
%
@@ -2193,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
diff --git a/macros/latex-dev/required/tools/array.pdf b/macros/latex-dev/required/tools/array.pdf
index 6c5188a5a3..175a0b8dfe 100644
--- a/macros/latex-dev/required/tools/array.pdf
+++ b/macros/latex-dev/required/tools/array.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/bm.dtx b/macros/latex-dev/required/tools/bm.dtx
index 80c73f5718..2b56b92b54 100644
--- a/macros/latex-dev/required/tools/bm.dtx
+++ b/macros/latex-dev/required/tools/bm.dtx
@@ -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@pmb@\@firstofone}
+\DeclareOption{warn}{\def\bm@info{\PackageWarningNoLine{bm}}}
+\DeclareOption{info}{\def\bm@info#1{\PackageInfo{bm}{#1\@gobble}}}
+\DeclareOption{silent}{\let\bm@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@pmb|\ldots\ (which will be defined later) are used
% as scratch macros.
+% (This csname saving no longer used, setup command is |\bm@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@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@pmb\install@mathalphabet
- \let\bm@pmb@\getanddefine@fonts
- \let\bm@pmb@@\or
+ \let\bm@install@mathalphabet\install@mathalphabet
+ \let\bm@getanddefine@fonts\getanddefine@fonts
+ \let\bm@or\or
\edef\bm@general{\f@encoding/\f@family/\f@series/\f@shape/\f@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@define\m@ne
+ \bm@info{No #1 for \string##2%
+ \ifx\bm@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@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@name\bm@general\@nil
- \let\install@mathalphabet\bm@pmb
- \let\getanddefine@fonts\bm@pmb@
- \let\or\bm@pmb@@}
+ \let\install@mathalphabet\bm@install@mathalphabet
+ \let\getanddefine@fonts\bm@getanddefine@fonts
+ \let\or\bm@or}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -647,13 +683,13 @@
\def\bm@boldtable{\m@ne}
\AtEndOfPackage{%
\def\bm@gr@up#1#2{%
- \bm@pmb{#2}}}
+ \bm@install@mathalphabet{#2}}}
\else
% \end{macrocode}
% Otherwise use the definition of |\bm| above to set up |\bm@boldtable|
% by comparing the fonts available in the normal and bold math versions.
% \begin{macrocode}
- \bm{bold}\bmmax
+ \bm@setup{bold}\bmmax
% \end{macrocode}
%
% \begin{macro}{\mathbf}
@@ -689,7 +725,7 @@
% \begin{macrocode}
\ifx\mv@heavy\@undefined
\else
- \bm{heavy}\hmmax
+ \bm@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@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@ifnextchar\@ifnextchar
% \end{macrocode}
% For Vladimir Volovich\ldots
% \changes{v1.0f}{1998/12/10}
@@ -1397,6 +1436,8 @@
% \begin{macro}{\bm@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@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@pmb@\@firstofone\else
\def\bm@pmb@#1{{%
\setbox\tw@\hbox{$\m@th\mkern.4mu$}%
\mathchoice
@@ -1434,6 +1476,7 @@
\raise1.5\dimen@\rlap{\copy\z@}%
\kern\dimen@
\box\z@}}%
+\fi
% \end{macrocode}
% \end{macro}
%
diff --git a/macros/latex-dev/required/tools/bm.pdf b/macros/latex-dev/required/tools/bm.pdf
index 94f2877ffc..125a480d07 100644
--- a/macros/latex-dev/required/tools/bm.pdf
+++ b/macros/latex-dev/required/tools/bm.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/calc.pdf b/macros/latex-dev/required/tools/calc.pdf
index 64253a0f2f..ec12e97f64 100644
--- a/macros/latex-dev/required/tools/calc.pdf
+++ b/macros/latex-dev/required/tools/calc.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/changes.txt b/macros/latex-dev/required/tools/changes.txt
index e1a1c1bf94..005a3ed4bc 100644
--- a/macros/latex-dev/required/tools/changes.txt
+++ b/macros/latex-dev/required/tools/changes.txt
@@ -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,41 @@ completeness or accuracy and it contains some references to files that
are not part of the distribution.
=======================================================================
+2021-04-25 David Carlisle <David.Carlisle@latex-project.org>
+
+ * bm.dtx: guard \kernel@ifnextchar (gh/554)
+ * bm.dtx: options to control poor man's bold and warnings (gh/71)
+
+2021-04-21 David Carlisle <David.Carlisle@latex-project.org>
+
+ * longtable.dtx: make \\ robust (gh/548)
+
+2021-04-20 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+
+ * array.dtx (section{The line separator \\}):
+ Use \protected for \\ variant (gh/548)}
+
+2021-04-18 Phelype Oleinik <phelype.oleinik@latex-project.org>
+
+ * trace.dtx:
+ Add support for \tracingstacklevels and \tracinglostchars=3.
+
+2021-04-18 David Carlisle <David.Carlisle@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@latex-project.org>
+
+ * longtable.dtx: \reset@font in captions gh/133
+
+ * longtable.dtx: Allow paragraphs in footnotes gh/364
+
+2021-03-10 Johannes Braams <Johannes.Braams@latex-project.org>
+
+ * layout.dtx: (subsection{Options}):
+ Option romanian added (gh/529)
+
2021-02-25 David Carlisle <David.Carlisle@latex-project.org>
* longtable.dtx
diff --git a/macros/latex-dev/required/tools/dcolumn.pdf b/macros/latex-dev/required/tools/dcolumn.pdf
index 6e4bc50606..2293c86e99 100644
--- a/macros/latex-dev/required/tools/dcolumn.pdf
+++ b/macros/latex-dev/required/tools/dcolumn.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/delarray.pdf b/macros/latex-dev/required/tools/delarray.pdf
index 4edd0c7f7a..951882d630 100644
--- a/macros/latex-dev/required/tools/delarray.pdf
+++ b/macros/latex-dev/required/tools/delarray.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/enumerate.pdf b/macros/latex-dev/required/tools/enumerate.pdf
index a3019efa0a..f6be172ebf 100644
--- a/macros/latex-dev/required/tools/enumerate.pdf
+++ b/macros/latex-dev/required/tools/enumerate.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/fileerr.pdf b/macros/latex-dev/required/tools/fileerr.pdf
index eec8fa5414..298c7ba4d6 100644
--- a/macros/latex-dev/required/tools/fileerr.pdf
+++ b/macros/latex-dev/required/tools/fileerr.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/fontsmpl.pdf b/macros/latex-dev/required/tools/fontsmpl.pdf
index 356c9515f4..6a66ff7089 100644
--- a/macros/latex-dev/required/tools/fontsmpl.pdf
+++ b/macros/latex-dev/required/tools/fontsmpl.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/ftnright.pdf b/macros/latex-dev/required/tools/ftnright.pdf
index 9571d279ee..a3addcfc41 100644
--- a/macros/latex-dev/required/tools/ftnright.pdf
+++ b/macros/latex-dev/required/tools/ftnright.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/hhline.pdf b/macros/latex-dev/required/tools/hhline.pdf
index 48010575fb..ee80fb369b 100644
--- a/macros/latex-dev/required/tools/hhline.pdf
+++ b/macros/latex-dev/required/tools/hhline.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/indentfirst.pdf b/macros/latex-dev/required/tools/indentfirst.pdf
index 4338ddc436..3e93185eae 100644
--- a/macros/latex-dev/required/tools/indentfirst.pdf
+++ b/macros/latex-dev/required/tools/indentfirst.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/layout.dtx b/macros/latex-dev/required/tools/layout.dtx
index 6962674255..de61aeae8c 100644
--- a/macros/latex-dev/required/tools/layout.dtx
+++ b/macros/latex-dev/required/tools/layout.dtx
@@ -30,7 +30,7 @@
%<+package>\ProvidesPackage{layout}
%<+driver>\ProvidesFile{layout.drv}
%\ProvidesFile{layout.dtx}
- [2020-07-25 v1.2d 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.
@@ -184,6 +184,18 @@
}
% \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}
diff --git a/macros/latex-dev/required/tools/layout.pdf b/macros/latex-dev/required/tools/layout.pdf
index 7dcf6ad05c..98bb6ab28c 100644
--- a/macros/latex-dev/required/tools/layout.pdf
+++ b/macros/latex-dev/required/tools/layout.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/longtable.dtx b/macros/latex-dev/required/tools/longtable.dtx
index c236aabb20..5569ae3d5c 100644
--- a/macros/latex-dev/required/tools/longtable.dtx
+++ b/macros/latex-dev/required/tools/longtable.dtx
@@ -30,14 +30,14 @@
%<package>\providecommand\DeclareRelease[3]{}
%<package>\providecommand\DeclareCurrentRelease[2]{}
%<package>
-%<package>\DeclareRelease{}{2020-01-02}{longtable-2020-01-07.sty}
+%<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-02-07 v4.14 Multi-page Table package (DPC)]
+ [2021-04-21 v4.15 Multi-page Table package (DPC)]
%
% \iffalse
%<*driver>
@@ -1282,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
@@ -1289,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@ii\vfuzz
+ \edef\LT@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@ii
+ \vbadness\@M
+ \setbox\tw@\copy\z@
+ \setbox\tw@\vsplit\tw@ to \ht\@arstrutbox
+ \setbox\tw@\vbox{\unvbox\tw@}%
+ \LT@reset@vfuzz
\advance\dimen@ \ht
\ifdim\ht\@arstrutbox>\ht\tw@\@arstrutbox\else\tw@\fi
\advance\dimen@\dp
@@ -1498,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@tabularcr{%
+\protected\def\LT@tabularcr{%
\relax\iffalse{\fi\ifnum0=`}\fi
\@ifstar
{\def\crcr{\LT@crcr\noalign{\nobreak}}\let\cr\crcr
@@ -2000,6 +2005,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@font} for gh/133}
% \begin{macrocode}
\def\LT@makecaption#1#2#3{%
\LT@mcol\LT@cols c{\hbox to\z@{\hss\parbox[t]\LTcapwidth{%
@@ -2007,6 +2014,7 @@
% Based on article class "\@makecaption", "#1" is "\@gobble" in star
% form, and "\@firstofone" otherwise.
% \begin{macrocode}
+ \reset@font
\sbox\@tempboxa{#1{#2: }#3}%
\ifdim\wd\@tempboxa>\hsize
#1{#2: }#3%
@@ -2219,10 +2227,12 @@
% \end{macro}
%
% \begin{macro}{\LT@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@p@ftntext#1{%
+\long\def\LT@p@ftntext#1{%
\edef\@tempa{\the\LT@p@ftn\noexpand\footnotetext[\the\c@footnote]}%
\global\LT@p@ftn\expandafter{\@tempa{#1}}}%
% \end{macrocode}
diff --git a/macros/latex-dev/required/tools/longtable.pdf b/macros/latex-dev/required/tools/longtable.pdf
index 3872426dec..c503bd9123 100644
--- a/macros/latex-dev/required/tools/longtable.pdf
+++ b/macros/latex-dev/required/tools/longtable.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/multicol.pdf b/macros/latex-dev/required/tools/multicol.pdf
index dfcb6eabd0..556603f749 100644
--- a/macros/latex-dev/required/tools/multicol.pdf
+++ b/macros/latex-dev/required/tools/multicol.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/rawfonts.pdf b/macros/latex-dev/required/tools/rawfonts.pdf
index 2bfd04d9ae..424fb693b0 100644
--- a/macros/latex-dev/required/tools/rawfonts.pdf
+++ b/macros/latex-dev/required/tools/rawfonts.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/shellesc.pdf b/macros/latex-dev/required/tools/shellesc.pdf
index 7abddc7dbf..94dea41431 100644
--- a/macros/latex-dev/required/tools/shellesc.pdf
+++ b/macros/latex-dev/required/tools/shellesc.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/showkeys.pdf b/macros/latex-dev/required/tools/showkeys.pdf
index 46943fcc0d..c558d2fbd2 100644
--- a/macros/latex-dev/required/tools/showkeys.pdf
+++ b/macros/latex-dev/required/tools/showkeys.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/somedefs.pdf b/macros/latex-dev/required/tools/somedefs.pdf
index 71027f1072..7dc1936536 100644
--- a/macros/latex-dev/required/tools/somedefs.pdf
+++ b/macros/latex-dev/required/tools/somedefs.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/tabularx.pdf b/macros/latex-dev/required/tools/tabularx.pdf
index 7ca0a8a02e..574096cd7a 100644
--- a/macros/latex-dev/required/tools/tabularx.pdf
+++ b/macros/latex-dev/required/tools/tabularx.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/theorem.pdf b/macros/latex-dev/required/tools/theorem.pdf
index f534d21bc2..196dc13cce 100644
--- a/macros/latex-dev/required/tools/theorem.pdf
+++ b/macros/latex-dev/required/tools/theorem.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/tools-overview.pdf b/macros/latex-dev/required/tools/tools-overview.pdf
index 403e819139..6fd1756018 100644
--- a/macros/latex-dev/required/tools/tools-overview.pdf
+++ b/macros/latex-dev/required/tools/tools-overview.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/trace.dtx b/macros/latex-dev/required/tools/trace.dtx
index 7ab6e18e25..d10243f690 100644
--- a/macros/latex-dev/required/tools/trace.dtx
+++ b/macros/latex-dev/required/tools/trace.dtx
@@ -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@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@ce@n| to setup tracing.
% \begin{macrocode}
\def\traceon{\let\conditionally@traceoff\unconditionally@traceoff
@@ -470,6 +470,8 @@
% |\tr@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@ce@n{%
- \@tracingtrue
+ \edef\tr@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@traceoff{%
+ \edef\conditionally@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@ne
\showboxdepth\m@ne
- \fi
+ \noexpand\fi
% \end{macrocode}
%
% \begin{macrocode}
\tracingstats\@ne
+ \ifdefined\tracingstacklevels \tracingstacklevels\z@ \fi
+ \errorcontextlines\m@ne
\tracingparagraphs\z@
\tracinggroups\z@
}
diff --git a/macros/latex-dev/required/tools/trace.pdf b/macros/latex-dev/required/tools/trace.pdf
index 5d66b884d1..35d766b041 100644
--- a/macros/latex-dev/required/tools/trace.pdf
+++ b/macros/latex-dev/required/tools/trace.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/varioref.pdf b/macros/latex-dev/required/tools/varioref.pdf
index 0bb2015760..d8fa68c00b 100644
--- a/macros/latex-dev/required/tools/varioref.pdf
+++ b/macros/latex-dev/required/tools/varioref.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/verbatim.pdf b/macros/latex-dev/required/tools/verbatim.pdf
index dfe2c00886..9ad8bc66e3 100644
--- a/macros/latex-dev/required/tools/verbatim.pdf
+++ b/macros/latex-dev/required/tools/verbatim.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/xr.pdf b/macros/latex-dev/required/tools/xr.pdf
index aa07a176cd..cf60d6ef58 100644
--- a/macros/latex-dev/required/tools/xr.pdf
+++ b/macros/latex-dev/required/tools/xr.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/xspace.pdf b/macros/latex-dev/required/tools/xspace.pdf
index 6d9e938780..d1540186ef 100644
--- a/macros/latex-dev/required/tools/xspace.pdf
+++ b/macros/latex-dev/required/tools/xspace.pdf
Binary files differ