summaryrefslogtreecommitdiff
path: root/macros/latex-dev/required
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex-dev/required')
-rw-r--r--macros/latex-dev/required/amsmath/README.md2
-rw-r--r--macros/latex-dev/required/amsmath/amsbsy.pdfbin174946 -> 174946 bytes
-rw-r--r--macros/latex-dev/required/amsmath/amscd.pdfbin179951 -> 179948 bytes
-rw-r--r--macros/latex-dev/required/amsmath/amsgen.pdfbin178193 -> 178193 bytes
-rw-r--r--macros/latex-dev/required/amsmath/amsldoc.pdfbin508230 -> 508207 bytes
-rw-r--r--macros/latex-dev/required/amsmath/amsmath.dtx36
-rw-r--r--macros/latex-dev/required/amsmath/amsmath.pdfbin420765 -> 420374 bytes
-rw-r--r--macros/latex-dev/required/amsmath/amsopn.pdfbin140093 -> 140093 bytes
-rw-r--r--macros/latex-dev/required/amsmath/amstext.pdfbin217504 -> 217504 bytes
-rw-r--r--macros/latex-dev/required/amsmath/amsxtra.pdfbin113560 -> 113560 bytes
-rw-r--r--macros/latex-dev/required/amsmath/changes.txt26
-rw-r--r--macros/latex-dev/required/amsmath/subeqn.pdfbin109733 -> 109740 bytes
-rw-r--r--macros/latex-dev/required/amsmath/technote.pdfbin147459 -> 147459 bytes
-rw-r--r--macros/latex-dev/required/amsmath/testmath.pdfbin454643 -> 454643 bytes
-rw-r--r--macros/latex-dev/required/firstaid/changes.txt22
-rw-r--r--macros/latex-dev/required/firstaid/latex2e-first-aid-for-external-files.dtx131
-rw-r--r--macros/latex-dev/required/firstaid/latex2e-first-aid-for-external-files.pdfbin273766 -> 281411 bytes
-rw-r--r--macros/latex-dev/required/graphics/README.md2
-rw-r--r--macros/latex-dev/required/graphics/changes.txt11
-rw-r--r--macros/latex-dev/required/graphics/color.dtx9
-rw-r--r--macros/latex-dev/required/graphics/color.pdfbin212179 -> 212777 bytes
-rw-r--r--macros/latex-dev/required/graphics/drivers.pdfbin286448 -> 286448 bytes
-rw-r--r--macros/latex-dev/required/graphics/epsfig.pdfbin159239 -> 159239 bytes
-rw-r--r--macros/latex-dev/required/graphics/graphics.dtx5
-rw-r--r--macros/latex-dev/required/graphics/graphics.pdfbin304170 -> 303762 bytes
-rw-r--r--macros/latex-dev/required/graphics/graphicx.pdfbin240618 -> 240618 bytes
-rw-r--r--macros/latex-dev/required/graphics/grfguide.pdfbin331361 -> 331361 bytes
-rw-r--r--macros/latex-dev/required/graphics/keyval.pdfbin239587 -> 239587 bytes
-rw-r--r--macros/latex-dev/required/graphics/lscape.pdfbin155987 -> 155987 bytes
-rw-r--r--macros/latex-dev/required/graphics/mathcolor.pdfbin460632 -> 460753 bytes
-rw-r--r--macros/latex-dev/required/graphics/rotating.pdfbin278452 -> 278524 bytes
-rw-r--r--macros/latex-dev/required/graphics/rotex.pdfbin172240 -> 172252 bytes
-rw-r--r--macros/latex-dev/required/graphics/trig.pdfbin199290 -> 199290 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/CHANGELOG.md129
-rw-r--r--macros/latex-dev/required/l3kernel/README.md4
-rw-r--r--macros/latex-dev/required/l3kernel/expl3.dtx15
-rw-r--r--macros/latex-dev/required/l3kernel/expl3.pdfbin610409 -> 610757 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/interface3.pdfbin1802512 -> 1809195 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/interface3.tex4
-rw-r--r--macros/latex-dev/required/l3kernel/l3.ins6
-rw-r--r--macros/latex-dev/required/l3kernel/l3basics.dtx33
-rw-r--r--macros/latex-dev/required/l3kernel/l3bitset.dtx21
-rw-r--r--macros/latex-dev/required/l3kernel/l3bootstrap.dtx10
-rw-r--r--macros/latex-dev/required/l3kernel/l3box.dtx8
-rw-r--r--macros/latex-dev/required/l3kernel/l3cctab.dtx12
-rw-r--r--macros/latex-dev/required/l3kernel/l3clist.dtx91
-rw-r--r--macros/latex-dev/required/l3kernel/l3coffins.dtx21
-rw-r--r--macros/latex-dev/required/l3kernel/l3color.dtx96
-rw-r--r--macros/latex-dev/required/l3kernel/l3debug.dtx6
-rw-r--r--macros/latex-dev/required/l3kernel/l3deprecation.dtx10
-rw-r--r--macros/latex-dev/required/l3kernel/l3doc.dtx94
-rw-r--r--macros/latex-dev/required/l3kernel/l3doc.pdfbin565557 -> 565661 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3docstrip.dtx4
-rw-r--r--macros/latex-dev/required/l3kernel/l3docstrip.pdfbin151323 -> 151434 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3expan.dtx27
-rw-r--r--macros/latex-dev/required/l3kernel/l3file.dtx76
-rw-r--r--macros/latex-dev/required/l3kernel/l3flag.dtx4
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-assign.dtx39
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-aux.dtx215
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-basics.dtx391
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-convert.dtx105
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-expo.dtx319
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-extended.dtx319
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-functions.dtx12
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-logic.dtx122
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-parse.dtx171
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-random.dtx113
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-round.dtx53
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-symbolic.dtx50
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-traps.dtx38
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-trig.dtx330
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp-types.dtx6
-rw-r--r--macros/latex-dev/required/l3kernel/l3fp.dtx78
-rw-r--r--macros/latex-dev/required/l3kernel/l3fparray.dtx53
-rw-r--r--macros/latex-dev/required/l3kernel/l3int.dtx267
-rw-r--r--macros/latex-dev/required/l3kernel/l3intarray.dtx6
-rw-r--r--macros/latex-dev/required/l3kernel/l3kernel-functions.dtx4
-rw-r--r--macros/latex-dev/required/l3kernel/l3keys.dtx166
-rw-r--r--macros/latex-dev/required/l3kernel/l3legacy.dtx4
-rw-r--r--macros/latex-dev/required/l3kernel/l3luatex.dtx8
-rw-r--r--macros/latex-dev/required/l3kernel/l3msg.dtx17
-rw-r--r--macros/latex-dev/required/l3kernel/l3names.dtx7
-rw-r--r--macros/latex-dev/required/l3kernel/l3news.pdfbin396223 -> 402138 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news01.pdfbin122959 -> 122959 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news02.pdfbin150919 -> 150919 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news03.pdfbin148747 -> 154683 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news04.pdfbin114754 -> 114754 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news05.pdfbin112524 -> 112524 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news06.pdfbin151591 -> 151591 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news07.pdfbin128344 -> 128344 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news08.pdfbin163484 -> 163484 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news09.pdfbin250161 -> 256104 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news10.pdfbin150302 -> 156257 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news11.pdfbin170102 -> 176068 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3news12.pdfbin205020 -> 210960 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3pdf.dtx26
-rw-r--r--macros/latex-dev/required/l3kernel/l3prefixes.csv13
-rw-r--r--macros/latex-dev/required/l3kernel/l3prefixes.pdfbin82843 -> 83253 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3prg.dtx47
-rw-r--r--macros/latex-dev/required/l3kernel/l3prop.dtx100
-rw-r--r--macros/latex-dev/required/l3kernel/l3quark.dtx6
-rw-r--r--macros/latex-dev/required/l3kernel/l3regex.dtx54
-rw-r--r--macros/latex-dev/required/l3kernel/l3seq.dtx357
-rw-r--r--macros/latex-dev/required/l3kernel/l3skip.dtx52
-rw-r--r--macros/latex-dev/required/l3kernel/l3sort.dtx4
-rw-r--r--macros/latex-dev/required/l3kernel/l3str-convert.dtx26
-rw-r--r--macros/latex-dev/required/l3kernel/l3str.dtx19
-rw-r--r--macros/latex-dev/required/l3kernel/l3styleguide.pdfbin296602 -> 296741 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3styleguide.tex4
-rw-r--r--macros/latex-dev/required/l3kernel/l3syntax-changes.pdfbin231447 -> 231575 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3syntax-changes.tex4
-rw-r--r--macros/latex-dev/required/l3kernel/l3sys.dtx48
-rw-r--r--macros/latex-dev/required/l3kernel/l3term-glossary.pdfbin242247 -> 242366 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/l3term-glossary.tex4
-rw-r--r--macros/latex-dev/required/l3kernel/l3text-case.dtx12
-rw-r--r--macros/latex-dev/required/l3kernel/l3text-map.dtx4
-rw-r--r--macros/latex-dev/required/l3kernel/l3text-purify.dtx4
-rw-r--r--macros/latex-dev/required/l3kernel/l3text.dtx31
-rw-r--r--macros/latex-dev/required/l3kernel/l3tl-analysis.dtx37
-rw-r--r--macros/latex-dev/required/l3kernel/l3tl-build.dtx4
-rw-r--r--macros/latex-dev/required/l3kernel/l3tl.dtx167
-rw-r--r--macros/latex-dev/required/l3kernel/l3token.dtx41
-rw-r--r--macros/latex-dev/required/l3kernel/l3unicode.dtx27
-rw-r--r--macros/latex-dev/required/l3kernel/source3.pdfbin7620915 -> 7688521 bytes
-rw-r--r--macros/latex-dev/required/l3kernel/source3.tex4
-rw-r--r--macros/latex-dev/required/l3kernel/source3body.tex44
-rw-r--r--macros/latex-dev/required/latex-lab/README.md2
-rw-r--r--macros/latex-dev/required/latex-lab/blocks-code.pdfbin871980 -> 892165 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/blocks-doc.pdfbin486159 -> 485202 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/changes.txt173
-rw-r--r--macros/latex-dev/required/latex-lab/documentmetadata-support-code.pdfbin539394 -> 563555 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/documentmetadata-support-doc.pdfbin420928 -> 421271 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/documentmetadata-support.dtx23
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-amsmath.dtx10
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-amsmath.pdfbin382063 -> 382747 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-bib.dtx10
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-bib.pdfbin383259 -> 383673 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-block.dtx2935
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-block.pdfbin871980 -> 892165 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-firstaid.dtx382
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-firstaid.pdfbin368000 -> 401935 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-float.dtx293
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-float.pdfbin426854 -> 444637 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-footnotes.dtx116
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-footnotes.pdfbin819698 -> 821807 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-graphic.dtx18
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-graphic.pdfbin517900 -> 517603 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-marginpar.dtx51
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-marginpar.pdfbin389702 -> 414685 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-math.dtx1644
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-math.pdfbin740772 -> 796674 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-mathpkg.pdfbin355789 -> 356138 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-mathtools.dtx14
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-mathtools.pdfbin382063 -> 372235 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-minipage.dtx55
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-minipage.pdfbin280811 -> 282259 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-namespace.dtx4
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-namespace.pdfbin235751 -> 235962 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-new-or-1.dtx28
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-new-or-1.pdfbin389721 -> 406321 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-new-or-2.pdfbin632196 -> 632196 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-sec.dtx196
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-sec.pdfbin527096 -> 544929 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-table.dtx451
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-table.pdfbin556567 -> 572577 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-testphase.dtx2
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-testphase.pdfbin298175 -> 298557 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-text.dtx8
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-text.pdfbin307812 -> 307847 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-title.pdfbin348117 -> 348117 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-toc-hyperref-changes.pdfbin296124 -> 296124 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-toc-kernel-changes.dtx176
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-toc-kernel-changes.pdfbin361081 -> 373186 bytes
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-toc.dtx179
-rw-r--r--macros/latex-dev/required/latex-lab/latex-lab-toc.pdfbin396814 -> 406053 bytes
-rw-r--r--macros/latex-dev/required/tools/README.md2
-rw-r--r--macros/latex-dev/required/tools/afterpage.pdfbin198100 -> 198100 bytes
-rw-r--r--macros/latex-dev/required/tools/array.dtx237
-rw-r--r--macros/latex-dev/required/tools/array.pdfbin839409 -> 875527 bytes
-rw-r--r--macros/latex-dev/required/tools/bm.pdfbin323640 -> 323640 bytes
-rw-r--r--macros/latex-dev/required/tools/calc.dtx8
-rw-r--r--macros/latex-dev/required/tools/calc.pdfbin370660 -> 370977 bytes
-rw-r--r--macros/latex-dev/required/tools/changes.txt84
-rw-r--r--macros/latex-dev/required/tools/dcolumn.pdfbin221038 -> 221038 bytes
-rw-r--r--macros/latex-dev/required/tools/delarray.pdfbin191058 -> 191058 bytes
-rw-r--r--macros/latex-dev/required/tools/enumerate.pdfbin215077 -> 215077 bytes
-rw-r--r--macros/latex-dev/required/tools/fileerr.pdfbin187692 -> 188284 bytes
-rw-r--r--macros/latex-dev/required/tools/fontsmpl.pdfbin146438 -> 146438 bytes
-rw-r--r--macros/latex-dev/required/tools/ftnright.pdfbin387219 -> 387607 bytes
-rw-r--r--macros/latex-dev/required/tools/hhline.pdfbin189678 -> 189678 bytes
-rw-r--r--macros/latex-dev/required/tools/indentfirst.pdfbin157352 -> 157352 bytes
-rw-r--r--macros/latex-dev/required/tools/l3sys-query.pdfbin482622 -> 482622 bytes
-rw-r--r--macros/latex-dev/required/tools/layout.pdfbin260278 -> 260278 bytes
-rw-r--r--macros/latex-dev/required/tools/longtable.dtx165
-rw-r--r--macros/latex-dev/required/tools/longtable.pdfbin399651 -> 402733 bytes
-rw-r--r--macros/latex-dev/required/tools/manifest.txt10
-rw-r--r--macros/latex-dev/required/tools/multicol-2024-05-23.sty1144
-rw-r--r--macros/latex-dev/required/tools/multicol.dtx884
-rw-r--r--macros/latex-dev/required/tools/multicol.pdfbin524670 -> 533038 bytes
-rw-r--r--macros/latex-dev/required/tools/rawfonts.pdfbin138956 -> 138956 bytes
-rw-r--r--macros/latex-dev/required/tools/shellesc.pdfbin176171 -> 176171 bytes
-rw-r--r--macros/latex-dev/required/tools/showkeys.pdfbin252923 -> 252922 bytes
-rw-r--r--macros/latex-dev/required/tools/somedefs.pdfbin167583 -> 167583 bytes
-rw-r--r--macros/latex-dev/required/tools/tabularx.pdfbin289601 -> 289601 bytes
-rw-r--r--macros/latex-dev/required/tools/theorem.dtx3
-rw-r--r--macros/latex-dev/required/tools/theorem.pdfbin351723 -> 352212 bytes
-rw-r--r--macros/latex-dev/required/tools/tools-overview.pdfbin73673 -> 73684 bytes
-rw-r--r--macros/latex-dev/required/tools/tools-overview.tex8
-rw-r--r--macros/latex-dev/required/tools/tools.ins17
-rw-r--r--macros/latex-dev/required/tools/trace.pdfbin222074 -> 222074 bytes
-rw-r--r--macros/latex-dev/required/tools/varioref.pdfbin393884 -> 393884 bytes
-rw-r--r--macros/latex-dev/required/tools/verbatim.pdfbin331587 -> 331587 bytes
-rw-r--r--macros/latex-dev/required/tools/xr.pdfbin323877 -> 323877 bytes
-rw-r--r--macros/latex-dev/required/tools/xspace.pdfbin257027 -> 257027 bytes
214 files changed, 9409 insertions, 4870 deletions
diff --git a/macros/latex-dev/required/amsmath/README.md b/macros/latex-dev/required/amsmath/README.md
index acf256c850..71ee8a9982 100644
--- a/macros/latex-dev/required/amsmath/README.md
+++ b/macros/latex-dev/required/amsmath/README.md
@@ -1,7 +1,7 @@
The amsmath bundle for LaTeX
============================
-Release 2024-11-01 pre-release 0
+Release 2025-06-01 pre-release 0a
Overview
--------
diff --git a/macros/latex-dev/required/amsmath/amsbsy.pdf b/macros/latex-dev/required/amsmath/amsbsy.pdf
index 98414b672d..77becc86df 100644
--- a/macros/latex-dev/required/amsmath/amsbsy.pdf
+++ b/macros/latex-dev/required/amsmath/amsbsy.pdf
Binary files differ
diff --git a/macros/latex-dev/required/amsmath/amscd.pdf b/macros/latex-dev/required/amsmath/amscd.pdf
index 9f6494bb8e..c4395865c4 100644
--- a/macros/latex-dev/required/amsmath/amscd.pdf
+++ b/macros/latex-dev/required/amsmath/amscd.pdf
Binary files differ
diff --git a/macros/latex-dev/required/amsmath/amsgen.pdf b/macros/latex-dev/required/amsmath/amsgen.pdf
index d67090a444..2303434c64 100644
--- a/macros/latex-dev/required/amsmath/amsgen.pdf
+++ b/macros/latex-dev/required/amsmath/amsgen.pdf
Binary files differ
diff --git a/macros/latex-dev/required/amsmath/amsldoc.pdf b/macros/latex-dev/required/amsmath/amsldoc.pdf
index e615a52dc4..6f4a9bcf4c 100644
--- a/macros/latex-dev/required/amsmath/amsldoc.pdf
+++ b/macros/latex-dev/required/amsmath/amsldoc.pdf
Binary files differ
diff --git a/macros/latex-dev/required/amsmath/amsmath.dtx b/macros/latex-dev/required/amsmath/amsmath.dtx
index ec44957a89..591d175642 100644
--- a/macros/latex-dev/required/amsmath/amsmath.dtx
+++ b/macros/latex-dev/required/amsmath/amsmath.dtx
@@ -85,7 +85,7 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% \end{macrocode}
%
% \begin{macrocode}
-\ProvidesPackage{amsmath}[2024/05/23 v2.17q AMS math features]
+\ProvidesPackage{amsmath}[2024/11/05 v2.17t AMS math features]
% \end{macrocode}
%
% \section{Catcode defenses}
@@ -166,7 +166,7 @@ Bug reports can be opened (category \texttt{#1}) at\\%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \section{Flush-left equations [DMJ]}
%
-% The left margin of math enviroments is controlled by
+% The left margin of math environments is controlled by
% \cs{@mathmargin}. This can be set to \cs{@centering} to
% implement the default behaviour, i.e., centered equations, and to
% something else to implement the flushleft style.
@@ -208,7 +208,7 @@ Bug reports can be opened (category \texttt{#1}) at\\%
%
% The next question is what happens when amsmath is used with
% one of the standard classes. Unfortunately, \latex/ implements
-% \opt{fleqn} somewhat clumsily; instead of paramaterizing the
+% \opt{fleqn} somewhat clumsily; instead of parameterizing the
% definitions of the math structures (as I've attempted to do
% here), \fn{fleqn.clo} declares a dimen \cn{mathindent} that is
% much like my \cs{@mathmargin} and then redefines \cn\[, \cn\],
@@ -653,7 +653,7 @@ Foreign command \@backslashchar#1;\MessageBreak
%
% the |withdelims| primitives do not work in xetex with OpenType
% fonts, and the relevant font dimen parameters are often not set
-% in luatex as theer are no matching values in the OpenType Math
+% in luatex as there are no matching values in the OpenType Math
% table, so here we use variants that use the font parameters if
% they are set, but scale using |\left\right| rather than the
% |withdelims| primitives.
@@ -3363,7 +3363,7 @@ ill-advised in LaTeX.%
% \end{macro}
%
% \begin{macro}{\column@plus}
-% \cs{\column@plus} is a useful abbreviation.
+% \cs{column@plus} is a useful abbreviation.
% \begin{macrocode}
\def\column@plus{%
\global\advance\column@\@ne
@@ -3786,7 +3786,7 @@ and fix things up.}
% (In earlier versions of the code anything other than \texttt{b}
% or \texttt{t} was interpreted as \texttt{c} and the data was
% otherwise dropped.)
-% \changes{v2.17g}{2020/03/10}{Explicity test for b/t/c and return
+% \changes{v2.17g}{2020/03/10}{Explicitly test for b/t/c and return
% optional argument is different (gh/5)}
% \begin{macrocode}
\def\ams@start@box#1{%
@@ -3919,7 +3919,7 @@ and fix things up.}
% \end{macrocode}
% If we picked up a bracket group by mistake here is the place to
% return it for processing.
-% \changes{v2.17g}{2020/03/10}{Explicity test for b/t/c and return
+% \changes{v2.17g}{2020/03/10}{Explicitly test for b/t/c and return
% optional argument is different (gh/5)}
% \begin{macrocode}
\ams@return@opt@arg
@@ -4018,7 +4018,7 @@ and fix things up.}
\crcr
% \end{macrocode}
% And put a mistaking picked up bracket group back:
-% \changes{v2.17g}{2020/03/10}{Explicity test for b/t/c and return
+% \changes{v2.17g}{2020/03/10}{Explicitly test for b/t/c and return
% optional argument is different (gh/5)}
% \begin{macrocode}
\ams@return@opt@arg
@@ -4592,7 +4592,7 @@ trying to recover with `aligned'%
% \env{alignat} (i.e., the $n$th field of \cs{maxcolumn@widths}.)
% It expands to a \<dimen>, so it can be used as the right-hand
% side of a \<variable assignment> or \<arithmetic> statement.
-% It's argument can be any \<number>, \<integer variable> or macro
+% Its argument can be any \<number>, \<integer variable> or macro
% that expands to one of these. [Check to make sure this is true.]
%
% This is subtler than it looks.
@@ -5041,7 +5041,7 @@ trying to recover with `aligned'%
% Next we consider the case when equations are flush-left, but tags
% are on the right. This case is somewhat more complicated than
% the previous one, since we can adjust the right margin by varying
-% the inter-align separatin. Thus, when a tag is found to be too
+% the inter-align separation. Thus, when a tag is found to be too
% close to its equation, we first attempt to decrease
% \cs{alignsep@} enough to move the equation off to an acceptable
% distance. Only if that would require a value of \cs{alignsep@}
@@ -5078,7 +5078,7 @@ trying to recover with `aligned'%
% \cs{alignsep@} are both~0. To get the number of align
% structures, we first count the number of columns by counting the
% number of entries in the \cs{fieldlengths@} for the current row.
-% The effective length is calcuated by \cs{x@rcalc@width} and put
+% The effective length is calculated by \cs{x@rcalc@width} and put
% in the temporary register \cs{@tempdimc}, using \cs{@tempdimb} as
% an auxiliary variable.
% \begin{macrocode}
@@ -5500,7 +5500,7 @@ trying to recover with `aligned'%
% might occur at the beginning of the current line. More
% specifically, we first set \cs{count@} equal to the number of
% interalign spaces preceding the current field (namely, $\lfloor
-% (\cs{\column@}-1)/2 \rfloor$), and then subtract \cs{count@} from
+% (\cs{column@}-1)/2 \rfloor$), and then subtract \cs{count@} from
% both \cs{@tempcnta} and \cs{@tempcntb}. The rationale is that
% for the purposes of adjusting the spacing between the tag and the
% equation, the only flexible interalign spaces are those after
@@ -5523,7 +5523,7 @@ trying to recover with `aligned'%
% \end{macro}
%
% \begin{macro}{\place@tag}
-% \cs{place@tag} takes care of the placment of tags in the
+% \cs{place@tag} takes care of the placement of tags in the
% \env{align} environments.
% \begin{macrocode}
\def\place@tag{%
@@ -6187,7 +6187,7 @@ Cannot use `split' here;\MessageBreak trying to recover with `aligned'}%
% in his \fn{amstex.doc} Spivak indicates those commands should never
% be used on a first or last line. Perhaps better to leave the
% question open unless/until real-life examples turn up.
-% \changes{v2.17m}{2022/02/03}{Make \cs{shoveright} robust (if def is not trival)}
+% \changes{v2.17m}{2022/02/03}{Make \cs{shoveright} robust (if def is not trivial)}
% \begin{macrocode}
\iftagsleft@
\protected\def\shoveright#1{%
@@ -6212,7 +6212,7 @@ Cannot use `split' here;\MessageBreak trying to recover with `aligned'}%
}
\fi
% \end{macrocode}
-% \changes{v2.17m}{2022/02/03}{Make \cs{shoveleft} robust (if def is not trival)}
+% \changes{v2.17m}{2022/02/03}{Make \cs{shoveleft} robust (if def is not trivial)}
% \begin{macrocode}
\if@fleqn
\def\shoveleft#1{#1}%
@@ -6576,14 +6576,14 @@ Cannot use `split' here;\MessageBreak trying to recover with `aligned'}%
\def\mathdisplay@@pop{\the\mathdisplay@stack}
% \end{macrocode}
%\changes{v2.17k}{2021/08/24}{Move the counter inside the equation and guard
-% with a mathopen for better compability with hyperref, issue gh/652}
+% with a mathopen for better compatibility with hyperref, issue gh/652}
% As with hyperref incrementing the counter creates a box to raise the anchor
% it should be in a place where is doesn't affect spacing.
% Currently the code from hyperref is used to avoid this problem:
% If fleqn isn't active the counter is set inside the equation and the potential
% box guarded by a mathopen to avoid side effects on following unary symbols.
% If fleqn is activated it has to be outside to avoid problems with labels.
-% This solution is temporary and not necessarly the best.
+% This solution is temporary and not necessarily the best.
% \begin{macrocode}
\if@fleqn
\renewenvironment{equation}{%
@@ -6637,7 +6637,7 @@ Cannot use `split' here;\MessageBreak trying to recover with `aligned'}%
%
% \section{Credits}
%
-% Much of the code for the \pkg{amsmath} package had its orgin in
+% Much of the code for the \pkg{amsmath} package had its origin in
% \fn{amstex.tex}, written by Michael Spivak. The initial work of
% porting \fn{amstex.tex} to \fn{amstex.sty} was done in 1988--1989
% by Frank Mittelbach and Rainer Sch\"opf. In 1994 David M. Jones
diff --git a/macros/latex-dev/required/amsmath/amsmath.pdf b/macros/latex-dev/required/amsmath/amsmath.pdf
index 2ae7c81905..573eae6303 100644
--- a/macros/latex-dev/required/amsmath/amsmath.pdf
+++ b/macros/latex-dev/required/amsmath/amsmath.pdf
Binary files differ
diff --git a/macros/latex-dev/required/amsmath/amsopn.pdf b/macros/latex-dev/required/amsmath/amsopn.pdf
index 6f1b3c0331..8490b1221b 100644
--- a/macros/latex-dev/required/amsmath/amsopn.pdf
+++ b/macros/latex-dev/required/amsmath/amsopn.pdf
Binary files differ
diff --git a/macros/latex-dev/required/amsmath/amstext.pdf b/macros/latex-dev/required/amsmath/amstext.pdf
index 37ad4cc7fa..5040a86665 100644
--- a/macros/latex-dev/required/amsmath/amstext.pdf
+++ b/macros/latex-dev/required/amsmath/amstext.pdf
Binary files differ
diff --git a/macros/latex-dev/required/amsmath/amsxtra.pdf b/macros/latex-dev/required/amsmath/amsxtra.pdf
index af44bc5e9b..465fd83cef 100644
--- a/macros/latex-dev/required/amsmath/amsxtra.pdf
+++ b/macros/latex-dev/required/amsmath/amsxtra.pdf
Binary files differ
diff --git a/macros/latex-dev/required/amsmath/changes.txt b/macros/latex-dev/required/amsmath/changes.txt
index 588e7d36d0..e56758374d 100644
--- a/macros/latex-dev/required/amsmath/changes.txt
+++ b/macros/latex-dev/required/amsmath/changes.txt
@@ -1,9 +1,33 @@
+2024-11-05 David Carlisle <David.Carlisle@latex-project.org>
+
+ * amsmath.dtx
+ Revert last \dots change (gh/1448)
+
================================================================================
All changes above are only part of the development branch for the next release.
================================================================================
#########################
-# 2023-11-01 Release
+# 2024-11-01a Release
+#########################
+
+2024-11-05 David Carlisle <David.Carlisle@latex-project.org>
+
+ * amsmath.dtx
+ Revert last \dots change (gh/1448)
+
+#########################
+# 2024-11-01 Release
+#########################
+
+2024-08-02 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+
+ * amsmath.dtx (section{Ellipsis dots}):
+ Support special \dots magic in case of robust symbols protected with
+ \protected or via \DeclareRobustCommand (gh/1265)
+
+#########################
+# 2024-06-01 Release
#########################
2024-05-23 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
diff --git a/macros/latex-dev/required/amsmath/subeqn.pdf b/macros/latex-dev/required/amsmath/subeqn.pdf
index 54f6fe9385..bec0ad6ebe 100644
--- a/macros/latex-dev/required/amsmath/subeqn.pdf
+++ b/macros/latex-dev/required/amsmath/subeqn.pdf
Binary files differ
diff --git a/macros/latex-dev/required/amsmath/technote.pdf b/macros/latex-dev/required/amsmath/technote.pdf
index 6526568bda..6bce154b91 100644
--- a/macros/latex-dev/required/amsmath/technote.pdf
+++ b/macros/latex-dev/required/amsmath/technote.pdf
Binary files differ
diff --git a/macros/latex-dev/required/amsmath/testmath.pdf b/macros/latex-dev/required/amsmath/testmath.pdf
index e1ce7c6acd..bbe1ff8e9b 100644
--- a/macros/latex-dev/required/amsmath/testmath.pdf
+++ b/macros/latex-dev/required/amsmath/testmath.pdf
Binary files differ
diff --git a/macros/latex-dev/required/firstaid/changes.txt b/macros/latex-dev/required/firstaid/changes.txt
index 7ddcfbcec2..9df9304805 100644
--- a/macros/latex-dev/required/firstaid/changes.txt
+++ b/macros/latex-dev/required/firstaid/changes.txt
@@ -1,3 +1,25 @@
+2024-11-24 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+
+ * latex2e-first-aid-for-external-files.dtx: add iftag@-test to cleveref firstaid for issue #1560
+
+2024-11-08 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+
+ * latex2e-first-aid-for-external-files.dtx: add missing \expandafter for issue #1544
+
+2024-11-04 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+
+ * latex2e-first-aid-for-external-files.dtx: correct spurious space
+
+2024-10-16 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+
+ * latex2e-first-aid-for-external-files.dtx: extend firstaid for cleveref
+ for issue #1393 and longtable.
+
+2024-06-25 David Carlisle <David.Carlisle@latex-project.org>
+
+ * latex2e-first-aid-for-external-files.dtx: add firstaid for arydshln
+ define two internal macros as \protected to be safe in colortbl
+
2024-03-22 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
* latex2e-first-aid-for-external-files.dtx: add firstaid for cleveref
diff --git a/macros/latex-dev/required/firstaid/latex2e-first-aid-for-external-files.dtx b/macros/latex-dev/required/firstaid/latex2e-first-aid-for-external-files.dtx
index 152737eaf7..7b26705bf2 100644
--- a/macros/latex-dev/required/firstaid/latex2e-first-aid-for-external-files.dtx
+++ b/macros/latex-dev/required/firstaid/latex2e-first-aid-for-external-files.dtx
@@ -111,8 +111,8 @@
% \end{macrocode}
%
% \begin{macrocode}
-\def\LaTeXFirstAidDate{2024/03/20}
-\def\LaTeXFirstAidVersion{v1.1e}
+\def\LaTeXFirstAidDate{2024/11/24}
+\def\LaTeXFirstAidVersion{v1.1j}
% \end{macrocode}
%
% \begin{macrocode}
@@ -121,7 +121,7 @@
LaTeX kernel fixes to external files and packages]
% \end{macrocode}
%
-%
+%
% \begin{macro}{\FirstAidNeededT}
% This is a very simple help to ensure that we only apply first aid
% to an unmodified package or class. It only works in the case the
@@ -132,7 +132,7 @@
% assume that the package/class in question got updated by its
% maintainer.
% \begin{macrocode}
-\ExplSyntaxOn
+\ExplSyntaxOn
\cs_new:Npn\FirstAidNeededT#1#2#3{
\exp_args:Ncx\str_if_eq:onF{ver@#1.#2}{#3}
{ \typeout{==>~ First~ Aid~ for~ #1.#2~ no~ longer~ applied!^^J
@@ -147,14 +147,14 @@
\ExplSyntaxOff
% \end{macrocode}
% \end{macro}
-%
+%
% \begin{macrocode}
%</kernel>
% \end{macrocode}
%
%
% \subsection{The \pkg{filehook} package first aid}
-%
+%
% The \pkg{filehook} package implements hooks into file loading
% commands. These days this is already provided by the kernel
% albeit not with the same user interface. Until that package gets
@@ -201,7 +201,7 @@
\newcommand\AtEndOfEveryFile [1]
{\AddToHook{file/after}{#1}}
% \end{macrocode}
-%
+%
% \begin{macrocode}
\newcommand\AtBeginOfIncludes [1]
{\AddToHook{include/before}{#1}}
@@ -210,14 +210,14 @@
\newcommand\AfterIncludes [1]
{\AddToHook{include/after}{#1}}
% \end{macrocode}
-%
+%
% \begin{macrocode}
\newcommand\AtBeginOfPackages [1]
{\AddToHook{package/before}{#1}}
\newcommand\AtEndOfPackages [1]
{\AddToHook{package/after}{#1}}
% \end{macrocode}
-%
+%
% \begin{macrocode}
\newcommand\AtBeginOfClasses [1]
{\AddToHook{class/before}{#1}}
@@ -232,7 +232,7 @@
{\AddToHook{file/#1/after}{#2}}
% \end{macrocode}
%
-% Some commands offered a starred form
+% Some commands offered a starred form
% \begin{macrocode}
\DeclareDocumentCommand \AtBeginOfPackageFile {smm}
{\IfBooleanTF{#1}%
@@ -242,7 +242,7 @@
{\AddToHook{package/#2/before}{#3}}%
}
% \end{macrocode}
-%
+%
% \begin{macrocode}
\DeclareDocumentCommand \AtEndOfPackageFile {smm}
{\IfBooleanTF{#1}%
@@ -254,7 +254,7 @@
% \end{macrocode}
%
% Are the * forms here of any use? I know they are use 3--4 times
-% on CTAN but I wonder if those are real or mistaken usages.
+% on CTAN but I wonder if those are real or mistaken usages.
% \begin{macrocode}
\DeclareDocumentCommand \AtBeginOfClassFile {smm}
{\IfBooleanTF{#1}%
@@ -271,7 +271,7 @@
{\AddToHook{class/#2/after}{#3}}%
}
% \end{macrocode}
-%
+%
% \begin{macrocode}
\newcommand\AtBeginOfIncludeFile [2]
{\AddToHook{include/#1/before}{#2}}
@@ -334,7 +334,7 @@
% \end{macrocode}
% Undo overwriting \cs{shipout}:
% \begin{macrocode}
- \cs_gset_eq:NN \shipout \pgfpages@originalshipout
+ \cs_gset_eq:NN \shipout \pgfpages@originalshipout
% \end{macrocode}
% Instead overwrite the L3 programming layer name of the
% primitive. This is really an absolute no-go, but for now the
@@ -343,7 +343,7 @@
% It will be replaced when the ``configuration points'' interface
% for \LaTeX{} becomes available. At that point the package will be
% able to set up a different strategy for doing shipouts and
-% without the need to overrite a primitive (which it did in the
+% without the need to overwrite a primitive (which it did in the
% past and which we do below) and then this code here can be taken
% out again.
% \begin{macrocode}
@@ -394,23 +394,23 @@
% \subsection{The \pkg{crop} package first aid}
%
% The crop packages fails currently due to two \LaTeX{} changes:
-% It doesn't know that \cs{stockheight} and \cs{stockwidth}
+% It doesn't know that \cs{stockheight} and \cs{stockwidth}
% are now defined, and doesn't take into account that \cs{rlap}
% is robust (https://github.com/rrthomas/crop/issues/2).
% The first is addressed by setting the dimension if they are zero or
% negative. For the second we locally change the meaning of \cs{protect}
-%
+%
% \begin{macrocode}
\AddToHook{file/crop.sty/after}[firstaid]{%
\FirstAidNeededT{crop}{sty}{2017/11/19 1.10 crop marks (mf)}%
{%
- \ifdim\stockwidth > 0pt \else \stockwidth\paperwidth \fi
- \ifdim\stockheight > 0pt \else \stockheight\paperheight \fi
+ \ifdim\stockwidth > 0pt \else \stockwidth\paperwidth \fi
+ \ifdim\stockheight > 0pt \else \stockheight\paperheight \fi
\renewcommand*\CROP@genreflect[1]{%
\leavevmode
\dimen0\CROP@horigin
\kern2\dimen0
- \begingroup
+ \begingroup
\set@typeset@protect %change protect
\reflectbox{%
\hb@xt@\paperwidth{%
@@ -446,7 +446,7 @@
% the classic \TeX{} implementation but with the extended
% allocation possibilities of all modern engines is no longer the
% case and there is a point where the allocations take a ``jump''
-% breaking the odering assumption. These days we are fairly close
+% breaking the ordering assumption. These days we are fairly close
% to that point and depending on how many packages are loaded
% before \pkg{bigfoot} the package breaks.
%
@@ -500,7 +500,7 @@
%
% So this needs to be removed as well by adding an additional
% \cs{unskip}.
-%
+%
% \begin{macrocode}
\AddToHook{file/varwidth.sty/after}[firstaid]{%
\FirstAidNeededT{varwidth}{sty}%
@@ -513,7 +513,7 @@
\count@\lastpenalty\unpenalty
\setbox\z@\lastbox
\ifvoid\z@ \advance\sift@deathcycles\@ne \else \sift@deathcycles\z@ \fi
- \ifnum\sift@deathcycles>33
+ \ifnum\sift@deathcycles>33
\let\@vwid@sift\relax
\PackageWarning{varwidth}{Failed to reprocess entire contents}%
\fi
@@ -564,23 +564,23 @@
%</kernel>
% \end{macrocode}
% \subsection{The \pkg{underscore} first aid}
-%
+%
% The \pkg{underscore} package makes the underscore active. This means that the
% underscore can not be used in label and references unless the package option \texttt{strings} is used
-% (which patches a selection of problematic commands like \cs{label} and \cs{ref})
-% or \pkg{babel} is used which redefines\footnote{unless the recommended option \texttt{safe=none} is used}
+% (which patches a selection of problematic commands like \cs{label} and \cs{ref})
+% or \pkg{babel} is used which redefines\footnote{unless the recommended option \texttt{safe=none} is used}
% a selection of problematic commands like \cs{@testdef} or \cs{@newl@bel}.
-%
-% With the new property commands the work-around do not work. We therefore make the
+%
+% With the new property commands the work-around do not work. We therefore make the
% underscore protected and use \cs{ifincsname} to allow its use in csnames.
-%
+%
% \begin{macrocode}
%<*underscore-ltx>
\ProvidesPackage{underscore-ltx}[2023/09/20 LaTeX firstaid to make underscore protected ]
\begingroup
\catcode`\_=\active
- \protected\gdef _{%
- \ifincsname %
+ \protected\gdef _{%
+ \ifincsname %
\string_%
\else
\ifx\protect\@typeset@protect
@@ -659,7 +659,7 @@
%
% The \pkg{cleveref} package expects only two data containers
% for its internal \cs{newlabel} command. This fails if
-% \pkg{xr-hyper} is used which expands every \cs{newlabel} to
+% \pkg{xr-hyper} is used which expands every \cs{newlabel} to
% five data container and puts the file name into the last one.
% \begin{macrocode}
\AddToHook{package/cleveref/after}[firstaid]{%
@@ -680,12 +680,12 @@
\expandafter\expandafter\expandafter\def%
\expandafter\expandafter\expandafter#2%
\expandafter\expandafter\expandafter{%
- \expandafter\@secondoffive#2}}% <----------- five
+ \expandafter\@secondoffive#2}}% <----------- five
% \end{macrocode}
% We also need to redefine the internal label commands of cleveref.
-% This must be done after \pkg{cleveref} has made its changes
-% in \texttt{begindocument} so we add it to the same hook using
-% the hook label used by \pkg{cleveref}.
+% This must be done after \pkg{cleveref} has made its changes
+% in \texttt{begindocument} so we add it to the same hook using
+% the hook label used by \pkg{cleveref}.
% This way it is guaranteed to overwrite the definitions.
% \begin{macrocode}
\AddToHook{begindocument}[cleveref]{%
@@ -716,11 +716,68 @@
{\string\newlabel{#2@cref}{{\cref@currentlabel}%
{[\@tempb][\arabic{page}][\cref@result]\thepage}{}{}{}}}% <------- five
\@esphack}%
- }
+ }
+% \end{macrocode}
+% \changes{v1.1g}{2024/10/16}{update cleveref data in label hook}
+% \changes{v1.1i}{2024/11/08}{add expandafter, issue \#1544}
+% cleveref patches and redefines \cs{refstepcounter} so that a call updates its data.
+% This fails if like e.g. in \pkg{longtable} the counter is stepped with
+% \cs{@kernel@refstepcounter}. We therefore move the data setup into the label hook.
+% As the hook is in a group we have to smuggle the data out of it.
+% \url{https://tex.stackexchange.com/a/722909/2388} and issue \#1393
+% \begin{macrocode}
+ \newcommand\firstaid@cref@smugglelabel{\let\cref@currentlabel\cref@gcurrentlabel@temp}
+ \newcommand\firstaid@cref@updatelabeldata[1]{%
+ \cref@constructprefix{#1}{\cref@result}%
+ \@ifundefined{cref@#1@alias}%
+ {\def\@tempa{#1}}%
+ {\def\@tempa{\csname cref@#1@alias\endcsname}}%
+ \protected@xdef\cref@gcurrentlabel@temp{%
+ [\@tempa][\arabic{#1}][\cref@result]%
+ \csname p@#1\expandafter\endcsname\csname the#1\endcsname}%
+ \aftergroup\firstaid@cref@smugglelabel
+ }
+% \end{macrocode}
+% we test if \cs{@currentcounter} is empty for unnumbered sections
+% \changes{v1.1h}{2024/11/01}{fix spurious space}
+% \changes{v1.1j}{2024/11/24}{add \cs{iftag@} test, issue \#1560}
+% \begin{macrocode}
+ \newif\iftag@
+ \AddToHook{label}[firstaid/cleveref]
+ {\ifx
+ \@currentcounter\@empty
+ \else
+ \iftag@\else
+ \firstaid@cref@updatelabeldata{\@currentcounter}%
+ \fi
+ \fi}
}%
}
% \end{macrocode}
%
+% \subsection{The \pkg{arydshln} package first aid}
+%
+% Making two internal commands robust to avoid expansion while constructing the array preamble.
+% \begin{macrocode}
+\AddToHook{package/arydshln/after}[firstaid]{%
+ \FirstAidNeededT{arydshln}{sty}{2019/02/21 v1.76 }
+ {%
+% add \protected
+\protected\def\adl@@vlineL#1#2#3#4{\adl@ivline#4\@nil{#1}{#2}%
+ \xdef\adl@colsL{\adl@colsL
+ \@elt{#3}{\number\@tempcnta}{\number\@tempcntb}%
+ {\adl@dashcolor}{\adl@gapcolor}}}%
+\protected\def\adl@@vlineR#1#2#3#4{\adl@ivline#4\@nil{#1}{#2}%
+ \xdef\adl@colsR{%
+ \@elt{#3}{\number\@tempcnta}{\number\@tempcntb}%
+ {\adl@dashcolor}{\adl@gapcolor}%
+ \adl@colsR}}%
+\let\adl@act@@vlineL\adl@@vlineL
+\let\adl@act@@vlineR\adl@@vlineR
+ }%
+}
+% \end{macrocode}
+%
% \begin{macrocode}
%</kernel>
% \end{macrocode}
diff --git a/macros/latex-dev/required/firstaid/latex2e-first-aid-for-external-files.pdf b/macros/latex-dev/required/firstaid/latex2e-first-aid-for-external-files.pdf
index 672d8f4fe0..9c59f5f868 100644
--- a/macros/latex-dev/required/firstaid/latex2e-first-aid-for-external-files.pdf
+++ b/macros/latex-dev/required/firstaid/latex2e-first-aid-for-external-files.pdf
Binary files differ
diff --git a/macros/latex-dev/required/graphics/README.md b/macros/latex-dev/required/graphics/README.md
index b622f8fbfd..0160491bb9 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 2024-11-01 pre-release 0
+Release 2025-06-01 pre-release 0
Overview
--------
diff --git a/macros/latex-dev/required/graphics/changes.txt b/macros/latex-dev/required/graphics/changes.txt
index face90b342..d437358079 100644
--- a/macros/latex-dev/required/graphics/changes.txt
+++ b/macros/latex-dev/required/graphics/changes.txt
@@ -9,7 +9,16 @@ All changes above are only part of the development branch for the next release.
================================================================================
#########################
-# 2023-11-01 Release
+# 2024-11-01 Release
+#########################
+
+2024-06-24 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+
+ * color.dtx (section{Extra Groups}):
+ Support new @endpe mechanism
+
+#########################
+# 2024-06-01 Release
#########################
2024-05-23 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
diff --git a/macros/latex-dev/required/graphics/color.dtx b/macros/latex-dev/required/graphics/color.dtx
index 130a960d09..b14c148f2f 100644
--- a/macros/latex-dev/required/graphics/color.dtx
+++ b/macros/latex-dev/required/graphics/color.dtx
@@ -21,7 +21,7 @@
%<driver> \ProvidesFile{color.drv}
% \fi
% \ProvidesFile{color.dtx}
- [2024/01/14 v1.3d Standard LaTeX Color (DPC)]
+ [2024/06/23 v1.3e Standard LaTeX Color (DPC)]
%
% \iffalse
%<*driver>
@@ -877,10 +877,15 @@
% commands. The |\endgraf| in its definition is required in the case
% of groups of text in vertical `par' mode, but doesn't do any harm in
% horizontal `LR' contexts.
+% The |\@endpefalse| is required for the newer \texttt{@endpe}
+% handling, again it is harmless if an older kernel is used
+% (because there it was a local assignment).
% \changes{v0.2d}{1994/05/13}
% {New definition, was previously just \cs{endgroup}}
+% \changes{v1.3e}{2024/06/23}
+% {Support new \texttt{@endpe} mechanism}
% \begin{macrocode}
-\def\color@endgroup{\endgraf\endgroup}
+\def\color@endgroup{\endgraf\@endpefalse\endgroup}
% \end{macrocode}
% \end{macro}
%
diff --git a/macros/latex-dev/required/graphics/color.pdf b/macros/latex-dev/required/graphics/color.pdf
index 964aa7edbd..081cfb5463 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.pdf b/macros/latex-dev/required/graphics/drivers.pdf
index b010839e78..03dc4fc6b4 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.pdf b/macros/latex-dev/required/graphics/epsfig.pdf
index 36457b3559..16b8cc6bdc 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.dtx b/macros/latex-dev/required/graphics/graphics.dtx
index 2392ac09d1..86556ea40a 100644
--- a/macros/latex-dev/required/graphics/graphics.dtx
+++ b/macros/latex-dev/required/graphics/graphics.dtx
@@ -27,7 +27,7 @@
%<driver> \ProvidesFile{graphics.drv}
% \fi
% \ProvidesFile{graphics.dtx}
- [2024/05/23 v1.4g Standard LaTeX Graphics (DPC,SPQR)]
+ [2024/08/06 v1.4g Standard LaTeX Graphics (DPC,SPQR)]
%
% \iffalse
%<*driver>
@@ -1050,7 +1050,8 @@
%
% \begin{macrocode}
\edef\Gin@gzext{\detokenize{gz}}
-% \edef{macrocode}
+% \end{macrocode}
+% \end{macro}
% \end{macro}
%
% \begin{macro}{\Gin@set@curr@file}
diff --git a/macros/latex-dev/required/graphics/graphics.pdf b/macros/latex-dev/required/graphics/graphics.pdf
index 559f3c5a81..24df86ee4e 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.pdf b/macros/latex-dev/required/graphics/graphicx.pdf
index d1568333c2..bdd0c30cca 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 4e68cea91e..8a060397b6 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/keyval.pdf b/macros/latex-dev/required/graphics/keyval.pdf
index 1cfd06071d..ac7d5d5f67 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.pdf b/macros/latex-dev/required/graphics/lscape.pdf
index b3ffd8c2cd..9a3b2f72d8 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/mathcolor.pdf b/macros/latex-dev/required/graphics/mathcolor.pdf
index 36905fbf31..6f843714d6 100644
--- a/macros/latex-dev/required/graphics/mathcolor.pdf
+++ b/macros/latex-dev/required/graphics/mathcolor.pdf
Binary files differ
diff --git a/macros/latex-dev/required/graphics/rotating.pdf b/macros/latex-dev/required/graphics/rotating.pdf
index 2ecb86346a..9d45e0a40c 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 251dcd20b1..b2b66d505e 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.pdf b/macros/latex-dev/required/graphics/trig.pdf
index d220e18d1e..9edb838d90 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/l3kernel/CHANGELOG.md b/macros/latex-dev/required/l3kernel/CHANGELOG.md
index c58c1a6188..3778678162 100644
--- a/macros/latex-dev/required/l3kernel/CHANGELOG.md
+++ b/macros/latex-dev/required/l3kernel/CHANGELOG.md
@@ -7,6 +7,110 @@ this project uses date-based 'snapshot' version identifiers.
## [Unreleased]
+## [2025-01-18]
+
+### Changed
+- Use a dedicated internal marker for `fp` and `int` expressions, allowing use
+ with LuaMetaTeX (see \#1518)
+
+### Fixed
+- Missing trailing period in `\tl_analysis_log:(N|n)` output (see \#1663)
+- Some state variables weren't correctly reset by `\keys_define:nn` and
+ `\keys_set:nn` breaking some nested usages in edge cases
+
+## [2025-01-14]
+
+### Added
+- `\int_step_tokens:nn`, `\int_step_tokens:nnn`, and `\int_step_tokens:nnnn`
+
+### Fixed
+- Check conditionals are defined when creating variants (see \#1189)
+
+## [2024-12-25]
+
+### Added
+- `\file_forget:n`
+
+### Changed
+- Expand 'value(s)' arg. to `\color_select:nn`, `\color_set:nnn`, etc. (see
+ \#1640)
+
+### Fixed
+- Initialize color `.` properly (see \#1642)
+
+## [2024-12-09]
+
+### Added
+- `\bitset_use:N` and `\clist_use:N`: this clarifies that bitsets and clists
+ can be used with `V`-type expansion
+- `\sys_if_engine_opentype:(TF)`
+- Add equivalent interfaces for regex functions:
+ - `\int_(g)set_regex_count:Nnn`, `\int_(g)set_regex_count:NNn`
+ - `\seq_(g)set_regex_extract_once:Nnn`, `\seq_(g)set_regex_extract_once:NNn`
+ - `\seq_(g)set_regex_extract_all:Nnn`, `\seq_(g)set_regex_extract_all:NNn`
+ - `\seq_(g)set_regex_split:Nnn`, `\seq_(g)set_regex_split:NNn`
+ - `\tl_if_regex_match:nn(TF)`, `\tl_if_regex_match:nN(TF)`
+ - `\tl_regex_(g)replace_once:Nnn`, `\tl_regex_(g)replace_once:NNn`
+ - `\tl_regex_(g)replace_all:Nnn`, `\tl_regex_(g)replace_all:NNn`
+
+### Fixed
+- `\prop_item:Nn` result not returned in `\exp_not:n` for linked properties
+ (see \#1630)
+
+### Removed
+- `\c_catcode_active_tl`: was missing a `_`, always intended to be internal
+
+## [2024-11-02]
+
+### Added
+- `V`-type variant for all `\<var>_set:Nn` functions
+
+### Fixed
+- Error detection in coffin code (see \#1580)
+
+## [2024-10-09]
+
+### Added
+- `\coffin_ht_plus_dp:(N|c)`
+
+### Fixed
+- Use TU-encoding with lualatex and xelatex in `l3doc`
+- Inconsistent local/global assignments in `l3doc` (see \#1593)
+
+## [2024-09-10]
+
+### Changed
+- Increase outdent of long function names in `l3doc` (issue \#1585)
+
+### Fixed
+- `\seq_map_pairwise_function:NNN` not work with `\seq_map_break:(n)` (issue \#1587)
+
+## [2024-08-30]
+
+### Changed
+- Reduce memory usage when building Unicode data storage
+- Avoid recursive doc for `\file_if_exist:n(TF)` (issue \#1573)
+
+### Fixed
+- Handling of `ltcmd` newlines (`\obeyedline`) in `l3doc` (issue \#1577)
+
+## [2024-08-16]
+
+### Added
+- Add quark (`\q_`) and scan mark (`\s_`) prefixes to naming scheme
+ (issue \#1565)
+
+## [2024-07-20]
+
+### Fixed
+- Implementation of deprecated `\tl_mixed_case:n(n)`
+- Redo the fix for LaTeX2e key properties (issue latex3/latex2e\#1415)
+
+## [2024-06-19]
+
+### Fixed
+- Avoid a low-level error when LaTeX2e key properties are given without a value
+
## [2024-05-27]
### Added
@@ -324,6 +428,7 @@ this project uses date-based 'snapshot' version identifiers.
- `\file_input_raw:n`
- `\int_if_zero:n(TF)`
- `\str_mdfive_hash:n`
+
### Changed
- Remove `\noexpand` inside math mode in `\text_expand:n`
- Re-implement `\dim_to_decimal_in_bp:n` and
@@ -476,14 +581,14 @@ this project uses date-based 'snapshot' version identifiers.
### Added
- Complete list of pdfTeX primitives
+### Changed
+- Leave catcode of `&` unchanged in code environment
+
### Fixed
- Allow for multi-part BCP47 strings in case changing
- Loading with plain TeX due to `\outer` status of `^^L`
issue ([\#1161](https://github.com/latex3/latex3/issues/1161))
-### Changed
-- Leave catcode of `&` unchanged in code environment
-
## [2023-01-16]
### Added
@@ -573,9 +678,8 @@ this project uses date-based 'snapshot' version identifiers.
### Changed
- Replace `LaTeX3` in message text by `LaTeX`
-
-### Changed
- Approach to setting current color data from LaTeX2e
+
## [2022-08-05]
### Added
@@ -1112,7 +1216,7 @@ this project uses date-based 'snapshot' version identifiers.
also *expandable*
### Fixed
-- Make `expl3` reload-safe for `latexrelease` (see latex3/latex2e#295)
+- Make `expl3` reload-safe for `latexrelease` (see latex3/latex2e\#295)
## [2020-02-25]
@@ -1742,7 +1846,18 @@ this project uses date-based 'snapshot' version identifiers.
- Step functions have been added for dim variables,
e.g. `\dim_step_inline:nnnn`
-[Unreleased]: https://github.com/latex3/latex3/compare/2024-05-27...HEAD
+[Unreleased]: https://github.com/latex3/latex3/compare/2025-01-18...HEAD
+[2025-01-18]: https://github.com/latex3/latex3/compare/2025-01-14...2025-01-18
+[2025-01-14]: https://github.com/latex3/latex3/compare/2024-12-25...2025-01-14
+[2024-12-25]: https://github.com/latex3/latex3/compare/2024-12-09...2024-12-25
+[2024-12-09]: https://github.com/latex3/latex3/compare/2024-11-02...2024-12-09
+[2024-11-02]: https://github.com/latex3/latex3/compare/2024-10-09...2024-11-02
+[2024-10-09]: https://github.com/latex3/latex3/compare/2024-09-10...2024-10-09
+[2024-09-10]: https://github.com/latex3/latex3/compare/2024-08-30...2024-09-10
+[2024-08-30]: https://github.com/latex3/latex3/compare/2024-08-16...2024-08-30
+[2024-08-16]: https://github.com/latex3/latex3/compare/2024-07-20...2024-08-16
+[2024-07-20]: https://github.com/latex3/latex3/compare/2024-06-19...2024-07-20
+[2024-06-19]: https://github.com/latex3/latex3/compare/2024-05-27...2024-06-19
[2024-05-27]: https://github.com/latex3/latex3/compare/2024-05-08...2024-05-27
[2024-05-08]: https://github.com/latex3/latex3/compare/2024-04-11...2024-05-08
[2024-04-11]: https://github.com/latex3/latex3/compare/2024-03-14...2024-04-11
diff --git a/macros/latex-dev/required/l3kernel/README.md b/macros/latex-dev/required/l3kernel/README.md
index 8946af1293..db98f70515 100644
--- a/macros/latex-dev/required/l3kernel/README.md
+++ b/macros/latex-dev/required/l3kernel/README.md
@@ -1,7 +1,7 @@
LaTeX3 Programming Conventions
==============================
-Release 2024-05-27
+Release 2025-01-18
Overview
--------
@@ -91,6 +91,6 @@ by e-mail: <latex-team@latex-project.org>.
-----
-<p>Copyright (C) 1998-2012,2015-2024 The LaTeX Project <br />
+<p>Copyright (C) 1998-2012,2015-2025 The LaTeX Project <br />
<a href="http://latex-project.org/">http://latex-project.org/</a> <br />
All rights reserved.</p>
diff --git a/macros/latex-dev/required/l3kernel/expl3.dtx b/macros/latex-dev/required/l3kernel/expl3.dtx
index 4b4e61d3c8..f84b346c05 100644
--- a/macros/latex-dev/required/l3kernel/expl3.dtx
+++ b/macros/latex-dev/required/l3kernel/expl3.dtx
@@ -2,7 +2,7 @@
%
%% File: expl3.dtx
%
-% Copyright (C) 1990-2024 The LaTeX Project
+% Copyright (C) 1990-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -24,7 +24,7 @@
%
%<*driver|generic|package|2ekernel>
%</driver|generic|package|2ekernel>
-\def\ExplFileDate{2024-05-27}%
+\def\ExplFileDate{2025-01-18}%
%<*driver>
\documentclass[full]{l3doc}
\usepackage{graphicx}
@@ -51,7 +51,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -454,6 +454,15 @@
% implementation in \LaTeX3 means that |toks| are not required, and that
% all operations for storing tokens can use the |tl| variable type.
%
+% There are two more special types of constants:
+% \begin{arg-description}
+% \item[q] constants of quark type;
+% \item[s] constants of scan mark type.
+% \end{arg-description}
+% The \meta{type} part of quark and scan mark constants is omitted, and
+% the \meta{module} part of general quarks and scan marks is often
+% omitted too.
+%
% Experienced \TeX{} programmers will notice that some of the variable
% types listed are native \TeX{} registers whilst others are not. In
% general, the underlying \TeX{} implementation for a data structure may
diff --git a/macros/latex-dev/required/l3kernel/expl3.pdf b/macros/latex-dev/required/l3kernel/expl3.pdf
index 7210fd3321..3d6a6263c1 100644
--- a/macros/latex-dev/required/l3kernel/expl3.pdf
+++ b/macros/latex-dev/required/l3kernel/expl3.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/interface3.pdf b/macros/latex-dev/required/l3kernel/interface3.pdf
index 69e5f39bc6..95e823a6bf 100644
--- a/macros/latex-dev/required/l3kernel/interface3.pdf
+++ b/macros/latex-dev/required/l3kernel/interface3.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/interface3.tex b/macros/latex-dev/required/l3kernel/interface3.tex
index 62501cfa53..f13ec99d5f 100644
--- a/macros/latex-dev/required/l3kernel/interface3.tex
+++ b/macros/latex-dev/required/l3kernel/interface3.tex
@@ -2,7 +2,7 @@
File: interface3.tex
-Copyright (C) 1990-2011,2017-2024 The LaTeX Project
+Copyright (C) 1990-2011,2017-2025 The LaTeX Project
It may be distributed and/or modified under the conditions of the
LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -58,7 +58,7 @@ for those people who are interested.
{latex-team@latex-project.org}%
}%
}
-\date{Released 2024-05-27}
+\date{Released 2025-01-18}
\pagenumbering{roman}
\maketitle
diff --git a/macros/latex-dev/required/l3kernel/l3.ins b/macros/latex-dev/required/l3kernel/l3.ins
index bf7a75381d..eafa8dcc33 100644
--- a/macros/latex-dev/required/l3kernel/l3.ins
+++ b/macros/latex-dev/required/l3kernel/l3.ins
@@ -2,7 +2,7 @@
File l3.ins
-Copyright (C) 2011,2012,2014-2024 The LaTeX Project
+Copyright (C) 2011,2012,2014-2025 The LaTeX Project
It may be distributed and/or modified under the conditions of the
LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -35,7 +35,7 @@ license information is placed in the derived files.
\preamble
-Copyright (C) 1990-2024 The LaTeX Project
+Copyright (C) 1990-2025 The LaTeX Project
It may be distributed and/or modified under the conditions of
the LaTeX Project Public License (LPPL), either version 1.3c of
@@ -156,7 +156,7 @@ and all files in that bundle must be distributed together.
\def\MetaPrefix{--}
\preamble
-Copyright (C) 1990-2024 The LaTeX Project
+Copyright (C) 1990-2025 The LaTeX Project
It may be distributed and/or modified under the conditions of
the LaTeX Project Public License (LPPL), either version 1.3c of
diff --git a/macros/latex-dev/required/l3kernel/l3basics.dtx b/macros/latex-dev/required/l3kernel/l3basics.dtx
index 69e4441580..552ead9f5a 100644
--- a/macros/latex-dev/required/l3kernel/l3basics.dtx
+++ b/macros/latex-dev/required/l3kernel/l3basics.dtx
@@ -2,7 +2,7 @@
%
%% File: l3basics.dtx
%
-% Copyright (C) 1990-2024 The LaTeX Project
+% Copyright (C) 1990-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -1151,10 +1151,9 @@
% argument (a single token denoted by |N|) is still free for definition.
% It would be used in constructions like
% \begin{quote}
-% |\bool_if:nTF {| \\
-% \verb" \cs_if_free_p:N \l_tmpz_tl || \cs_if_free_p:N \g_tmpz_tl " \\
-% |}|
-% \Arg{true code} \Arg{false code}
+% "\bool_if:nTF" \\
+% " { \cs_if_free_p:N \l_tmpz_tl || \cs_if_free_p:N \g_tmpz_tl }" \\
+% " "\Arg{true code} \Arg{false code}
% \end{quote}
%
% For each predicate defined, a \enquote{branching conditional}
@@ -1171,7 +1170,7 @@
%
% \subsection{Tests on control sequences}
%
-% \begin{function}[EXP,pTF]{\cs_if_eq:NN}
+% \begin{function}[EXP,pTF]{\cs_if_eq:NN, \cs_if_eq:Nc, \cs_if_eq:cN, \cs_if_eq:cc}
% \begin{syntax}
% \cs{cs_if_eq_p:NN} \meta{cs_1} \meta{cs_2}
% \cs{cs_if_eq:NNTF} \meta{cs_1} \meta{cs_2} \Arg{true code} \Arg{false code}
@@ -1187,9 +1186,10 @@
% \cs{cs_if_exist:NTF} \meta{control sequence} \Arg{true code} \Arg{false code}
% \end{syntax}
% Tests whether the \meta{control sequence} is currently defined
-% (whether as a function or another control sequence type). Any
-% definition of \meta{control sequence} other than \tn{relax}
-% evaluates as \texttt{true}.
+% (whether as a function or another control sequence type),
+% and its meaning is not the primitive \tn{relax} token.
+% This is different from \cs{if_cs_exist:N}, which evaluates to
+% \texttt{true} if passed the token \tn{relax} as an argument.
% \end{function}
%
% \begin{function}[EXP,pTF]{\cs_if_free:N, \cs_if_free:c}
@@ -1197,10 +1197,7 @@
% \cs{cs_if_free_p:N} \meta{control sequence}
% \cs{cs_if_free:NTF} \meta{control sequence} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests whether the \meta{control sequence} is currently free to
-% be defined. This test is \texttt{false} if the
-% \meta{control sequence} currently exists (as defined by
-% \cs{cs_if_exist:NTF}).
+% This test is the negation of the above \cs{cs_if_exist:NTF}.
% \end{function}
%
% \subsection{Primitive conditionals}
@@ -1282,7 +1279,7 @@
% Check if <cs> appears in the hash table or if the control sequence
% that can be formed from <tokens> appears in the hash table. The
% latter function does not turn the control sequence in question into
-% "\scan_stop:"! This can be useful when dealing with control
+% the primitive \tn{relax} token. This can be useful when dealing with control
% sequences which cannot be entered as a single token.
% \begin{texnote}
% These are the \TeX{} primitives \tn{ifdefined} and \tn{ifcsname}.
@@ -1327,8 +1324,8 @@
%
% \begin{function}[added = 2017-07-16, updated = 2023-05-23]{\debug_on:n, \debug_off:n}
% \begin{syntax}
-% \cs{debug_on:n} |{| \meta{comma-separated list} |}|
-% \cs{debug_off:n} |{| \meta{comma-separated list} |}|
+% \cs{debug_on:n} \Arg{comma-separated list}
+% \cs{debug_off:n} \Arg{comma-separated list}
% \end{syntax}
% Turn on and off within a group various debugging code, some of which
% is also available as \pkg{expl3} load-time options. The items that
@@ -2458,7 +2455,7 @@
%
% \subsection{Exist or free}
%
-% A control sequence is said to \emph{exist} (to be used) if has an entry in
+% A control sequence is said to \emph{exist} (to be used) if it has an entry in
% the hash table and its meaning is different from the primitive
% \tn{relax} token. A control sequence is said to be \emph{free}
% (to be defined) if it does not already exist.
diff --git a/macros/latex-dev/required/l3kernel/l3bitset.dtx b/macros/latex-dev/required/l3kernel/l3bitset.dtx
index 4559b56fd3..16a0fd7aac 100644
--- a/macros/latex-dev/required/l3kernel/l3bitset.dtx
+++ b/macros/latex-dev/required/l3kernel/l3bitset.dtx
@@ -2,7 +2,7 @@
%
%% File: l3bitset.dtx
%
-% Copyright (C) 2020-2024 The LaTeX Project
+% Copyright (C) 2020-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -42,7 +42,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -240,6 +240,16 @@
% implementation based on \cs{fp_eval:n} otherwise.
% \end{function}
%
+% \begin{function}[EXP, added = 2024-11-12]{\bitset_use:N, \bitset_use:c}
+% \begin{syntax}
+% \cs{bitset_use:N} \meta{bitset var}
+% \end{syntax}
+% This leaves the current value of the bitset expressed as
+% a binary (string) number in the input stream.
+% If no bit has been set yet, the output is zero. This is
+% functionally equivalent to \cs{bitset_to_bin:N}.
+% \end{function}
+%
% \begin{function}[added = 2023-11-15]
% {\bitset_show:N, \bitset_show:c}
% \begin{syntax}
@@ -524,6 +534,13 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\bitset_use:N, \bitset_use:c}
+% \begin{macrocode}
+\cs_new_eq:NN \bitset_use:N \tl_use:N
+\cs_generate_variant:Nn \bitset_use:N { c }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}
% {
% \bitset_item:Nn, \bitset_item:cn
diff --git a/macros/latex-dev/required/l3kernel/l3bootstrap.dtx b/macros/latex-dev/required/l3kernel/l3bootstrap.dtx
index 861f0bb5a6..a1b36c6074 100644
--- a/macros/latex-dev/required/l3kernel/l3bootstrap.dtx
+++ b/macros/latex-dev/required/l3kernel/l3bootstrap.dtx
@@ -2,7 +2,7 @@
%
%% File: l3bootstrap.dtx
%
-% Copyright (C) 2011-2024 The LaTeX Project
+% Copyright (C) 2011-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -70,14 +70,14 @@
% \cs{ExplSyntaxOn} \meta{code} \cs{ExplSyntaxOff}
% \end{syntax}
% The \cs{ExplSyntaxOn} function switches to a category code
-% regime in which spaces and new lines are ignored, and in which the colon (|:|)
+% régime in which spaces and new lines are ignored, and in which the colon (|:|)
% and underscore (|_|) are treated as \enquote{letters}, thus allowing
% access to the names of code functions and variables. Within this
% environment, |~| is used to input a space. The \cs{ExplSyntaxOff}
-% reverts to the document category code regime.
+% reverts to the document category code régime.
% \begin{texnote}
% Spaces introduced by~|~| behave much in the same way as normal
-% space characters in the standard category code regime: they are
+% space characters in the standard category code régime: they are
% ignored after a control word or at the start of a line, and
% multiple consecutive~|~| are equivalent to a single one. However,
% |~|~is \emph{not} ignored at the end of a line.
diff --git a/macros/latex-dev/required/l3kernel/l3box.dtx b/macros/latex-dev/required/l3kernel/l3box.dtx
index 808d22da23..136af6afc0 100644
--- a/macros/latex-dev/required/l3kernel/l3box.dtx
+++ b/macros/latex-dev/required/l3kernel/l3box.dtx
@@ -2,7 +2,7 @@
%
%% File: l3box.dtx
%
-% Copyright (C) 2005-2024 The LaTeX Project
+% Copyright (C) 2005-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -906,9 +906,9 @@
% \begin{syntax}
% \cs{box_set_trim:Nnnnn} \meta{box} \Arg{left} \Arg{bottom} \Arg{right} \Arg{top}
% \end{syntax}
-% Adjusts the bounding box of the \meta{box} \meta{left} is removed from
+% Adjusts the bounding box of the \meta{box}: \meta{left} is removed from
% the left-hand edge of the bounding box, \meta{right} from the right-hand
-% edge and so fourth. All adjustments are \meta{dim exprs}.
+% edge, and so forth. All adjustments are \meta{dim exprs}.
% Material outside of the bounding box is still displayed in the output
% unless \cs{box_set_clipped:N} is subsequently applied.
% The updated \meta{box} is an
diff --git a/macros/latex-dev/required/l3kernel/l3cctab.dtx b/macros/latex-dev/required/l3kernel/l3cctab.dtx
index 4bf8db41a6..012c0489e6 100644
--- a/macros/latex-dev/required/l3kernel/l3cctab.dtx
+++ b/macros/latex-dev/required/l3kernel/l3cctab.dtx
@@ -2,7 +2,7 @@
%
%% File: l3cctab.dtx
%
-% Copyright (C) 2018-2024 The LaTeX Project
+% Copyright (C) 2018-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -117,7 +117,7 @@
% Ends the scope of a \meta{category code table} started using
% \cs{cctab_begin:N}, returning the codes to those in force before the
% matching \cs{cctab_begin:N} was used. This must be used within the
-% same \TeX{} group (and at the same \TeX{} group level) as the
+% same \TeX{} group and at the same \TeX{} group level as the
% matching \cs{cctab_begin:N}.
% \end{function}
%
@@ -866,8 +866,7 @@
\group_begin:
\int_set:Nn \tex_endlinechar:D { 32 }
\char_set_catcode_invalid:n { 0 }
- \bool_lazy_or:nnTF
- { \sys_if_engine_xetex_p: } { \sys_if_engine_luatex_p: }
+ \sys_if_engine_opentype:TF
{ \int_step_function:nN { 31 } \char_set_catcode_invalid:n }
{ \int_step_function:nN { 31 } \char_set_catcode_active:n }
\int_step_function:nnN { 33 } { 64 } \char_set_catcode_other:n
@@ -892,8 +891,7 @@
\char_set_catcode_group_end:n { 125 } % right brace
\char_set_catcode_space:n { 126 } % tilde
\char_set_catcode_invalid:n { 127 } % ^^?
- \bool_lazy_or:nnF
- { \sys_if_engine_xetex_p: } { \sys_if_engine_luatex_p: }
+ \sys_if_engine_opentype:F
{ \int_step_function:nnN { 128 } { 255 } \char_set_catcode_active:n }
\@@_gset:n { \c_code_cctab }
\group_end:
diff --git a/macros/latex-dev/required/l3kernel/l3clist.dtx b/macros/latex-dev/required/l3kernel/l3clist.dtx
index 5adb01cffb..0e1666076d 100644
--- a/macros/latex-dev/required/l3kernel/l3clist.dtx
+++ b/macros/latex-dev/required/l3kernel/l3clist.dtx
@@ -3,7 +3,7 @@
%% File: l3clist.dtx
%
% Copyright (C) 2004-2011 Frank Mittelbach, The LaTeX Project
-% (C) 2012-2024 The LaTeX Project
+% (C) 2012-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -324,8 +324,10 @@
% {
% \clist_remove_all:Nn, \clist_remove_all:cn,
% \clist_remove_all:NV, \clist_remove_all:cV,
+% \clist_remove_all:Ne, \clist_remove_all:ce,
% \clist_gremove_all:Nn, \clist_gremove_all:cn,
-% \clist_gremove_all:NV, \clist_gremove_all:cV
+% \clist_gremove_all:NV, \clist_gremove_all:cV,
+% \clist_gremove_all:Ne, \clist_gremove_all:ce
% }
% \begin{syntax}
% \cs{clist_remove_all:Nn} \meta{clist~var} \Arg{item}
@@ -350,7 +352,7 @@
% Reverses the order of items stored in the \meta{clist~var}.
% \end{function}
%
-% \begin{function}[added = 2014-07-18]{\clist_reverse:n}
+% \begin{function}[added = 2014-07-18, EXP]{\clist_reverse:n}
% \begin{syntax}
% \cs{clist_reverse:n} \Arg{comma list}
% \end{syntax}
@@ -391,7 +393,7 @@
% \cs{clist_if_empty_p:n} \Arg{comma list}
% \cs{clist_if_empty:nTF} \Arg{comma list} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if the \meta{clist~var} is empty (containing no items).
+% Tests if the \meta{comma~list} is empty (containing no items).
% The rules for space trimming are as for other \texttt{n}-type
% comma-list functions, hence the comma list |{~,~,,~}| (without
% outer braces) is empty, while |{~,{},}| (without outer braces)
@@ -562,7 +564,8 @@
%
% \begin{function}[EXP, added = 2013-05-26]{\clist_use:Nnnn, \clist_use:cnnn}
% \begin{syntax}
-% \cs{clist_use:Nnnn} \meta{clist~var} \Arg{separator~between~two} \Arg{separator~between~more~than~two} \Arg{separator~between~final~two}
+% \cs{clist_use:Nnnn} \meta{clist~var} \Arg{separator~between~two} \\
+% ~~\Arg{separator~between~more~than~two} \Arg{separator~between~final~two}
% \end{syntax}
% Places the contents of the \meta{clist~var} in the input stream,
% with the appropriate \meta{separator} between the items. Namely, if
@@ -616,10 +619,27 @@
% \end{texnote}
% \end{function}
%
+% \begin{function}[EXP, added = 2024-11-12]{\clist_use:N, \clist_use:c}
+% \begin{syntax}
+% \cs{clist_use:N} \meta{clist~var}
+% \end{syntax}
+% Places the contents of the \meta{clist~var} in the input stream,
+% with a comma between each item. The result is exaclty the stored
+% \meta{clist}, which will include braces around (for example)
+% entries with retained spaces at the ends.
+% \begin{texnote}
+% The result is returned as-is, in the same way as \cs{tl_use:N}
+% and \emph{without} protection from expansion,
+% cf.~\cs{clist_use:Nnnnn}, etc. It is equivalent to \texttt{V}-type
+% expansion of a \texttt{clist}.
+% \end{texnote}
+% \end{function}
+%
% \begin{function}[EXP, added = 2021-05-10]{\clist_use:nnnn, \clist_use:nn}
% \begin{syntax}
-% \cs{clist_use:nnnn} \meta{comma~list} \Arg{separator~between~two} \Arg{separator~between~more~than~two} \Arg{separator~between~final~two}
-% \cs{clist_use:nn} \meta{comma~list} \Arg{separator}
+% \cs{clist_use:nnnn} \Arg{comma~list} \Arg{separator~between~two} \\
+% ~~\Arg{separator~between~more~than~two} \Arg{separator~between~final~two}
+% \cs{clist_use:nn} \Arg{comma~list} \Arg{separator}
% \end{syntax}
% Places the contents of the \meta{comma~list} in the input stream,
% with the appropriate \meta{separator} between the items. As for
@@ -648,60 +668,60 @@
% \begin{function}[noTF, added = 2012-05-14, updated = 2019-02-16]
% {\clist_get:NN, \clist_get:cN}
% \begin{syntax}
-% \cs{clist_get:NN} \meta{clist~var} \meta{token list variable}
+% \cs{clist_get:NN} \meta{clist~var} \meta{tl~var}
% \end{syntax}
% Stores the left-most item from a \meta{clist~var} in the
-% \meta{token list variable} without removing it from the
-% \meta{clist~var}. The \meta{token list variable} is assigned locally.
+% \meta{tl~var} without removing it from the
+% \meta{clist~var}. The \meta{tl~var} is assigned locally.
% In the non-branching version, if the \meta{clist~var} is empty the
-% \meta{token list variable} is set to the marker value \cs{q_no_value}.
+% \meta{tl~var} is set to the marker value \cs{q_no_value}.
% \end{function}
%
% \begin{function}[updated = 2011-09-06]{\clist_pop:NN, \clist_pop:cN}
% \begin{syntax}
-% \cs{clist_pop:NN} \meta{clist~var} \meta{token list variable}
+% \cs{clist_pop:NN} \meta{clist~var} \meta{tl~var}
% \end{syntax}
% Pops the left-most item from a \meta{clist~var} into the
-% \meta{token list variable}, \emph{i.e.}~removes the item from the
-% comma list and stores it in the \meta{token list variable}.
+% \meta{tl~var}, \emph{i.e.}~removes the item from the
+% comma list and stores it in the \meta{tl~var}.
% Both of the variables are assigned locally.
% \end{function}
%
% \begin{function}{\clist_gpop:NN, \clist_gpop:cN}
% \begin{syntax}
-% \cs{clist_gpop:NN} \meta{clist~var} \meta{token list variable}
+% \cs{clist_gpop:NN} \meta{clist~var} \meta{tl~var}
% \end{syntax}
% Pops the left-most item from a \meta{clist~var} into the
-% \meta{token list variable}, \emph{i.e.}~removes the item from the
-% comma list and stores it in the \meta{token list variable}.
+% \meta{tl~var}, \emph{i.e.}~removes the item from the
+% comma list and stores it in the \meta{tl~var}.
% The \meta{clist~var} is modified globally, while the assignment of
-% the \meta{token list variable} is local.
+% the \meta{tl~var} is local.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-14]{\clist_pop:NN, \clist_pop:cN}
% \begin{syntax}
-% \cs{clist_pop:NNTF} \meta{clist~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{clist_pop:NNTF} \meta{clist~var} \meta{tl~var} \Arg{true code} \Arg{false code}
% \end{syntax}
% If the \meta{clist~var} is empty, leaves the \meta{false code} in the
-% input stream. The value of the \meta{token list variable} is
+% input stream. The value of the \meta{tl~var} is
% not defined in this case and should not be relied upon. If the
% \meta{clist~var} is non-empty, pops the top item from the
-% \meta{clist~var} in the \meta{token list variable}, \emph{i.e.}~removes
+% \meta{clist~var} in the \meta{tl~var}, \emph{i.e.}~removes
% the item from the \meta{clist~var}. Both the \meta{clist~var} and the
-% \meta{token list variable} are assigned locally.
+% \meta{tl~var} are assigned locally.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-14]{\clist_gpop:NN, \clist_gpop:cN}
% \begin{syntax}
-% \cs{clist_gpop:NNTF} \meta{clist~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{clist_gpop:NNTF} \meta{clist~var} \meta{tl~var} \Arg{true code} \Arg{false code}
% \end{syntax}
% If the \meta{clist~var} is empty, leaves the \meta{false code} in the
-% input stream. The value of the \meta{token list variable} is
+% input stream. The value of the \meta{tl~var} is
% not defined in this case and should not be relied upon. If the
% \meta{clist~var} is non-empty, pops the top item from the
-% \meta{clist~var} in the \meta{token list variable}, \emph{i.e.}~removes
+% \meta{clist~var} in the \meta{tl~var}, \emph{i.e.}~removes
% the item from the \meta{clist~var}. The \meta{clist~var} is modified
-% globally, while the \meta{token list variable} is assigned locally.
+% globally, while the \meta{tl~var} is assigned locally.
% \end{function}
%
% \begin{function}
@@ -1429,13 +1449,15 @@
% \begin{macro}
% {
% \clist_remove_all:Nn, \clist_remove_all:cn,
-% \clist_remove_all:NV, \clist_remove_all:cV
+% \clist_remove_all:NV, \clist_remove_all:cV,
+% \clist_remove_all:Ne, \clist_remove_all:ce
% }
% \UnitTested
% \begin{macro}
% {
% \clist_gremove_all:Nn, \clist_gremove_all:cn,
-% \clist_gremove_all:NV, \clist_gremove_all:cV
+% \clist_gremove_all:NV, \clist_gremove_all:cV,
+% \clist_gremove_all:Ne, \clist_gremove_all:ce
% }
% \UnitTested
% \begin{macro}{\@@_remove_all:NNNn}
@@ -1509,8 +1531,8 @@
\cs_new:Npn \@@_remove_all:
{ \exp_after:wN \@@_remove_all:w \@@_tmp:w , }
\cs_new:Npn \@@_remove_all:w #1 , \s_@@_mark , #2 , { \exp_not:n {#1} }
-\cs_generate_variant:Nn \clist_remove_all:Nn { c , NV , cV }
-\cs_generate_variant:Nn \clist_gremove_all:Nn { c , NV , cV }
+\cs_generate_variant:Nn \clist_remove_all:Nn { c , NV , cV , Ne , ce }
+\cs_generate_variant:Nn \clist_gremove_all:Nn { c , NV , cV , Ne , ce }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -2002,6 +2024,13 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\clist_use:N, \clist_use:c}
+% \begin{macrocode}
+\cs_new_eq:NN \clist_use:N \tl_use:N
+\cs_generate_variant:Nn \clist_use:N { c }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}
% {
% \clist_use:nnnn, \clist_use:nn, \@@_use:Nw,
diff --git a/macros/latex-dev/required/l3kernel/l3coffins.dtx b/macros/latex-dev/required/l3kernel/l3coffins.dtx
index 62dc5f92ad..2d1d86a75c 100644
--- a/macros/latex-dev/required/l3kernel/l3coffins.dtx
+++ b/macros/latex-dev/required/l3kernel/l3coffins.dtx
@@ -2,7 +2,7 @@
%
%% File: l3coffins.dtx
%
-% Copyright (C) 2010-2024 The LaTeX Project
+% Copyright (C) 2010-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -327,6 +327,14 @@
% in a form suitable for use in a \meta{dim expr}.
% \end{function}
%
+% \begin{function}[added = 2024-10-01]{\coffin_ht_plus_dp:N, \coffin_ht_plus_dp:c}
+% \begin{syntax}
+% \cs{coffin_ht_plus_dp:N} \meta{coffin}
+% \end{syntax}
+% Calculates the total vertical size (height plus depth) of the \meta{coffin}
+% in a form suitable for use in a \meta{dim expr}.
+% \end{function}
+%
% \begin{function}{\coffin_wd:N, \coffin_wd:c}
% \begin{syntax}
% \cs{coffin_wd:N} \meta{coffin}
@@ -866,7 +874,7 @@
% \begin{macrocode}
\cs_new_protected:Npn \coffin_set_eq:NN #1#2
{
- \@@_if_exist:NT #1
+ \@@_if_exist:NT #2
{
\box_set_eq:NN #1 #2
\prop_set_eq:cc { coffin ~ \@@_to_value:N #1 ~ corners }
@@ -878,7 +886,7 @@
\cs_generate_variant:Nn \coffin_set_eq:NN { c , Nc , cc }
\cs_new_protected:Npn \coffin_gset_eq:NN #1#2
{
- \@@_if_exist:NT #1
+ \@@_if_exist:NT #2
{
\box_gset_eq:NN #1 #2
\prop_gset_eq:cc { coffin ~ \@@_to_value:N #1 ~ corners }
@@ -924,7 +932,8 @@
% \begin{macro}
% {
% \coffin_dp:N, \coffin_dp:c, \coffin_ht:N, \coffin_ht:c,
-% \coffin_wd:N, \coffin_wd:c
+% \coffin_ht_plus_dp:N, \coffin_ht_plus_dp:c,
+% \coffin_wd:N, \coffin_wd:c,
% }
% Coffins are just boxes when it comes to measurement. However, semantically
% a separate set of functions are required.
@@ -933,6 +942,8 @@
\cs_new_eq:NN \coffin_dp:c \box_dp:c
\cs_new_eq:NN \coffin_ht:N \box_ht:N
\cs_new_eq:NN \coffin_ht:c \box_ht:c
+\cs_new_eq:NN \coffin_ht_plus_dp:N \box_ht_plus_dp:N
+\cs_new_eq:NN \coffin_ht_plus_dp:c \box_ht_plus_dp:c
\cs_new_eq:NN \coffin_wd:N \box_wd:N
\cs_new_eq:NN \coffin_wd:c \box_wd:c
% \end{macrocode}
diff --git a/macros/latex-dev/required/l3kernel/l3color.dtx b/macros/latex-dev/required/l3kernel/l3color.dtx
index b56fb9e0ac..bbfec94de4 100644
--- a/macros/latex-dev/required/l3kernel/l3color.dtx
+++ b/macros/latex-dev/required/l3kernel/l3color.dtx
@@ -2,7 +2,7 @@
%
%% File: l3color.dtx
%
-% Copyright (C) 2017-2024 The LaTeX Project
+% Copyright (C) 2017-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -103,7 +103,7 @@
% \begin{itemize}
% \item \texttt{Gray} Grayscale color, with a single axis running from
% $0$ (fully black) to $15$ (fully white)
-% \item \texttt{hsb} Hue-saturation-brightness color, with three axes,all
+% \item \texttt{hsb} Hue-saturation-brightness color, with three axes, all
% real values in the range $[0,1]$ for hue saturation and brightness
% \item \texttt{Hsb} Hue-saturation-brightness color, with three axes, integer
% in the range $[0,360]$ for hue, real values in the range $[0,1]$ for
@@ -142,7 +142,7 @@
% Section~\ref{l3color:sec:new-models} for more detail of color support
% for additional models.
%
-% When color is selected by model, the \meta{values} given are specified as
+% When color is selected by model, the \meta{value(s)} given are specified as
% a comma-separated list. The length of the list will therefore be determined
% by the detail of the model involved.
%
@@ -233,19 +233,20 @@
% color specification as the \meta{name}.
% \end{function}
%
-% \begin{function}{\color_set:nnn}
+% \begin{function}[updated = 2024-12-24]{\color_set:nnn}
% \begin{syntax}
% \cs{color_set:nnn} \Arg{name} \Arg{model(s)} \Arg{value(s)}
% \end{syntax}
% Stores the color specification equivalent to the \meta{model(s)} and
-% \meta{values} as the \meta{name}.
+% \meta{value(s)} as the \meta{name}. The \meta{value(s)} are expanded before
+% parsing.
% \end{function}
%
% \begin{function}{\color_set_eq:nn}
% \begin{syntax}
-% \cs{color_set_eq:nn} \Arg{name1} \Arg{name2}
+% \cs{color_set_eq:nn} \Arg{name_1} \Arg{name_2}
% \end{syntax}
-% Copies the color specification in \meta{name2} to \meta{name1}. The
+% Copies the color specification in \meta{name_2} to \meta{name_1}. The
% special name |.| may be used to represent the current color, allowing
% it to be saved to a name.
% \end{function}
@@ -276,7 +277,7 @@
% These commands set the current color (|.|): other more specialised functions
% such as fill and stroke selectors do \emph{not} adjust this value.
%
-% \begin{function}{\color_select:n}
+% \begin{function}[updated = 2024-12-24]{\color_select:n}
% \begin{syntax}
% \cs{color_select:n} \Arg{color expression}
% \end{syntax}
@@ -289,7 +290,8 @@
% \cs{color_select:nn} \Arg{model(s)} \Arg{value(s)}
% \end{syntax}
% Activates the color specification equivalent to the \meta{model(s)} and
-% \meta{value(s)} for typeset material.
+% \meta{value(s)} for typeset material. The \meta{value(s)} are fully
+% expanded before parsing.
% \end{function}
%
% \begin{variable}{\l_color_fixed_model_tl}
@@ -316,16 +318,17 @@
% color specification for filling or stroking.
% \end{function}
%
-% \begin{function}{\color_fill:nn, \color_stroke:nn}
+% \begin{function}[updated = 2024-12-24]{\color_fill:nn, \color_stroke:nn}
% \begin{syntax}
% \cs{color_fill:nn} \Arg{model(s)} \Arg{value(s)}
% \end{syntax}
% Activates the color specification equivalent to the \meta{model(s)} and
-% \meta{value(s)} for filling or stroking.
+% \meta{value(s)} for filling or stroking. The \meta{value(s)} are fully
+% expanded before parsing.
% \end{function}
%
% \begin{variable}[module = color]{color.sc}
-% When using \texttt{dvips}, this PostScript variables hold the stroke color.
+% When using \texttt{dvips}, this PostScript variable holds the stroke color.
% \end{variable}
%
% \subsection{Coloring math mode material}
@@ -336,13 +339,15 @@
% required needs careful handling. The functionality here covers this important
% use case.
%
-% \begin{function}[added = 2022-01-26]{\color_math:nn, \color_math:nnn}
+% \begin{function}[added = 2022-01-26, updated = 2024-12-24]
+% {\color_math:nn, \color_math:nnn}
% \begin{syntax}
-% \cs{color_math:nn} \Arg{color expression}\Arg{content}
+% \cs{color_math:nn} \Arg{color expression} \Arg{content}
% \cs{color_math:nnn} \Arg{model(s)} \Arg{value(s)} \Arg{content}
% \end{syntax}
% Works as for \cs[no-index]{color_select:n(n)} but applies color only to the math mode
-% \meta{content}. The function does not generate a group and the \meta{content}
+% \meta{content}. The \meta{value(s)} are fully expanded before parsing.
+% The function does not generate a group and the \meta{content}
% therefore retains its math atom states. Sub/superscripts are also properly
% handled.
% \end{function}
@@ -406,20 +411,21 @@
%
% \begin{function}{\color_export:nnN}
% \begin{syntax}
-% \cs{color_export:nnN} \Arg{color expression} \Arg{format} \Arg{tl}
+% \cs{color_export:nnN} \Arg{color expression} \Arg{format} \meta{tl var}
% \end{syntax}
% Parses the \meta{color expression} as described earlier,
% then converts to the \meta{format} specified and assigns the data to the
-% \meta{tl}.
+% \meta{tl var}.
% \end{function}
%
-% \begin{function}{\color_export:nnnN}
+% \begin{function}[updated = 2024-12-24]{\color_export:nnnN}
% \begin{syntax}
-% \cs{color_export:nnnN} \Arg{model} \Arg{value(s)} \Arg{format} \Arg{tl}
+% \cs{color_export:nnnN} \Arg{model} \Arg{value(s)} \Arg{format} \meta{tl var}
% \end{syntax}
% Expresses the combination of \meta{model} and \meta{value(s)} in an
% internal representation, then converts to the \meta{format} specified and
-% assigns the data to the \meta{tl}.
+% assigns the data to the \meta{tl var}. The \meta{value(s)} are fully
+% expanded before parsing.
% \end{function}
%
% \section{Creating new color models}
@@ -495,7 +501,7 @@
%
% Color profiles are used to ensure color accuracy by linking to collaboration.
% Applying a profile can be used to standardise color which is otherwise
-% device-dependence.
+% device-dependent.
%
% \begin{function}[added = 2021-02-23]{\color_profile_apply:nn}
% \begin{syntax}
@@ -697,14 +703,14 @@
% \begin{macro}{\@@_convert:nnnN, \@@_convert:nVnN, \@@_convert:nnVN}
% \begin{macro}[EXP]
% {
-% \@@_convert_gray_gray:w
-% \@@_convert_gray_rgb:w
-% \@@_convert_gray_cmyk:w
-% \@@_convert_cmyk_gray:w
-% \@@_convert_cmyk_rgb:w
-% \@@_convert_cmyk_cmyk:w
-% \@@_convert_rgb_gray:w
-% \@@_convert_rgb_rgb:w
+% \@@_convert_gray_gray:w,
+% \@@_convert_gray_rgb:w,
+% \@@_convert_gray_cmyk:w,
+% \@@_convert_cmyk_gray:w,
+% \@@_convert_cmyk_rgb:w,
+% \@@_convert_cmyk_cmyk:w,
+% \@@_convert_rgb_gray:w,
+% \@@_convert_rgb_rgb:w,
% \@@_convert_rgb_cmyk:w
% }
% \begin{macro}[EXP]{\@@_convert_rgb_cmyk:nnn}
@@ -1433,6 +1439,7 @@
%
% \begin{macro}{\color_select:n}
% \begin{macro}{\color_select:nn}
+% \begin{macro}{\@@_select_main:Nnn}
% \begin{macro}{\@@_select_main:Nw, \@@_select_loop:Nw}
% \begin{macro}{\@@_select:nnN}
% \begin{macro}{\@@_select_swap:Nnn}
@@ -1449,8 +1456,7 @@
}
\cs_new_protected:Npn \color_select:nn #1#2
{
- \@@_select_main:Nw \l_@@_current_tl
- #1 / / \s_@@_mark #2 / / \s_@@_stop
+ \@@_select_main:Nnn \l_@@_current_tl {#1} {#2}
\@@_finalise_current:
\@@_select:N \l_@@_current_tl
}
@@ -1459,6 +1465,15 @@
% model, we don't need most of the data: just set up and apply the backend
% function.
% \begin{macrocode}
+\cs_new_protected:Npn \@@_select_main:Nnn #1#2#3
+ {
+ \use:e
+ {
+ \exp_not:N \@@_select_main:Nw \exp_not:N #1
+ \exp_not:n {#2} / / \exp_not:N \s_@@_mark
+ #3 / / \exp_not:N \s_@@_stop
+ }
+ }
\cs_new_protected:Npn \@@_select_main:Nw
#1 #2 / #3 / #4 \s_@@_mark #5 / #6 / #7 \s_@@_stop
{
@@ -1505,6 +1520,7 @@
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
%
% \subsection{Math color}
%
@@ -1545,10 +1561,7 @@
\cs_new_protected:Npn \color_math:nnn #1#2#3
{
\@@_math:nn {#3}
- {
- \@@_select_main:Nw \l_@@_current_tl
- #1 / / \s_@@_mark #2 / / \s_@@_stop
- }
+ { \@@_select_main:Nnn \l_@@_current_tl {#1} {#2} }
}
\cs_new_protected:Npn \@@_math:nn #1#2
{
@@ -1720,14 +1733,12 @@
}
\cs_new_protected:Npn \color_fill:nn #1#2
{
- \@@_select_main:Nw \l_@@_current_tl
- #1 / / \s_@@_mark #2 / / \s_@@_stop
+ \@@_select_main:Nnn \l_@@_current_tl {#1} {#2}
\exp_after:wN \@@_draw:nnn \l_@@_current_tl { fill }
}
\cs_new_protected:Npn \color_stroke:nn #1#2
{
- \@@_select_main:Nw \l_@@_current_tl
- #1 / / \s_@@_mark #2 / / \s_@@_stop
+ \@@_select_main:Nnn \l_@@_current_tl {#1} {#2}
\exp_after:wN \@@_draw:nnn \l_@@_current_tl { stroke }
}
\cs_new_protected:Npn \@@_draw:nnn #1#2#3
@@ -1910,6 +1921,8 @@
\prop_new:c { l_@@_named_._prop }
\tl_new:c { l_@@_named_._tl }
\tl_set:ce { l_@@_named_._tl } { \@@_model:N \l_@@_current_tl }
+\prop_put:cve { l_@@_named_._prop } { l_@@_named_._tl }
+ { \@@_values:N \l_@@_current_tl }
% \end{macrocode}
% \end{variable}
%
@@ -1932,8 +1945,7 @@
}
\cs_new_protected:Npn \color_export:nnnN #1#2#3#4
{
- \@@_select_main:Nw #4
- #1 / / \s_@@_mark #2 / / \s_@@_stop
+ \@@_select_main:Nnn #4 {#1} {#2}
\@@_export:nN {#3} #4
}
\cs_new_protected:Npn \@@_export:nN #1#2
diff --git a/macros/latex-dev/required/l3kernel/l3debug.dtx b/macros/latex-dev/required/l3kernel/l3debug.dtx
index 21e6747a84..3c8f60341e 100644
--- a/macros/latex-dev/required/l3kernel/l3debug.dtx
+++ b/macros/latex-dev/required/l3kernel/l3debug.dtx
@@ -2,7 +2,7 @@
%
%% File: l3debug.dtx
%
-% Copyright (C) 2019-2024 The LaTeX Project
+% Copyright (C) 2019-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -69,7 +69,7 @@
%
% Standard file identification.
% \begin{macrocode}
-\ProvidesExplFile{l3debug.def}{2024-05-27}{}{L3 Debugging support}
+\ProvidesExplFile{l3debug.def}{2025-01-18}{}{L3 Debugging support}
% \end{macrocode}
%
% \begin{variable}{\s_@@_stop}
diff --git a/macros/latex-dev/required/l3kernel/l3deprecation.dtx b/macros/latex-dev/required/l3kernel/l3deprecation.dtx
index 5852205ddc..3f41595f56 100644
--- a/macros/latex-dev/required/l3kernel/l3deprecation.dtx
+++ b/macros/latex-dev/required/l3kernel/l3deprecation.dtx
@@ -2,7 +2,7 @@
%
%% File: l3deprecation.dtx
%
-% Copyright (C) 2017-2024 The LaTeX Project
+% Copyright (C) 2017-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -505,10 +505,10 @@
{ \text_uppercase:nn {#1} {#2} }
\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \text_titlecase_first:n }
\cs_new:Npn \tl_mixed_case:n #1
- { \text_titlecase_first:n {#1} }
+ { \text_titlecase_first:n { \text_lowercase:n {#1} } }
\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \text_titlecase_first:nn }
\cs_new:Npn \tl_mixed_case:nn #1#2
- { \text_titlecase_first:nn {#1} {#2} }
+ { \text_titlecase_first:nn {#1} { \text_lowercase:n {#2} } }
% \end{macrocode}
% \end{macro}
%
@@ -571,7 +571,7 @@
% \char_lower_case:N, \char_upper_case:N,
% \char_mixed_case:Nn, \char_fold_case:N,
% \char_str_lower_case:N, \char_str_upper_case:N,
-% \char_str_mixed_case:Nn, \char_str_fold_case:N,
+% \char_str_mixed_case:N, \char_str_fold_case:N,
% }
% \begin{macrocode}
\__kernel_patch_deprecation:nnNNpn { 2020-01-03 } { \text_lowercase:n }
diff --git a/macros/latex-dev/required/l3kernel/l3doc.dtx b/macros/latex-dev/required/l3kernel/l3doc.dtx
index 43b719ce59..84245e202c 100644
--- a/macros/latex-dev/required/l3kernel/l3doc.dtx
+++ b/macros/latex-dev/required/l3kernel/l3doc.dtx
@@ -2,7 +2,7 @@
%
%% File: l3doc.dtx
%
-% Copyright (C) 1990-2024 The LaTeX Project
+% Copyright (C) 1990-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -31,7 +31,7 @@
\askforoverwritefalse
\preamble
-Copyright (C) 1990-2024 The LaTeX Project
+Copyright (C) 1990-2025 The LaTeX Project
It may be distributed and/or modified under the conditions of
the LaTeX Project Public License (LPPL), either version 1.3c of
@@ -71,7 +71,7 @@ and all files in that bundle must be distributed together.
% This isn't included in the typeset documentation because it's a bit
% ugly:
%<*class>
-\ProvidesExplClass{l3doc}{2024-05-27}{}
+\ProvidesExplClass{l3doc}{2025-01-18}{}
{L3 Experimental documentation class}
%</class>
% \fi
@@ -84,7 +84,7 @@ and all files in that bundle must be distributed together.
% require you to do updates, if the class changes.}}
%
% \author{\Team}
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
% \maketitle
% \tableofcontents
%
@@ -471,7 +471,7 @@ and all files in that bundle must be distributed together.
% \cs{tl_if_empty_p:N} \meta{tl~var}
% \cs{tl_if_empty:NTF} \meta{tl~var} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if the \meta{token list variable} is entirely empty
+% Tests if the \meta{tl~var} is entirely empty
% (\emph{i.e.}~contains no tokens at all).
% \end{function}
% \end{verbatim}
@@ -484,7 +484,7 @@ and all files in that bundle must be distributed together.
% \cs{tl_if_empty_p:N} \meta{tl~var}
% \cs{tl_if_empty:NTF} \meta{tl~var} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if the \meta{token list variable} is entirely empty
+% Tests if the \meta{tl~var} is entirely empty
% (\emph{i.e.}~contains no tokens at all).
% \end{function}
% \end{minipage}
@@ -959,8 +959,8 @@ and all files in that bundle must be distributed together.
% \begin{macrocode}
\bool_new:N \g_@@_typeset_documentation_bool
\bool_new:N \g_@@_typeset_implementation_bool
-\bool_set_true:N \g_@@_typeset_documentation_bool
-\bool_set_true:N \g_@@_typeset_implementation_bool
+\bool_gset_true:N \g_@@_typeset_documentation_bool
+\bool_gset_true:N \g_@@_typeset_implementation_bool
% \end{macrocode}
% \end{variable}
%
@@ -1531,12 +1531,22 @@ and all files in that bundle must be distributed together.
% \begin{macrocode}
\bool_if:NT \g_@@_lmodern_bool
{
- \RequirePackage[T1]{fontenc}
- \RequirePackage{lmodern}
- \group_begin:
- \ttfamily
- \DeclareFontShape{T1}{lmtt}{m}{it}{<->ec-lmtto10}{}
- \group_end:
+ \sys_if_engine_opentype:TF
+ {
+ \group_begin:
+ \ttfamily
+ \DeclareFontShape{TU}{lmtt}{m}{it}
+ {<-> \UnicodeFontFile{lmmonoslant10-regular}{}}{}
+ \group_end:
+ }
+ {
+ \RequirePackage[T1]{fontenc}
+ \RequirePackage{lmodern}
+ \group_begin:
+ \ttfamily
+ \DeclareFontShape{T1}{lmtt}{m}{it}{<->ec-lmtto10}{}
+ \group_end:
+ }
}
% \end{macrocode}
%
@@ -1618,7 +1628,7 @@ and all files in that bundle must be distributed together.
%
% \subsection{Design}
%
-% Increase the text width slightly so that width the standard fonts
+% Increase the text width slightly so that with the standard fonts
% 72~columns of code may appear in a \env{macrocode} environment.
% Increase the marginpar width slightly, for long command names. And
% increase the left margin by a similar amount.
@@ -2160,10 +2170,18 @@ and all files in that bundle must be distributed together.
%
% \begin{macro}{\@@_names_get_seq:nN}
% The argument~|#1| (argument of a |function| or |macro| environment)
-% has catcodes $10$ (space), $12$ (other) and $13$ (active). Sanitize
-% catcodes. If the |verb| option was used, output a one-item
-% sequence. Otherwise, remove any \enquote{\%} character at the
-% beginning of a line. Remove tabs and newlines. Finally, convert
+% has catcodes $10$ (space), $12$ (other) and $13$ (active), and
+% since \LaTeX{} 2024-06-01 also macro \cs{obeyedline} in replacement
+% of active |^^M| tokens (due to the revised behavior of |+v|
+% argument type in |ltcmd|).
+% If the |verb| option was used, sanitize catcodes and output
+% a one-item sequence.
+% Otherwise, remove any \enquote{\%} character at the beginning of
+% a line using new end-of-line marker \cs{obeyedline}. Remove any
+% remaining \cs{obeyedline}. Then sanitize catcodes so we keep those
+% verbatim \cs{obeyedline} typed in by user. Remove remaining
+% \enquote{\%} character at the beginning of a line using traditional
+% |^^M| marker. Remove tabs and newlines. Finally, convert
% |_@@| and |@@| to |__|\meta{module name} (if it is non-empty). At
% this point, \cs{l_@@_tmpa_tl} contains a comma-delimited list of
% names, where |@| and~|_| have category code letter. Turn it to a
@@ -2172,17 +2190,20 @@ and all files in that bundle must be distributed together.
% \begin{macrocode}
\cs_new_protected:Npn \@@_names_get_seq:nN #1#2
{
- \__kernel_tl_set:Nx \l_@@_tmpa_tl { \tl_to_str:n {#1} }
\bool_if:NTF \l_@@_names_verb_bool
{
\seq_clear:N #2
- \seq_put_right:NV #2 \l_@@_tmpa_tl
+ \seq_put_right:No #2 { \tl_to_str:n {#1} }
}
{
+ \tl_set:Nn \l_@@_tmpa_tl {#1}
\tl_remove_all:Ne \l_@@_tmpa_tl
- { \iow_char:N \^^M \c_percent_str }
+ { \exp_not:N \obeyedline \c_percent_str }
\tl_remove_all:Ne \l_@@_tmpa_tl
- { \token_to_str:N \obeyedline \c_space_tl \c_percent_str }
+ { \exp_not:N \obeyedline }
+ \__kernel_tl_set:Nx \l_@@_tmpa_tl { \tl_to_str:N \l_@@_tmpa_tl }
+ \tl_remove_all:Ne \l_@@_tmpa_tl
+ { \iow_char:N \^^M \c_percent_str }
\tl_remove_all:Ne \l_@@_tmpa_tl { \tl_to_str:n { ^ ^ A } }
\tl_remove_all:Ne \l_@@_tmpa_tl { \iow_char:N \^^I }
\tl_remove_all:Ne \l_@@_tmpa_tl { \iow_char:N \^^M }
@@ -2529,7 +2550,7 @@ and all files in that bundle must be distributed together.
\cs_new_protected:Npn \@@_function_typeset_stop:
{
\par
- \dim_set:Nn \prevdepth { \box_dp:N \l_@@_descr_coffin }
+ \dim_set:Nn \prevdepth { \coffin_dp:N \l_@@_descr_coffin }
\allowbreak
}
% \end{macrocode}
@@ -2594,7 +2615,7 @@ and all files in that bundle must be distributed together.
\dim_zero:N \l_@@_trial_width_dim
\hcoffin_set:Nn \l_@@_functions_coffin { \@@_typeset_functions: }
\dim_set:Nn \l_@@_trial_width_dim
- { \box_wd:N \l_@@_functions_coffin }
+ { \coffin_wd:N \l_@@_functions_coffin }
\bool_set:Nn \l_@@_long_name_bool
{ \dim_compare_p:nNn \l_@@_trial_width_dim > \marginparwidth }
}
@@ -2643,7 +2664,7 @@ and all files in that bundle must be distributed together.
\coffin_join:NnnNnnnn
\l_@@_output_coffin {l} {b}
\l_@@_descr_coffin {l} {t}
- {0.75\marginparwidth + \marginparsep} {-\medskipamount}
+ {\marginparwidth + \marginparsep} {-\medskipamount}
\coffin_typeset:Nnnnn \l_@@_output_coffin
{\l_@@_descr_coffin-l} {\l_@@_descr_coffin-t}
{0pt} {0pt}
@@ -2695,8 +2716,7 @@ and all files in that bundle must be distributed together.
% \end{macro}
%
% ^^A TODO: collect all index targets from a given function environment in a box and stick it at the top.
-% \begin{macro}
-% {\@@_typeset_function_block:nN, \@@_typeset_function_block:eN}
+% \begin{macro}{\@@_typeset_function_block:nN}
% \begin{macro}{\@@_function_index:n, \@@_function_index:e}
% |#1| is a csname, |#2| a boolean indicating whether to add |TF| or not.
% \begin{macrocode}
@@ -2712,7 +2732,6 @@ and all files in that bundle must be distributed together.
{ \@@_typeset_variant_list:nN {#1} #2 }
\\
}
-\cs_generate_variant:Nn \@@_typeset_function_block:nN { e }
\cs_new_protected:Npn \@@_function_index:n #1
{
\seq_gput_right:Nn \g_doc_functions_seq {#1}
@@ -2840,7 +2859,7 @@ and all files in that bundle must be distributed together.
{
\textwidth
\bool_if:NT \l_@@_long_name_bool
- { + 0.75 \marginparwidth - \l_@@_trial_width_dim }
+ { + \marginparwidth - \l_@@_trial_width_dim }
}
\hbox_gset:Nw \g_@@_syntax_box
\small \ttfamily
@@ -3213,7 +3232,7 @@ and all files in that bundle must be distributed together.
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\@@_print_macroname_aux:nn}
+% \begin{macro}{\@@_print_macroname_aux:nn, \@@_print_macroname_aux:on}
% |#1| is prefix, |#2| is optional |TF| suffix.
% \begin{macrocode}
\cs_new_protected:Npn \@@_print_macroname_aux:nn #1#2
@@ -3589,7 +3608,7 @@ and all files in that bundle must be distributed together.
% \begin{macrocode}
\newenvironment{TemplateInterfaceDescription}[1]
{
- \subsection{The~object~type~`#1'}
+ \subsection{The~template~type~`#1'}
\begingroup
\@beginparpenalty\@M
\description
@@ -3608,7 +3627,7 @@ and all files in that bundle must be distributed together.
% \begin{macrocode}
\newenvironment{TemplateDescription}[2]
{
- \subsection{The~template~`#2'~(object~type~#1)}
+ \subsection{The~template~`#2'~(template~type~#1)}
\subsubsection*{Attributes:}
\begingroup
\@beginparpenalty\@M
@@ -3714,7 +3733,7 @@ and all files in that bundle must be distributed together.
{
\clist_map_inline:nn {#1}
{
- \clist_put_right:Nn \g_docinput_clist {##1}
+ \clist_gput_right:Nn \g_docinput_clist {##1}
\@@_input:n {##1}
}
}
@@ -3839,7 +3858,7 @@ and all files in that bundle must be distributed together.
{ MMMMV - \filesep \int_use:N \c@CodelineNo }
}
}
-\tl_gclear:N \filesep
+\tl_clear_new:N \filesep
\cs_new_protected:Npn \@@_index_page_hc:nn #1#2
{
\protected@write \@indexfile {}
@@ -4254,7 +4273,6 @@ and all files in that bundle must be distributed together.
{#2}
\l_@@_index_internal_bool
}
-\cs_generate_variant:Nn \@@_special_index:nn { o }
% \end{macrocode}
% \end{macro}
%
@@ -4698,7 +4716,7 @@ and all files in that bundle must be distributed together.
% \begin{macrocode}
\tl_const:Nn \Team
{
- The~\LaTeX3~Project\thanks
+ The~\LaTeX~Project~team\thanks
{\url{https://www.latex-project.org/latex3/}}
}
% \end{macrocode}
@@ -4712,7 +4730,7 @@ and all files in that bundle must be distributed together.
}
\author
{
- The~\LaTeX3~Project\thanks{E-mail:~
+ The~\LaTeX~Project~team\thanks{E-mail:~
\href{mailto:latex-l@listserv.uni-heidelberg.de}
{latex-l@listserv.uni-heidelberg.de}}
}
diff --git a/macros/latex-dev/required/l3kernel/l3doc.pdf b/macros/latex-dev/required/l3kernel/l3doc.pdf
index 4700ff58b5..061aa7a638 100644
--- a/macros/latex-dev/required/l3kernel/l3doc.pdf
+++ b/macros/latex-dev/required/l3kernel/l3doc.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3docstrip.dtx b/macros/latex-dev/required/l3kernel/l3docstrip.dtx
index fecb228324..4c6592789b 100644
--- a/macros/latex-dev/required/l3kernel/l3docstrip.dtx
+++ b/macros/latex-dev/required/l3kernel/l3docstrip.dtx
@@ -2,7 +2,7 @@
%
%% File l3dosctrip.dtx
%
-% Copyright (C) 2012-2024 The LaTeX Project
+% Copyright (C) 2012-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -63,7 +63,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
diff --git a/macros/latex-dev/required/l3kernel/l3docstrip.pdf b/macros/latex-dev/required/l3kernel/l3docstrip.pdf
index 8b13f9e4e9..b0d80d627b 100644
--- a/macros/latex-dev/required/l3kernel/l3docstrip.pdf
+++ b/macros/latex-dev/required/l3kernel/l3docstrip.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3expan.dtx b/macros/latex-dev/required/l3kernel/l3expan.dtx
index d13578bde1..ee5ad95896 100644
--- a/macros/latex-dev/required/l3kernel/l3expan.dtx
+++ b/macros/latex-dev/required/l3kernel/l3expan.dtx
@@ -2,7 +2,7 @@
%
%% File: l3expan.dtx
%
-% Copyright (C) 1990-2024 The LaTeX Project
+% Copyright (C) 1990-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -75,8 +75,8 @@
% If \cs{seq_gpush:No} was not defined it could be coded in the following way:
% \begin{verbatim}
% \exp_args:NNo \seq_gpush:Nn
-% \g_file_name_stack
-% { \l_tmpa_tl }
+% \g_file_name_stack
+% { \l_tmpa_tl }
% \end{verbatim}
% In other words, the first argument to \cs{exp_args:NNo} is the base
% function and the other arguments are preprocessed and then passed to
@@ -2203,6 +2203,7 @@
% \@@_generate_variant_T_form:nnn,
% \@@_generate_variant_F_form:nnn,
% \@@_generate_variant_TF_form:nnn,
+% \@@_generate_variant_check:nn
% }
% \begin{macrocode}
\cs_new_protected:Npn \prg_generate_conditional_variant:Nnn #1
@@ -2244,13 +2245,23 @@
\@@_generate_variant:w #2 \s_@@_mark {#3} {#4} {#5}
}
\cs_new_protected:Npn \@@_generate_variant_p_form:nnn #1#2
- { \cs_generate_variant:cn { #1 _p : #2 } }
+ { \@@_generate_variant_check:nn { #1 _p : #2 } }
\cs_new_protected:Npn \@@_generate_variant_T_form:nnn #1#2
- { \cs_generate_variant:cn { #1 : #2 T } }
+ { \@@_generate_variant_check:nn { #1 : #2 T } }
\cs_new_protected:Npn \@@_generate_variant_F_form:nnn #1#2
- { \cs_generate_variant:cn { #1 : #2 F } }
+ { \@@_generate_variant_check:nn { #1 : #2 F } }
\cs_new_protected:Npn \@@_generate_variant_TF_form:nnn #1#2
- { \cs_generate_variant:cn { #1 : #2 TF } }
+ { \@@_generate_variant_check:nn { #1 : #2 TF } }
+\cs_new_protected:Npn \@@_generate_variant_check:nn #1#2
+ {
+ \cs_if_exist:cTF {#1}
+ { \cs_generate_variant:cn {#1} {#2} }
+ {
+ \msg_error:nne
+ { kernel } { conditional-base-undefined }
+ { \token_to_str:c {#1} }
+ }
+ }
% \end{macrocode}
% \end{macro}
%
diff --git a/macros/latex-dev/required/l3kernel/l3file.dtx b/macros/latex-dev/required/l3kernel/l3file.dtx
index 546222711e..460d8794d8 100644
--- a/macros/latex-dev/required/l3kernel/l3file.dtx
+++ b/macros/latex-dev/required/l3kernel/l3file.dtx
@@ -2,7 +2,7 @@
%
%% File: l3file.dtx
%
-% Copyright (C) 1990-2024 The LaTeX Project
+% Copyright (C) 1990-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -225,8 +225,8 @@
%
% \begin{function}[noTF, added = 2012-06-24, updated = 2019-03-23]{\ior_get:NN}
% \begin{syntax}
-% \cs{ior_get:NN} \meta{stream} \meta{token list variable}
-% \cs{ior_get:NNTF} \meta{stream} \meta{token list variable} \meta{true code} \meta{false code}
+% \cs{ior_get:NN} \meta{stream} \meta{tl~var}
+% \cs{ior_get:NNTF} \meta{stream} \meta{tl~var} \Arg{true code} \Arg{false code}
% \end{syntax}
% Function that reads one or more lines (until an equal number of left
% and right braces are found) from the file input \meta{stream} and stores
@@ -243,7 +243,7 @@
% converted to the token \cs{par}. Therefore, blank lines can be
% skipped by using a test such as
% \begin{verbatim}
-% \ior_get:NN \l_my_stream \l_tmpa_tl
+% \ior_get:NN \l_my_ior \l_tmpa_tl
% \tl_set:Nn \l_tmpb_tl { \par }
% \tl_if_eq:NNF \l_tmpa_tl \l_tmpb_tl
% ...
@@ -267,8 +267,8 @@
% \begin{function}[noTF, added = 2016-12-04, updated = 2019-03-23]
% {\ior_str_get:NN}
% \begin{syntax}
-% \cs{ior_str_get:NN} \meta{stream} \meta{token list variable}
-% \cs{ior_str_get:NNTF} \meta{stream} \meta{token list variable} \meta{true code} \meta{false code}
+% \cs{ior_str_get:NN} \meta{stream} \meta{tl~var}
+% \cs{ior_str_get:NNTF} \meta{stream} \meta{tl~var} \Arg{true code} \Arg{false code}
% \end{syntax}
% Function that reads one line from the file input \meta{stream} and stores
% the result locally in the \meta{token list} variable.
@@ -277,7 +277,7 @@
% characters which are given category code $10$ (space).
% Multiple whitespace characters are retained by this process. It
% always only reads one line and any blank lines in the input
-% result in the \meta{token list variable} being empty. Unlike
+% result in the \meta{tl~var} being empty. Unlike
% \cs{ior_get:NN}, line ends do not receive any special treatment. Thus
% input
% \begin{verbatim}
@@ -429,7 +429,7 @@
%
% \begin{function}[added = 2019-03-23]{\ior_get_term:nN, \ior_str_get_term:nN}
% \begin{syntax}
-% \cs{ior_get_term:nN} \Arg{prompt} \meta{token list variable}
+% \cs{ior_get_term:nN} \Arg{prompt} \meta{tl~var}
% \end{syntax}
% Function that reads one or more lines (until an equal number of left
% and right braces are found) from the terminal and stores
@@ -718,8 +718,33 @@
% \cs{file_if_exist_p:n} \Arg{file name}
% \cs{file_if_exist:nTF} \Arg{file name} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if \meta{file name} is found in the path as detailed for
-% \cs{file_if_exist:nTF}.
+% Expands the argument of the \meta{file name} to give a string, then
+% searches for this string using the current \TeX{} search
+% path and the additional paths controlled by
+% \cs{l_file_search_path_seq}.
+%
+% Since \TeX{} cannot remove files, only write to them, once a file
+% has been found during a \TeX{} run, it will exist until the end of
+% the run unless a non-\TeX{} process intervenes. Since file operations
+% are relatively slow, \pkg{expl3} therefore internally tracks when a
+% file is seen, and uses this information to avoid multiple filesystem
+% checks. See \cs{file_forget:n} for how to indicate to \pkg{expl3} that
+% a file may have been deleted \emph{during} a \TeX{} run, so that its
+% presence in the filesystem can be reasserted with \cs{file_if_exist:nTF}
+% and similar commands.
+% \end{function}
+%
+% \begin{function}[added = 2024-12-09]{\file_forget:n}
+% \begin{syntax}
+% \cs{file_forget:n} \Arg{file name}
+% \end{syntax}
+% Resets the internal tracker for files such that a subsequent use of
+% \cs{file_if_exist:nTF}, \cs{file_size:n}, etc., for the \meta{file name} will
+% re-query the filesystem rather than use any cached information. This can
+% be used whether or not the file has previously been seen. This function
+% is intended to be used where non-\TeX{} processes may result in file
+% deletion, for example if \LuaTeX{} is in use, |os.remove()| may be used
+% to delete a file part-way through a run.
% \end{function}
%
% \subsection{Information about files and file contents}
@@ -844,11 +869,11 @@
% \file_compare_timestamp:VNV
% }
% \begin{syntax}
-% \cs{file_compare_timestamp_p:nNn} \Arg{file-1} \meta{comparator} \Arg{file-2}
-% \cs{file_compare_timestamp:nNnTF} \Arg{file-1} \meta{comparator} \Arg{file-2} \Arg{true code} \Arg{false code}
+% \cs{file_compare_timestamp_p:nNn} \Arg{file-1} \meta{relation} \Arg{file-2}
+% \cs{file_compare_timestamp:nNnTF} \Arg{file-1} \meta{relation} \Arg{file-2} \Arg{true code} \Arg{false code}
% \end{syntax}
% Compares the file stamps on the two \meta{files} as indicated by
-% the \meta{comparator}, and inserts either the \meta{true code}
+% the \meta{relation}, and inserts either the \meta{true code}
% or \meta{false case} as required. A file which is not found
% is treated as older than any file which is found. This allows for
% example the construct
@@ -865,8 +890,8 @@
% \begin{function}[noTF, updated = 2019-02-16]
% {\file_get_full_name:nN, \file_get_full_name:VN}
% \begin{syntax}
-% \cs{file_get_full_name:nN} \Arg{file name} \meta{tl}
-% \cs{file_get_full_name:nNTF} \Arg{file name} \meta{tl} \Arg{true code} \Arg{false code}
+% \cs{file_get_full_name:nN} \Arg{file name} \meta{tl var}
+% \cs{file_get_full_name:nNTF} \Arg{file name} \meta{tl var} \Arg{true code} \Arg{false code}
% \end{syntax}
% Searches for \meta{file name} in the path as detailed for
% \cs{file_if_exist:nTF}, and if found sets the \meta{tl var} the
@@ -941,15 +966,15 @@
% \begin{function}[noTF, added = 2019-01-16, updated = 2019-02-16]
% {\file_get:nnN, \file_get:VnN}
% \begin{syntax}
-% \cs{file_get:nnN} \Arg{file name} \Arg{setup} \meta{tl}
-% \cs{file_get:nnNTF} \Arg{file name} \Arg{setup} \meta{tl} \Arg{true code} \Arg{false code}
+% \cs{file_get:nnN} \Arg{file name} \Arg{setup} \meta{tl var}
+% \cs{file_get:nnNTF} \Arg{file name} \Arg{setup} \meta{tl var} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Defines \meta{tl} to the contents of \meta{file name}.
+% Defines \meta{tl var} to the contents of \meta{file name}.
% Category codes may need to be set appropriately via the \meta{setup}
% argument.
-% The non-branching version sets the \meta{tl} to \cs{q_no_value} if the file is
+% The non-branching version sets the \meta{tl var} to \cs{q_no_value} if the file is
% not found. The branching version runs the \meta{true code} after the
-% assignment to \meta{tl} if the file is found, and \meta{false code}
+% assignment to \meta{tl var} if the file is found, and \meta{false code}
% otherwise. The file content will be tokenized using the current
% category code régime,
% \end{function}
@@ -3118,6 +3143,15 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\file_forget:n}
+% Just a wrapper around a csname: we have to do a lookup here to make
+% sure any paths are handled.
+% \begin{macrocode}
+\cs_new_protected:Npn \file_forget:n #1
+ { \cs_undefine:c { @@_seen_ \file_full_name:n {#1} : } }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\file_get_full_name:nN, \file_get_full_name:VN}
% \begin{macro}[TF]{\file_get_full_name:nN, \file_get_full_name:VN}
% \begin{macro}{\@@_get_full_name_search:nN}
diff --git a/macros/latex-dev/required/l3kernel/l3flag.dtx b/macros/latex-dev/required/l3kernel/l3flag.dtx
index 88e726df35..2763ccfe25 100644
--- a/macros/latex-dev/required/l3kernel/l3flag.dtx
+++ b/macros/latex-dev/required/l3kernel/l3flag.dtx
@@ -2,7 +2,7 @@
%
%% File: l3flag.dtx
%
-% Copyright (C) 2011-2024 The LaTeX Project
+% Copyright (C) 2011-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
diff --git a/macros/latex-dev/required/l3kernel/l3fp-assign.dtx b/macros/latex-dev/required/l3kernel/l3fp-assign.dtx
index e6fa97423e..f7fc361dab 100644
--- a/macros/latex-dev/required/l3kernel/l3fp-assign.dtx
+++ b/macros/latex-dev/required/l3kernel/l3fp-assign.dtx
@@ -2,7 +2,7 @@
%
%% File: l3fp-assign.dtx
%
-% Copyright (C) 2011-2024 The LaTeX Project
+% Copyright (C) 2011-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -42,7 +42,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
% \maketitle
%
% \begin{documentation}
@@ -75,7 +75,9 @@
% \begin{macro}
% {
% \fp_set:Nn, \fp_set:cn,
+% \fp_set:NV, \fp_set:cV,
% \fp_gset:Nn, \fp_gset:cn,
+% \fp_gset:NV, \fp_gset:cV,
% \fp_const:Nn, \fp_const:cn
% }
% Simply use \cs{@@_parse:n} within various \texttt{f}-expanding
@@ -87,8 +89,8 @@
{ \__kernel_tl_gset:Nx #1 { \exp_not:f { \@@_parse:n {#2} } } }
\cs_new_protected:Npn \fp_const:Nn #1#2
{ \tl_const:Ne #1 { \exp_not:f { \@@_parse:n {#2} } } }
-\cs_generate_variant:Nn \fp_set:Nn {c}
-\cs_generate_variant:Nn \fp_gset:Nn {c}
+\cs_generate_variant:Nn \fp_set:Nn { NV , c , cV }
+\cs_generate_variant:Nn \fp_gset:Nn { NV , c , cV }
\cs_generate_variant:Nn \fp_const:Nn {c}
% \end{macrocode}
% \end{macro}
@@ -202,9 +204,9 @@
{
\@@_show_validate:nn { #1 }
{
- \s_@@ \@@_chk:w ??? ;~ or \iow_newline:
- \s_@@_tuple \_@@_tuple_chk:w ? ;~ or \iow_newline:
- \s_@@_symbolic \@@_symbolic_chk:w ? , ? ;
+ \s_@@ \@@_chk:w ??? \@@_sep: or \iow_newline:
+ \s_@@_tuple \_@@_tuple_chk:w ? \@@_sep: or \iow_newline:
+ \s_@@_symbolic \@@_symbolic_chk:w ? , ? \@@_sep:
}
}
\cs_new:Npn \@@_show_validate_aux:n #1
@@ -220,46 +222,49 @@
{ \s_@@ }
{
\@@_show_validate:w #1 \s_@@
- \@@_chk:w ??? ; \s_@@_stop
+ \@@_chk:w ??? \@@_sep: \s_@@_stop
}
{ \s_@@_tuple }
{
\@@_tuple_show_validate:w #1
- \s_@@_tuple \_@@_tuple_chk:w ?? ; \s_@@_stop
+ \s_@@_tuple \_@@_tuple_chk:w ?? \@@_sep: \s_@@_stop
}
{ \s_@@_symbolic }
{
\@@_symbolic_show_validate:w #1
- \s_@@_symbolic \@@_symbolic_chk:w ? , ?? ; \s_@@_stop
+ \s_@@_symbolic \@@_symbolic_chk:w ? , ?? \@@_sep: \s_@@_stop
}
}
{ #2 }
}
}
\cs_new:Npn \@@_show_validate:w
- #1 \s_@@ \@@_chk:w #2#3#4#5 ; #6 \s_@@_stop
+ #1 \s_@@ \@@_chk:w #2#3#4#5 \@@_sep: #6 \s_@@_stop
{
\str_if_eq:nnF { #2 } {?}
{
\token_if_eq_meaning:NNTF #2 1
- { \s_@@ \@@_chk:w #2 #3 { #4 } #5 ; }
- { \s_@@ \@@_chk:w #2 #3 #4 #5 ; }
+ { \s_@@ \@@_chk:w #2 #3 { #4 } #5 \@@_sep: }
+ { \s_@@ \@@_chk:w #2 #3 #4 #5 \@@_sep: }
\@@_show_validate_aux:n { #6 }
}
}
\cs_new:Npn \@@_tuple_show_validate:w
- #1 \s_@@_tuple \_@@_tuple_chk:w #2#3 ; #4 \s_@@_stop
+ #1 \s_@@_tuple \_@@_tuple_chk:w #2#3 \@@_sep: #4 \s_@@_stop
{
\str_if_eq:nnF { #2 } {?}
- { \s_@@_tuple \@@_tuple_chk:w { \@@_show_validate_aux:n { #2 } } ; }
+ {
+ \s_@@_tuple \@@_tuple_chk:w { \@@_show_validate_aux:n { #2 } }
+ \@@_sep:
+ }
}
\cs_new:Npn \@@_symbolic_show_validate:w
- #1 \s_@@_symbolic \@@_symbolic_chk:w #2 , #3#4 ; #5 \s_@@_stop
+ #1 \s_@@_symbolic \@@_symbolic_chk:w #2 , #3#4 \@@_sep: #5 \s_@@_stop
{
\str_if_eq:nnF { #2 } {?}
{
\s_@@_symbolic \@@_symbolic_chk:w \exp_not:n { #2 } ,
- { \@@_show_validate_aux:n { #3 } };
+ { \@@_show_validate_aux:n { #3 } }\@@_sep:
\@@_show_validate_aux:n { #5 }
}
}
diff --git a/macros/latex-dev/required/l3kernel/l3fp-aux.dtx b/macros/latex-dev/required/l3kernel/l3fp-aux.dtx
index 1ad33e235e..05f514f82e 100644
--- a/macros/latex-dev/required/l3kernel/l3fp-aux.dtx
+++ b/macros/latex-dev/required/l3kernel/l3fp-aux.dtx
@@ -2,7 +2,7 @@
%
%% File: l3fp-aux.dtx
%
-% Copyright (C) 2011-2024 The LaTeX Project
+% Copyright (C) 2011-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -79,12 +79,27 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\@@_sep:}
+% We need a way to stop the expansion in \cs{@@_int_eval:w} and similar with a
+% token that isn't absorbed so that it works as a marker for right-delimited
+% arguments. Additionally the used token should be impossible to form a valid
+% expression for these expression primitives (the otherwise often used
+% |;| is turned into a binary operator in some engines for instance). And
+% since this is about right-delimiting I think it's funny to use
+% \cs{tex_right:D}. An unexpandable primitive is used because it is guaranteed
+% to never be a valid token in such an expression and survives all kinds of
+% expansion (just like |;| would).
+% \begin{macrocode}
+\cs_new_eq:NN \@@_sep: \tex_right:D
+% \end{macrocode}
+% \end{macro}
+%
% \subsection{Internal representation}
%
% Internally, a floating point number \meta{X} is a
% token list containing
% \begin{quote}
-% \cs{s_@@} \cs{@@_chk:w} \meta{case} \meta{sign} \meta{body} |;|
+% \cs{s_@@} \cs{@@_chk:w} \meta{case} \meta{sign} \meta{body} \cs{@@_sep:}
% \end{quote}
% Let us explain each piece separately.
%
@@ -117,15 +132,15 @@
%
% Special floating point numbers have the form
% \begin{quote}
-% \cs{s_@@} \cs{@@_chk:w} \meta{case} \meta{sign} \cs[no-index]{s_@@_\ldots} |;|
+% \cs{s_@@} \cs{@@_chk:w} \meta{case} \meta{sign} \cs[no-index]{s_@@_\ldots} \cs{@@_sep:}
% \end{quote}
-% where \cs[no-index]{s_@@_\ldots} is a scan mark carrying information about how the
-% number was formed (useful for debugging).
+% where \cs[no-index]{s_@@_\ldots} is a scan mark carrying information about how
+% the number was formed (useful for debugging).
%
% Normal floating point numbers ($\meta{case} = 1$) have the form
% \begin{quote}
% \cs{s_@@} \cs{@@_chk:w} 1 \meta{sign} \Arg{exponent}
-% \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4} |;|
+% \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4} \cs{@@_sep:}
% \end{quote}
% Here, the \meta{exponent} is an integer, between
% $-\ExplSyntaxOn\int_use:N\c__fp_minus_min_exponent_int$ and
@@ -135,8 +150,9 @@
% \[
% (-1)^{\meta{sign}/2} \meta{X_1}\meta{X_2}\meta{X_3}\meta{X_4}\cdot 10^{\meta{exponent}-16}
% \]
-% where we have concatenated the $16$ digits. Currently, floating point numbers are normalized such that
-% the \meta{exponent} is minimal, in other words, $1000 \leq \meta{X_1} \leq 9999$.
+% where we have concatenated the $16$ digits. Currently, floating point numbers
+% are normalized such that the \meta{exponent} is minimal, in other words,
+% $1000 \leq \meta{X_1} \leq 9999$.
%
% \begin{table}\centering
% \caption{Internal representation of floating point numbers.}
@@ -176,8 +192,8 @@
% Those functions place a semicolon after one or two arguments
% (typically digits).
% \begin{macrocode}
-\cs_new:Npn \@@_use_s:n #1 { #1; }
-\cs_new:Npn \@@_use_s:nn #1#2 { #1#2; }
+\cs_new:Npn \@@_use_s:n #1 { #1\@@_sep: }
+\cs_new:Npn \@@_use_s:nn #1#2 { #1#2\@@_sep: }
% \end{macrocode}
% \end{macro}
%
@@ -186,9 +202,9 @@
% Those functions select specific arguments among a set of arguments
% delimited by a semicolon.
% \begin{macrocode}
-\cs_new:Npn \@@_use_none_until_s:w #1; { }
-\cs_new:Npn \@@_use_i_until_s:nw #1#2; {#1}
-\cs_new:Npn \@@_use_ii_until_s:nnw #1#2#3; {#2}
+\cs_new:Npn \@@_use_none_until_s:w #1\@@_sep: { }
+\cs_new:Npn \@@_use_i_until_s:nw #1#2\@@_sep: {#1}
+\cs_new:Npn \@@_use_ii_until_s:nnw #1#2#3\@@_sep: {#2}
% \end{macrocode}
% \end{macro}
%
@@ -196,7 +212,8 @@
% Many internal functions take arguments delimited by semicolons, and
% it is occasionally useful to swap two such arguments.
% \begin{macrocode}
-\cs_new:Npn \@@_reverse_args:Nww #1 #2; #3; { #1 #3; #2; }
+\cs_new:Npn \@@_reverse_args:Nww #1 #2\@@_sep: #3\@@_sep:
+ { #1 #3\@@_sep: #2\@@_sep: }
% \end{macrocode}
% \end{macro}
%
@@ -204,7 +221,8 @@
% Rotate three arguments delimited by semicolons. This is the inverse
% (or the square) of the Forth primitive |ROT|, hence the name.
% \begin{macrocode}
-\cs_new:Npn \@@_rrot:www #1; #2; #3; { #2; #3; #1; }
+\cs_new:Npn \@@_rrot:www #1\@@_sep: #2\@@_sep: #3\@@_sep:
+ { #2\@@_sep: #3\@@_sep: #1\@@_sep: }
% \end{macrocode}
% \end{macro}
%
@@ -212,8 +230,8 @@
% Many internal functions take arguments delimited by semicolons, and
% it is occasionally useful to remove one or two such arguments.
% \begin{macrocode}
-\cs_new:Npn \@@_use_i:ww #1; #2; { #1; }
-\cs_new:Npn \@@_use_i:www #1; #2; #3; { #1; }
+\cs_new:Npn \@@_use_i:ww #1\@@_sep: #2\@@_sep: { #1\@@_sep: }
+\cs_new:Npn \@@_use_i:www #1\@@_sep: #2\@@_sep: #3\@@_sep: { #1\@@_sep: }
% \end{macrocode}
% \end{macro}
%
@@ -241,8 +259,8 @@
% expanded. We define \cs{@@_chk:w} to produce an error.
% \begin{macrocode}
\scan_new:N \s_@@
-\cs_new_protected:Npn \@@_chk:w #1 ;
- { \@@_misused:n { \s_@@ \@@_chk:w #1 ; } }
+\cs_new_protected:Npn \@@_chk:w #1 \@@_sep:
+ { \@@_misused:n { \s_@@ \@@_chk:w #1 \@@_sep: } }
% \end{macrocode}
% \end{macro}
%
@@ -287,13 +305,14 @@
%
% \begin{variable}
% {\c_zero_fp, \c_minus_zero_fp, \c_inf_fp, \c_minus_inf_fp, \c_nan_fp}
-% The special floating points. We define the floating points here as \enquote{exact}.
+% The special floating points. We define the floating points here as
+% \enquote{exact}.
% \begin{macrocode}
-\tl_const:Nn \c_zero_fp { \s_@@ \@@_chk:w 0 0 \s_@@_exact ; }
-\tl_const:Nn \c_minus_zero_fp { \s_@@ \@@_chk:w 0 2 \s_@@_exact ; }
-\tl_const:Nn \c_inf_fp { \s_@@ \@@_chk:w 2 0 \s_@@_exact ; }
-\tl_const:Nn \c_minus_inf_fp { \s_@@ \@@_chk:w 2 2 \s_@@_exact ; }
-\tl_const:Nn \c_nan_fp { \s_@@ \@@_chk:w 3 1 \s_@@_exact ; }
+\tl_const:Nn \c_zero_fp { \s_@@ \@@_chk:w 0 0 \s_@@_exact \@@_sep: }
+\tl_const:Nn \c_minus_zero_fp { \s_@@ \@@_chk:w 0 2 \s_@@_exact \@@_sep: }
+\tl_const:Nn \c_inf_fp { \s_@@ \@@_chk:w 2 0 \s_@@_exact \@@_sep: }
+\tl_const:Nn \c_minus_inf_fp { \s_@@ \@@_chk:w 2 2 \s_@@_exact \@@_sep: }
+\tl_const:Nn \c_nan_fp { \s_@@ \@@_chk:w 3 1 \s_@@_exact \@@_sep: }
% \end{macrocode}
% \end{variable}
%
@@ -343,7 +362,7 @@
{
\s_@@ \@@_chk:w 1 0
{ \int_eval:n { \c_@@_max_exponent_int + 1 } }
- {1000} {0000} {0000} {0000} ;
+ {1000} {0000} {0000} {0000} \@@_sep:
}
% \end{macrocode}
% \end{variable}
@@ -353,9 +372,9 @@
% a zero or infinity with a given sign.
% \begin{macrocode}
\cs_new:Npn \@@_zero_fp:N #1
- { \s_@@ \@@_chk:w 0 #1 \s_@@_underflow ; }
+ { \s_@@ \@@_chk:w 0 #1 \s_@@_underflow \@@_sep: }
\cs_new:Npn \@@_inf_fp:N #1
- { \s_@@ \@@_chk:w 2 #1 \s_@@_overflow ; }
+ { \s_@@ \@@_chk:w 2 #1 \s_@@_overflow \@@_sep: }
% \end{macrocode}
% \end{macro}
%
@@ -411,7 +430,7 @@
% to $\pm\infty$. The functions \cs{@@_underflow:w} and
% \cs{@@_overflow:w} are defined in \pkg{l3fp-traps}.
% \begin{macrocode}
-\cs_new:Npn \@@_sanitize:Nw #1 #2;
+\cs_new:Npn \@@_sanitize:Nw #1 #2\@@_sep:
{
\if_case:w
\if_int_compare:w #2 > \c_@@_max_exponent_int 1 ~ \else:
@@ -423,8 +442,8 @@
\fi:
\s_@@ \@@_chk:w 1 #1 {#2}
}
-\cs_new:Npn \@@_sanitize:wN #1; #2 { \@@_sanitize:Nw #2 #1; }
-\cs_new:Npn \@@_sanitize_zero:w \s_@@ \@@_chk:w #1 #2 #3;
+\cs_new:Npn \@@_sanitize:wN #1\@@_sep: #2 { \@@_sanitize:Nw #2 #1\@@_sep: }
+\cs_new:Npn \@@_sanitize_zero:w \s_@@ \@@_chk:w #1 #2 #3\@@_sep:
{ \c_zero_fp }
% \end{macrocode}
% \end{macro}
@@ -472,19 +491,19 @@
%
% \begin{macro}[EXP]{\@@_exp_after_special:nNNw}
% \begin{syntax}
-% \cs{@@_exp_after_special:nNNw} \Arg{after} \meta{case} \meta{sign} \meta{scan mark} |;|
+% \cs{@@_exp_after_special:nNNw} \Arg{after} \meta{case} \meta{sign} \meta{scan mark} \cs{@@_sep:}
% \end{syntax}
% Special floating point numbers are easy to jump over since they
% contain few tokens.
% \begin{macrocode}
-\cs_new:Npn \@@_exp_after_special:nNNw #1#2#3#4;
+\cs_new:Npn \@@_exp_after_special:nNNw #1#2#3#4\@@_sep:
{
\exp_after:wN \s_@@
\exp_after:wN \@@_chk:w
\exp_after:wN #2
\exp_after:wN #3
\exp_after:wN #4
- \exp_after:wN ;
+ \exp_after:wN \@@_sep:
#1
}
% \end{macrocode}
@@ -496,19 +515,19 @@
% the digits were not braced but instead were delimited arguments (for
% instance delimited by |,|). That may be changed some day.
% \begin{macrocode}
-\cs_new:Npn \@@_exp_after_normal:nNNw #1 1 #2 #3 #4#5#6#7;
+\cs_new:Npn \@@_exp_after_normal:nNNw #1 1 #2 #3 #4#5#6#7\@@_sep:
{
\exp_after:wN \@@_exp_after_normal:Nwwwww
\exp_after:wN #2
- \int_value:w #3 \exp_after:wN ;
- \int_value:w 1 #4 \exp_after:wN ;
- \int_value:w 1 #5 \exp_after:wN ;
- \int_value:w 1 #6 \exp_after:wN ;
- \int_value:w 1 #7 \exp_after:wN ; #1
+ \int_value:w #3 \exp_after:wN \@@_sep:
+ \int_value:w 1 #4 \exp_after:wN \@@_sep:
+ \int_value:w 1 #5 \exp_after:wN \@@_sep:
+ \int_value:w 1 #6 \exp_after:wN \@@_sep:
+ \int_value:w 1 #7 \exp_after:wN \@@_sep: #1
}
\cs_new:Npn \@@_exp_after_normal:Nwwwww
- #1 #2; 1 #3 ; 1 #4 ; 1 #5 ; 1 #6 ;
- { \s_@@ \@@_chk:w 1 #1 {#2} {#3} {#4} {#5} {#6} ; }
+ #1 #2\@@_sep: 1 #3 \@@_sep: 1 #4 \@@_sep: 1 #5 \@@_sep: 1 #6 \@@_sep:
+ { \s_@@ \@@_chk:w 1 #1 {#2} {#3} {#4} {#5} {#6} \@@_sep: }
% \end{macrocode}
% \end{macro}
%
@@ -517,17 +536,17 @@
% \begin{macro}{\s_@@_tuple, \@@_tuple_chk:w}
% \begin{variable}{\c_@@_empty_tuple_fp}
% Floating point tuples take the form \cs{s_@@_tuple}
-% \cs{@@_tuple_chk:w} |{| \meta{fp 1} \meta{fp 2} \dots |}| |;| where
-% each \meta{fp} is a floating point number or tuple, hence ends with
-% |;| itself. When a tuple is typeset, \cs{@@_tuple_chk:w} produces
+% \cs{@@_tuple_chk:w} |{| \meta{fp 1} \meta{fp 2} \dots |}| \cs{@@_sep:}
+% where each \meta{fp} is a floating point number or tuple, hence ends with
+% \cs{@@_sep:} itself. When a tuple is typeset, \cs{@@_tuple_chk:w} produces
% an error, just like usual floating point numbers.
% Tuples may have zero or one element.
% \begin{macrocode}
\scan_new:N \s_@@_tuple
-\cs_new_protected:Npn \@@_tuple_chk:w #1 ;
- { \@@_misused:n { \s_@@_tuple \@@_tuple_chk:w #1 ; } }
+\cs_new_protected:Npn \@@_tuple_chk:w #1 \@@_sep:
+ { \@@_misused:n { \s_@@_tuple \@@_tuple_chk:w #1 \@@_sep: } }
\tl_const:Nn \c_@@_empty_tuple_fp
- { \s_@@_tuple \@@_tuple_chk:w { } ; }
+ { \s_@@_tuple \@@_tuple_chk:w { } \@@_sep: }
% \end{macrocode}
% \end{variable}
% \end{macro}
@@ -540,15 +559,15 @@
% with the |\use_none:n #1| construction.
% \begin{macrocode}
\cs_new:Npn \@@_array_count:n #1
- { \@@_tuple_count:w \s_@@_tuple \@@_tuple_chk:w {#1} ; }
-\cs_new:Npn \@@_tuple_count:w \s_@@_tuple \@@_tuple_chk:w #1 ;
+ { \@@_tuple_count:w \s_@@_tuple \@@_tuple_chk:w {#1} \@@_sep: }
+\cs_new:Npn \@@_tuple_count:w \s_@@_tuple \@@_tuple_chk:w #1 \@@_sep:
{
\int_value:w \@@_int_eval:w 0
- \@@_tuple_count_loop:Nw #1 { ? \prg_break: } ;
+ \@@_tuple_count_loop:Nw #1 { ? \prg_break: } \@@_sep:
\prg_break_point:
\@@_int_eval_end:
}
-\cs_new:Npn \@@_tuple_count_loop:Nw #1#2;
+\cs_new:Npn \@@_tuple_count_loop:Nw #1#2\@@_sep:
{ \use_none:n #1 + 1 \@@_tuple_count_loop:Nw }
% \end{macrocode}
% \end{macro}
@@ -570,10 +589,10 @@
% \begin{macrocode}
\cs_new:Npn \@@_array_if_all_fp:nTF #1
{
- \@@_array_if_all_fp_loop:w #1 { \s_@@ \prg_break: } ;
+ \@@_array_if_all_fp_loop:w #1 { \s_@@ \prg_break: } \@@_sep:
\prg_break_point: \use_i:nn
}
-\cs_new:Npn \@@_array_if_all_fp_loop:w #1#2 ;
+\cs_new:Npn \@@_array_if_all_fp_loop:w #1#2 \@@_sep:
{
\@@_if_type_fp:NTwFw
#1 \@@_array_if_all_fp_loop:w
@@ -680,16 +699,16 @@
% item in the tuple and expand it.
% \begin{quote}
% \cs{@@_exp_after_array_f:w}\\
-% \meta{fp_1} |;|\\
+% \meta{fp_1} \cs{@@_sep:}\\
% \ldots{}\\
-% \meta{fp_n} |;|\\
+% \meta{fp_n} \cs{@@_sep:}\\
% \cs{s_@@_expr_stop}
% \end{quote}
% \begin{macrocode}
\cs_new:Npn \@@_exp_after_tuple_o:w
{ \@@_exp_after_tuple_f:nw { \exp_after:wN \exp_stop_f: } }
\cs_new:Npn \@@_exp_after_tuple_f:nw
- #1 \s_@@_tuple \@@_tuple_chk:w #2 ;
+ #1 \s_@@_tuple \@@_tuple_chk:w #2 \@@_sep:
{
\exp_after:wN \s_@@_tuple
\exp_after:wN \@@_tuple_chk:w
@@ -697,7 +716,7 @@
\exp:w \exp_end_continue_f:w
\@@_exp_after_array_f:w #2 \s_@@_expr_stop
\exp_after:wN }
- \exp_after:wN ;
+ \exp_after:wN \@@_sep:
\exp:w \exp_end_continue_f:w #1
}
\cs_new:Npn \@@_exp_after_array_f:w
@@ -780,7 +799,8 @@
\int_const:Nn \c_@@_leading_shift_int { - 5 0000 }
\int_const:Nn \c_@@_middle_shift_int { 5 0000 * 9999 }
\int_const:Nn \c_@@_trailing_shift_int { 5 0000 * 10000 }
-\cs_new:Npn \@@_pack:NNNNNw #1 #2#3#4#5 #6; { + #1#2#3#4#5 ; {#6} }
+\cs_new:Npn \@@_pack:NNNNNw #1 #2#3#4#5 #6\@@_sep:
+ { + #1#2#3#4#5 \@@_sep: {#6} }
% \end{macrocode}
% \end{variable}
% \end{macro}
@@ -802,8 +822,8 @@
\int_const:Nn \c_@@_big_leading_shift_int { - 15 2374 }
\int_const:Nn \c_@@_big_middle_shift_int { 15 2374 * 9999 }
\int_const:Nn \c_@@_big_trailing_shift_int { 15 2374 * 10000 }
-\cs_new:Npn \@@_pack_big:NNNNNNw #1#2 #3#4#5#6 #7;
- { + #1#2#3#4#5#6 ; {#7} }
+\cs_new:Npn \@@_pack_big:NNNNNNw #1#2 #3#4#5#6 #7\@@_sep:
+ { + #1#2#3#4#5#6 \@@_sep: {#7} }
% \end{macrocode}
% \end{variable}
% \end{macro}
@@ -824,37 +844,37 @@
\int_const:Nn \c_@@_Bigg_leading_shift_int { - 20 0000 }
\int_const:Nn \c_@@_Bigg_middle_shift_int { 20 0000 * 9999 }
\int_const:Nn \c_@@_Bigg_trailing_shift_int { 20 0000 * 10000 }
-\cs_new:Npn \@@_pack_Bigg:NNNNNNw #1#2 #3#4#5#6 #7;
- { + #1#2#3#4#5#6 ; {#7} }
+\cs_new:Npn \@@_pack_Bigg:NNNNNNw #1#2 #3#4#5#6 #7\@@_sep:
+ { + #1#2#3#4#5#6 \@@_sep: {#7} }
% \end{macrocode}
% \end{variable}
% \end{macro}
%
% \begin{macro}[EXP]{\@@_pack_twice_four:wNNNNNNNN}
% \begin{syntax}
-% \cs{@@_pack_twice_four:wNNNNNNNN} \meta{tokens} |;| \meta{$\geq 8$ digits}
+% \cs{@@_pack_twice_four:wNNNNNNNN} \meta{tokens} \cs{@@_sep:} \meta{$\geq 8$ digits}
% \end{syntax}
% Grabs two sets of $4$ digits and places them before the semi-colon
% delimiter. Putting several copies of this function before a
% semicolon packs more digits since each takes the digits
% packed by the others in its first argument.
% \begin{macrocode}
-\cs_new:Npn \@@_pack_twice_four:wNNNNNNNN #1; #2#3#4#5 #6#7#8#9
- { #1 {#2#3#4#5} {#6#7#8#9} ; }
+\cs_new:Npn \@@_pack_twice_four:wNNNNNNNN #1\@@_sep: #2#3#4#5 #6#7#8#9
+ { #1 {#2#3#4#5} {#6#7#8#9} \@@_sep: }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[EXP]{\@@_pack_eight:wNNNNNNNN}
% \begin{syntax}
-% \cs{@@_pack_eight:wNNNNNNNN} \meta{tokens} |;| \meta{$\geq 8$ digits}
+% \cs{@@_pack_eight:wNNNNNNNN} \meta{tokens} \cs{@@_sep:} \meta{$\geq 8$ digits}
% \end{syntax}
% Grabs one set of $8$ digits and places them before the semi-colon
% delimiter as a single group. Putting several copies of this
% function before a semicolon packs more digits since each
% takes the digits packed by the others in its first argument.
% \begin{macrocode}
-\cs_new:Npn \@@_pack_eight:wNNNNNNNN #1; #2#3#4#5 #6#7#8#9
- { #1 {#2#3#4#5#6#7#8#9} ; }
+\cs_new:Npn \@@_pack_eight:wNNNNNNNN #1\@@_sep: #2#3#4#5 #6#7#8#9
+ { #1 {#2#3#4#5#6#7#8#9} \@@_sep: }
% \end{macrocode}
% \end{macro}
%
@@ -875,17 +895,17 @@
%
% This is used in \pkg{l3fp-basics} and \pkg{l3fp-extended}.
% \begin{macrocode}
-\cs_new:Npn \@@_basics_pack_low:NNNNNw #1 #2#3#4#5 #6;
- { + #1 - 1 ; {#2#3#4#5} {#6} ; }
-\cs_new:Npn \@@_basics_pack_high:NNNNNw #1 #2#3#4#5 #6;
+\cs_new:Npn \@@_basics_pack_low:NNNNNw #1 #2#3#4#5 #6\@@_sep:
+ { + #1 - 1 \@@_sep: {#2#3#4#5} {#6} \@@_sep: }
+\cs_new:Npn \@@_basics_pack_high:NNNNNw #1 #2#3#4#5 #6\@@_sep:
{
\if_meaning:w 2 #1
\@@_basics_pack_high_carry:w
\fi:
- ; {#2#3#4#5} {#6}
+ \@@_sep: {#2#3#4#5} {#6}
}
-\cs_new:Npn \@@_basics_pack_high_carry:w \fi: ; #1
- { \fi: + 1 ; {1000} }
+\cs_new:Npn \@@_basics_pack_high_carry:w \fi: \@@_sep: #1
+ { \fi: + 1 \@@_sep: {1000} }
% \end{macrocode}
% \end{macro}
%
@@ -897,16 +917,16 @@
% This is used in \pkg{l3fp-basics} for additions and
% divisions. Their syntax is confusing, hence the name.
% \begin{macrocode}
-\cs_new:Npn \@@_basics_pack_weird_low:NNNNw #1 #2#3#4 #5;
+\cs_new:Npn \@@_basics_pack_weird_low:NNNNw #1 #2#3#4 #5\@@_sep:
{
\if_meaning:w 2 #1
+ 1
\fi:
\@@_int_eval_end:
- #2#3#4; {#5} ;
+ #2#3#4\@@_sep: {#5} \@@_sep:
}
\cs_new:Npn \@@_basics_pack_weird_high:NNNNNNNNw
- 1 #1#2#3#4 #5#6#7#8 #9; { ; {#1#2#3#4} {#5#6#7#8} {#9} }
+ 1 #1#2#3#4 #5#6#7#8 #9\@@_sep: { \@@_sep: {#1#2#3#4} {#5#6#7#8} {#9} }
% \end{macrocode}
% \end{macro}
%
@@ -922,7 +942,7 @@
% and $1000\leq\meta{X_1}<9999$. The first argument determines
% by how much we shift the digits. \meta{f_1} is called as follows:
% \begin{syntax}
-% \meta{f_1} \meta{rounding} \Arg{X'_1} \Arg{X'_2} \meta{extra-digits} |;|
+% \meta{f_1} \meta{rounding} \Arg{X'_1} \Arg{X'_2} \meta{extra-digits} \cs{@@_sep:}
% \end{syntax}
% where $0\leq\meta{X'_i}<10^{8}-1$ are $8$ digit integers,
% forming the truncation of our number. In other words,
@@ -972,9 +992,9 @@
% If the \meta{shift} is zero, or too big, life is very easy.
% \begin{macrocode}
\cs_new:Npn \@@_decimate_:Nnnnn #1 #2#3#4#5
- { #1 0 {#2#3} {#4#5} ; }
+ { #1 0 {#2#3} {#4#5} \@@_sep: }
\cs_new:Npn \@@_decimate_tiny:Nnnnn #1 #2#3#4#5
- { #1 1 { 0000 0000 } { 0000 0000 } 0 #2#3#4#5 ; }
+ { #1 1 { 0000 0000 } { 0000 0000 } 0 #2#3#4#5 \@@_sep: }
% \end{macrocode}
% \end{macro}
%
@@ -1015,8 +1035,8 @@
{
\exp_after:wN ##1
\int_value:w
- \exp_after:wN \@@_round_digit:Nw #2 ;
- \@@_decimate_pack:nnnnnnnnnnw #3 ;
+ \exp_after:wN \@@_round_digit:Nw #2 \@@_sep:
+ \@@_decimate_pack:nnnnnnnnnnw #3 \@@_sep:
}
}
\@@_tmp:w {i} {\use_none:nnn #50}{ 0{#2}#3{#4}#5 }
@@ -1106,7 +1126,7 @@
% follow, simply anything ending in a semicolon. This, in turn, means
% that the \meta{junk} may not contain semicolons.
% \begin{macrocode}
-\cs_new:Npn \@@_case_return:nw #1#2 \fi: #3 ; { \fi: #1 }
+\cs_new:Npn \@@_case_return:nw #1#2 \fi: #3 \@@_sep: { \fi: #1 }
% \end{macrocode}
% \end{macro}
%
@@ -1115,7 +1135,7 @@
% point, and returns its first argument (an \meta{fp~var}) then expands
% once after it.
% \begin{macrocode}
-\cs_new:Npn \@@_case_return_o:Nw #1#2 \fi: #3 \s_@@ #4 ;
+\cs_new:Npn \@@_case_return_o:Nw #1#2 \fi: #3 \s_@@ #4 \@@_sep:
{ \fi: \exp_after:wN #1 }
% \end{macrocode}
% \end{macro}
@@ -1133,7 +1153,7 @@
% Same as \cs{@@_case_return_o:Nw} but with two trailing floating
% points.
% \begin{macrocode}
-\cs_new:Npn \@@_case_return_o:Nww #1#2 \fi: #3 \s_@@ #4 ; #5 ;
+\cs_new:Npn \@@_case_return_o:Nww #1#2 \fi: #3 \s_@@ #4 \@@_sep: #5 \@@_sep:
{ \fi: \exp_after:wN #1 }
% \end{macrocode}
% \end{macro}
@@ -1143,9 +1163,10 @@
% or second of two trailing floating point numbers, expanding once
% after the result.
% \begin{macrocode}
-\cs_new:Npn \@@_case_return_i_o:ww #1 \fi: #2 \s_@@ #3 ; \s_@@ #4 ;
- { \fi: \@@_exp_after_o:w \s_@@ #3 ; }
-\cs_new:Npn \@@_case_return_ii_o:ww #1 \fi: #2 \s_@@ #3 ;
+\cs_new:Npn \@@_case_return_i_o:ww
+ #1 \fi: #2 \s_@@ #3 \@@_sep: \s_@@ #4 \@@_sep:
+ { \fi: \@@_exp_after_o:w \s_@@ #3 \@@_sep: }
+\cs_new:Npn \@@_case_return_ii_o:ww #1 \fi: #2 \s_@@ #3 \@@_sep:
{ \fi: \@@_exp_after_o:w }
% \end{macrocode}
% \end{macro}
@@ -1157,7 +1178,7 @@
% floating point numbers, this holds if the rounding digit resulting
% from \cs{@@_decimate:nNnnnn} is~$0$.
% \begin{macrocode}
-\prg_new_conditional:Npnn \@@_int:w \s_@@ \@@_chk:w #1 #2 #3 #4;
+\prg_new_conditional:Npnn \@@_int:w \s_@@ \@@_chk:w #1 #2 #3 #4\@@_sep:
{ TF , T , F , p }
{
\if_case:w #1 \exp_stop_f:
@@ -1199,26 +1220,26 @@
\cs_new:Npn \@@_small_int:wTF \s_@@ \@@_chk:w #1#2
{
\if_case:w #1 \exp_stop_f:
- \@@_case_return:nw { \@@_small_int_true:wTF 0 ; }
+ \@@_case_return:nw { \@@_small_int_true:wTF 0 \@@_sep: }
\or: \exp_after:wN \@@_small_int_normal:NnwTF
\or:
\@@_case_return:nw
{
\exp_after:wN \@@_small_int_true:wTF \int_value:w
- \if_meaning:w 2 #2 - \fi: 1 0000 0000 ;
+ \if_meaning:w 2 #2 - \fi: 1 0000 0000 \@@_sep:
}
\else: \@@_case_return:nw \use_ii:nn
\fi:
#2
}
-\cs_new:Npn \@@_small_int_true:wTF #1; #2#3 { #2 {#1} }
-\cs_new:Npn \@@_small_int_normal:NnwTF #1#2#3;
+\cs_new:Npn \@@_small_int_true:wTF #1\@@_sep: #2#3 { #2 {#1} }
+\cs_new:Npn \@@_small_int_normal:NnwTF #1#2#3\@@_sep:
{
\@@_decimate:nNnnnn { \c_@@_prec_int - #2 }
\@@_small_int_test:NnnwNw
#3 #1
}
-\cs_new:Npn \@@_small_int_test:NnnwNw #1#2#3#4; #5
+\cs_new:Npn \@@_small_int_test:NnnwNw #1#2#3#4\@@_sep: #5
{
\if_meaning:w 0 #1
\exp_after:wN \@@_small_int_true:wTF
@@ -1228,7 +1249,7 @@
\else:
#3
\fi:
- \exp_after:wN ;
+ \exp_after:wN \@@_sep:
\else:
\exp_after:wN \use_ii:nn
\fi:
diff --git a/macros/latex-dev/required/l3kernel/l3fp-basics.dtx b/macros/latex-dev/required/l3kernel/l3fp-basics.dtx
index e2d93219b0..25df2952ad 100644
--- a/macros/latex-dev/required/l3kernel/l3fp-basics.dtx
+++ b/macros/latex-dev/required/l3kernel/l3fp-basics.dtx
@@ -2,7 +2,7 @@
%
%% File: l3fp-basics.dtx
%
-% Copyright (C) 2011-2024 The LaTeX Project
+% Copyright (C) 2011-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -42,7 +42,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -156,7 +156,7 @@
% discarded.
% \begin{macrocode}
\cs_new:cpn { @@_+_o:ww }
- \s_@@ #1 \@@_chk:w #2 #3 ; \s_@@ \@@_chk:w #4 #5
+ \s_@@ #1 \@@_chk:w #2 #3 \@@_sep: \s_@@ \@@_chk:w #4 #5
{
\if_case:w
\if_meaning:w #2 #4
@@ -176,7 +176,7 @@
\else: \exp_after:wN \@@_add_return_ii_o:Nww \int_value:w
\fi:
#1 #5
- \s_@@ \@@_chk:w #2 #3 ;
+ \s_@@ \@@_chk:w #2 #3 \@@_sep:
\s_@@ \@@_chk:w #4 #5
}
% \end{macrocode}
@@ -186,7 +186,7 @@
% Ignore the first operand, and return the second, but using the sign
% |#1| rather than |#4|. As usual, expand after the floating point.
% \begin{macrocode}
-\cs_new:Npn \@@_add_return_ii_o:Nww #1 #2 ; \s_@@ \@@_chk:w #3 #4
+\cs_new:Npn \@@_add_return_ii_o:Nww #1 #2 \@@_sep: \s_@@ \@@_chk:w #3 #4
{ \@@_exp_after_o:w \s_@@ \@@_chk:w #3 #1 }
% \end{macrocode}
% \end{macro}
@@ -216,7 +216,7 @@
% identical.
% \begin{macrocode}
\cs_new:Npn \@@_add_inf_o:Nww
- #1 \s_@@ \@@_chk:w 2 #2 #3; \s_@@ \@@_chk:w 2 #4
+ #1 \s_@@ \@@_chk:w 2 #2 #3\@@_sep: \s_@@ \@@_chk:w 2 #4
{
\if_meaning:w #1 #2
\@@_case_return_i_o:ww
@@ -227,7 +227,7 @@
{ \token_if_eq_meaning:NNTF #1 #4 + - }
}
\fi:
- \s_@@ \@@_chk:w 2 #2 #3;
+ \s_@@ \@@_chk:w 2 #2 #3\@@_sep:
\s_@@ \@@_chk:w 2 #4
}
% \end{macrocode}
@@ -237,9 +237,9 @@
% \begin{quote}
% \cs{@@_add_normal_o:Nww} \meta{sign_2}
% \cs{s_@@} \cs{@@_chk:w} |1| \meta{sign_1}
-% \meta{exp_1} \meta{body_1} |;|
+% \meta{exp_1} \meta{body_1} \cs{@@_sep:}
% \cs{s_@@} \cs{@@_chk:w} |1| \meta{initial sign_2}
-% \meta{exp_2} \meta{body_2} |;|
+% \meta{exp_2} \meta{body_2} \cs{@@_sep:}
% \end{quote}
% We now have two normal numbers to add, and we have to check signs
% and exponents more carefully before performing the addition.
@@ -264,8 +264,8 @@
% \begin{macro}[EXP]{\@@_add_npos_o:NnwNnw}
% \begin{quote}
% \cs{@@_add_npos_o:NnwNnw} \meta{sign_1} \meta{exp_1} \meta{body_1}
-% |;| \cs{s_@@} \cs{@@_chk:w} |1| \meta{initial sign_2} \meta{exp_2}
-% \meta{body_2} |;|
+% \cs{@@_sep:} \cs{s_@@} \cs{@@_chk:w} |1| \meta{initial sign_2}
+% \meta{exp_2} \meta{body_2} \cs{@@_sep:}
% \end{quote}
% Since we are doing an addition, the final sign is \meta{sign_1}.
% Start an \cs{@@_int_eval:w}, responsible for computing the exponent:
@@ -278,7 +278,7 @@
% the final sign with us in the midst of the calculation to round
% properly at the end.
% \begin{macrocode}
-\cs_new:Npn \@@_add_npos_o:NnwNnw #1#2#3 ; \s_@@ \@@_chk:w 1 #4 #5
+\cs_new:Npn \@@_add_npos_o:NnwNnw #1#2#3 \@@_sep: \s_@@ \@@_chk:w 1 #4 #5
{
\exp_after:wN \@@_sanitize:Nw
\exp_after:wN #1
@@ -290,7 +290,7 @@
#5
\exp_after:wN \@@_add_big_ii_o:wNww \int_value:w
\fi:
- \@@_int_eval:w #5 - #2 ; #1 #3;
+ \@@_int_eval:w #5 - #2 \@@_sep: #1 #3\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -298,14 +298,14 @@
% \begin{macro}[rEXP]{\@@_add_big_i_o:wNww}
% \begin{macro}[rEXP]{\@@_add_big_ii_o:wNww}
% \begin{quote}
-% \cs{@@_add_big_i_o:wNww} \meta{shift} |;| \meta{final sign}
-% \meta{body_1} |;| \meta{body_2} |;|
+% \cs{@@_add_big_i_o:wNww} \meta{shift} \cs{@@_sep:} \meta{final sign}
+% \meta{body_1} \cs{@@_sep:} \meta{body_2} \cs{@@_sep:}
% \end{quote}
% Used in \pkg{l3fp-expo}.
% Shift the significand of the small number, then add with
% \cs{@@_add_significand_o:NnnwnnnnN}.
% \begin{macrocode}
-\cs_new:Npn \@@_add_big_i_o:wNww #1; #2 #3; #4;
+\cs_new:Npn \@@_add_big_i_o:wNww #1\@@_sep: #2 #3\@@_sep: #4\@@_sep:
{
\@@_decimate:nNnnnn {#1}
\@@_add_significand_o:NnnwnnnnN
@@ -313,7 +313,7 @@
#3
#2
}
-\cs_new:Npn \@@_add_big_ii_o:wNww #1; #2 #3; #4;
+\cs_new:Npn \@@_add_big_ii_o:wNww #1\@@_sep: #2 #3\@@_sep: #4\@@_sep:
{
\@@_decimate:nNnnnn {#1}
\@@_add_significand_o:NnnwnnnnN
@@ -331,7 +331,7 @@
% \begin{quote}\raggedright
% \cs{@@_add_significand_o:NnnwnnnnN}
% \meta{rounding digit}
-% \Arg{Y'_1} \Arg{Y'_2} \meta{extra-digits} |;|
+% \Arg{Y'_1} \Arg{Y'_2} \meta{extra-digits} \cs{@@_sep:}
% \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4}
% \meta{final sign}
% \end{quote}
@@ -344,19 +344,19 @@
% give an exact power of $10$, for which it is easy to correct
% the result at the end.
% \begin{macrocode}
-\cs_new:Npn \@@_add_significand_o:NnnwnnnnN #1 #2#3 #4; #5#6#7#8
+\cs_new:Npn \@@_add_significand_o:NnnwnnnnN #1 #2#3 #4\@@_sep: #5#6#7#8
{
\exp_after:wN \@@_add_significand_test_o:N
\int_value:w \@@_int_eval:w 1#5#6 + #2
\exp_after:wN \@@_add_significand_pack:NNNNNNN
- \int_value:w \@@_int_eval:w 1#7#8 + #3 ; #1
+ \int_value:w \@@_int_eval:w 1#7#8 + #3 \@@_sep: #1
}
\cs_new:Npn \@@_add_significand_pack:NNNNNNN #1 #2#3#4#5#6#7
{
\if_meaning:w 2 #1
+ 1
\fi:
- ; #2 #3 #4 #5 #6 #7 ;
+ \@@_sep: #2 #3 #4 #5 #6 #7 \@@_sep:
}
\cs_new:Npn \@@_add_significand_test_o:N #1
{
@@ -373,7 +373,7 @@
% \begin{macro}[rEXP]{\@@_add_significand_no_carry_o:wwwNN}
% \begin{quote}
% \cs{@@_add_significand_no_carry_o:wwwNN}
-% \meta{8d} |;| \meta{6d} |;| \meta{2d} |;|
+% \meta{8d} \cs{@@_sep:} \meta{6d} \cs{@@_sep:} \meta{2d} \cs{@@_sep:}
% \meta{rounding digit} \meta{sign}
% \end{quote}
% If there's no carry, grab all the digits again and round. The
@@ -381,14 +381,14 @@
% case where rounding brings a carry.
% \begin{macrocode}
\cs_new:Npn \@@_add_significand_no_carry_o:wwwNN
- #1; #2; #3#4 ; #5#6
+ #1\@@_sep: #2\@@_sep: #3#4 \@@_sep: #5#6
{
\exp_after:wN \@@_basics_pack_high:NNNNNw
\int_value:w \@@_int_eval:w 1 #1
\exp_after:wN \@@_basics_pack_low:NNNNNw
\int_value:w \@@_int_eval:w 1 #2 #3#4
+ \@@_round:NNN #6 #4 #5
- \exp_after:wN ;
+ \exp_after:wN \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -396,14 +396,14 @@
% \begin{macro}[rEXP]{\@@_add_significand_carry_o:wwwNN}
% \begin{quote}
% \cs{@@_add_significand_carry_o:wwwNN}
-% \meta{8d} |;| \meta{6d} |;| \meta{2d} |;|
+% \meta{8d} \cs{@@_sep:} \meta{6d} \cs{@@_sep:} \meta{2d} \cs{@@_sep:}
% \meta{rounding digit} \meta{sign}
% \end{quote}
% The case where there is a carry is very similar. Rounding can even
% raise the first digit from $1$ to $2$, but we don't care.
% \begin{macrocode}
\cs_new:Npn \@@_add_significand_carry_o:wwwNN
- #1; #2; #3#4; #5#6
+ #1\@@_sep: #2\@@_sep: #3#4\@@_sep: #5#6
{
+ 1
\exp_after:wN \@@_basics_pack_weird_high:NNNNNNNNw
@@ -413,8 +413,8 @@
\exp_after:wN \@@_round:NNN
\exp_after:wN #6
\exp_after:wN #3
- \int_value:w \@@_round_digit:Nw #4 #5 ;
- \exp_after:wN ;
+ \int_value:w \@@_round_digit:Nw #4 #5 \@@_sep:
+ \exp_after:wN \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -425,9 +425,9 @@
% \begin{macro}[EXP]{\@@_sub_eq_o:Nnwnw, \@@_sub_npos_ii_o:Nnwnw}
% \begin{quote}
% \cs{@@_sub_npos_o:NnwNnw}
-% \meta{sign_1} \meta{exp_1} \meta{body_1} |;|
+% \meta{sign_1} \meta{exp_1} \meta{body_1} \cs{@@_sep:}
% \cs{s_@@} \cs{@@_chk:w} |1|
-% \meta{initial sign_2} \meta{exp_2} \meta{body_2} |;|
+% \meta{initial sign_2} \meta{exp_2} \meta{body_2} \cs{@@_sep:}
% \end{quote}
% Rounding properly in some modes requires to know what the sign of
% the result will be. Thus, we start by comparing the exponents and
@@ -435,23 +435,26 @@
% number is larger, swap the numbers and call
% \cs{@@_sub_npos_i_o:Nnwnw} with the opposite of \meta{sign_1}.
% \begin{macrocode}
-\cs_new:Npn \@@_sub_npos_o:NnwNnw #1#2#3; \s_@@ \@@_chk:w 1 #4#5#6;
+\cs_new:Npn \@@_sub_npos_o:NnwNnw
+ #1#2#3\@@_sep: \s_@@ \@@_chk:w 1 #4#5#6\@@_sep:
{
- \if_case:w \@@_compare_npos:nwnw {#2} #3; {#5} #6; \exp_stop_f:
+ \if_case:w
+ \@@_compare_npos:nwnw {#2} #3\@@_sep: {#5} #6\@@_sep: \exp_stop_f:
\exp_after:wN \@@_sub_eq_o:Nnwnw
\or:
\exp_after:wN \@@_sub_npos_i_o:Nnwnw
\else:
\exp_after:wN \@@_sub_npos_ii_o:Nnwnw
\fi:
- #1 {#2} #3; {#5} #6;
+ #1 {#2} #3\@@_sep: {#5} #6\@@_sep:
}
-\cs_new:Npn \@@_sub_eq_o:Nnwnw #1#2; #3; { \exp_after:wN \c_zero_fp }
-\cs_new:Npn \@@_sub_npos_ii_o:Nnwnw #1 #2; #3;
+\cs_new:Npn \@@_sub_eq_o:Nnwnw #1#2\@@_sep: #3\@@_sep:
+ { \exp_after:wN \c_zero_fp }
+\cs_new:Npn \@@_sub_npos_ii_o:Nnwnw #1 #2\@@_sep: #3\@@_sep:
{
\exp_after:wN \@@_sub_npos_i_o:Nnwnw
\int_value:w \@@_neg_sign:N #1
- #3; #2;
+ #3\@@_sep: #2\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -460,15 +463,15 @@
% \begin{macro}[EXP]{\@@_sub_npos_i_o:Nnwnw}
% After the computation is done, \cs{@@_sanitize:Nw} checks for
% overflow/underflow. It expects the \meta{final sign} and the
-% \meta{exponent} (delimited by |;|). Start an integer expression for
-% the exponent, which starts with the exponent of the largest number,
+% \meta{exponent} (delimited by \cs{@@_sep:}). Start an integer expression
+% for the exponent, which starts with the exponent of the largest number,
% and may be decreased if the two numbers are very close. If the two
% numbers have the same exponent, call the \texttt{near} auxiliary.
% Otherwise, decimate $y$, then call the \texttt{far} auxiliary to
% evaluate the difference between the two significands. Note that we
% decimate by $1$ less than one could expect.
% \begin{macrocode}
-\cs_new:Npn \@@_sub_npos_i_o:Nnwnw #1 #2#3; #4#5;
+\cs_new:Npn \@@_sub_npos_i_o:Nnwnw #1 #2#3\@@_sep: #4#5\@@_sep:
{
\exp_after:wN \@@_sanitize:Nw
\exp_after:wN #1
@@ -509,16 +512,16 @@
\exp_after:wN \@@_sub_back_near_after:wNNNNw
\int_value:w \@@_int_eval:w 10#5#6 - #1#2 - 11
\exp_after:wN \@@_sub_back_near_pack:NNNNNNw
- \int_value:w \@@_int_eval:w 11#7#8 - #3#4 \exp_after:wN ;
+ \int_value:w \@@_int_eval:w 11#7#8 - #3#4 \exp_after:wN \@@_sep:
}
-\cs_new:Npn \@@_sub_back_near_pack:NNNNNNw #1#2#3#4#5#6#7 ;
- { + #1#2 ; {#3#4#5#6} {#7} ; }
-\cs_new:Npn \@@_sub_back_near_after:wNNNNw 10 #1#2#3#4 #5 ;
+\cs_new:Npn \@@_sub_back_near_pack:NNNNNNw #1#2#3#4#5#6#7 \@@_sep:
+ { + #1#2 \@@_sep: {#3#4#5#6} {#7} \@@_sep: }
+\cs_new:Npn \@@_sub_back_near_after:wNNNNw 10 #1#2#3#4 #5 \@@_sep:
{
\if_meaning:w 0 #1
\exp_after:wN \@@_sub_back_shift:wnnnn
\fi:
- ; {#1#2#3#4} {#5}
+ \@@_sep: {#1#2#3#4} {#5}
}
% \end{macrocode}
% \end{macro}
@@ -532,8 +535,8 @@
% \@@_sub_back_shift_iv:nnnnw
% }
% \begin{quote}
-% \cs{@@_sub_back_shift:wnnnn} |;|
-% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} |;|
+% \cs{@@_sub_back_shift:wnnnn} \cs{@@_sep:}
+% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} \cs{@@_sep:}
% \end{quote}
% This function is called with $\meta{Z_1}\leq 999$. Act with
% \tn{number} to trim leading zeros from \meta{Z_1} \meta{Z_2} (we
@@ -547,30 +550,31 @@
% |#2#3| is ignored), get four blocks of $4$~digits and finally clean
% up. Trailing zeros are added so that digits can be grabbed safely.
% \begin{macrocode}
-\cs_new:Npn \@@_sub_back_shift:wnnnn ; #1#2
+\cs_new:Npn \@@_sub_back_shift:wnnnn \@@_sep: #1#2
{
\exp_after:wN \@@_sub_back_shift_ii:ww
- \int_value:w #1 #2 0 ;
+ \int_value:w #1 #2 0 \@@_sep:
}
-\cs_new:Npn \@@_sub_back_shift_ii:ww #1 0 ; #2#3 ;
+\cs_new:Npn \@@_sub_back_shift_ii:ww #1 0 \@@_sep: #2#3 \@@_sep:
{
\if_meaning:w @ #1 @
- 7
- \exp_after:wN \use_i:nnn
\exp_after:wN \@@_sub_back_shift_iii:NNNNNNNNw
- \int_value:w #2#3 0 ~ 123456789;
+ \int_value:w #2#3 0 ~ 123456789\@@_sep:
\else:
- - \@@_sub_back_shift_iii:NNNNNNNNw #1 123456789;
+ - \@@_sub_back_shift_iii:NNNNNNNNw #1 123456789\@@_sep:
\fi:
\exp_after:wN \@@_pack_twice_four:wNNNNNNNN
\exp_after:wN \@@_pack_twice_four:wNNNNNNNN
\exp_after:wN \@@_sub_back_shift_iv:nnnnw
- \exp_after:wN ;
+ \exp_after:wN \@@_sep:
\int_value:w
- #1 ~ #2#3 0 ~ 0000 0000 0000 000 ;
+ #1 ~ #2#3 0 ~ 0000 0000 0000 000 \@@_sep:
}
-\cs_new:Npn \@@_sub_back_shift_iii:NNNNNNNNw #1#2#3#4#5#6#7#8#9; {#8}
-\cs_new:Npn \@@_sub_back_shift_iv:nnnnw #1 ; #2 ; { ; #1 ; }
+\cs_new:Npn \@@_sub_back_shift_iii:NNNNNNNNw #1#2#3#4#5#6#7#8#9\@@_sep: {#8}
+\cs_new:Npn \@@_sub_back_shift_iv:nnnnw #1 \@@_sep: #2 \@@_sep:
+ { \@@_sep: #1 \@@_sep: }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -578,7 +582,7 @@
% \begin{macro}[rEXP]{\@@_sub_back_far_o:NnnwnnnnN}
% \begin{quote}\raggedright
% \cs{@@_sub_back_far_o:NnnwnnnnN}
-% \meta{rounding} \Arg{Y'_1} \Arg{Y'_2} \meta{extra-digits} |;|
+% \meta{rounding} \Arg{Y'_1} \Arg{Y'_2} \meta{extra-digits} \cs{@@_sep:}
% \Arg{X_1} \Arg{X_2} \Arg{X_3} \Arg{X_4}
% \meta{final sign}
% \end{quote}
@@ -591,9 +595,9 @@
% and semi-colon delimiters to allow the \texttt{not_far} auxiliary to
% grab each piece individually, the \texttt{very_far} auxiliary to use
% \cs{@@_pack_eight:wNNNNNNNN}, and the \texttt{quite_far} to ignore
-% the significands easily (using the |;| delimiter).
+% the significands easily (using the \cs{@@_sep:} delimiter).
% \begin{macrocode}
-\cs_new:Npn \@@_sub_back_far_o:NnnwnnnnN #1 #2#3 #4; #5#6#7#8
+\cs_new:Npn \@@_sub_back_far_o:NnnwnnnnN #1 #2#3 #4\@@_sep: #5#6#7#8
{
\if_case:w
\if_int_compare:w 1 #2 = #5#6 \use_i:nnnn #7 \exp_stop_f:
@@ -610,7 +614,7 @@
\or: \exp_after:wN \@@_sub_back_very_far_o:wwwwNN
\else: \exp_after:wN \@@_sub_back_not_far_o:wwwwNN
\fi:
- #2 ~ #3 ; #5 #6 ~ #7 #8 ; #1
+ #2 ~ #3 \@@_sep: #5 #6 ~ #7 #8 \@@_sep: #1
}
% \end{macrocode}
% \end{macro}
@@ -626,7 +630,7 @@
% (remember that the \meta{rounding} digit is only equal to $5$ if
% there was no further non-zero digit).
% \begin{macrocode}
-\cs_new:Npn \@@_sub_back_quite_far_o:wwNN #1; #2; #3#4
+\cs_new:Npn \@@_sub_back_quite_far_o:wwNN #1\@@_sep: #2\@@_sep: #3#4
{
\exp_after:wN \@@_sub_back_quite_far_ii:NN
\exp_after:wN #3
@@ -639,8 +643,8 @@
\else:
\exp_after:wN \use_ii:nn
\fi:
- { ; {1000} {0000} {0000} {0000} ; }
- { - 1 ; {9999} {9999} {9999} {9999} ; }
+ { \@@_sep: {1000} {0000} {0000} {0000} \@@_sep: }
+ { - 1 \@@_sep: {9999} {9999} {9999} {9999} \@@_sep: }
}
% \end{macrocode}
% \end{macro}
@@ -661,7 +665,7 @@
% about its parity, which is identical to that of the last digit
% of~|#2|.
% \begin{macrocode}
-\cs_new:Npn \@@_sub_back_not_far_o:wwwwNN #1 ~ #2; #3 ~ #4; #5#6
+\cs_new:Npn \@@_sub_back_not_far_o:wwwwNN #1 ~ #2\@@_sep: #3 ~ #4\@@_sep: #5#6
{
- 1
\exp_after:wN \@@_sub_back_near_after:wNNNNw
@@ -671,7 +675,7 @@
- \exp_after:wN \@@_round_neg:NNN
\exp_after:wN #6
\use_none:nnnnnnn #2 #5
- \exp_after:wN ;
+ \exp_after:wN \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -693,9 +697,10 @@
\@@_pack_eight:wNNNNNNNN
\@@_sub_back_very_far_ii_o:nnNwwNN
{ 0 #1#2#3 #4#5#6#7 }
- ;
+ \@@_sep:
}
-\cs_new:Npn \@@_sub_back_very_far_ii_o:nnNwwNN #1#2 ; #3 ; #4 ~ #5; #6#7
+\cs_new:Npn \@@_sub_back_very_far_ii_o:nnNwwNN
+ #1#2 \@@_sep: #3 \@@_sep: #4 ~ #5\@@_sep: #6#7
{
\exp_after:wN \@@_basics_pack_high:NNNNNw
\int_value:w \@@_int_eval:w 1#4 - #1 - 1
@@ -706,8 +711,8 @@
\int_value:w
\if_int_odd:w \@@_int_eval:w #5 - #2 \@@_int_eval_end:
1 \else: 2 \fi:
- \int_value:w \@@_round_digit:Nw #3 #6 ;
- \exp_after:wN ;
+ \int_value:w \@@_round_digit:Nw #3 #6 \@@_sep:
+ \exp_after:wN \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -757,7 +762,7 @@
% argument |#4|, because it differs in the case of divisions.
% \begin{macrocode}
\cs_new:Npn \@@_mul_cases_o:NnNnww
- #1#2#3#4 \s_@@ \@@_chk:w #5#6#7; \s_@@ \@@_chk:w #8#9
+ #1#2#3#4 \s_@@ \@@_chk:w #5#6#7\@@_sep: \s_@@ \@@_chk:w #8#9
{
\if_case:w \@@_int_eval:w
\if_int_compare:w #5 #8 = 11 ~
@@ -791,7 +796,7 @@
\or: \@@_case_return_o:Nww \c_minus_inf_fp
#4
\fi:
- \s_@@ \@@_chk:w #5 #6 #7;
+ \s_@@ \@@_chk:w #5 #6 #7\@@_sep:
\s_@@ \@@_chk:w #8 #9
}
% \end{macrocode}
@@ -805,8 +810,8 @@
% \begin{macro}[EXP]{\@@_mul_npos_o:Nww}
% \begin{quote}
% \cs{@@_mul_npos_o:Nww} \meta{final sign}
-% \cs{s_@@} \cs{@@_chk:w} |1| \meta{sign_1} \Arg{exp_1} \meta{body_1} |;|
-% \cs{s_@@} \cs{@@_chk:w} |1| \meta{sign_2} \Arg{exp_2} \meta{body_2} |;|
+% \cs{s_@@} \cs{@@_chk:w} |1| \meta{sign_1} \Arg{exp_1} \meta{body_1} \cs{@@_sep:}
+% \cs{s_@@} \cs{@@_chk:w} |1| \meta{sign_2} \Arg{exp_2} \meta{body_2} \cs{@@_sep:}
% \end{quote}
% After the computation, \cs{@@_sanitize:Nw} checks for overflow or
% underflow. As we did for addition, \cs{@@_int_eval:w} computes the
@@ -818,7 +823,8 @@
% This is also used in \pkg{l3fp-convert}.
% \begin{macrocode}
\cs_new:Npn \@@_mul_npos_o:Nww
- #1 \s_@@ \@@_chk:w #2 #3 #4 #5 ; \s_@@ \@@_chk:w #6 #7 #8 #9 ;
+ #1 \s_@@ \@@_chk:w #2 #3 #4 #5 \@@_sep:
+ \s_@@ \@@_chk:w #6 #7 #8 #9 \@@_sep:
{
\exp_after:wN \@@_sanitize:Nw
\exp_after:wN #1
@@ -871,13 +877,13 @@
\exp_after:wN \@@_mul_significand_drop:NNNNNw
\int_value:w \@@_int_eval:w 99990000 + #3*#9 + #4*#8 +
\exp_after:wN \@@_mul_significand_drop:NNNNNw
- \int_value:w \@@_int_eval:w 100000000 + #4*#9 ;
- ; \exp_after:wN ;
+ \int_value:w \@@_int_eval:w 100000000 + #4*#9 \@@_sep:
+ \@@_sep: \exp_after:wN \@@_sep:
}
-\cs_new:Npn \@@_mul_significand_drop:NNNNNw #1#2#3#4#5 #6;
- { #1#2#3#4#5 ; + #6 }
-\cs_new:Npn \@@_mul_significand_keep:NNNNNw #1#2#3#4#5 #6;
- { #1#2#3#4#5 ; #6 ; }
+\cs_new:Npn \@@_mul_significand_drop:NNNNNw #1#2#3#4#5 #6\@@_sep:
+ { #1#2#3#4#5 \@@_sep: + #6 }
+\cs_new:Npn \@@_mul_significand_keep:NNNNNw #1#2#3#4#5 #6\@@_sep:
+ { #1#2#3#4#5 \@@_sep: #6 \@@_sep: }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -885,10 +891,10 @@
% \begin{macro}[rEXP]{\@@_mul_significand_test_f:NNN}
% \begin{quote}
% \cs{@@_mul_significand_test_f:NNN} \meta{sign} |1|
-% \meta{digits 1--8} |;| \meta{digits 9--12} |;| \meta{digits 13--16} |;|
+% \meta{digits 1--8} \cs{@@_sep:} \meta{digits 9--12} \cs{@@_sep:} \meta{digits 13--16} \cs{@@_sep:}
% |+| \meta{digits 17--20} |+| \meta{digits 21--24}
-% |+| \meta{digits 25--28} |+| \meta{digits 29--32} |;|
-% \cs{exp_after:wN} |;|
+% |+| \meta{digits 25--28} |+| \meta{digits 29--32} \cs{@@_sep:}
+% \cs{exp_after:wN} \cs{@@_sep:}
% \end{quote}
% If the \meta{digit 1} is non-zero, then for rounding we only care
% about the digits $16$ and $17$, and whether further digits are zero
@@ -916,7 +922,8 @@
% integer expression), and replaces it by a \meta{rounding digit},
% suitable for \cs{@@_round:NNN}.
% \begin{macrocode}
-\cs_new:Npn \@@_mul_significand_large_f:NwwNNNN #1 #2; #3; #4#5#6#7; +
+\cs_new:Npn \@@_mul_significand_large_f:NwwNNNN
+ #1 #2\@@_sep: #3\@@_sep: #4#5#6#7\@@_sep: +
{
\exp_after:wN \@@_basics_pack_high:NNNNNw
\int_value:w \@@_int_eval:w 1#2
@@ -938,7 +945,8 @@
% \texttt{small_pack} auxiliary, by the next digit, to form a $9$
% digit number.
% \begin{macrocode}
-\cs_new:Npn \@@_mul_significand_small_f:NNwwwN #1 #2#3; #4#5; #6; + #7
+\cs_new:Npn \@@_mul_significand_small_f:NNwwwN
+ #1 #2#3\@@_sep: #4#5\@@_sep: #6\@@_sep: + #7
{
- 1
\exp_after:wN \@@_basics_pack_high:NNNNNw
@@ -994,9 +1002,9 @@
% \begin{quote}
% \cs{@@_div_npos_o:Nww} \meta{final sign}
% \cs{s_@@} \cs{@@_chk:w} |1| \meta{sign_A} \Arg{exp A}
-% \Arg{A_1} \Arg{A_2} \Arg{A_3} \Arg{A_4} |;|
+% \Arg{A_1} \Arg{A_2} \Arg{A_3} \Arg{A_4} \cs{@@_sep:}
% \cs{s_@@} \cs{@@_chk:w} |1| \meta{sign_Z} \Arg{exp Z}
-% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} |;|
+% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} \cs{@@_sep:}
% \end{quote}
% We want to compute $A/Z$. As for multiplication,
% \cs{@@_sanitize:Nw} checks for overflow or underflow; we provide it
@@ -1008,16 +1016,17 @@
% semi-colon, and the \meta{final sign}, used for rounding at the end.
% \begin{macrocode}
\cs_new:Npn \@@_div_npos_o:Nww
- #1 \s_@@ \@@_chk:w 1 #2 #3 #4 ; \s_@@ \@@_chk:w 1 #5 #6 #7#8#9;
+ #1 \s_@@ \@@_chk:w 1 #2 #3 #4 \@@_sep:
+ \s_@@ \@@_chk:w 1 #5 #6 #7#8#9\@@_sep:
{
\exp_after:wN \@@_sanitize:Nw
\exp_after:wN #1
\int_value:w \@@_int_eval:w
#3 - #6
\exp_after:wN \@@_div_significand_i_o:wnnw
- \int_value:w \@@_int_eval:w #7 \use_i:nnnn #8 + 1 ;
+ \int_value:w \@@_int_eval:w #7 \use_i:nnnn #8 + 1 \@@_sep:
#4
- {#7}{#8}#9 ;
+ {#7}{#8}#9 \@@_sep:
#1
}
% \end{macrocode}
@@ -1196,9 +1205,9 @@
%
% \begin{macro}[rEXP]{\@@_div_significand_i_o:wnnw}
% \begin{quote}
-% \cs{@@_div_significand_i_o:wnnw} \meta{y} |;|
+% \cs{@@_div_significand_i_o:wnnw} \meta{y} \cs{@@_sep:}
% \Arg{A_1} \Arg{A_2} \Arg{A_3} \Arg{A_4}
-% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} |;| \meta{sign}
+% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} \cs{@@_sep:} \meta{sign}
% \end{quote}
% Compute $10^{6} + Q_{A}$ (a $7$~digit number thanks to the shift),
% unbrace \meta{A_1} and \meta{A_2}, and prepare the
@@ -1208,13 +1217,13 @@
% hence the \cs{int_value:w}. Here, |#4| is six brace groups, which
% give the six first |n|-type arguments of the \texttt{calc} function.
% \begin{macrocode}
-\cs_new:Npn \@@_div_significand_i_o:wnnw #1 ; #2#3 #4 ;
+\cs_new:Npn \@@_div_significand_i_o:wnnw #1 \@@_sep: #2#3 #4 \@@_sep:
{
\exp_after:wN \@@_div_significand_test_o:w
\int_value:w \@@_int_eval:w
\exp_after:wN \@@_div_significand_calc:wwnnnnnnn
- \int_value:w \@@_int_eval:w 999999 + #2 #3 0 / #1 ;
- #2 #3 ;
+ \int_value:w \@@_int_eval:w 999999 + #2 #3 0 / #1 \@@_sep:
+ #2 #3 \@@_sep:
#4
{ \exp_after:wN \@@_div_significand_ii:wwn \int_value:w #1 }
{ \exp_after:wN \@@_div_significand_ii:wwn \int_value:w #1 }
@@ -1231,15 +1240,15 @@
% \@@_div_significand_calc_ii:wwnnnnnnn,
% }
% \begin{quote}
-% \cs{@@_div_significand_calc:wwnnnnnnn} \meta{$10^{6}+{}$Q_{A}} |;|
-% \meta{A_1} \meta{A_2} |;| \Arg{A_3} \Arg{A_4}
+% \cs{@@_div_significand_calc:wwnnnnnnn} \meta{$10^{6}+{}$Q_{A}} \cs{@@_sep:}
+% \meta{A_1} \meta{A_2} \cs{@@_sep:} \Arg{A_3} \Arg{A_4}
% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4}
% \Arg{continuation}
% \end{quote}
% expands to
% \begin{quote}
-% \meta{$10^{6}+{}$Q_{A}} \meta{continuation} |;|
-% \meta{B_1} \meta{B_2} |;| \Arg{B_3} \Arg{B_4}
+% \meta{$10^{6}+{}$Q_{A}} \meta{continuation} \cs{@@_sep:}
+% \meta{B_1} \meta{B_2} \cs{@@_sep:} \Arg{B_3} \Arg{B_4}
% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4}
% \end{quote}
% where $B = 10^{4} A - Q_{A} \cdot Z$. This function is also used to
@@ -1292,10 +1301,10 @@
\fi:
}
\cs_new:Npn \@@_div_significand_calc_i:wwnnnnnnn
- #1; #2;#3#4 #5#6#7#8 #9
+ #1\@@_sep: #2\@@_sep:#3#4 #5#6#7#8 #9
{
1 1 #1
- #9 \exp_after:wN ;
+ #9 \exp_after:wN \@@_sep:
\int_value:w \@@_int_eval:w \c_@@_Bigg_leading_shift_int
+ #2 - #1 * #5 - #5#60
\exp_after:wN \@@_pack_Bigg:NNNNNNw
@@ -1306,14 +1315,14 @@
+ #4 - #1 * #7 - #80
\exp_after:wN \@@_pack_Bigg:NNNNNNw
\int_value:w \@@_int_eval:w \c_@@_Bigg_trailing_shift_int
- - #1 * #8 ;
+ - #1 * #8 \@@_sep:
{#5}{#6}{#7}{#8}
}
\cs_new:Npn \@@_div_significand_calc_ii:wwnnnnnnn
- #1; #2;#3#4 #5#6#7#8 #9
+ #1\@@_sep: #2\@@_sep:#3#4 #5#6#7#8 #9
{
1 0 #1
- #9 \exp_after:wN ;
+ #9 \exp_after:wN \@@_sep:
\int_value:w \@@_int_eval:w \c_@@_Bigg_leading_shift_int
+ #2 - #1 * #5
\exp_after:wN \@@_pack_Bigg:NNNNNNw
@@ -1324,7 +1333,7 @@
+ #4 - #1 * #7
\exp_after:wN \@@_pack_Bigg:NNNNNNw
\int_value:w \@@_int_eval:w \c_@@_Bigg_trailing_shift_int
- - #1 * #8 ;
+ - #1 * #8 \@@_sep:
{#5}{#6}{#7}{#8}
}
% \end{macrocode}
@@ -1333,8 +1342,8 @@
%
% \begin{macro}[EXP]{\@@_div_significand_ii:wwn}
% \begin{quote}
-% \cs{@@_div_significand_ii:wwn} \meta{y} |;|
-% \meta{B_1} |;| \Arg{B_2} \Arg{B_3} \Arg{B_4}
+% \cs{@@_div_significand_ii:wwn} \meta{y} \cs{@@_sep:}
+% \meta{B_1} \cs{@@_sep:} \Arg{B_2} \Arg{B_3} \Arg{B_4}
% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4}
% \meta{continuations} \meta{sign}
% \end{quote}
@@ -1347,20 +1356,21 @@
% auxiliary is also used to compute $Q_{C}$ and $Q_{D}$ with the
% inputs $C$ and $D$ instead of $B$.
% \begin{macrocode}
-\cs_new:Npn \@@_div_significand_ii:wwn #1; #2;#3
+\cs_new:Npn \@@_div_significand_ii:wwn #1\@@_sep: #2\@@_sep:#3
{
\exp_after:wN \@@_div_significand_pack:NNN
\int_value:w \@@_int_eval:w
\exp_after:wN \@@_div_significand_calc:wwnnnnnnn
- \int_value:w \@@_int_eval:w 999999 + #2 #3 0 / #1 ; #2 #3 ;
+ \int_value:w \@@_int_eval:w
+ 999999 + #2 #3 0 / #1 \@@_sep: #2 #3 \@@_sep:
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[rEXP]{\@@_div_significand_iii:wwnnnnn}
% \begin{quote}
-% \cs{@@_div_significand_iii:wwnnnnn} \meta{y} |;|
-% \meta{E_1} |;| \Arg{E_2} \Arg{E_3} \Arg{E_4}
+% \cs{@@_div_significand_iii:wwnnnnn} \meta{y} \cs{@@_sep:}
+% \meta{E_1} \cs{@@_sep:} \Arg{E_2} \Arg{E_3} \Arg{E_4}
% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} \meta{sign}
% \end{quote}
% We compute $P \simeq 2E/Z$ by rounding $2 E_{1} E_{2}/Z_{1}Z_{2}$.
@@ -1368,12 +1378,12 @@
% add (roughly) $5\cdot P$, which amounts to adding $P/2 \simeq E/Z$
% to $Q_{D}$, the appropriate correction from a hypothetical $Q_{E}$.
% \begin{macrocode}
-\cs_new:Npn \@@_div_significand_iii:wwnnnnn #1; #2;#3#4#5 #6#7
+\cs_new:Npn \@@_div_significand_iii:wwnnnnn #1\@@_sep: #2\@@_sep:#3#4#5 #6#7
{
0
\exp_after:wN \@@_div_significand_iv:wwnnnnnnn
- \int_value:w \@@_int_eval:w ( 2 * #2 #3) / #6 #7 ; % <- P
- #2 ; {#3} {#4} {#5}
+ \int_value:w \@@_int_eval:w ( 2 * #2 #3) / #6 #7 \@@_sep: % <- P
+ #2 \@@_sep: {#3} {#4} {#5}
{#6} {#7}
}
% \end{macrocode}
@@ -1386,8 +1396,8 @@
% \@@_div_significand_vi:Nw
% }
% \begin{quote}
-% \cs{@@_div_significand_iv:wwnnnnnnn} \meta{P} |;|
-% \meta{E_1} |;| \Arg{E_2} \Arg{E_3} \Arg{E_4}
+% \cs{@@_div_significand_iv:wwnnnnnnn} \meta{P} \cs{@@_sep:}
+% \meta{E_1} \cs{@@_sep:} \Arg{E_2} \Arg{E_3} \Arg{E_4}
% \Arg{Z_1} \Arg{Z_2} \Arg{Z_3} \Arg{Z_4} \meta{sign}
% \end{quote}
% This adds to the current expression ($10^{7} + 10\cdot Q_{D}$) a
@@ -1427,7 +1437,8 @@
% argument of \cs{@@_div_significand_vi:Nw}, a sum of several terms, is
% also zero. Otherwise, there was an exact agreement: $T = 0$.
% \begin{macrocode}
-\cs_new:Npn \@@_div_significand_iv:wwnnnnnnn #1; #2;#3#4#5 #6#7#8#9
+\cs_new:Npn \@@_div_significand_iv:wwnnnnnnn
+ #1\@@_sep: #2\@@_sep:#3#4#5 #6#7#8#9
{
+ 5 * #1
\exp_after:wN \@@_div_significand_vi:Nw
@@ -1435,17 +1446,17 @@
\exp_after:wN \@@_div_significand_v:NN
\int_value:w \@@_int_eval:w 499950 + 2*#4 - #1*#8 +
\exp_after:wN \@@_div_significand_v:NN
- \int_value:w \@@_int_eval:w 500000 + 2*#5 - #1*#9 ;
+ \int_value:w \@@_int_eval:w 500000 + 2*#5 - #1*#9 \@@_sep:
}
\cs_new:Npn \@@_div_significand_v:NN #1#2 { #1#2 \@@_int_eval_end: + }
-\cs_new:Npn \@@_div_significand_vi:Nw #1#2;
+\cs_new:Npn \@@_div_significand_vi:Nw #1#2\@@_sep:
{
\if_meaning:w 0 #1
\if_int_compare:w \@@_int_eval:w #2 > 0 + 1 \fi:
\else:
\if_meaning:w - #1 - \else: + \fi: 1
\fi:
- ;
+ \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -1459,7 +1470,7 @@
% \cs{@@_div_significand_pack:NNN} $10^{6} + Q_{B}$
% \cs{@@_div_significand_pack:NNN} $10^{6} + Q_{C}$
% \cs{@@_div_significand_pack:NNN}
-% $10^{7} + 10\cdot Q_{D} + 5 \cdot P + \varepsilon$ |;| \meta{sign}
+% $10^{7} + 10\cdot Q_{D} + 5 \cdot P + \varepsilon$ \cs{@@_sep:} \meta{sign}
% \end{quote}
% Here, $\varepsilon = \operatorname{sign}(T)$ is $0$ in case $2E=PZ$,
% $1$ in case $2E>PZ$, which means that $P$ was the correct value, but
@@ -1468,14 +1479,14 @@
% nothing special: it removes the $10^{6}$ and carries two digits (for
% the $10^{5}$'s and the $10^{4}$'s).
% \begin{macrocode}
-\cs_new:Npn \@@_div_significand_pack:NNN 1 #1 #2 { + #1 #2 ; }
+\cs_new:Npn \@@_div_significand_pack:NNN 1 #1 #2 { + #1 #2 \@@_sep: }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[rEXP]{\@@_div_significand_test_o:w}
% \begin{quote}
-% \cs{@@_div_significand_test_o:w} |1| |0| \meta{5d} |;|
-% ~~\meta{4d} |;| \meta{4d} |;| \meta{5d} |;| \meta{sign}
+% \cs{@@_div_significand_test_o:w} |1| |0| \meta{5d} \cs{@@_sep:}
+% ~~\meta{4d} \cs{@@_sep:} \meta{4d} \cs{@@_sep:} \meta{5d} \cs{@@_sep:} \meta{sign}
% \end{quote}
% The reason we know that the first two digits are |1| and |0| is that
% the final result is known to be between $0.1$ (inclusive) and $10$,
@@ -1500,30 +1511,30 @@
%
% \begin{macro}[EXP]{\@@_div_significand_small_o:wwwNNNNwN}
% \begin{quote}
-% \cs{@@_div_significand_small_o:wwwNNNNwN} |0| \meta{4d} |;|
-% ~~\meta{4d} |;| \meta{4d} |;| \meta{5d} |;| \meta{final sign}
+% \cs{@@_div_significand_small_o:wwwNNNNwN} |0| \meta{4d} \cs{@@_sep:}
+% ~~\meta{4d} \cs{@@_sep:} \meta{4d} \cs{@@_sep:} \meta{5d} \cs{@@_sep:} \meta{final sign}
% \end{quote}
% Standard use of the functions \cs{@@_basics_pack_low:NNNNNw} and
% \cs{@@_basics_pack_high:NNNNNw}. We finally get to use the
% \meta{final sign} which has been sitting there for a while.
% \begin{macrocode}
\cs_new:Npn \@@_div_significand_small_o:wwwNNNNwN
- 0 #1; #2; #3; #4#5#6#7#8; #9
+ 0 #1\@@_sep: #2\@@_sep: #3\@@_sep: #4#5#6#7#8\@@_sep: #9
{
\exp_after:wN \@@_basics_pack_high:NNNNNw
\int_value:w \@@_int_eval:w 1 #1#2
\exp_after:wN \@@_basics_pack_low:NNNNNw
\int_value:w \@@_int_eval:w 1 #3#4#5#6#7
+ \@@_round:NNN #9 #7 #8
- \exp_after:wN ;
+ \exp_after:wN \@@_sep:
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[rEXP]{\@@_div_significand_large_o:wwwNNNNwN}
% \begin{quote}
-% \cs{@@_div_significand_large_o:wwwNNNNwN} \meta{5d} |;|
-% ~~\meta{4d} |;| \meta{4d} |;| \meta{5d} |;| \meta{sign}
+% \cs{@@_div_significand_large_o:wwwNNNNwN} \meta{5d} \cs{@@_sep:}
+% ~~\meta{4d} \cs{@@_sep:} \meta{4d} \cs{@@_sep:} \meta{5d} \cs{@@_sep:} \meta{sign}
% \end{quote}
% We know that the final result cannot reach $10$, hence |1#1#2|,
% together with contributions from the level below, cannot reach
@@ -1531,7 +1542,7 @@
% from the last two of our $18$ digits.
% \begin{macrocode}
\cs_new:Npn \@@_div_significand_large_o:wwwNNNNwN
- #1; #2; #3; #4#5#6#7#8; #9
+ #1\@@_sep: #2\@@_sep: #3\@@_sep: #4#5#6#7#8\@@_sep: #9
{
+ 1
\exp_after:wN \@@_basics_pack_weird_high:NNNNNNNNw
@@ -1541,8 +1552,8 @@
\exp_after:wN \@@_round:NNN
\exp_after:wN #9
\exp_after:wN #6
- \int_value:w \@@_round_digit:Nw #7 #8 ;
- \exp_after:wN ;
+ \int_value:w \@@_round_digit:Nw #7 #8 \@@_sep:
+ \exp_after:wN \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -1555,7 +1566,7 @@
% Positive infinity, and \texttt{nan}, are unchanged. Finally, for
% normal positive numbers, there is some work to do.
% \begin{macrocode}
-\cs_new:Npn \@@_sqrt_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+\cs_new:Npn \@@_sqrt_o:w #1 \s_@@ \@@_chk:w #2#3#4\@@_sep: @
{
\if_meaning:w 0 #2 \@@_case_return_same_o:w \fi:
\if_meaning:w 2 #3
@@ -1563,7 +1574,7 @@
\fi:
\if_meaning:w 1 #2 \else: \@@_case_return_same_o:w \fi:
\@@_sqrt_npos_o:w
- \s_@@ \@@_chk:w #2 #3 #4;
+ \s_@@ \@@_chk:w #2 #3 #4\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -1581,7 +1592,7 @@
% $a_1'\in[10^{6}, 10^{7})$ instead of $[10^{7}, 10^{8})$, then use
% Newton's method starting at $17782794 \simeq 10^{7.25}$.
% \begin{macrocode}
-\cs_new:Npn \@@_sqrt_npos_o:w \s_@@ \@@_chk:w 1 0 #1#2#3#4#5;
+\cs_new:Npn \@@_sqrt_npos_o:w \s_@@ \@@_chk:w 1 0 #1#2#3#4#5\@@_sep:
{
\exp_after:wN \@@_sanitize:Nw
\exp_after:wN 0
@@ -1590,18 +1601,18 @@
\exp_after:wN \@@_sqrt_npos_auxi_o:wwnnN
\fi:
#1 / 2
- \@@_sqrt_Newton_o:wwn 56234133; 0; {#2#3} {#4#5} 0
+ \@@_sqrt_Newton_o:wwn 56234133\@@_sep: 0\@@_sep: {#2#3} {#4#5} 0
}
-\cs_new:Npn \@@_sqrt_npos_auxi_o:wwnnN #1 / 2 #2; 0; #3#4#5
+\cs_new:Npn \@@_sqrt_npos_auxi_o:wwnnN #1 / 2 #2\@@_sep: 0\@@_sep: #3#4#5
{
( #1 + 1 ) / 2
\@@_pack_eight:wNNNNNNNN
\@@_sqrt_npos_auxii_o:wNNNNNNNN
- ;
+ \@@_sep:
0 #3 #4
}
-\cs_new:Npn \@@_sqrt_npos_auxii_o:wNNNNNNNN #1; #2#3#4#5#6#7#8#9
- { \@@_sqrt_Newton_o:wwn 17782794; 0; {#1} {#2#3#4#5#6#7#8#9} }
+\cs_new:Npn \@@_sqrt_npos_auxii_o:wNNNNNNNN #1\@@_sep: #2#3#4#5#6#7#8#9
+ { \@@_sqrt_Newton_o:wwn 17782794\@@_sep: 0\@@_sep: {#1} {#2#3#4#5#6#7#8#9} }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1670,7 +1681,7 @@
% |#3 * 100000000 / #1|. In any case, the result is within $[10^{7},
% 10^{8}]$.
% \begin{macrocode}
-\cs_new:Npn \@@_sqrt_Newton_o:wwn #1; #2; #3
+\cs_new:Npn \@@_sqrt_Newton_o:wwn #1\@@_sep: #2\@@_sep: #3
{
\if_int_compare:w #1 = #2 \exp_stop_f:
\exp_after:wN \@@_sqrt_auxi_o:NNNNwnnN
@@ -1678,16 +1689,16 @@
\exp_after:wN \@@_use_none_until_s:w
\fi:
\exp_after:wN \@@_sqrt_Newton_o:wwn
- \int_value:w \@@_int_eval:w (#1 + #3 * 1 0000 0000 / #1) / 2 ;
- #1; {#3}
+ \int_value:w \@@_int_eval:w (#1 + #3 * 1 0000 0000 / #1) / 2 \@@_sep:
+ #1\@@_sep: {#3}
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[rEXP]{\@@_sqrt_auxi_o:NNNNwnnN}
% This function is followed by $10^{8}+x-1$, which has~$9$ digits
-% starting with~$1$, then |;| \Arg{a_1} \Arg{a_2} \meta{a'}. Here, $x
-% \simeq \sqrt{10^{8} a_1}$ and we want to estimate the square root of
+% starting with~$1$, then \cs{@@_sep:} \Arg{a_1} \Arg{a_2} \meta{a'}. Here,
+% $x \simeq \sqrt{10^{8} a_1}$ and we want to estimate the square root of
% $a = 10^{-8} a_1 + 10^{-16} a_2 + 10^{-17} a'$. We set up an
% initial underestimate
% \[
@@ -1708,7 +1719,7 @@
% construction, the underestimates~$y$ are always increasing, $a - y^2
% < 3.2 \cdot 10^{-8}$ for all. Also, $y<1$.
% \begin{macrocode}
-\cs_new:Npn \@@_sqrt_auxi_o:NNNNwnnN 1 #1#2#3#4#5;
+\cs_new:Npn \@@_sqrt_auxi_o:NNNNwnnN 1 #1#2#3#4#5\@@_sep:
{
\@@_sqrt_auxii_o:NnnnnnnnN
\@@_sqrt_auxiii_o:wnnnnnnnn
@@ -1794,9 +1805,9 @@
\exp_after:wN \@@_pack_big:NNNNNNw
\int_value:w \@@_int_eval:w
\c_@@_big_trailing_shift_int
- - #6 * #6 ;
+ - #6 * #6 \@@_sep:
% (
- - 257 ) * 5000 0000 / (#2#3 + 1) + 10 0000 0000 ;
+ - 257 ) * 5000 0000 / (#2#3 + 1) + 10 0000 0000 \@@_sep:
{#2}{#3}{#4}{#5}{#6} {#7}{#8}#9
}
% \end{macrocode}
@@ -1811,8 +1822,8 @@
% \@@_sqrt_auxvii_o:NNNNNw
% }
% We receive here the difference $a-y^2=d=\sum_i d_i \cdot 10^{-4i}$,
-% as \meta{d_2} |;| \Arg{d_3} \ldots{} \Arg{d_{10}}, where each block
-% has~$4$ digits, except \meta{d_2}. This function finds the largest
+% as \meta{d_2} \cs{@@_sep:} \Arg{d_3} \ldots{} \Arg{d_{10}}, where each
+% block has~$4$ digits, except \meta{d_2}. This function finds the largest
% $j\leq 6$ such that $10^{4j}(a-y^2) < 2\cdot 10^{8}$, then leaves an
% open parenthesis and the integer
% $\bigl\lfloor 10^{4j}(a-y^2)\bigr\rfloor$ in an integer
@@ -1846,7 +1857,7 @@
% \]
% \begin{macrocode}
\cs_new:Npn \@@_sqrt_auxiii_o:wnnnnnnnn
- #1; #2#3#4#5#6#7#8#9
+ #1\@@_sep: #2#3#4#5#6#7#8#9
{
\if_int_compare:w #1 > \c_one_int
\exp_after:wN \@@_sqrt_auxiv_o:NNNNNw
@@ -1866,13 +1877,13 @@
\fi:
\fi:
}
-\cs_new:Npn \@@_sqrt_auxiv_o:NNNNNw 1#1#2#3#4#5#6;
+\cs_new:Npn \@@_sqrt_auxiv_o:NNNNNw 1#1#2#3#4#5#6\@@_sep:
{ \@@_sqrt_auxviii_o:nnnnnnn {#1#2#3#4#5#6} {00000000} }
-\cs_new:Npn \@@_sqrt_auxv_o:NNNNNw 1#1#2#3#4#5#6;
+\cs_new:Npn \@@_sqrt_auxv_o:NNNNNw 1#1#2#3#4#5#6\@@_sep:
{ \@@_sqrt_auxviii_o:nnnnnnn {000#1#2#3#4#5} {#60000} }
-\cs_new:Npn \@@_sqrt_auxvi_o:NNNNNw 1#1#2#3#4#5#6;
+\cs_new:Npn \@@_sqrt_auxvi_o:NNNNNw 1#1#2#3#4#5#6\@@_sep:
{ \@@_sqrt_auxviii_o:nnnnnnn {0000000#1} {#2#3#4#5#6} }
-\cs_new:Npn \@@_sqrt_auxvii_o:NNNNNw 1#1#2#3#4#5#6;
+\cs_new:Npn \@@_sqrt_auxvii_o:NNNNNw 1#1#2#3#4#5#6\@@_sep:
{
\if_int_compare:w #1#2 = \c_zero_int
\exp_after:wN \@@_sqrt_auxx_o:Nnnnnnnn
@@ -1895,9 +1906,9 @@
\exp_after:wN \@@_basics_pack_low:NNNNNw
\int_value:w \@@_int_eval:w #1 + 1#4#5
\exp_after:wN \@@_basics_pack_low:NNNNNw
- \int_value:w \@@_int_eval:w #2 + 1#6#7 ;
+ \int_value:w \@@_int_eval:w #2 + 1#6#7 \@@_sep:
}
-\cs_new:Npn \@@_sqrt_auxix_o:wnwnw #1; #2#3; #4#5;
+\cs_new:Npn \@@_sqrt_auxix_o:wnwnw #1\@@_sep: #2#3\@@_sep: #4#5\@@_sep:
{
\@@_sqrt_auxii_o:NnnnnnnnN
\@@_sqrt_auxiii_o:wnnnnnnnn {#1}{#2}{#3}{#4}{#5}
@@ -1942,10 +1953,10 @@
{
\exp_after:wN \@@_sqrt_auxxi_o:wwnnN
\int_value:w \@@_int_eval:w
- (#8 + 2499) / 5000 * 5000 ;
- {#4} {#5} {#6} {#7} ;
+ (#8 + 2499) / 5000 * 5000 \@@_sep:
+ {#4} {#5} {#6} {#7} \@@_sep:
}
-\cs_new:Npn \@@_sqrt_auxxi_o:wwnnN #1; #2; #3#4#5
+\cs_new:Npn \@@_sqrt_auxxi_o:wwnnN #1\@@_sep: #2\@@_sep: #3#4#5
{
\@@_sqrt_auxii_o:NnnnnnnnN
\@@_sqrt_auxxii_o:nnnnnnnnw
@@ -1967,7 +1978,7 @@
% \texttt{auxxiv} function with argument~$9998$. For an exact result
% call it with~$9999$, and for an overestimate call it with~$10000$.
% \begin{macrocode}
-\cs_new:Npn \@@_sqrt_auxxii_o:nnnnnnnnw 0; #1#2#3#4#5#6#7#8 #9;
+\cs_new:Npn \@@_sqrt_auxxii_o:nnnnnnnnw 0\@@_sep: #1#2#3#4#5#6#7#8 #9\@@_sep:
{
\if_int_compare:w #1#2 > \c_zero_int
\if_int_compare:w #1#2 = \c_one_int
@@ -1985,12 +1996,12 @@
\exp_after:wN \@@_sqrt_auxxiv_o:wnnnnnnnN
\int_value:w 10000
\fi:
- ;
+ \@@_sep:
}
-\cs_new:Npn \@@_sqrt_auxxiii_o:w \fi: \fi: \fi: \fi: #1 \fi: ;
+\cs_new:Npn \@@_sqrt_auxxiii_o:w \fi: \fi: \fi: \fi: #1 \fi: \@@_sep:
{
\fi: \fi: \fi: \fi: \fi:
- \@@_sqrt_auxxiv_o:wnnnnnnnN 9999 ;
+ \@@_sqrt_auxxiv_o:wnnnnnnnN 9999 \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -2016,7 +2027,7 @@
% $0001$, $4999$, $5000$, $5001$, or~$9999$, which it converts to $0$,
% $1$, $4$, $5$, $6$, and~$9$, respectively.
% \begin{macrocode}
-\cs_new:Npn \@@_sqrt_auxxiv_o:wnnnnnnnN #1; #2#3#4#5#6 #7#8#9
+\cs_new:Npn \@@_sqrt_auxxiv_o:wnnnnnnnN #1\@@_sep: #2#3#4#5#6 #7#8#9
{
\exp_after:wN \@@_basics_pack_high:NNNNNw
\int_value:w \@@_int_eval:w 1 0000 0000 + #2#3
@@ -2030,8 +2041,8 @@
\int_value:w
\exp_after:wN \use_i:nn
\exp_after:wN \@@_round_digit:Nw
- \int_value:w \@@_int_eval:w #6 + 19999 - #1 ;
- \exp_after:wN ;
+ \int_value:w \@@_int_eval:w #6 + 19999 - #1 \@@_sep:
+ \exp_after:wN \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -2041,7 +2052,7 @@
% \begin{macro}[EXP]{\@@_logb_o:w, \@@_logb_aux_o:w}
% The exponent of a normal number is its \meta{exponent} minus one.
% \begin{macrocode}
-\cs_new:Npn \@@_logb_o:w ? \s_@@ \@@_chk:w #1#2; @
+\cs_new:Npn \@@_logb_o:w ? \s_@@ \@@_chk:w #1#2\@@_sep: @
{
\if_case:w #1 \exp_stop_f:
\@@_case_use:nw
@@ -2050,9 +2061,9 @@
\or: \@@_case_return_o:Nw \c_inf_fp
\else: \@@_case_return_same_o:w
\fi:
- \s_@@ \@@_chk:w #1 #2;
+ \s_@@ \@@_chk:w #1 #2\@@_sep:
}
-\cs_new:Npn \@@_logb_aux_o:w \s_@@ \@@_chk:w #1 #2 #3 #4 ;
+\cs_new:Npn \@@_logb_aux_o:w \s_@@ \@@_chk:w #1 #2 #3 #4 \@@_sep:
{
\exp_after:wN \@@_parse:n \exp_after:wN
{ \int_value:w \int_eval:w #3 - 1 \exp_after:wN }
@@ -2064,7 +2075,7 @@
% \begin{macro}[EXP]{\@@_sign_aux_o:w}
% Find the sign of the floating point: \texttt{nan}, |+0|, |-0|, |+1| or |-1|.
% \begin{macrocode}
-\cs_new:Npn \@@_sign_o:w ? \s_@@ \@@_chk:w #1#2; @
+\cs_new:Npn \@@_sign_o:w ? \s_@@ \@@_chk:w #1#2\@@_sep: @
{
\if_case:w #1 \exp_stop_f:
\@@_case_return_same_o:w
@@ -2072,9 +2083,9 @@
\or: \exp_after:wN \@@_sign_aux_o:w
\else: \@@_case_return_same_o:w
\fi:
- \s_@@ \@@_chk:w #1 #2;
+ \s_@@ \@@_chk:w #1 #2\@@_sep:
}
-\cs_new:Npn \@@_sign_aux_o:w \s_@@ \@@_chk:w #1 #2 #3 ;
+\cs_new:Npn \@@_sign_aux_o:w \s_@@ \@@_chk:w #1 #2 #3 \@@_sep:
{ \exp_after:wN \@@_set_sign_o:w \exp_after:wN #2 \c_one_fp @ }
% \end{macrocode}
% \end{macro}
@@ -2088,7 +2099,7 @@
% also expands after itself in the input stream, just like
% \cs{@@_+_o:ww}.
% \begin{macrocode}
-\cs_new:Npn \@@_set_sign_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+\cs_new:Npn \@@_set_sign_o:w #1 \s_@@ \@@_chk:w #2#3#4\@@_sep: @
{
\exp_after:wN \@@_exp_after_o:w
\exp_after:wN \s_@@
@@ -2096,7 +2107,7 @@
\exp_after:wN #2
\int_value:w
\if_case:w #3 \exp_stop_f: #1 \or: 1 \or: 0 \fi: \exp_stop_f:
- #4;
+ #4\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -2120,11 +2131,11 @@
}
\cs_new:Npn \@@_tuple_set_sign_aux_o:Nnw #1#2
{ \@@_tuple_map_o:nw \@@_tuple_set_sign_aux_o:w }
-\cs_new:Npn \@@_tuple_set_sign_aux_o:w #1#2 ;
+\cs_new:Npn \@@_tuple_set_sign_aux_o:w #1#2 \@@_sep:
{
\@@_change_func_type:NNN #1 \@@_set_sign_o:w
\@@_parse_apply_unary_error:NNw
- 2 #1 #2 ; @
+ 2 #1 #2 \@@_sep: @
}
% \end{macrocode}
% \end{macro}
@@ -2137,12 +2148,18 @@
% Importantly we need to dispatch according to the type, and we make
% sure to apply the operator in the correct order.
% \begin{macrocode}
-\cs_new:cpn { @@_*_tuple_o:ww } #1 ;
- { \@@_tuple_map_o:nw { \@@_binary_type_o:Nww * #1 ; } }
-\cs_new:cpn { @@_tuple_*_o:ww } #1 ; #2 ;
- { \@@_tuple_map_o:nw { \@@_binary_rev_type_o:Nww * #2 ; } #1 ; }
-\cs_new:cpn { @@_tuple_/_o:ww } #1 ; #2 ;
- { \@@_tuple_map_o:nw { \@@_binary_rev_type_o:Nww / #2 ; } #1 ; }
+\cs_new:cpn { @@_*_tuple_o:ww } #1 \@@_sep:
+ { \@@_tuple_map_o:nw { \@@_binary_type_o:Nww * #1 \@@_sep: } }
+\cs_new:cpn { @@_tuple_*_o:ww } #1 \@@_sep: #2 \@@_sep:
+ {
+ \@@_tuple_map_o:nw { \@@_binary_rev_type_o:Nww * #2 \@@_sep: }
+ #1 \@@_sep:
+ }
+\cs_new:cpn { @@_tuple_/_o:ww } #1 \@@_sep: #2 \@@_sep:
+ {
+ \@@_tuple_map_o:nw { \@@_binary_rev_type_o:Nww / #2 \@@_sep: }
+ #1 \@@_sep:
+ }
% \end{macrocode}
% \end{macro}
%
@@ -2154,15 +2171,15 @@
\cs_set_protected:Npn \@@_tmp:w #1
{
\cs_new:cpn { @@_tuple_#1_tuple_o:ww }
- \s_@@_tuple \@@_tuple_chk:w ##1 ;
- \s_@@_tuple \@@_tuple_chk:w ##2 ;
+ \s_@@_tuple \@@_tuple_chk:w ##1 \@@_sep:
+ \s_@@_tuple \@@_tuple_chk:w ##2 \@@_sep:
{
\int_compare:nNnTF
{ \@@_array_count:n {##1} } = { \@@_array_count:n {##2} }
{ \@@_tuple_mapthread_o:nww { \@@_binary_type_o:Nww #1 } }
{ \@@_invalid_operation_o:nww #1 }
- \s_@@_tuple \@@_tuple_chk:w {##1} ;
- \s_@@_tuple \@@_tuple_chk:w {##2} ;
+ \s_@@_tuple \@@_tuple_chk:w {##1} \@@_sep:
+ \s_@@_tuple \@@_tuple_chk:w {##2} \@@_sep:
}
}
\@@_tmp:w +
diff --git a/macros/latex-dev/required/l3kernel/l3fp-convert.dtx b/macros/latex-dev/required/l3kernel/l3fp-convert.dtx
index 4983a3dd1f..085ebf4028 100644
--- a/macros/latex-dev/required/l3kernel/l3fp-convert.dtx
+++ b/macros/latex-dev/required/l3kernel/l3fp-convert.dtx
@@ -2,7 +2,7 @@
%
%% File: l3fp-convert.dtx
%
-% Copyright (C) 2011-2024 The LaTeX Project
+% Copyright (C) 2011-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -72,7 +72,7 @@
% representation. We loop through all items, putting |,~| between all
% of them and making sure to remove the leading |,~|.
% \begin{macrocode}
-\cs_new:Npn \@@_tuple_convert:Nw #1 \s_@@_tuple \@@_tuple_chk:w #2 ;
+\cs_new:Npn \@@_tuple_convert:Nw #1 \s_@@_tuple \@@_tuple_chk:w #2 \@@_sep:
{
\int_case:nnF { \@@_array_count:n {#2} }
{
@@ -81,14 +81,14 @@
}
{
\@@_tuple_convert_loop:nNw { } #1
- #2 { ? \@@_tuple_convert_end:w } ;
+ #2 { ? \@@_tuple_convert_end:w } \@@_sep:
@ { \use_none:nn }
}
}
-\cs_new:Npn \@@_tuple_convert_loop:nNw #1#2#3#4; #5 @ #6
+\cs_new:Npn \@@_tuple_convert_loop:nNw #1#2#3#4\@@_sep: #5 @ #6
{
\use_none:n #3
- \exp_args:Nf \@@_tuple_convert_loop:nNw { #2 #3#4 ; } #2 #5
+ \exp_args:Nf \@@_tuple_convert_loop:nNw { #2 #3#4 \@@_sep: } #2 #5
@ { #6 , ~ #1 }
}
\cs_new:Npn \@@_tuple_convert_end:w #1 @ #2
@@ -108,14 +108,17 @@
% which removes a trailing dot if any. We then clean-up with the
% \texttt{end} auxiliary, keeping only the number.
% \begin{macrocode}
-\cs_new:Npn \@@_trim_zeros:w #1 ;
+\cs_new:Npn \@@_trim_zeros:w #1 \@@_sep:
{
- \@@_trim_zeros_loop:w #1
- ; \@@_trim_zeros_loop:w 0; \@@_trim_zeros_dot:w .; \s_@@_stop
+ \@@_trim_zeros_loop:w #1 \@@_sep:
+ \@@_trim_zeros_loop:w 0\@@_sep:
+ \@@_trim_zeros_dot:w .\@@_sep:
+ \s_@@_stop
}
-\cs_new:Npn \@@_trim_zeros_loop:w #1 0; #2 { #2 #1 ; #2 }
-\cs_new:Npn \@@_trim_zeros_dot:w #1 .; { \@@_trim_zeros_end:w #1 ; }
-\cs_new:Npn \@@_trim_zeros_end:w #1 ; #2 \s_@@_stop { #1 }
+\cs_new:Npn \@@_trim_zeros_loop:w #1 0\@@_sep: #2 { #2 #1 \@@_sep: #2 }
+\cs_new:Npn \@@_trim_zeros_dot:w #1 .\@@_sep:
+ { \@@_trim_zeros_end:w #1 \@@_sep: }
+\cs_new:Npn \@@_trim_zeros_end:w #1 \@@_sep: #2 \s_@@_stop { #1 }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -148,9 +151,9 @@
#1 \@@_to_scientific:w \@@_to_scientific_recover:w
#1
}
-\cs_new:Npn \@@_to_scientific_recover:w #1 #2 ;
+\cs_new:Npn \@@_to_scientific_recover:w #1 #2 \@@_sep:
{
- \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { }
+ \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 \@@_sep: } } { } { }
nan
}
\cs_new:Npn \@@_tuple_to_scientific:w
@@ -201,14 +204,14 @@
\s_@@ \@@_chk:w #1 #2
}
\cs_new:Npn \@@_to_scientific_normal:wnnnnn
- \s_@@ \@@_chk:w 1 #1 #2 #3#4#5#6 ;
+ \s_@@ \@@_chk:w 1 #1 #2 #3#4#5#6 \@@_sep:
{
\exp_after:wN \@@_to_scientific_normal:wNw
\exp_after:wN e
\int_value:w \@@_int_eval:w #2 - 1
- ; #3 #4 #5 #6 ;
+ \@@_sep: #3 #4 #5 #6 \@@_sep:
}
-\cs_new:Npn \@@_to_scientific_normal:wNw #1 ; #2#3;
+\cs_new:Npn \@@_to_scientific_normal:wNw #1 \@@_sep: #2#3\@@_sep:
{ #2.#3 #1 }
% \end{macrocode}
% \end{macro}
@@ -242,9 +245,9 @@
#1 \@@_to_decimal:w \@@_to_decimal_recover:w
#1
}
-\cs_new:Npn \@@_to_decimal_recover:w #1 #2 ;
+\cs_new:Npn \@@_to_decimal_recover:w #1 #2 \@@_sep:
{
- \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { }
+ \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 \@@_sep: } } { } { }
nan
}
\cs_new:Npn \@@_tuple_to_decimal:w
@@ -297,7 +300,7 @@
\s_@@ \@@_chk:w #1 #2
}
\cs_new:Npn \@@_to_decimal_normal:wnnnnn
- \s_@@ \@@_chk:w 1 #1 #2 #3#4#5#6 ;
+ \s_@@ \@@_chk:w 1 #1 #2 #3#4#5#6 \@@_sep:
{
\int_compare:nNnTF {#2} > 0
{
@@ -309,7 +312,7 @@
{
\exp_after:wN \exp_after:wN
\exp_after:wN \@@_to_decimal_huge:wnnnn
- \prg_replicate:nn { #2 - \c_@@_prec_int } { 0 } ;
+ \prg_replicate:nn { #2 - \c_@@_prec_int } { 0 } \@@_sep:
}
{#3} {#4} {#5} {#6}
}
@@ -318,19 +321,19 @@
\exp_after:wN 0
\exp_after:wN .
\exp:w \exp_end_continue_f:w \prg_replicate:nn { - #2 } { 0 }
- #3#4#5#6 ;
+ #3#4#5#6 \@@_sep:
}
}
-\cs_new:Npn \@@_to_decimal_large:Nnnw #1#2#3#4;
+\cs_new:Npn \@@_to_decimal_large:Nnnw #1#2#3#4\@@_sep:
{
\exp_after:wN \@@_trim_zeros:w \int_value:w
\if_int_compare:w #2 > \c_zero_int
#2
\fi:
\exp_stop_f:
- #3.#4 ;
+ #3.#4 \@@_sep:
}
-\cs_new:Npn \@@_to_decimal_huge:wnnnn #1; #2#3#4#5 { #2#3#4#5 #1 }
+\cs_new:Npn \@@_to_decimal_huge:wnnnn #1\@@_sep: #2#3#4#5 { #2#3#4#5 #1 }
% \end{macrocode}
% \end{macro}
%
@@ -355,9 +358,9 @@
% \begin{macrocode}
\cs_new:Npn \@@_to_tl_dispatch:w #1
{ \@@_change_func_type:NNN #1 \@@_to_tl:w \@@_to_tl_recover:w #1 }
-\cs_new:Npn \@@_to_tl_recover:w #1 #2 ;
+\cs_new:Npn \@@_to_tl_recover:w #1 #2 \@@_sep:
{
- \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { }
+ \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 \@@_sep: } } { } { }
nan
}
\cs_new:Npn \@@_tuple_to_tl:w
@@ -395,15 +398,15 @@
\s_@@ \@@_chk:w 1 0 {#1}
}
\cs_new:Npn \@@_to_tl_scientific:wnnnnn
- \s_@@ \@@_chk:w 1 #1 #2 #3#4#5#6 ;
+ \s_@@ \@@_chk:w 1 #1 #2 #3#4#5#6 \@@_sep:
{
\exp_after:wN \@@_to_tl_scientific:wNw
\exp_after:wN e
\int_value:w \@@_int_eval:w #2 - 1
- ; #3 #4 #5 #6 ;
+ \@@_sep: #3 #4 #5 #6 \@@_sep:
}
-\cs_new:Npn \@@_to_tl_scientific:wNw #1 ; #2#3;
- { \@@_trim_zeros:w #2.#3 ; #1 }
+\cs_new:Npn \@@_to_tl_scientific:wNw #1 \@@_sep: #2#3\@@_sep:
+ { \@@_trim_zeros:w #2.#3 \@@_sep: #1 }
% \end{macrocode}
% \end{macro}
%
@@ -431,14 +434,14 @@
\exp_after:wN \@@_to_dim_dispatch:w
\exp:w \exp_end_continue_f:w \@@_parse:n
}
-\cs_new:Npn \@@_to_dim_dispatch:w #1#2 ;
+\cs_new:Npn \@@_to_dim_dispatch:w #1#2 \@@_sep:
{
\@@_change_func_type:NNN #1 \@@_to_dim:w \@@_to_dim_recover:w
- #1 #2 ;
+ #1 #2 \@@_sep:
}
\cs_new:Npn \@@_to_dim_recover:w #1
{ \@@_invalid_operation:nnw { 0pt } { fp_to_dim } }
-\cs_new:Npn \@@_to_dim:w #1 ; { \@@_to_decimal:w #1 ; pt }
+\cs_new:Npn \@@_to_dim:w #1 \@@_sep: { \@@_to_decimal:w #1 \@@_sep: pt }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -459,17 +462,17 @@
\exp_after:wN \@@_to_int_dispatch:w
\exp:w \exp_end_continue_f:w \@@_parse:n
}
-\cs_new:Npn \@@_to_int_dispatch:w #1#2 ;
+\cs_new:Npn \@@_to_int_dispatch:w #1#2 \@@_sep:
{
\@@_change_func_type:NNN #1 \@@_to_int:w \@@_to_int_recover:w
- #1 #2 ;
+ #1 #2 \@@_sep:
}
\cs_new:Npn \@@_to_int_recover:w #1
{ \@@_invalid_operation:nnw { 0 } { fp_to_int } }
-\cs_new:Npn \@@_to_int:w #1;
+\cs_new:Npn \@@_to_int:w #1\@@_sep:
{
\exp_after:wN \@@_to_decimal:w \exp:w \exp_end_continue_f:w
- \@@_round:Nwn \@@_round_to_nearest:NNN #1; { 0 }
+ \@@_round:Nwn \@@_round_to_nearest:NNN #1\@@_sep: { 0 }
}
% \end{macrocode}
% \end{macro}
@@ -490,7 +493,7 @@
% points), then multiplied by $2^{-16} = 0.0000152587890625$ to give a
% value expressed in points. The auxiliary \cs{@@_mul_npos_o:Nww}
% expects the desired \meta{final sign} and two floating point
-% operands (of the form \cs{s_@@} \ldots{} |;|) as arguments.
+% operands (of the form \cs{s_@@} \ldots{} \cs{@@_sep:}) as arguments.
% This set of functions is also used to convert dimension registers to
% floating points while parsing expressions: in this context there is
% an additional exponent, which is the first argument of
@@ -504,7 +507,7 @@
\exp_after:wN \@@_from_dim_test:ww
\exp_after:wN 0
\exp_after:wN ,
- \int_value:w \tex_glueexpr:D #1 ;
+ \int_value:w \tex_glueexpr:D #1 \@@_sep:
}
\cs_new:Npn \@@_from_dim_test:ww #1, #2
{
@@ -520,18 +523,18 @@
\fi:
\fi:
}
-\cs_new:Npn \@@_from_dim:wNw #1,#2#3;
+\cs_new:Npn \@@_from_dim:wNw #1,#2#3\@@_sep:
{
- \@@_pack_twice_four:wNNNNNNNN \@@_from_dim:wNNnnnnnn ;
- #3 000 0000 00 {10}987654321; #2 {#1}
+ \@@_pack_twice_four:wNNNNNNNN \@@_from_dim:wNNnnnnnn \@@_sep:
+ #3 000 0000 00 {10}987654321\@@_sep: #2 {#1}
}
-\cs_new:Npn \@@_from_dim:wNNnnnnnn #1; #2#3#4#5#6#7#8#9
- { \@@_from_dim:wnnnnwNn #1 {#2#300} {0000} ; }
-\cs_new:Npn \@@_from_dim:wnnnnwNn #1; #2#3#4#5#6; #7#8
+\cs_new:Npn \@@_from_dim:wNNnnnnnn #1\@@_sep: #2#3#4#5#6#7#8#9
+ { \@@_from_dim:wnnnnwNn #1 {#2#300} {0000} \@@_sep: }
+\cs_new:Npn \@@_from_dim:wnnnnwNn #1\@@_sep: #2#3#4#5#6\@@_sep: #7#8
{
\@@_mul_npos_o:Nww #7
- \s_@@ \@@_chk:w 1 #7 {#5} #1 ;
- \s_@@ \@@_chk:w 1 0 {#8} {1525} {8789} {0625} {0000} ;
+ \s_@@ \@@_chk:w 1 #7 {#5} #1 \@@_sep:
+ \s_@@ \@@_chk:w 1 0 {#8} {1525} {8789} {0625} {0000} \@@_sep:
\prg_do_nothing:
}
% \end{macrocode}
@@ -603,16 +606,16 @@
{
\exp_last_unbraced:Ne \use_ii:nn
{
- \@@_array_to_clist_loop:Nw #1 { ? \prg_break: } ;
+ \@@_array_to_clist_loop:Nw #1 { ? \prg_break: } \@@_sep:
\prg_break_point:
}
}
}
-\cs_new:Npn \@@_array_to_clist_loop:Nw #1#2;
+\cs_new:Npn \@@_array_to_clist_loop:Nw #1#2\@@_sep:
{
\use_none:n #1
, ~
- \exp_not:f { \@@_to_tl_dispatch:w #1 #2 ; }
+ \exp_not:f { \@@_to_tl_dispatch:w #1 #2 \@@_sep: }
\@@_array_to_clist_loop:Nw
}
% \end{macrocode}
diff --git a/macros/latex-dev/required/l3kernel/l3fp-expo.dtx b/macros/latex-dev/required/l3kernel/l3fp-expo.dtx
index 7577f640d4..39fd6e3dc9 100644
--- a/macros/latex-dev/required/l3kernel/l3fp-expo.dtx
+++ b/macros/latex-dev/required/l3kernel/l3fp-expo.dtx
@@ -2,7 +2,7 @@
%
%% File: l3fp-expo.dtx
%
-% Copyright (C) 2011-2024 The LaTeX Project
+% Copyright (C) 2011-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -42,7 +42,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -135,15 +135,24 @@
% Those are needed in the implementation. It turns out that we don't
% need the value of $\ln(5)$.
% \begin{macrocode}
-\tl_const:Nn \c_@@_ln_i_fixed_tl { {0000}{0000}{0000}{0000}{0000}{0000};}
-\tl_const:Nn \c_@@_ln_ii_fixed_tl { {6931}{4718}{0559}{9453}{0941}{7232};}
-\tl_const:Nn \c_@@_ln_iii_fixed_tl {{10986}{1228}{8668}{1096}{9139}{5245};}
-\tl_const:Nn \c_@@_ln_iv_fixed_tl {{13862}{9436}{1119}{8906}{1883}{4464};}
-\tl_const:Nn \c_@@_ln_vi_fixed_tl {{17917}{5946}{9228}{0550}{0081}{2477};}
-\tl_const:Nn \c_@@_ln_vii_fixed_tl {{19459}{1014}{9055}{3133}{0510}{5353};}
-\tl_const:Nn \c_@@_ln_viii_fixed_tl{{20794}{4154}{1679}{8359}{2825}{1696};}
-\tl_const:Nn \c_@@_ln_ix_fixed_tl {{21972}{2457}{7336}{2193}{8279}{0490};}
-\tl_const:Nn \c_@@_ln_x_fixed_tl {{23025}{8509}{2994}{0456}{8401}{7991};}
+\tl_const:Nn \c_@@_ln_i_fixed_tl
+ { {0000}{0000}{0000}{0000}{0000}{0000}\@@_sep:}
+\tl_const:Nn \c_@@_ln_ii_fixed_tl
+ { {6931}{4718}{0559}{9453}{0941}{7232}\@@_sep:}
+\tl_const:Nn \c_@@_ln_iii_fixed_tl
+ {{10986}{1228}{8668}{1096}{9139}{5245}\@@_sep:}
+\tl_const:Nn \c_@@_ln_iv_fixed_tl
+ {{13862}{9436}{1119}{8906}{1883}{4464}\@@_sep:}
+\tl_const:Nn \c_@@_ln_vi_fixed_tl
+ {{17917}{5946}{9228}{0550}{0081}{2477}\@@_sep:}
+\tl_const:Nn \c_@@_ln_vii_fixed_tl
+ {{19459}{1014}{9055}{3133}{0510}{5353}\@@_sep:}
+\tl_const:Nn \c_@@_ln_viii_fixed_tl
+ {{20794}{4154}{1679}{8359}{2825}{1696}\@@_sep:}
+\tl_const:Nn \c_@@_ln_ix_fixed_tl
+ {{21972}{2457}{7336}{2193}{8279}{0490}\@@_sep:}
+\tl_const:Nn \c_@@_ln_x_fixed_tl
+ {{23025}{8509}{2994}{0456}{8401}{7991}\@@_sep:}
% \end{macrocode}
% \end{variable}
%
@@ -156,7 +165,7 @@
% $+\infty$ or a \texttt{nan} is itself. Positive normal numbers call
% \cs{@@_ln_npos_o:w}.
% \begin{macrocode}
-\cs_new:Npn \@@_ln_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+\cs_new:Npn \@@_ln_o:w #1 \s_@@ \@@_chk:w #2#3#4\@@_sep: @
{
\if_meaning:w 2 #3
\@@_case_use:nw { \@@_invalid_operation_o:nw { ln } }
@@ -168,7 +177,7 @@
\else:
\@@_case_return_same_o:w
\fi:
- \@@_ln_npos_o:w \s_@@ \@@_chk:w #2#3#4;
+ \@@_ln_npos_o:w \s_@@ \@@_chk:w #2#3#4\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -180,7 +189,7 @@
% In all other cases, the final result is at least $10^{-4}$, and
% then an error of $0.5\cdot 10^{-20}$ is acceptable.
% \begin{macrocode}
-\cs_new:Npn \@@_ln_npos_o:w \s_@@ \@@_chk:w 10#1#2#3;
+\cs_new:Npn \@@_ln_npos_o:w \s_@@ \@@_chk:w 10#1#2#3\@@_sep:
{ %^^A todo: ln(1) should be "exact zero", not "underflow"
\exp_after:wN \@@_sanitize:Nw
\int_value:w % for the overall sign
@@ -203,7 +212,7 @@
% \end{syntax}
% This function expands to
% \begin{syntax}
-% \meta{continuation} \Arg{Y_1} \Arg{Y_2} \Arg{Y_3} \Arg{Y_4} \Arg{Y_5} \Arg{Y_6} |;|
+% \meta{continuation} \Arg{Y_1} \Arg{Y_2} \Arg{Y_3} \Arg{Y_4} \Arg{Y_5} \Arg{Y_6} \cs{@@_sep:}
% \end{syntax}
% where $Y = - \ln(X)$ as an extended fixed point.
% \begin{macrocode}
@@ -225,7 +234,7 @@
\or: 2
\else: 1
\fi:
- ; { #1 #2 #3 #4 }
+ \@@_sep: { #1 #2 #3 #4 }
}
% \end{macrocode}
% \end{macro}
@@ -234,7 +243,7 @@
% We have thus found $c \in [1,10]$ such that $0.7\leq ac < 1.4$
% in all cases. Compute $ 1 + x = 1 + ac \in [1.7,2.4)$.
% \begin{macrocode}
-\cs_new:Npn \@@_ln_x_ii:wnnnn #1; #2#3#4#5
+\cs_new:Npn \@@_ln_x_ii:wnnnn #1\@@_sep: #2#3#4#5
{
\exp_after:wN \@@_ln_div_after:Nw
\cs:w c_@@_ln_ \@@_int_to_roman:w #1 _fixed_tl \exp_after:wN \cs_end:
@@ -244,14 +253,14 @@
\exp_after:wN \@@_ln_x_iii_var:NNNNNw
\int_value:w \@@_int_eval:w 9999 9990 + #1*#2#3 +
\exp_after:wN \@@_ln_x_iii:NNNNNNw
- \int_value:w \@@_int_eval:w 10 0000 0000 + #1*#4#5 ;
+ \int_value:w \@@_int_eval:w 10 0000 0000 + #1*#4#5 \@@_sep:
{20000} {0000} {0000} {0000}
} %^^A todo: reoptimize (a generalization attempt failed).
-\cs_new:Npn \@@_ln_x_iii:NNNNNNw #1#2 #3#4#5#6 #7;
- { #1#2; {#3#4#5#6} {#7} }
-\cs_new:Npn \@@_ln_x_iii_var:NNNNNw #1 #2#3#4#5 #6;
+\cs_new:Npn \@@_ln_x_iii:NNNNNNw #1#2 #3#4#5#6 #7\@@_sep:
+ { #1#2\@@_sep: {#3#4#5#6} {#7} }
+\cs_new:Npn \@@_ln_x_iii_var:NNNNNw #1 #2#3#4#5 #6\@@_sep:
{
- #1#2#3#4#5 + 1 ;
+ #1#2#3#4#5 + 1 \@@_sep:
{#1#2#3#4#5} {#6}
}
% \end{macrocode}
@@ -322,16 +331,16 @@
% ^^A todo: doc
%
% \begin{syntax}
-% \cs{@@_ln_x_iv:wnnnnnnnn} \meta{1 or 2} \meta{8d} |;| \Arg{4d} \Arg{4d} \meta{fixed-tl}
+% \cs{@@_ln_x_iv:wnnnnnnnn} \meta{1 or 2} \meta{8d} \cs{@@_sep:} \Arg{4d} \Arg{4d} \meta{fixed-tl}
% \end{syntax}
% The number is $x$. Compute $y$ by adding 1 to the five first digits.
% \begin{macrocode}
-\cs_new:Npn \@@_ln_x_iv:wnnnnnnnn #1; #2#3#4#5 #6#7#8#9
+\cs_new:Npn \@@_ln_x_iv:wnnnnnnnn #1\@@_sep: #2#3#4#5 #6#7#8#9
{
\exp_after:wN \@@_div_significand_pack:NNN
\int_value:w \@@_int_eval:w
- \@@_ln_div_i:w #1 ;
- #6 #7 ; {#8} {#9}
+ \@@_ln_div_i:w #1 \@@_sep:
+ #6 #7 \@@_sep: {#8} {#9}
{#2} {#3} {#4} {#5}
{ \exp_after:wN \@@_ln_div_ii:wwn \int_value:w #1 }
{ \exp_after:wN \@@_ln_div_ii:wwn \int_value:w #1 }
@@ -339,23 +348,25 @@
{ \exp_after:wN \@@_ln_div_ii:wwn \int_value:w #1 }
{ \exp_after:wN \@@_ln_div_vi:wwn \int_value:w #1 }
}
-\cs_new:Npn \@@_ln_div_i:w #1;
+\cs_new:Npn \@@_ln_div_i:w #1\@@_sep:
{
\exp_after:wN \@@_div_significand_calc:wwnnnnnnn
- \int_value:w \@@_int_eval:w 999999 + 2 0000 0000 / #1 ; % Q1
+ \int_value:w \@@_int_eval:w 999999 + 2 0000 0000 / #1 \@@_sep: % Q1
}
-\cs_new:Npn \@@_ln_div_ii:wwn #1; #2;#3 % y; B1;B2 <- for k=1
+\cs_new:Npn \@@_ln_div_ii:wwn
+ #1\@@_sep: #2\@@_sep:#3 % y\@@_sep: B1\@@_sep:B2 <- for k=1
{
\exp_after:wN \@@_div_significand_pack:NNN
\int_value:w \@@_int_eval:w
\exp_after:wN \@@_div_significand_calc:wwnnnnnnn
- \int_value:w \@@_int_eval:w 999999 + #2 #3 / #1 ; % Q2
- #2 #3 ;
+ \int_value:w \@@_int_eval:w 999999 + #2 #3 / #1 \@@_sep: % Q2
+ #2 #3 \@@_sep:
}
-\cs_new:Npn \@@_ln_div_vi:wwn #1; #2;#3#4#5 #6#7#8#9 %y;F1;F2F3F4x1x2x3x4
+\cs_new:Npn \@@_ln_div_vi:wwn
+ #1\@@_sep: #2\@@_sep:#3#4#5 #6#7#8#9 %y\@@_sep:F1\@@_sep:F2F3F4x1x2x3x4
{
\exp_after:wN \@@_div_significand_pack:NNN
- \int_value:w \@@_int_eval:w 1000000 + #2 #3 / #1 ; % Q6
+ \int_value:w \@@_int_eval:w 1000000 + #2 #3 / #1 \@@_sep: % Q6
}
% \end{macrocode}
% We now have essentially
@@ -368,8 +379,8 @@
% \cs{@@_div_significand_pack:NNN} $10^6 + Q_{3}$
% \cs{@@_div_significand_pack:NNN} $10^6 + Q_{4}$
% \cs{@@_div_significand_pack:NNN} $10^6 + Q_{5}$
-% \cs{@@_div_significand_pack:NNN} $10^6 + Q_{6}$ |;|
-% \meta{exponent} |;| \meta{continuation}
+% \cs{@@_div_significand_pack:NNN} $10^6 + Q_{6}$ \cs{@@_sep:}
+% \meta{exponent} \cs{@@_sep:} \meta{continuation}
% \end{syntax}
% where \meta{fixed tl} holds the logarithm of a number
% in $[1,10]$, and \meta{exponent} is
@@ -378,8 +389,9 @@
% correct order to add the $Q_{i}$ together and put semicolons
% between each piece. Once those have been expanded, we get
% \begin{syntax}
-% \cs{@@_ln_div_after:Nw} \meta{fixed-tl} \meta{1d} |;| \meta{4d} |;| \meta{4d} |;|
-% ~~\meta{4d} |;| \meta{4d} |;| \meta{4d} |;| \meta{4d} |;| \meta{exponent} |;|
+% \cs{@@_ln_div_after:Nw} \meta{fixed-tl} \meta{1d} \cs{@@_sep:} \meta{4d} \cs{@@_sep:}
+% ~~\meta{4d} \cs{@@_sep:} \meta{4d} \cs{@@_sep:} \meta{4d} \cs{@@_sep:} \meta{4d} \cs{@@_sep:}
+% ~~\meta{4d} \cs{@@_sep:} \meta{exponent} \cs{@@_sep:}
% \end{syntax}
% ^^A todo: redoc.
% Just as with division, we know that the first two digits
@@ -388,7 +400,7 @@
% We then compute $1-2/(x+1)$, after testing whether $2/(x+1)$ is
% greater than or smaller than $1$.
% \begin{macrocode}
-\cs_new:Npn \@@_ln_div_after:Nw #1#2;
+\cs_new:Npn \@@_ln_div_after:Nw #1#2\@@_sep:
{
\if_meaning:w 0 #2
\exp_after:wN \@@_ln_t_small:Nw
@@ -398,31 +410,35 @@
\fi:
#1
}
-\cs_new:Npn \@@_ln_t_small:Nw #1 #2; #3; #4; #5; #6; #7;
+\cs_new:Npn \@@_ln_t_small:Nw
+ #1 #2\@@_sep: #3\@@_sep: #4\@@_sep: #5\@@_sep: #6\@@_sep: #7\@@_sep:
{
\exp_after:wN \@@_ln_t_large:NNw
\exp_after:wN + % <sign>
\exp_after:wN #1
- \int_value:w \@@_int_eval:w 9999 - #2 \exp_after:wN ;
- \int_value:w \@@_int_eval:w 9999 - #3 \exp_after:wN ;
- \int_value:w \@@_int_eval:w 9999 - #4 \exp_after:wN ;
- \int_value:w \@@_int_eval:w 9999 - #5 \exp_after:wN ;
- \int_value:w \@@_int_eval:w 9999 - #6 \exp_after:wN ;
- \int_value:w \@@_int_eval:w 1 0000 - #7 ;
+ \int_value:w \@@_int_eval:w 9999 - #2 \exp_after:wN \@@_sep:
+ \int_value:w \@@_int_eval:w 9999 - #3 \exp_after:wN \@@_sep:
+ \int_value:w \@@_int_eval:w 9999 - #4 \exp_after:wN \@@_sep:
+ \int_value:w \@@_int_eval:w 9999 - #5 \exp_after:wN \@@_sep:
+ \int_value:w \@@_int_eval:w 9999 - #6 \exp_after:wN \@@_sep:
+ \int_value:w \@@_int_eval:w 1 0000 - #7 \@@_sep:
}
% \end{macrocode}
%
% \begin{syntax}
% \cs{@@_ln_t_large:NNw} \meta{sign} \meta{fixed tl}
-% ~~\meta{t_1}|;| \meta{t_2} |;| \meta{t_3}|;| \meta{t_4}|;| \meta{t_5} |;| \meta{t_6}|;|
-% ~~\meta{exponent} |;| \meta{continuation}
+% ~~\meta{t_1}\cs{@@_sep:} \meta{t_2} \cs{@@_sep:} \meta{t_3}\cs{@@_sep:} \meta{t_4}
+% ~~\cs{@@_sep:} \meta{t_5} \cs{@@_sep:} \meta{t_6}\cs{@@_sep:}
+% ~~\meta{exponent} \cs{@@_sep:} \meta{continuation}
% \end{syntax}
% Compute the square $|t|^2$, and keep $|t|$ at the end with its
% sign. We know that $|t|<0.1765$, so every piece has at most $4$
% digits. However, since we were not careful in \cs{@@_ln_t_small:w},
% they can have less than $4$ digits.
% \begin{macrocode}
-\cs_new:Npn \@@_ln_t_large:NNw #1 #2 #3; #4; #5; #6; #7; #8;
+\cs_new:Npn \@@_ln_t_large:NNw
+ #1 #2
+ #3\@@_sep: #4\@@_sep: #5\@@_sep: #6\@@_sep: #7\@@_sep: #8\@@_sep:
{
\exp_after:wN \@@_ln_square_t_after:w
\int_value:w \@@_int_eval:w 9999 0000 + #3*#3
@@ -436,7 +452,7 @@
\int_value:w \@@_int_eval:w
1 0000 0000 + 2*#3*#7 + 2*#4*#6 + #5*#5
+ (2*#3*#8 + 2*#4*#7 + 2*#5*#6) / 1 0000
- % ; ; ;
+ % \@@_sep: \@@_sep: \@@_sep:
\exp_after:wN \@@_ln_twice_t_after:w
\int_value:w \@@_int_eval:w -1 + 2*#3
\exp_after:wN \@@_ln_twice_t_pack:Nw
@@ -448,15 +464,16 @@
\exp_after:wN \@@_ln_twice_t_pack:Nw
\int_value:w \@@_int_eval:w 9999 + 2*#7
\exp_after:wN \@@_ln_twice_t_pack:Nw
- \int_value:w \@@_int_eval:w 10000 + 2*#8 ; ;
+ \int_value:w \@@_int_eval:w 10000 + 2*#8 \@@_sep: \@@_sep:
{ \@@_ln_c:NwNw #1 }
#2
}
-\cs_new:Npn \@@_ln_twice_t_pack:Nw #1 #2; { + #1 ; {#2} }
-\cs_new:Npn \@@_ln_twice_t_after:w #1; { ;;; {#1} }
-\cs_new:Npn \@@_ln_square_t_pack:NNNNNw #1 #2#3#4#5 #6;
- { + #1#2#3#4#5 ; {#6} }
-\cs_new:Npn \@@_ln_square_t_after:w 1 0 #1#2#3 #4;
+\cs_new:Npn \@@_ln_twice_t_pack:Nw #1 #2\@@_sep: { + #1 \@@_sep: {#2} }
+\cs_new:Npn \@@_ln_twice_t_after:w #1\@@_sep:
+ { \@@_sep:\@@_sep:\@@_sep: {#1} }
+\cs_new:Npn \@@_ln_square_t_pack:NNNNNw #1 #2#3#4#5 #6\@@_sep:
+ { + #1#2#3#4#5 \@@_sep: {#6} }
+\cs_new:Npn \@@_ln_square_t_after:w 1 0 #1#2#3 #4\@@_sep:
{ \@@_ln_Taylor:wwNw {0#1#2#3} {#4} }
% \end{macrocode}
% \end{macro}
@@ -465,10 +482,10 @@
% Denoting $T=t^2$, we get
% \begin{syntax}
% \cs{@@_ln_Taylor:wwNw}
-% ~~\Arg{T_1} \Arg{T_2} \Arg{T_3} \Arg{T_4} \Arg{T_5} \Arg{T_6} |;| |;|
-% ~~\Arg{(2t)_1} \Arg{(2t)_2} \Arg{(2t)_3} \Arg{(2t)_4} \Arg{(2t)_5} \Arg{(2t)_6} |;|
+% ~~\Arg{T_1} \Arg{T_2} \Arg{T_3} \Arg{T_4} \Arg{T_5} \Arg{T_6} \cs{@@_sep:} \cs{@@_sep:}
+% ~~\Arg{(2t)_1} \Arg{(2t)_2} \Arg{(2t)_3} \Arg{(2t)_4} \Arg{(2t)_5} \Arg{(2t)_6} \cs{@@_sep:}
% ~~|{| \cs{@@_ln_c:NwNw} \meta{sign} |}|
-% ~~\meta{fixed tl} \meta{exponent} |;| \meta{continuation}
+% ~~\meta{fixed tl} \meta{exponent} \cs{@@_sep:} \meta{continuation}
% \end{syntax}
% And we want to compute
% \[
@@ -491,26 +508,30 @@
% (${}<10^4$).
% \begin{macrocode}
\cs_new:Npn \@@_ln_Taylor:wwNw
- { \@@_ln_Taylor_loop:www 21 ; {0000}{0000}{0000}{0000}{0000}{0000} ; }
-\cs_new:Npn \@@_ln_Taylor_loop:www #1; #2; #3;
+ {
+ \@@_ln_Taylor_loop:www
+ 21 \@@_sep: {0000}{0000}{0000}{0000}{0000}{0000} \@@_sep:
+ }
+\cs_new:Npn \@@_ln_Taylor_loop:www #1\@@_sep: #2\@@_sep: #3\@@_sep:
{
\if_int_compare:w #1 = \c_one_int
\@@_ln_Taylor_break:w
\fi:
- \exp_after:wN \@@_fixed_div_int:wwN \c_@@_one_fixed_tl #1;
- \@@_fixed_add:wwn #2;
- \@@_fixed_mul:wwn #3;
+ \exp_after:wN \@@_fixed_div_int:wwN \c_@@_one_fixed_tl #1\@@_sep:
+ \@@_fixed_add:wwn #2\@@_sep:
+ \@@_fixed_mul:wwn #3\@@_sep:
{
\exp_after:wN \@@_ln_Taylor_loop:www
- \int_value:w \@@_int_eval:w #1 - 2 ;
+ \int_value:w \@@_int_eval:w #1 - 2 \@@_sep:
}
- #3;
+ #3\@@_sep:
}
-\cs_new:Npn \@@_ln_Taylor_break:w \fi: #1 \@@_fixed_add:wwn #2#3; #4 ;;
+\cs_new:Npn \@@_ln_Taylor_break:w
+ \fi: #1 \@@_fixed_add:wwn #2#3\@@_sep: #4 \@@_sep:\@@_sep:
{
\fi:
\exp_after:wN \@@_fixed_mul:wwn
- \exp_after:wN { \int_value:w \@@_int_eval:w 10000 + #2 } #3;
+ \exp_after:wN { \int_value:w \@@_int_eval:w 10000 + #2 } #3\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -518,8 +539,8 @@
% \begin{macro}{\@@_ln_c:NwNw}
% \begin{syntax}
% \cs{@@_ln_c:NwNw} \meta{sign}
-% ~~\Arg{r_1} \Arg{r_2} \Arg{r_3} \Arg{r_4} \Arg{r_5} \Arg{r_6} |;|
-% ~~\meta{fixed tl} \meta{exponent} |;| \meta{continuation}
+% ~~\Arg{r_1} \Arg{r_2} \Arg{r_3} \Arg{r_4} \Arg{r_5} \Arg{r_6} \cs{@@_sep:}
+% ~~\meta{fixed tl} \meta{exponent} \cs{@@_sep:} \meta{continuation}
% \end{syntax}
% We are now reduced to finding $\ln(c)$ and $\meta{exponent}\ln(10)$
% in a table, and adding it to the mixture. The first step is to
@@ -530,14 +551,14 @@
% is $1$ and $c=1$, we shift to working in units of $\cdot 10^4$,
% since the final result is at least $\ln(10/7) \simeq 0.35$.
% \begin{macrocode}
-\cs_new:Npn \@@_ln_c:NwNw #1 #2; #3
+\cs_new:Npn \@@_ln_c:NwNw #1 #2\@@_sep: #3
{
\if_meaning:w + #1
\exp_after:wN \exp_after:wN \exp_after:wN \@@_fixed_sub:wwn
\else:
\exp_after:wN \exp_after:wN \exp_after:wN \@@_fixed_add:wwn
\fi:
- #3 #2 ;
+ #3 #2 \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -545,7 +566,7 @@
% \begin{macro}{\@@_ln_exponent:wn}
% \begin{syntax}
% \cs{@@_ln_exponent:wn}
-% ~~\Arg{s_1} \Arg{s_2} \Arg{s_3} \Arg{s_4} \Arg{s_5} \Arg{s_6} |;|
+% ~~\Arg{s_1} \Arg{s_2} \Arg{s_3} \Arg{s_4} \Arg{s_5} \Arg{s_6} \cs{@@_sep:}
% ~~\Arg{exponent}
% \end{syntax}
% Compute \meta{exponent} times $\ln(10)$. Apart from the cases where
@@ -559,7 +580,7 @@
% Besides, we already have addition and subtraction for $24$ digits
% fixed point numbers.
% \begin{macrocode}
-\cs_new:Npn \@@_ln_exponent:wn #1; #2
+\cs_new:Npn \@@_ln_exponent:wn #1\@@_sep: #2
{
\if_case:w #2 \exp_stop_f:
0 \@@_case_return:nw { \@@_fixed_to_float_o:Nw 2 }
@@ -576,16 +597,16 @@
\exp_after:wN \@@_fixed_add:wwn \int_value:w -
\fi:
\fi:
- #2; #1;
+ #2\@@_sep: #1\@@_sep:
}
% \end{macrocode}
% Now we painfully write all the cases.\footnote{Bruno: do rounding.}
% No overflow nor underflow can happen, except when computing \texttt{ln(1)}.
% \begin{macrocode}
-\cs_new:Npn \@@_ln_exponent_one:ww 1; #1;
+\cs_new:Npn \@@_ln_exponent_one:ww 1\@@_sep: #1\@@_sep:
{
0
- \exp_after:wN \@@_fixed_sub:wwn \c_@@_ln_x_fixed_tl #1;
+ \exp_after:wN \@@_fixed_sub:wwn \c_@@_ln_x_fixed_tl #1\@@_sep:
\@@_fixed_to_float_o:wN 0
}
% \end{macrocode}
@@ -594,14 +615,14 @@
% in the conversion from fixed point to floating point). Note that here
% the exponent has been made positive.
% \begin{macrocode}
-\cs_new:Npn \@@_ln_exponent_small:NNww #1#2#3; #4#5#6#7#8#9;
+\cs_new:Npn \@@_ln_exponent_small:NNww #1#2#3\@@_sep: #4#5#6#7#8#9\@@_sep:
{
4
\exp_after:wN \@@_fixed_mul:wwn
\c_@@_ln_x_fixed_tl
- {#3}{0000}{0000}{0000}{0000}{0000} ;
+ {#3}{0000}{0000}{0000}{0000}{0000} \@@_sep:
#2
- {0000}{#4}{#5}{#6}{#7}{#8};
+ {0000}{#4}{#5}{#6}{#7}{#8}\@@_sep:
\@@_fixed_to_float_o:wN #1
}
% \end{macrocode}
@@ -613,7 +634,7 @@
%
% \begin{macro}[EXP]{\@@_exp_o:w}
% \begin{macrocode}
-\cs_new:Npn \@@_exp_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+\cs_new:Npn \@@_exp_o:w #1 \s_@@ \@@_chk:w #2#3#4\@@_sep: @
{
\if_case:w #2 \exp_stop_f:
\@@_case_return_o:Nw \c_one_fp
@@ -630,7 +651,7 @@
\or:
\@@_case_return_same_o:w
\fi:
- \s_@@ \@@_chk:w #2#3#4;
+ \s_@@ \@@_chk:w #2#3#4\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -645,7 +666,7 @@
\@@_exp_pos_o:NNwnw - \@@_fixed_inv_to_float_o:wN
\fi:
}
-\cs_new:Npn \@@_exp_pos_o:NNwnw #1#2#3 \fi: #4#5;
+\cs_new:Npn \@@_exp_pos_o:NNwnw #1#2#3 \fi: #4#5\@@_sep:
{
\fi:
\if_int_compare:w #4 > \c_@@_max_exp_exponent_int
@@ -696,33 +717,33 @@
% delimited by a semicolon, form a fixed point number, so we pack it
% in blocks of $4$ digits.
% \begin{macrocode}
-\cs_new:Npn \@@_exp_Taylor:Nnnwn #1#2#3 #4; #5 #6
+\cs_new:Npn \@@_exp_Taylor:Nnnwn #1#2#3 #4\@@_sep: #5 #6
{
#6
\@@_pack_twice_four:wNNNNNNNN
\@@_pack_twice_four:wNNNNNNNN
\@@_pack_twice_four:wNNNNNNNN
\@@_exp_Taylor_ii:ww
- ; #2#3#4 0000 0000 ;
+ \@@_sep: #2#3#4 0000 0000 \@@_sep:
}
-\cs_new:Npn \@@_exp_Taylor_ii:ww #1; #2;
- { \@@_exp_Taylor_loop:www 10 ; #1 ; #1 ; \s_@@_stop }
-\cs_new:Npn \@@_exp_Taylor_loop:www #1; #2; #3;
+\cs_new:Npn \@@_exp_Taylor_ii:ww #1\@@_sep: #2\@@_sep:
+ { \@@_exp_Taylor_loop:www 10 \@@_sep: #1 \@@_sep: #1 \@@_sep: \s_@@_stop }
+\cs_new:Npn \@@_exp_Taylor_loop:www #1\@@_sep: #2\@@_sep: #3\@@_sep:
{
\if_int_compare:w #1 = \c_one_int
\exp_after:wN \@@_exp_Taylor_break:Nww
\fi:
- \@@_fixed_div_int:wwN #3 ; #1 ;
+ \@@_fixed_div_int:wwN #3 \@@_sep: #1 \@@_sep:
\@@_fixed_add_one:wN
- \@@_fixed_mul:wwn #2 ;
+ \@@_fixed_mul:wwn #2 \@@_sep:
{
\exp_after:wN \@@_exp_Taylor_loop:www
- \int_value:w \@@_int_eval:w #1 - 1 ;
- #2 ;
+ \int_value:w \@@_int_eval:w #1 - 1 \@@_sep:
+ #2 \@@_sep:
}
}
-\cs_new:Npn \@@_exp_Taylor_break:Nww #1 #2; #3 \s_@@_stop
- { \@@_fixed_add_one:wN #2 ; }
+\cs_new:Npn \@@_exp_Taylor_break:Nww #1 #2\@@_sep: #3 \s_@@_stop
+ { \@@_fixed_add_one:wN #2 \@@_sep: }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -824,23 +845,23 @@
% on to the Taylor series, eventually multiplied with the mantissa
% that we have just computed.
% \begin{macrocode}
-\cs_new:Npn \@@_exp_pos_large:NnnNwn #1#2#3 #4#5; #6
+\cs_new:Npn \@@_exp_pos_large:NnnNwn #1#2#3 #4#5\@@_sep: #6
{
\exp_after:wN \exp_after:wN \exp_after:wN \@@_exp_large:NwN
\exp_after:wN \exp_after:wN \exp_after:wN #6
\exp_after:wN \c_@@_one_fixed_tl
\int_value:w #3 #4 \exp_stop_f:
- #5 00000 ;
+ #5 00000 \@@_sep:
}
-\cs_new:Npn \@@_exp_large:NwN #1#2; #3
+\cs_new:Npn \@@_exp_large:NwN #1#2\@@_sep: #3
{
\if_case:w #3 ~
\exp_after:wN \@@_fixed_continue:wn
\else:
\exp_after:wN \@@_exp_intarray:w
- \int_value:w \@@_int_eval:w 36 * #1 + 4 * #3 \exp_after:wN ;
+ \int_value:w \@@_int_eval:w 36 * #1 + 4 * #3 \exp_after:wN \@@_sep:
\fi:
- #2;
+ #2\@@_sep:
{
\if_meaning:w 0 #1
\exp_after:wN \@@_exp_large_after:wwn
@@ -850,7 +871,7 @@
\fi:
}
}
-\cs_new:Npn \@@_exp_intarray:w #1 ;
+\cs_new:Npn \@@_exp_intarray:w #1 \@@_sep:
{
+
\__kernel_intarray_item:Nn \c_@@_exp_intarray
@@ -865,13 +886,15 @@
\int_value:w \__kernel_intarray_item:Nn
\c_@@_exp_intarray { \@@_int_eval:w #1 - 1 }
\exp_after:wN \@@_exp_intarray_aux:w
- \int_value:w \__kernel_intarray_item:Nn \c_@@_exp_intarray {#1} ; ;
+ \int_value:w \__kernel_intarray_item:Nn
+ \c_@@_exp_intarray {#1} \@@_sep: \@@_sep:
}
-\cs_new:Npn \@@_exp_intarray_aux:w 1 #1#2#3#4#5 ; { ; {#1#2#3#4} {#5} }
-\cs_new:Npn \@@_exp_large_after:wwn #1; #2; #3
+\cs_new:Npn \@@_exp_intarray_aux:w 1 #1#2#3#4#5 \@@_sep:
+ { \@@_sep: {#1#2#3#4} {#5} }
+\cs_new:Npn \@@_exp_large_after:wwn #1\@@_sep: #2\@@_sep: #3
{
- \@@_exp_Taylor:Nnnwn ? { } { } 0 #2; {} #3
- \@@_fixed_mul:wwn #1;
+ \@@_exp_Taylor:Nnnwn ? { } { } 0 #2\@@_sep: {} #3
+ \@@_fixed_mul:wwn #1\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -921,7 +944,7 @@
% \end{itemize}
% \begin{macrocode}
\cs_new:cpn { @@_ \iow_char:N \^ _o:ww }
- \s_@@ \@@_chk:w #1#2#3; \s_@@ \@@_chk:w #4#5#6;
+ \s_@@ \@@_chk:w #1#2#3\@@_sep: \s_@@ \@@_chk:w #4#5#6\@@_sep:
{
\if_meaning:w 0 #4
\@@_case_return_o:Nw \c_one_fp
@@ -940,10 +963,10 @@
\else:
\exp_after:wN \@@_pow_zero_or_inf:ww
\fi:
- \s_@@ \@@_chk:w #1#2#3;
+ \s_@@ \@@_chk:w #1#2#3\@@_sep:
}
- { \s_@@ \@@_chk:w #4#5#6; \s_@@ \@@_chk:w #1#2#3; }
- \s_@@ \@@_chk:w #4#5#6;
+ { \s_@@ \@@_chk:w #4#5#6\@@_sep: \s_@@ \@@_chk:w #1#2#3\@@_sep: }
+ \s_@@ \@@_chk:w #4#5#6\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -959,7 +982,7 @@
% unless $b=-\infty$.
% \begin{macrocode}
\cs_new:Npn \@@_pow_zero_or_inf:ww
- \s_@@ \@@_chk:w #1#2; \s_@@ \@@_chk:w #3#4
+ \s_@@ \@@_chk:w #1#2\@@_sep: \s_@@ \@@_chk:w #3#4
{
\if_meaning:w 1 #4
\@@_case_return_same_o:w
@@ -976,7 +999,7 @@
\@@_case_use:nw
{
\@@_division_by_zero_o:NNww \c_inf_fp ^
- \s_@@ \@@_chk:w #1 #2 ;
+ \s_@@ \@@_chk:w #1 #2 \@@_sep:
}
\fi:
\s_@@ \@@_chk:w #3#4
@@ -1000,7 +1023,7 @@
% \end{itemize}
% \begin{macrocode}
\cs_new:Npn \@@_pow_normal_o:ww
- \s_@@ \@@_chk:w 1 #1#2#3; \s_@@ \@@_chk:w #4#5
+ \s_@@ \@@_chk:w 1 #1#2#3\@@_sep: \s_@@ \@@_chk:w #4#5
{
\if:w 0 \@@_str_if_eq:nn { #2 #3 } { 1 {1000} {0000} {0000} {0000} }
\if_int_compare:w #4 #1 = 32 \exp_stop_f:
@@ -1024,7 +1047,7 @@
\or:
\@@_case_return_ii_o:ww
\fi:
- \s_@@ \@@_chk:w 1 #1 {#2} #3 ;
+ \s_@@ \@@_chk:w 1 #1 {#2} #3 \@@_sep:
\s_@@ \@@_chk:w #4 #5
}
% \end{macrocode}
@@ -1069,17 +1092,18 @@
% float. Then comes an exponent and the $4$ brace groups of $x$,
% followed by $b$. Compute $-\ln(x)$.
% \begin{macrocode}
-\cs_new:Npn \@@_pow_npos_aux:NNnww #1#2#3#4#5; \s_@@ \@@_chk:w 1#6#7#8;
+\cs_new:Npn \@@_pow_npos_aux:NNnww
+ #1#2#3#4#5\@@_sep: \s_@@ \@@_chk:w 1#6#7#8\@@_sep:
{
#1
\@@_int_eval:w
\@@_ln_significand:NNNNnnnN #4#5
\@@_pow_exponent:wnN {#3}
- \@@_fixed_mul:wwn #8 {0000}{0000} ;
- \@@_pow_B:wwN #7;
+ \@@_fixed_mul:wwn #8 {0000}{0000} \@@_sep:
+ \@@_pow_B:wwN #7\@@_sep:
#1 #2 0 % fixed_to_float_o:wN
}
-\cs_new:Npn \@@_pow_exponent:wnN #1; #2
+\cs_new:Npn \@@_pow_exponent:wnN #1\@@_sep: #2
{
\if_int_compare:w #2 > \c_zero_int
\exp_after:wN \@@_pow_exponent:Nwnnnnnw % n\ln(10) - (-\ln(x))
@@ -1088,9 +1112,9 @@
\exp_after:wN \@@_pow_exponent:Nwnnnnnw % -(|n|\ln(10) + (-\ln(x)))
\exp_after:wN -
\fi:
- #2; #1;
+ #2\@@_sep: #1\@@_sep:
}
-\cs_new:Npn \@@_pow_exponent:Nwnnnnnw #1#2; #3#4#5#6#7#8;
+\cs_new:Npn \@@_pow_exponent:Nwnnnnnw #1#2\@@_sep: #3#4#5#6#7#8\@@_sep:
{ %^^A todo: use that in ln.
\exp_after:wN \@@_fixed_mul_after:wwn
\int_value:w \@@_int_eval:w \c_@@_leading_shift_int
@@ -1109,9 +1133,9 @@
\exp_after:wN \@@_pack:NNNNNw
\int_value:w \@@_int_eval:w \c_@@_trailing_shift_int
#1 #2*8401 - #1 #7
- #1 ( #2*7991 - #8 ) / 1 0000 ; ;
+ #1 ( #2*7991 - #8 ) / 1 0000 \@@_sep: \@@_sep:
}
-\cs_new:Npn \@@_pow_B:wwN #1#2#3#4#5#6; #7;
+\cs_new:Npn \@@_pow_B:wwN #1#2#3#4#5#6\@@_sep: #7\@@_sep:
{
\if_int_compare:w #7 < \c_zero_int
\exp_after:wN \@@_pow_C_neg:w \int_value:w -
@@ -1122,23 +1146,23 @@
\exp_after:wN \@@_pow_C_overflow:w \int_value:w
\fi:
\fi:
- #7 \exp_after:wN ;
+ #7 \exp_after:wN \@@_sep:
\int_value:w \@@_int_eval:w 10 0000 + #1 \@@_int_eval_end:
- #2#3#4#5#6 0000 0000 0000 0000 0000 0000 ; %^^A todo: how many 0?
+ #2#3#4#5#6 0000 0000 0000 0000 0000 0000 \@@_sep: %^^A todo: how many 0?
}
-\cs_new:Npn \@@_pow_C_overflow:w #1; #2; #3
+\cs_new:Npn \@@_pow_C_overflow:w #1\@@_sep: #2\@@_sep: #3
{
+ 2 * \c_@@_max_exponent_int
\exp_after:wN \@@_fixed_continue:wn \c_@@_one_fixed_tl
}
-\cs_new:Npn \@@_pow_C_neg:w #1 ; 1
+\cs_new:Npn \@@_pow_C_neg:w #1 \@@_sep: 1
{
\exp_after:wN \exp_after:wN \exp_after:wN \@@_pow_C_pack:w
\prg_replicate:nn {#1} {0}
}
-\cs_new:Npn \@@_pow_C_pos:w #1; 1
- { \@@_pow_C_pos_loop:wN #1; }
-\cs_new:Npn \@@_pow_C_pos_loop:wN #1; #2
+\cs_new:Npn \@@_pow_C_pos:w #1\@@_sep: 1
+ { \@@_pow_C_pos_loop:wN #1\@@_sep: }
+\cs_new:Npn \@@_pow_C_pos_loop:wN #1\@@_sep: #2
{
\if_meaning:w 0 #1
\exp_after:wN \@@_pow_C_pack:w
@@ -1149,7 +1173,7 @@
\else:
\exp_after:wN \@@_pow_C_overflow:w \int_value:w
\fi:
- \@@_int_eval:w #1 - 1 \exp_after:wN ;
+ \@@_int_eval:w #1 - 1 \exp_after:wN \@@_sep:
\fi:
}
\cs_new:Npn \@@_pow_C_pack:w
@@ -1173,20 +1197,21 @@
% called, |(-0.1)**(12345.67)| gives $+0$ rather than complaining
% that the sign is not defined.
% \begin{macrocode}
-\cs_new:Npn \@@_pow_neg:www \s_@@ \@@_chk:w #1#2; #3; #4;
+\cs_new:Npn \@@_pow_neg:www
+ \s_@@ \@@_chk:w #1#2\@@_sep: #3\@@_sep: #4\@@_sep:
{
- \if_case:w \@@_pow_neg_case:w #4 ;
+ \if_case:w \@@_pow_neg_case:w #4 \@@_sep:
\exp_after:wN \@@_pow_neg_aux:wNN
\or:
\if_int_compare:w \@@_int_eval:w #1 / 2 = \c_one_int
- \@@_invalid_operation_o:Nww ^ #3; #4;
+ \@@_invalid_operation_o:Nww ^ #3\@@_sep: #4\@@_sep:
\exp:w \exp_end_continue_f:w
\exp_after:wN \exp_after:wN
\exp_after:wN \@@_use_none_until_s:w
\fi:
\fi:
\@@_exp_after_o:w
- \s_@@ \@@_chk:w #1#2;
+ \s_@@ \@@_chk:w #1#2\@@_sep:
}
\cs_new:Npn \@@_pow_neg_aux:wNN #1 \s_@@ \@@_chk:w #2#3
{
@@ -1216,7 +1241,7 @@
% |0|~if and only if the number was an integer, and |#3| is the $8$
% least significant digits of that integer.
% \begin{macrocode}
-\cs_new:Npn \@@_pow_neg_case:w \s_@@ \@@_chk:w #1#2#3;
+\cs_new:Npn \@@_pow_neg_case:w \s_@@ \@@_chk:w #1#2#3\@@_sep:
{
\if_case:w #1 \exp_stop_f:
-1
@@ -1236,7 +1261,7 @@
{#2} {#3} {#4} {#5}
\fi:
}
-\cs_new:Npn \@@_pow_neg_case_aux:Nnnw #1#2#3#4 ;
+\cs_new:Npn \@@_pow_neg_case_aux:Nnnw #1#2#3#4 \@@_sep:
{
\if_meaning:w 0 #1
\if_int_odd:w #3 \exp_stop_f:
@@ -1270,7 +1295,7 @@
% with $24$ digits instead of~$16$. It is easy to check that
% computing factorials with this precision is enough.
% \begin{macrocode}
-\cs_new:Npn \@@_fact_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+\cs_new:Npn \@@_fact_o:w #1 \s_@@ \@@_chk:w #2#3#4\@@_sep: @
{
\if_case:w #2 \exp_stop_f:
\@@_case_return_o:Nw \c_one_fp
@@ -1286,7 +1311,7 @@
\@@_case_use:nw { \@@_invalid_operation_o:fw { fact } }
\fi:
\@@_fact_pos_o:w
- \s_@@ \@@_chk:w #2 #3 #4 ;
+ \s_@@ \@@_chk:w #2 #3 #4 \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -1298,11 +1323,11 @@
% \cs{@@_sanitize:Nw} with a positive sign marker~|0| and an integer
% expression that will mop up any exponent in the calculation.
% \begin{macrocode}
-\cs_new:Npn \@@_fact_pos_o:w #1;
+\cs_new:Npn \@@_fact_pos_o:w #1\@@_sep:
{
- \@@_small_int:wTF #1;
+ \@@_small_int:wTF #1\@@_sep:
{ \@@_fact_int_o:n }
- { \@@_invalid_operation_o:fw { fact } #1; }
+ { \@@_invalid_operation_o:fw { fact } #1\@@_sep: }
}
\cs_new:Npn \@@_fact_int_o:n #1
{
@@ -1316,7 +1341,7 @@
\exp_after:wN \@@_sanitize:Nw
\exp_after:wN 0
\int_value:w \@@_int_eval:w
- \@@_fact_loop_o:w #1 . 4 , { 1 } { } { } { } { } { } ;
+ \@@_fact_loop_o:w #1 . 4 , { 1 } { } { } { } { } { } \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -1325,7 +1350,7 @@
% The loop receives an integer |#1| whose factorial we want to
% compute, which we progressively decrement, and the result so far as
% an extended-precision number |#2| in the form
-% \meta{exponent}|,|\meta{mantissa}|;|. The loop goes in steps of two
+% \meta{exponent}|,|\meta{mantissa}\cs{@@_sep:}. The loop goes in steps of two
% because we compute |#1*#1-1| as an integer expression (it must fit
% since |#1| is at most $3248$), then multiply with the result so far.
% We don't need to fill in most of the mantissa with zeros because
@@ -1335,7 +1360,7 @@
% chosen because the normalization step cannot deal with larger
% integers.
% \begin{macrocode}
-\cs_new:Npn \@@_fact_loop_o:w #1 . #2 ;
+\cs_new:Npn \@@_fact_loop_o:w #1 . #2 \@@_sep:
{
\if_int_compare:w #1 < 12 \exp_stop_f:
\@@_fact_small_o:w #1
@@ -1343,14 +1368,14 @@
\exp_after:wN \@@_ep_mul:wwwwn
\exp_after:wN 4 \exp_after:wN ,
\exp_after:wN { \int_value:w \@@_int_eval:w #1 * (#1 - 1) }
- { } { } { } { } { } ;
- #2 ;
+ { } { } { } { } { } \@@_sep:
+ #2 \@@_sep:
{
\exp_after:wN \@@_fact_loop_o:w
\int_value:w \@@_int_eval:w #1 - 2 .
}
}
-\cs_new:Npn \@@_fact_small_o:w #1 \fi: #2 ; #3 ; #4
+\cs_new:Npn \@@_fact_small_o:w #1 \fi: #2 \@@_sep: #3 \@@_sep: #4
{
\fi:
\exp_after:wN \@@_ep_mul:wwwwn
@@ -1362,8 +1387,8 @@
1 \or: 1 \or: 2 \or: 6 \or: 24 \or: 120 \or: 720 \or: 5040
\or: 40320 \or: 362880 \or: 3628800 \or: 39916800
\fi:
- } { } { } { } { } { } ;
- #3 ;
+ } { } { } { } { } { } \@@_sep:
+ #3 \@@_sep:
\@@_ep_to_float_o:wwN 0
}
% \end{macrocode}
diff --git a/macros/latex-dev/required/l3kernel/l3fp-extended.dtx b/macros/latex-dev/required/l3kernel/l3fp-extended.dtx
index 596dc86ef2..ce61593e9d 100644
--- a/macros/latex-dev/required/l3kernel/l3fp-extended.dtx
+++ b/macros/latex-dev/required/l3kernel/l3fp-extended.dtx
@@ -2,7 +2,7 @@
%
%% File: l3fp-extended.dtx
%
-% Copyright (C) 2011-2024 The LaTeX Project
+% Copyright (C) 2011-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -42,7 +42,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -76,7 +76,7 @@
% enough to be rounded away when converting back to a floating point
% number. The fixed point numbers are expressed as
% \begin{quote}
-% \Arg{a_1} \Arg{a_2} \Arg{a_3} \Arg{a_4} \Arg{a_5} \Arg{a_6} |;|
+% \Arg{a_1} \Arg{a_2} \Arg{a_3} \Arg{a_4} \Arg{a_5} \Arg{a_6} \cs{@@_sep:}
% \end{quote}
% where each \meta{a_i} is exactly $4$ digits (ranging from |0000| to
% |9999|), except \meta{a_1}, which may be any \enquote{not-too-large}
@@ -89,7 +89,8 @@
%
% Most functions we define here have the form
% \begin{syntax}
-% \cs{@@_fixed_\meta{calculation}:wwn} \meta{operand_1} |;| \meta{operand_2} |;| \Arg{continuation}
+% \cs{@@_fixed_\meta{calculation}:wwn} \meta{operand_1} \cs{@@_sep:}
+% ~~\meta{operand_2} \cs{@@_sep:} \Arg{continuation}
% \end{syntax}
% They perform the \meta{calculation} on the two \meta{operands}, then
% feed the result ($6$ brace groups followed by a semicolon) to the
@@ -97,9 +98,9 @@
% Some functions only accept an \texttt{N}-type \meta{continuation}.
% This allows constructions such as
% \begin{quote}
-% \cs{@@_fixed_add:wwn} \meta{X_1} |;| \meta{X_2} |;| \\
-% \cs{@@_fixed_mul:wwn} \meta{X_3} |;| \\
-% \cs{@@_fixed_add:wwn} \meta{X_4} |;| \\
+% \cs{@@_fixed_add:wwn} \meta{X_1} \cs{@@_sep:} \meta{X_2} \cs{@@_sep:} \\
+% \cs{@@_fixed_mul:wwn} \meta{X_3} \cs{@@_sep:} \\
+% \cs{@@_fixed_add:wwn} \meta{X_4} \cs{@@_sep:} \\
% \end{quote}
% to compute $(X_1+X_2)\cdot X_3 + X_4$. This turns out to be very
% appropriate for computing continued fractions and Taylor series.
@@ -116,29 +117,29 @@
% The fixed-point number~$1$, used in \pkg{l3fp-expo}.
% \begin{macrocode}
\tl_const:Nn \c_@@_one_fixed_tl
- { {10000} {0000} {0000} {0000} {0000} {0000} ; }
+ { {10000} {0000} {0000} {0000} {0000} {0000} \@@_sep: }
% \end{macrocode}
% \end{variable}
%
% \begin{macro}[EXP]{\@@_fixed_continue:wn}
% This function simply calls the next function.
% \begin{macrocode}
-\cs_new:Npn \@@_fixed_continue:wn #1; #2 { #2 #1; }
+\cs_new:Npn \@@_fixed_continue:wn #1\@@_sep: #2 { #2 #1\@@_sep: }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[EXP]{\@@_fixed_add_one:wN}
% \begin{syntax}
-% \cs{@@_fixed_add_one:wN} \meta{a} |;| \meta{continuation}
+% \cs{@@_fixed_add_one:wN} \meta{a} \cs{@@_sep:} \meta{continuation}
% \end{syntax}
% This function adds $1$ to the fixed point \meta{a}, by changing
% $a_1$ to $10000+a_1$, then calls the \meta{continuation}. This
% requires $a_1 + 10000 < 2^{31}$.
% \begin{macrocode}
-\cs_new:Npn \@@_fixed_add_one:wN #1#2; #3
+\cs_new:Npn \@@_fixed_add_one:wN #1#2\@@_sep: #3
{
\exp_after:wN #3 \exp_after:wN
- { \int_value:w \@@_int_eval:w \c_@@_myriad_int + #1 } #2 ;
+ { \int_value:w \@@_int_eval:w \c_@@_myriad_int + #1 } #2 \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -151,13 +152,13 @@
% exactly $4$~digits. The choice of shifts allows~|#1| to be in the
% range $[0, 5\cdot 10^{8}-1]$.
% \begin{macrocode}
-\cs_new:Npn \@@_fixed_div_myriad:wn #1#2#3#4#5#6;
+\cs_new:Npn \@@_fixed_div_myriad:wn #1#2#3#4#5#6\@@_sep:
{
\exp_after:wN \@@_fixed_mul_after:wwn
\int_value:w \@@_int_eval:w \c_@@_leading_shift_int
\exp_after:wN \@@_pack:NNNNNw
\int_value:w \@@_int_eval:w \c_@@_trailing_shift_int
- + #1 ; {#2}{#3}{#4}{#5};
+ + #1 \@@_sep: {#2}{#3}{#4}{#5}\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -167,7 +168,8 @@
% calling this auxiliary. It braces the last block of digits, and
% places the \meta{continuation} |#3| in front.
% \begin{macrocode}
-\cs_new:Npn \@@_fixed_mul_after:wwn #1; #2; #3 { #3 {#1} #2; }
+\cs_new:Npn \@@_fixed_mul_after:wwn #1\@@_sep: #2\@@_sep: #3
+ { #3 {#1} #2\@@_sep: }
% \end{macrocode}
% \end{macro}
%
@@ -176,20 +178,20 @@
% \begin{macro}[EXP]{\@@_fixed_mul_short:wwn}
% \begin{syntax}\parskip=0pt\obeylines
% \cs{@@_fixed_mul_short:wwn}
-% | |\Arg{a_1} \Arg{a_2} \Arg{a_3} \Arg{a_4} \Arg{a_5} \Arg{a_6} |;|
-% | |\Arg{b_0} \Arg{b_1} \Arg{b_2} |;| \Arg{continuation}
+% | |\Arg{a_1} \Arg{a_2} \Arg{a_3} \Arg{a_4} \Arg{a_5} \Arg{a_6} \cs{@@_sep:}
+% | |\Arg{b_0} \Arg{b_1} \Arg{b_2} \cs{@@_sep:} \Arg{continuation}
% \end{syntax}
% Computes the product $c=ab$ of $a=\sum_i \meta{a_i} 10^{-4i}$ and
% $b=\sum_i \meta{b_i} 10^{-4i}$, rounds it to the closest multiple of
% $10^{-24}$, and leaves \meta{continuation} \Arg{c_1} \ldots{}
-% \Arg{c_6} |;| in the input stream, where each of the \meta{c_i} are
+% \Arg{c_6} \cs{@@_sep:} in the input stream, where each of the \meta{c_i} are
% blocks of $4$~digits, except \meta{c_1}, which is any \TeX{}
% integer. Note that indices for \meta{b} start at~$0$: for instance
% a second operand of |{0001}{0000}{0000}| leaves the first operand
% unchanged (rather than dividing it by $10^{4}$, as
% \cs{@@_fixed_mul:wwn} would).
% \begin{macrocode}
-\cs_new:Npn \@@_fixed_mul_short:wwn #1#2#3#4#5#6; #7#8#9;
+\cs_new:Npn \@@_fixed_mul_short:wwn #1#2#3#4#5#6\@@_sep: #7#8#9\@@_sep:
{
\exp_after:wN \@@_fixed_mul_after:wwn
\int_value:w \@@_int_eval:w \c_@@_leading_shift_int
@@ -210,7 +212,7 @@
\int_value:w \@@_int_eval:w \c_@@_trailing_shift_int
+ #4*#9 + #5*#8 + #6*#7
+ ( #5*#9 + #6*#8 + #6*#9 / \c_@@_myriad_int )
- / \c_@@_myriad_int ; ;
+ / \c_@@_myriad_int \@@_sep: \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -225,7 +227,7 @@
% \@@_fixed_div_int_after:Nw
% }
% \begin{syntax}
-% \cs{@@_fixed_div_int:wwN} \meta{a} |;| \meta{n} |;| \meta{continuation}
+% \cs{@@_fixed_div_int:wwN} \meta{a} \cs{@@_sep:} \meta{n} \cs{@@_sep:} \meta{continuation}
% \end{syntax}
% Divides the fixed point number \meta{a} by the (small) integer
% $0<\meta{n}<10^4$ and feeds the result to the \meta{continuation}.
@@ -255,7 +257,7 @@
% \cs{@@_fixed_div_int_pack:Nw} $9999 + Q_{4}$ \\
% \cs{@@_fixed_div_int_pack:Nw} $9999 + Q_{5}$ \\
% \cs{@@_fixed_div_int_pack:Nw} $9999$ \\
-% \cs{@@_fixed_div_int_auxii:wnn} $Q_{6}$ |;| \Arg{n} \Arg{a_{6}}
+% \cs{@@_fixed_div_int_auxii:wnn} $Q_{6}$ \cs{@@_sep:} \Arg{n} \Arg{a_{6}}
% \end{quote}
% where expansion is happening from the last line up. The
% \texttt{iii} auxiliary adds $Q_{6} + 2 \simeq a_{6}/n + 1$ to the
@@ -268,27 +270,27 @@
% brace group is produced by the \texttt{after} auxiliary, which
% places the \meta{continuation} as appropriate.
% \begin{macrocode}
-\cs_new:Npn \@@_fixed_div_int:wwN #1#2#3#4#5#6 ; #7 ; #8
+\cs_new:Npn \@@_fixed_div_int:wwN #1#2#3#4#5#6 \@@_sep: #7 \@@_sep: #8
{
\exp_after:wN \@@_fixed_div_int_after:Nw
\exp_after:wN #8
\int_value:w \@@_int_eval:w - 1
\@@_fixed_div_int:wnN
- #1; {#7} \@@_fixed_div_int_auxi:wnn
- #2; {#7} \@@_fixed_div_int_auxi:wnn
- #3; {#7} \@@_fixed_div_int_auxi:wnn
- #4; {#7} \@@_fixed_div_int_auxi:wnn
- #5; {#7} \@@_fixed_div_int_auxi:wnn
- #6; {#7} \@@_fixed_div_int_auxii:wnn ;
+ #1\@@_sep: {#7} \@@_fixed_div_int_auxi:wnn
+ #2\@@_sep: {#7} \@@_fixed_div_int_auxi:wnn
+ #3\@@_sep: {#7} \@@_fixed_div_int_auxi:wnn
+ #4\@@_sep: {#7} \@@_fixed_div_int_auxi:wnn
+ #5\@@_sep: {#7} \@@_fixed_div_int_auxi:wnn
+ #6\@@_sep: {#7} \@@_fixed_div_int_auxii:wnn \@@_sep:
}
-\cs_new:Npn \@@_fixed_div_int:wnN #1; #2 #3
+\cs_new:Npn \@@_fixed_div_int:wnN #1\@@_sep: #2 #3
{
\exp_after:wN #3
- \int_value:w \@@_int_eval:w #1 / #2 - 1 ;
+ \int_value:w \@@_int_eval:w #1 / #2 - 1 \@@_sep:
{#2}
{#1}
}
-\cs_new:Npn \@@_fixed_div_int_auxi:wnn #1; #2 #3
+\cs_new:Npn \@@_fixed_div_int_auxi:wnn #1\@@_sep: #2 #3
{
+ #1
\exp_after:wN \@@_fixed_div_int_pack:Nw
@@ -296,9 +298,9 @@
\exp_after:wN \@@_fixed_div_int:wnN
\int_value:w \@@_int_eval:w #3 - #1*#2 \@@_int_eval_end:
}
-\cs_new:Npn \@@_fixed_div_int_auxii:wnn #1; #2 #3 { + #1 + 2 ; }
-\cs_new:Npn \@@_fixed_div_int_pack:Nw #1 #2; { + #1; {#2} }
-\cs_new:Npn \@@_fixed_div_int_after:Nw #1 #2; { #1 {#2} }
+\cs_new:Npn \@@_fixed_div_int_auxii:wnn #1\@@_sep: #2 #3 { + #1 + 2 \@@_sep: }
+\cs_new:Npn \@@_fixed_div_int_pack:Nw #1 #2\@@_sep: { + #1\@@_sep: {#2} }
+\cs_new:Npn \@@_fixed_div_int_after:Nw #1 #2\@@_sep: { #1 {#2} }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -314,7 +316,7 @@
% \@@_fixed_add_after:NNNNNwn
% }
% \begin{syntax}
-% \cs{@@_fixed_add:wwn} \meta{a} |;| \meta{b} |;| \Arg{continuation}
+% \cs{@@_fixed_add:wwn} \meta{a} \cs{@@_sep:} \meta{b} \cs{@@_sep:} \Arg{continuation}
% \end{syntax}
% Computes $a+b$ (resp.\ $a-b$) and feeds the result to the
% \meta{continuation}. This function requires $0\leq a_{1},b_{1}\leq
@@ -333,7 +335,7 @@
% \begin{macrocode}
\cs_new:Npn \@@_fixed_add:wwn { \@@_fixed_add:Nnnnnwnn + }
\cs_new:Npn \@@_fixed_sub:wwn { \@@_fixed_add:Nnnnnwnn - }
-\cs_new:Npn \@@_fixed_add:Nnnnnwnn #1 #2#3#4#5 #6; #7#8
+\cs_new:Npn \@@_fixed_add:Nnnnnwnn #1 #2#3#4#5 #6\@@_sep: #7#8
{
\exp_after:wN \@@_fixed_add_after:NNNNNwn
\int_value:w \@@_int_eval:w 9 9999 9998 + #2#3 #1 #7#8
@@ -341,15 +343,16 @@
\int_value:w \@@_int_eval:w 1 9999 9998 + #4#5
\@@_fixed_add:nnNnnnwn #6 #1
}
-\cs_new:Npn \@@_fixed_add:nnNnnnwn #1#2 #3 #4#5 #6#7 ; #8
+\cs_new:Npn \@@_fixed_add:nnNnnnwn #1#2 #3 #4#5 #6#7 \@@_sep: #8
{
#3 #4#5
\exp_after:wN \@@_fixed_add_pack:NNNNNwn
- \int_value:w \@@_int_eval:w 2 0000 0000 #3 #6#7 + #1#2 ; {#8} ;
+ \int_value:w \@@_int_eval:w
+ 2 0000 0000 #3 #6#7 + #1#2 \@@_sep: {#8} \@@_sep:
}
-\cs_new:Npn \@@_fixed_add_pack:NNNNNwn #1 #2#3#4#5 #6; #7
- { + #1 ; {#7} {#2#3#4#5} {#6} }
-\cs_new:Npn \@@_fixed_add_after:NNNNNwn 1 #1 #2#3#4#5 #6; #7
+\cs_new:Npn \@@_fixed_add_pack:NNNNNwn #1 #2#3#4#5 #6\@@_sep: #7
+ { + #1 \@@_sep: {#7} {#2#3#4#5} {#6} }
+\cs_new:Npn \@@_fixed_add_after:NNNNNwn 1 #1 #2#3#4#5 #6\@@_sep: #7
{ #7 {#1#2#3#4#5} {#6} }
% \end{macrocode}
% \end{macro}
@@ -361,7 +364,7 @@
% \begin{macro}[EXP]{\@@_fixed_mul:wwn}
% \begin{macro}[EXP]{\@@_fixed_mul:nnnnnnnw}
% \begin{syntax}
-% \cs{@@_fixed_mul:wwn} \meta{a} |;| \meta{b} |;| \Arg{continuation}
+% \cs{@@_fixed_mul:wwn} \meta{a} \cs{@@_sep:} \meta{b} \cs{@@_sep:} \Arg{continuation}
% \end{syntax}
% Computes $a\times b$ and feeds the result to \meta{continuation}.
% This function requires $0\leq a_{1}, b_{1} < 10000$. Once more, we
@@ -402,7 +405,7 @@
% is finally placed in front of the $6$ brace groups by
% \cs{@@_fixed_mul_after:wwn}.
% \begin{macrocode}
-\cs_new:Npn \@@_fixed_mul:wwn #1#2#3#4 #5; #6#7#8#9
+\cs_new:Npn \@@_fixed_mul:wwn #1#2#3#4 #5\@@_sep: #6#7#8#9
{
\exp_after:wN \@@_fixed_mul_after:wwn
\int_value:w \@@_int_eval:w \c_@@_leading_shift_int
@@ -424,10 +427,10 @@
+ ( #3*#9 + #4*#8
+ \@@_fixed_mul:nnnnnnnw #5 {#6}{#7} {#1}{#2}
}
-\cs_new:Npn \@@_fixed_mul:nnnnnnnw #1#2 #3#4 #5#6 #7#8 ;
+\cs_new:Npn \@@_fixed_mul:nnnnnnnw #1#2 #3#4 #5#6 #7#8 \@@_sep:
{
#1*#4 + #2*#3 + #5*#8 + #6*#7 ) / \c_@@_myriad_int
- + #1*#3 + #5*#7 ; ;
+ + #1*#3 + #5*#7 \@@_sep: \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -442,9 +445,9 @@
% \@@_fixed_mul_one_minus_mul:wwn,
% }
% \begin{syntax}
-% \cs{@@_fixed_mul_add:wwwn} \meta{a} |;| \meta{b} |;| \meta{c} |;| \Arg{continuation}
-% \cs{@@_fixed_mul_sub_back:wwwn} \meta{a} |;| \meta{b} |;| \meta{c} |;| \Arg{continuation}
-% \cs{@@_fixed_one_minus_mul:wwn} \meta{a} |;| \meta{b} |;| \Arg{continuation}
+% \cs{@@_fixed_mul_add:wwwn} \meta{a} \cs{@@_sep:} \meta{b} \cs{@@_sep:} \meta{c} \cs{@@_sep:} \Arg{continuation}
+% \cs{@@_fixed_mul_sub_back:wwwn} \meta{a} \cs{@@_sep:} \meta{b} \cs{@@_sep:} \meta{c} \cs{@@_sep:} \Arg{continuation}
+% \cs{@@_fixed_one_minus_mul:wwn} \meta{a} \cs{@@_sep:} \meta{b} \cs{@@_sep:} \Arg{continuation}
% \end{syntax}
% Sometimes called |FMA| (fused multiply-add), these functions
% compute $a\times b + c$, $c - a\times b$, and $1 - a\times b$ and
@@ -482,32 +485,33 @@
% Each of the three function starts the first two levels (the first,
% corresponding to $10^{-4}$, is empty), with $c_{1} c_{2}$ in the
% first level, calls the \texttt{i} auxiliary with arguments described
-% later, and adds a trailing ${} + c_{5}c_{6}$ |;|
-% \Arg{continuation}~|;|. The ${} + c_{5}c_{6}$ piece, which is
+% later, and adds a trailing ${} + c_{5}c_{6}$ \cs{@@_sep:}
+% \Arg{continuation}~\cs{@@_sep:}. The ${} + c_{5}c_{6}$ piece, which is
% omitted for \cs{@@_fixed_one_minus_mul:wwn}, is taken in the
% integer expression for the $10^{-24}$ level.
% \begin{macrocode}
-\cs_new:Npn \@@_fixed_mul_add:wwwn #1; #2; #3#4#5#6#7#8;
+\cs_new:Npn \@@_fixed_mul_add:wwwn #1\@@_sep: #2\@@_sep: #3#4#5#6#7#8\@@_sep:
{
\exp_after:wN \@@_fixed_mul_after:wwn
\int_value:w \@@_int_eval:w \c_@@_big_leading_shift_int
\exp_after:wN \@@_pack_big:NNNNNNw
\int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int + #3 #4
\@@_fixed_mul_add:Nwnnnwnnn +
- + #5 #6 ; #2 ; #1 ; #2 ; +
- + #7 #8 ; ;
+ + #5 #6 \@@_sep: #2 \@@_sep: #1 \@@_sep: #2 \@@_sep: +
+ + #7 #8 \@@_sep: \@@_sep:
}
-\cs_new:Npn \@@_fixed_mul_sub_back:wwwn #1; #2; #3#4#5#6#7#8;
+\cs_new:Npn \@@_fixed_mul_sub_back:wwwn
+ #1\@@_sep: #2\@@_sep: #3#4#5#6#7#8\@@_sep:
{
\exp_after:wN \@@_fixed_mul_after:wwn
\int_value:w \@@_int_eval:w \c_@@_big_leading_shift_int
\exp_after:wN \@@_pack_big:NNNNNNw
\int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int + #3 #4
\@@_fixed_mul_add:Nwnnnwnnn -
- + #5 #6 ; #2 ; #1 ; #2 ; -
- + #7 #8 ; ;
+ + #5 #6 \@@_sep: #2 \@@_sep: #1 \@@_sep: #2 \@@_sep: -
+ + #7 #8 \@@_sep: \@@_sep:
}
-\cs_new:Npn \@@_fixed_one_minus_mul:wwn #1; #2;
+\cs_new:Npn \@@_fixed_one_minus_mul:wwn #1\@@_sep: #2\@@_sep:
{
\exp_after:wN \@@_fixed_mul_after:wwn
\int_value:w \@@_int_eval:w \c_@@_big_leading_shift_int
@@ -515,17 +519,17 @@
\int_value:w \@@_int_eval:w \c_@@_big_middle_shift_int +
1 0000 0000
\@@_fixed_mul_add:Nwnnnwnnn -
- ; #2 ; #1 ; #2 ; -
- ; ;
+ \@@_sep: #2 \@@_sep: #1 \@@_sep: #2 \@@_sep: -
+ \@@_sep: \@@_sep:
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[EXP]{\@@_fixed_mul_add:Nwnnnwnnn}
% \begin{syntax}
-% \cs{@@_fixed_mul_add:Nwnnnwnnn} \meta{op} |+| \meta{c_3} \meta{c_4} |;|
-% ~~\meta{b} |;| \meta{a} |;| \meta{b} |;| \meta{op}
-% ~~|+| \meta{c_5} \meta{c_6} |;|
+% \cs{@@_fixed_mul_add:Nwnnnwnnn} \meta{op} |+| \meta{c_3} \meta{c_4} \cs{@@_sep:}
+% ~~\meta{b} \cs{@@_sep:} \meta{a} \cs{@@_sep:} \meta{b} \cs{@@_sep:} \meta{op}
+% ~~|+| \meta{c_5} \meta{c_6} \cs{@@_sep:}
% \end{syntax}
% Here, \meta{op} is either |+| or |-|. Arguments |#3|, |#4|, |#5|
% are \meta{b_1}, \meta{b_2}, \meta{b_3}; arguments |#7|, |#8|, |#9|
@@ -539,7 +543,7 @@
% we've read, but not \meta{b}, since there is another copy later in
% the input stream.
% \begin{macrocode}
-\cs_new:Npn \@@_fixed_mul_add:Nwnnnwnnn #1 #2; #3#4#5#6; #7#8#9
+\cs_new:Npn \@@_fixed_mul_add:Nwnnnwnnn #1 #2\@@_sep: #3#4#5#6\@@_sep: #7#8#9
{
#1 #7*#3
\exp_after:wN \@@_pack_big:NNNNNNw
@@ -557,8 +561,8 @@
%
% \begin{macro}[EXP]{\@@_fixed_mul_add:nnnnwnnnn}
% \begin{syntax}
-% \cs{@@_fixed_mul_add:nnnnwnnnn} \meta{a} |;| \meta{b} |;| \meta{op}
-% ~~|+| \meta{c_5} \meta{c_6} |;|
+% \cs{@@_fixed_mul_add:nnnnwnnnn} \meta{a} \cs{@@_sep:} \meta{b} \cs{@@_sep:} \meta{op}
+% ~~|+| \meta{c_5} \meta{c_6} \cs{@@_sep:}
% \end{syntax}
% Level $10^{-20}$ is $(a_{1} \cdot b_{4} + a_{2} \cdot b_{3} + a_{3}
% \cdot b_{2} + a_{4} \cdot b_{1})$, multiplied by the sign, which was
@@ -577,7 +581,7 @@
% To do all this, we keep $a_{1}$, $a_{5}$, $a_{6}$, and the
% corresponding pieces of \meta{b}.
% \begin{macrocode}
-\cs_new:Npn \@@_fixed_mul_add:nnnnwnnnn #1#2#3#4#5; #6#7#8#9
+\cs_new:Npn \@@_fixed_mul_add:nnnnwnnnn #1#2#3#4#5\@@_sep: #6#7#8#9
{
( #1*#9 + #2*#8 + #3*#7 + #4*#6 )
\exp_after:wN \@@_pack_big:NNNNNNw
@@ -585,7 +589,7 @@
\@@_fixed_mul_add:nnnnwnnwN
{ #6 + #4*#7 + #3*#8 + #2*#9 + #1 }
{ #7 + #4*#8 + #3*#9 + #2 }
- {#1} #5;
+ {#1} #5\@@_sep:
{#6}
}
% \end{macrocode}
@@ -594,8 +598,8 @@
% \begin{macro}[EXP]{\@@_fixed_mul_add:nnnnwnnwN}
% \begin{syntax}
% \cs{@@_fixed_mul_add:nnnnwnnwN} \Arg{partial_1} \Arg{partial_2}
-% ~~\Arg{a_1} \Arg{a_5} \Arg{a_6} |;| \Arg{b_1} \Arg{b_5} \Arg{b_6} |;|
-% ~~\meta{op} |+| \meta{c_5} \meta{c_6} |;|
+% ~~\Arg{a_1} \Arg{a_5} \Arg{a_6} \cs{@@_sep:} \Arg{b_1} \Arg{b_5} \Arg{b_6} \cs{@@_sep:}
+% ~~\meta{op} |+| \meta{c_5} \meta{c_6} \cs{@@_sep:}
% \end{syntax}
% Complete the \meta{partial_1} and \meta{partial_2} expressions as
% explained for the \texttt{ii} auxiliary. The second one is divided
@@ -607,7 +611,7 @@
% expected by the packing auxiliaries. See \pkg{l3fp-aux} for the
% definition of the shifts and packing auxiliaries.
% \begin{macrocode}
-\cs_new:Npn \@@_fixed_mul_add:nnnnwnnwN #1#2 #3#4#5; #6#7#8; #9
+\cs_new:Npn \@@_fixed_mul_add:nnnnwnnwN #1#2 #3#4#5\@@_sep: #6#7#8\@@_sep: #9
{
#9 (#4* #1 *#7)
#9 (#5*#6+#4* #2 *#7+#3*#8) / \c_@@_myriad_int
@@ -637,21 +641,22 @@
\cs_new:Npn \@@_ep_to_fixed:wwn #1,#2
{
\exp_after:wN \@@_ep_to_fixed_auxi:www
- \int_value:w \@@_int_eval:w 1 0000 0000 + #2 \exp_after:wN ;
+ \int_value:w \@@_int_eval:w 1 0000 0000 + #2 \exp_after:wN \@@_sep:
\exp:w \exp_end_continue_f:w
- \prg_replicate:nn { 4 - \int_max:nn {#1} { -32 } } { 0 } ;
+ \prg_replicate:nn { 4 - \int_max:nn {#1} { -32 } } { 0 } \@@_sep:
}
-\cs_new:Npn \@@_ep_to_fixed_auxi:www 1#1; #2; #3#4#5#6#7;
+\cs_new:Npn \@@_ep_to_fixed_auxi:www
+ 1#1\@@_sep: #2\@@_sep: #3#4#5#6#7\@@_sep:
{
\@@_pack_eight:wNNNNNNNN
\@@_pack_twice_four:wNNNNNNNN
\@@_pack_twice_four:wNNNNNNNN
\@@_pack_twice_four:wNNNNNNNN
- \@@_ep_to_fixed_auxii:nnnnnnnwn ;
+ \@@_ep_to_fixed_auxii:nnnnnnnwn \@@_sep:
#2 #1#3#4#5#6#7 0000 !
}
-\cs_new:Npn \@@_ep_to_fixed_auxii:nnnnnnnwn #1#2#3#4#5#6#7; #8! #9
- { #9 {#1#2}{#3}{#4}{#5}{#6}{#7}; }
+\cs_new:Npn \@@_ep_to_fixed_auxii:nnnnnnnwn #1#2#3#4#5#6#7\@@_sep: #8! #9
+ { #9 {#1#2}{#3}{#4}{#5}{#6}{#7}\@@_sep: }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -675,14 +680,14 @@
% any digit that did not make it in the final mantissa (typically only
% zeros, unless the original first block has more than~$4$ digits).
% \begin{macrocode}
-\cs_new:Npn \@@_ep_to_ep:wwN #1,#2#3#4#5#6#7; #8
+\cs_new:Npn \@@_ep_to_ep:wwN #1,#2#3#4#5#6#7\@@_sep: #8
{
\exp_after:wN #8
\int_value:w \@@_int_eval:w #1 + 4
\exp_after:wN \use_i:nn
\exp_after:wN \@@_ep_to_ep_loop:N
\int_value:w \@@_int_eval:w 1 0000 0000 + #2 \@@_int_eval_end:
- #3#4#5#6#7 ; ; !
+ #3#4#5#6#7 \@@_sep: \@@_sep: !
}
\cs_new:Npn \@@_ep_to_ep_loop:N #1
{
@@ -694,21 +699,21 @@
\@@_ep_to_ep_loop:N
}
\cs_new:Npn \@@_ep_to_ep_end:www
- #1 \fi: \@@_ep_to_ep_loop:N #2; #3!
+ #1 \fi: \@@_ep_to_ep_loop:N #2\@@_sep: #3!
{
\fi:
- \if_meaning:w ; #1
+ \if_meaning:w \@@_sep: #1
- 2 * \c_@@_max_exponent_int
\@@_ep_to_ep_zero:ww
\fi:
\@@_pack_twice_four:wNNNNNNNN
\@@_pack_twice_four:wNNNNNNNN
\@@_pack_twice_four:wNNNNNNNN
- \@@_use_i:ww , ;
- #1 #2 0000 0000 0000 0000 0000 0000 ;
+ \@@_use_i:ww , \@@_sep:
+ #1 #2 0000 0000 0000 0000 0000 0000 \@@_sep:
}
-\cs_new:Npn \@@_ep_to_ep_zero:ww \fi: #1; #2; #3;
- { \fi: , {1000}{0000}{0000}{0000}{0000}{0000} ; }
+\cs_new:Npn \@@_ep_to_ep_zero:ww \fi: #1\@@_sep: #2\@@_sep: #3\@@_sep:
+ { \fi: , {1000}{0000}{0000}{0000}{0000}{0000} \@@_sep: }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -723,12 +728,14 @@
% works if the numbers are normalized so that their first block is
% in~$[1000,9999]$.
% \begin{macrocode}
-\cs_new:Npn \@@_ep_compare:wwww #1,#2#3#4#5#6#7;
- { \@@_ep_compare_aux:wwww {#1}{#2}{#3}{#4}{#5}; #6#7; }
-\cs_new:Npn \@@_ep_compare_aux:wwww #1;#2;#3,#4#5#6#7#8#9;
+\cs_new:Npn \@@_ep_compare:wwww #1,#2#3#4#5#6#7\@@_sep:
+ { \@@_ep_compare_aux:wwww {#1}{#2}{#3}{#4}{#5}\@@_sep: #6#7\@@_sep: }
+\cs_new:Npn \@@_ep_compare_aux:wwww
+ #1\@@_sep:#2\@@_sep:#3,#4#5#6#7#8#9\@@_sep:
{
\if_case:w
- \@@_compare_npos:nwnw #1; {#3}{#4}{#5}{#6}{#7}; \exp_stop_f:
+ \@@_compare_npos:nwnw
+ #1\@@_sep: {#3}{#4}{#5}{#6}{#7}\@@_sep: \exp_stop_f:
\if_int_compare:w #2 = #8#9 \exp_stop_f:
0
\else:
@@ -749,19 +756,19 @@
% and~|#4| as fixed point numbers, and sum the exponents |#1|
% and~|#3|. The result's first block is in $[100,9999]$.
% \begin{macrocode}
-\cs_new:Npn \@@_ep_mul:wwwwn #1,#2; #3,#4;
+\cs_new:Npn \@@_ep_mul:wwwwn #1,#2\@@_sep: #3,#4\@@_sep:
{
- \@@_ep_to_ep:wwN #3,#4;
+ \@@_ep_to_ep:wwN #3,#4\@@_sep:
\@@_fixed_continue:wn
{
- \@@_ep_to_ep:wwN #1,#2;
+ \@@_ep_to_ep:wwN #1,#2\@@_sep:
\@@_ep_mul_raw:wwwwN
}
\@@_fixed_continue:wn
}
-\cs_new:Npn \@@_ep_mul_raw:wwwwN #1,#2; #3,#4; #5
+\cs_new:Npn \@@_ep_mul_raw:wwwwN #1,#2\@@_sep: #3,#4\@@_sep: #5
{
- \@@_fixed_mul:wwn #2; #4;
+ \@@_fixed_mul:wwn #2\@@_sep: #4\@@_sep:
{ \exp_after:wN #5 \int_value:w \@@_int_eval:w #1 + #3 , }
}
% \end{macrocode}
@@ -901,12 +908,12 @@
% \meta{denominator} \meta{numerator}, responsible for estimating the
% inverse of the denominator.
% \begin{macrocode}
-\cs_new:Npn \@@_ep_div:wwwwn #1,#2; #3,#4;
+\cs_new:Npn \@@_ep_div:wwwwn #1,#2\@@_sep: #3,#4\@@_sep:
{
- \@@_ep_to_ep:wwN #1,#2;
+ \@@_ep_to_ep:wwN #1,#2\@@_sep:
\@@_fixed_continue:wn
{
- \@@_ep_to_ep:wwN #3,#4;
+ \@@_ep_to_ep:wwN #3,#4\@@_sep:
\@@_ep_div_esti:wwwwn
}
}
@@ -935,24 +942,25 @@
% $10^{-9}a/(1-\epsilon)$, that is, $1/(10\meta{d})$ and we finally
% multiply this by the numerator~|#8|.
% \begin{macrocode}
-\cs_new:Npn \@@_ep_div_esti:wwwwn #1,#2#3; #4,
+\cs_new:Npn \@@_ep_div_esti:wwwwn #1,#2#3\@@_sep: #4,
{
\exp_after:wN \@@_ep_div_estii:wwnnwwn
\int_value:w \@@_int_eval:w 10 0000 0000 / ( #2 + 1 )
- \exp_after:wN ;
+ \exp_after:wN \@@_sep:
\int_value:w \@@_int_eval:w #4 - #1 + 1 ,
- {#2} #3;
+ {#2} #3\@@_sep:
}
-\cs_new:Npn \@@_ep_div_estii:wwnnwwn #1; #2,#3#4#5; #6; #7
+\cs_new:Npn \@@_ep_div_estii:wwnnwwn
+ #1\@@_sep: #2,#3#4#5\@@_sep: #6\@@_sep: #7
{
\exp_after:wN \@@_ep_div_estiii:NNNNNwwwn
\int_value:w \@@_int_eval:w 10 0000 0000 - 1750
- + #1 000 + (10 0000 0000 / #3 - #1) * (1000 - #4 / 10) ;
- {#3}{#4}#5; #6; { #7 #2, }
+ + #1 000 + (10 0000 0000 / #3 - #1) * (1000 - #4 / 10) \@@_sep:
+ {#3}{#4}#5\@@_sep: #6\@@_sep: { #7 #2, }
}
-\cs_new:Npn \@@_ep_div_estiii:NNNNNwwwn 1#1#2#3#4#5#6; #7;
+\cs_new:Npn \@@_ep_div_estiii:NNNNNwwwn 1#1#2#3#4#5#6\@@_sep: #7\@@_sep:
{
- \@@_fixed_mul_short:wwn #7; {#1}{#2#3#4#5}{#6};
+ \@@_fixed_mul_short:wwn #7\@@_sep: {#1}{#2#3#4#5}{#6}\@@_sep:
\@@_ep_div_epsi:wnNNNNNn {#1#2#3#4}#5#6
\@@_fixed_mul:wwn
}
@@ -978,28 +986,29 @@
% combination of \texttt{short_mul} and \texttt{div_myriad} is both
% faster and more precise than a simple \texttt{mul}.
% \begin{macrocode}
-\cs_new:Npn \@@_ep_div_epsi:wnNNNNNn #1#2#3#4#5#6;
+\cs_new:Npn \@@_ep_div_epsi:wnNNNNNn #1#2#3#4#5#6\@@_sep:
{
\exp_after:wN \@@_ep_div_epsii:wwnNNNNNn
\int_value:w \@@_int_eval:w 1 9998 - #2
\exp_after:wN \@@_ep_div_eps_pack:NNNNNw
\int_value:w \@@_int_eval:w 1 9999 9998 - #3#4
\exp_after:wN \@@_ep_div_eps_pack:NNNNNw
- \int_value:w \@@_int_eval:w 2 0000 0000 - #5#6 ; ;
+ \int_value:w \@@_int_eval:w 2 0000 0000 - #5#6 \@@_sep: \@@_sep:
}
-\cs_new:Npn \@@_ep_div_eps_pack:NNNNNw #1#2#3#4#5#6;
- { + #1 ; {#2#3#4#5} {#6} }
-\cs_new:Npn \@@_ep_div_epsii:wwnNNNNNn 1#1; #2; #3#4#5#6#7#8
+\cs_new:Npn \@@_ep_div_eps_pack:NNNNNw #1#2#3#4#5#6\@@_sep:
+ { + #1 \@@_sep: {#2#3#4#5} {#6} }
+\cs_new:Npn \@@_ep_div_epsii:wwnNNNNNn 1#1\@@_sep: #2\@@_sep: #3#4#5#6#7#8
{
- \@@_fixed_mul:wwn {0000}{#1}#2; {0000}{#1}#2;
+ \@@_fixed_mul:wwn {0000}{#1}#2\@@_sep: {0000}{#1}#2\@@_sep:
\@@_fixed_add_one:wN
- \@@_fixed_mul:wwn {10000} {#1} #2 ;
+ \@@_fixed_mul:wwn {10000} {#1} #2 \@@_sep:
{
- \@@_fixed_mul_short:wwn {0000}{#1}#2; {#3}{#4#5#6#7}{#8000};
+ \@@_fixed_mul_short:wwn
+ {0000}{#1}#2\@@_sep: {#3}{#4#5#6#7}{#8000}\@@_sep:
\@@_fixed_div_myriad:wn
\@@_fixed_mul:wwn
}
- \@@_fixed_add:wwn {#3}{#4#5#6#7}{#8000}{0000}{0000}{0000};
+ \@@_fixed_add:wwn {#3}{#4#5#6#7}{#8000}{0000}{0000}{0000}\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -1047,9 +1056,9 @@
% mantissa and an altered continuation where we have stored the
% result's exponent.
% \begin{macrocode}
-\cs_new:Npn \@@_ep_isqrt:wwn #1,#2;
+\cs_new:Npn \@@_ep_isqrt:wwn #1,#2\@@_sep:
{
- \@@_ep_to_ep:wwN #1,#2;
+ \@@_ep_to_ep:wwN #1,#2\@@_sep:
\@@_ep_isqrt_auxi:wwn
}
\cs_new:Npn \@@_ep_isqrt_auxi:wwn #1,
@@ -1060,10 +1069,10 @@
{ (1 - #1) / 2 , 535 , { 0 } { } }
{ 1 - #1 / 2 , 168 , { } { 0 } }
}
-\cs_new:Npn \@@_ep_isqrt_auxii:wwnnnwn #1, #2, #3#4 #5#6; #7
+\cs_new:Npn \@@_ep_isqrt_auxii:wwnnnwn #1, #2, #3#4 #5#6\@@_sep: #7
{
\@@_ep_isqrt_esti:wwwnnwn #2, 0, #5, {#3} {#4}
- {#5} #6 ; { #7 #1 , }
+ {#5} #6 \@@_sep: { #7 #1 , }
}
% \end{macrocode}
% \end{macro}
@@ -1106,13 +1115,14 @@
{
\exp_after:wN \@@_ep_isqrt_estiii:NNNNNwwwn
\int_value:w \@@_int_eval:w 1000 0000 + #2 * #2 #5 * 5
- \exp_after:wN , \int_value:w \@@_int_eval:w 10000 + #2 ;
+ \exp_after:wN , \int_value:w \@@_int_eval:w 10000 + #2 \@@_sep:
}
-\cs_new:Npn \@@_ep_isqrt_estiii:NNNNNwwwn 1#1#2#3#4#5#6, 1#7#8; #9;
+\cs_new:Npn \@@_ep_isqrt_estiii:NNNNNwwwn
+ 1#1#2#3#4#5#6, 1#7#8\@@_sep: #9\@@_sep:
{
- \@@_fixed_mul_short:wwn #9; {#1} {#2#3#4#5} {#600} ;
+ \@@_fixed_mul_short:wwn #9\@@_sep: {#1} {#2#3#4#5} {#600} \@@_sep:
\@@_ep_isqrt_epsi:wN
- \@@_fixed_mul_short:wwn {#7} {#80} {0000} ;
+ \@@_fixed_mul_short:wwn {#7} {#80} {0000} \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -1124,19 +1134,19 @@
% multiplications. The \texttt{epsii} auxiliary receives $z$ as~|#1|
% and $y$ as~|#2|.
% \begin{macrocode}
-\cs_new:Npn \@@_ep_isqrt_epsi:wN #1;
+\cs_new:Npn \@@_ep_isqrt_epsi:wN #1\@@_sep:
{
- \@@_fixed_sub:wwn {15000}{0000}{0000}{0000}{0000}{0000}; #1;
- \@@_ep_isqrt_epsii:wwN #1;
- \@@_ep_isqrt_epsii:wwN #1;
- \@@_ep_isqrt_epsii:wwN #1;
+ \@@_fixed_sub:wwn {15000}{0000}{0000}{0000}{0000}{0000}\@@_sep: #1\@@_sep:
+ \@@_ep_isqrt_epsii:wwN #1\@@_sep:
+ \@@_ep_isqrt_epsii:wwN #1\@@_sep:
+ \@@_ep_isqrt_epsii:wwN #1\@@_sep:
}
-\cs_new:Npn \@@_ep_isqrt_epsii:wwN #1; #2;
+\cs_new:Npn \@@_ep_isqrt_epsii:wwN #1\@@_sep: #2\@@_sep:
{
- \@@_fixed_mul:wwn #1; #1;
- \@@_fixed_mul_sub_back:wwwn #2;
- {15000}{0000}{0000}{0000}{0000}{0000};
- \@@_fixed_mul:wwn #1;
+ \@@_fixed_mul:wwn #1\@@_sep: #1\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #2\@@_sep:
+ {15000}{0000}{0000}{0000}{0000}{0000}\@@_sep:
+ \@@_fixed_mul:wwn #1\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -1156,9 +1166,10 @@
% \begin{macrocode}
\cs_new:Npn \@@_ep_to_float_o:wwN #1,
{ + \@@_int_eval:w #1 \@@_fixed_to_float_o:wN }
-\cs_new:Npn \@@_ep_inv_to_float_o:wwN #1,#2;
+\cs_new:Npn \@@_ep_inv_to_float_o:wwN #1,#2\@@_sep:
{
- \@@_ep_div:wwwwn 1,{1000}{0000}{0000}{0000}{0000}{0000}; #1,#2;
+ \@@_ep_div:wwwwn
+ 1,{1000}{0000}{0000}{0000}{0000}{0000}\@@_sep: #1,#2\@@_sep:
\@@_ep_to_float_o:wwN
}
% \end{macrocode}
@@ -1178,9 +1189,9 @@
% a floating point number. This could perhaps remain in
% \pkg{l3fp-trig}.
% \begin{macrocode}
-\cs_new:Npn \@@_fixed_to_float_rad_o:wN #1;
+\cs_new:Npn \@@_fixed_to_float_rad_o:wN #1\@@_sep:
{
- \@@_fixed_mul:wwn #1; {5729}{5779}{5130}{8232}{0876}{7981};
+ \@@_fixed_mul:wwn #1\@@_sep: {5729}{5779}{5130}{8232}{0876}{7981}\@@_sep:
{ \@@_ep_to_float_o:wwN 2, }
}
% \end{macrocode}
@@ -1190,11 +1201,11 @@
% \begin{macro}[rEXP]
% {\@@_fixed_to_float_o:wN, \@@_fixed_to_float_o:Nw}
% \begin{syntax}
-% \ldots{} \cs{@@_int_eval:w} \meta{exponent} \cs{@@_fixed_to_float_o:wN} \Arg{a_1} \Arg{a_2} \Arg{a_3} \Arg{a_4} \Arg{a_5} \Arg{a_6} |;| \meta{sign}
+% \ldots{} \cs{@@_int_eval:w} \meta{exponent} \cs{@@_fixed_to_float_o:wN} \Arg{a_1} \Arg{a_2} \Arg{a_3} \Arg{a_4} \Arg{a_5} \Arg{a_6} \cs{@@_sep:} \meta{sign}
% \end{syntax}
% yields
% \begin{quote}
-% \meta{exponent'} |;| \Arg{a'_1} \Arg{a'_2} \Arg{a'_3} \Arg{a'_4} |;|
+% \meta{exponent'} \cs{@@_sep:} \Arg{a'_1} \Arg{a'_2} \Arg{a'_3} \Arg{a'_4} \cs{@@_sep:}
% \end{quote}
% And the \texttt{to_fixed} version gives six brace groups instead of
% $4$, ensuring that $1000\leq\meta{a'_1}\leq 9999$. At this stage, we
@@ -1204,9 +1215,9 @@
%
%^^A todo: round properly when rounding to infinity: I need the sign.
% \begin{macrocode}
-\cs_new:Npn \@@_fixed_to_float_o:Nw #1#2;
- { \@@_fixed_to_float_o:wN #2; #1 }
-\cs_new:Npn \@@_fixed_to_float_o:wN #1#2#3#4#5#6; #7
+\cs_new:Npn \@@_fixed_to_float_o:Nw #1#2\@@_sep:
+ { \@@_fixed_to_float_o:wN #2\@@_sep: #1 }
+\cs_new:Npn \@@_fixed_to_float_o:wN #1#2#3#4#5#6\@@_sep: #7
{ % for the 8-digit-at-the-start thing
+ \@@_int_eval:w \c_@@_block_int
\exp_after:wN \exp_after:wN
@@ -1217,8 +1228,8 @@
\int_value:w 1#2 \exp_after:wN \@@_use_none_stop_f:n
\int_value:w 1#3#4 \exp_after:wN \@@_use_none_stop_f:n
\int_value:w 1#5#6
- \exp_after:wN ;
- \exp_after:wN ;
+ \exp_after:wN \@@_sep:
+ \exp_after:wN \@@_sep:
}
\cs_new:Npn \@@_fixed_to_loop:N #1
{
@@ -1230,36 +1241,36 @@
\exp_after:wN #1
\fi:
}
-\cs_new:Npn \@@_fixed_to_loop_end:w #1 #2 ;
+\cs_new:Npn \@@_fixed_to_loop_end:w #1 #2 \@@_sep:
{
- \if_meaning:w ; #1
+ \if_meaning:w \@@_sep: #1
\exp_after:wN \@@_fixed_to_float_zero:w
\else:
\exp_after:wN \@@_pack_twice_four:wNNNNNNNN
\exp_after:wN \@@_pack_twice_four:wNNNNNNNN
\exp_after:wN \@@_fixed_to_float_pack:ww
- \exp_after:wN ;
+ \exp_after:wN \@@_sep:
\fi:
- #1 #2 0000 0000 0000 0000 ;
+ #1 #2 0000 0000 0000 0000 \@@_sep:
}
-\cs_new:Npn \@@_fixed_to_float_zero:w ; 0000 0000 0000 0000 ;
+\cs_new:Npn \@@_fixed_to_float_zero:w \@@_sep: 0000 0000 0000 0000 \@@_sep:
{
- - 2 * \c_@@_max_exponent_int ;
- {0000} {0000} {0000} {0000} ;
+ - 2 * \c_@@_max_exponent_int \@@_sep:
+ {0000} {0000} {0000} {0000} \@@_sep:
}
-\cs_new:Npn \@@_fixed_to_float_pack:ww #1 ; #2#3 ; ;
+\cs_new:Npn \@@_fixed_to_float_pack:ww #1 \@@_sep: #2#3 \@@_sep: \@@_sep:
{
\if_int_compare:w #2 > 4 \exp_stop_f:
\exp_after:wN \@@_fixed_to_float_round_up:wnnnnw
\fi:
- ; #1 ;
+ \@@_sep: #1 \@@_sep:
}
-\cs_new:Npn \@@_fixed_to_float_round_up:wnnnnw ; #1#2#3#4 ;
+\cs_new:Npn \@@_fixed_to_float_round_up:wnnnnw \@@_sep: #1#2#3#4 \@@_sep:
{
\exp_after:wN \@@_basics_pack_high:NNNNNw
\int_value:w \@@_int_eval:w 1 #1#2
\exp_after:wN \@@_basics_pack_low:NNNNNw
- \int_value:w \@@_int_eval:w 1 #3#4 + 1 ;
+ \int_value:w \@@_int_eval:w 1 #3#4 + 1 \@@_sep:
}
% \end{macrocode}
% \end{macro}
diff --git a/macros/latex-dev/required/l3kernel/l3fp-functions.dtx b/macros/latex-dev/required/l3kernel/l3fp-functions.dtx
index b9e269b988..2413838ca7 100644
--- a/macros/latex-dev/required/l3kernel/l3fp-functions.dtx
+++ b/macros/latex-dev/required/l3kernel/l3fp-functions.dtx
@@ -42,7 +42,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -138,7 +138,7 @@
\@@_exp_after_array_f:w #2 \s_@@_expr_stop
\exp_after:wN
}
- \exp_after:wN ;
+ \exp_after:wN \@@_sep:
}
}
% \end{macrocode}
@@ -191,7 +191,7 @@
\exp_not:N \@@_symbolic_chk:w
\exp_not:N \@@_function_arg_o:w
\int_use:N \l_@@_function_arg_int
- ########1 , { } ;
+ ########1 , { } \@@_sep:
}
}
\cs_set:Npn \@@_function_arg_o:w ##1 @
@@ -203,7 +203,7 @@
\@@_exp_after_symbolic_loop:N ##1
{ , \tex_romannumeral:D \use_none:nn }
\exp_after:wN \c_zero_int
- \exp_after:wN { \exp_after:wN } \exp_after:wN ;
+ \exp_after:wN { \exp_after:wN } \exp_after:wN \@@_sep:
}
\fp_set:Nn \l_@@_symbolic_fp {#4}
\use:e
@@ -250,9 +250,9 @@
#2
}
\cs_new:Npn \@@_function_arg_few:w #1 @ { \exp_after:wN \c_nan_fp }
-\cs_new:Npn \@@_function_arg_get:w #1#2#3; #4 @
+\cs_new:Npn \@@_function_arg_get:w #1#2#3\@@_sep: #4 @
{
- \@@_exp_after_array_f:w #3; \s_@@_expr_stop
+ \@@_exp_after_array_f:w #3\@@_sep: \s_@@_expr_stop
\exp_after:wN \exp_stop_f:
}
% \end{macrocode}
diff --git a/macros/latex-dev/required/l3kernel/l3fp-logic.dtx b/macros/latex-dev/required/l3kernel/l3fp-logic.dtx
index 486a3bc579..29b149498b 100644
--- a/macros/latex-dev/required/l3kernel/l3fp-logic.dtx
+++ b/macros/latex-dev/required/l3kernel/l3fp-logic.dtx
@@ -2,7 +2,7 @@
%
%% File: l3fp-logic.dtx
%
-% Copyright (C) 2011-2024 The LaTeX Project
+% Copyright (C) 2011-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -42,7 +42,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -75,8 +75,8 @@
% \subsection{Syntax of internal functions}
%
% \begin{itemize}
-% \item \cs{@@_compare_npos:nwnw} \Arg{expo_1} \meta{body_1} |;|
-% \Arg{expo_2} \meta{body_2} |;|
+% \item \cs{@@_compare_npos:nwnw} \Arg{expo_1} \meta{body_1} \cs{@@_sep:}
+% \Arg{expo_2} \meta{body_2} \cs{@@_sep:}
% \item \cs{@@_minmax_o:Nw} \meta{sign} \meta{floating point array}
% \item \cs{@@_not_o:w} |?| \meta{floating point array} (with one floating point number only)
% \item \cs{@@_&_o:ww} \meta{floating point} \meta{floating point}
@@ -123,7 +123,7 @@
\exp_after:wN \@@_compare_return:w
\exp:w \exp_end_continue_f:w \@@_parse:n {#1}
}
-\cs_new:Npn \@@_compare_return:w #1#2#3;
+\cs_new:Npn \@@_compare_return:w #1#2#3\@@_sep:
{
\if_charcode:w 0
\@@_if_type_fp:NTwFw
@@ -156,10 +156,10 @@
\prg_return_false:
\fi:
}
-\cs_new:Npn \@@_compare_aux:wn #1; #2
+\cs_new:Npn \@@_compare_aux:wn #1\@@_sep: #2
{
\exp_after:wN \@@_compare_back_any:ww
- \exp:w \exp_end_continue_f:w \@@_parse:n {#2} #1;
+ \exp:w \exp_end_continue_f:w \@@_parse:n {#2} #1\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -167,7 +167,7 @@
%
% \begin{macro}[EXP]{\@@_compare_back:ww, \@@_bcmp:ww, \@@_compare_back_any:ww, \@@_compare_nan:w}
% \begin{quote}
-% \cs{@@_compare_back_any:ww} \meta{y} |;| \meta{x} |;|
+% \cs{@@_compare_back_any:ww} \meta{y} \cs{@@_sep:} \meta{x} \cs{@@_sep:}
% \end{quote}
% Expands (in the same way as \cs{int_eval:n}) to $-1$ if $x<y$, $0$
% if $x=y$, $1$ if $x>y$, and $2$ otherwise (denoted as $x?y$). If
@@ -180,7 +180,7 @@
% a different type, the highest type is a larger number. Finally, if
% $y\leq 0$, then $x>y$, unless both are zero.
% \begin{macrocode}
-\cs_new:Npn \@@_compare_back:ww #1#2; #3#4;
+\cs_new:Npn \@@_compare_back:ww #1#2\@@_sep: #3#4\@@_sep:
{
\cs:w
@@
@@ -189,9 +189,9 @@
\@@_type_from_scan:N #3
:ww
\cs_end:
- #1#2; #3#4;
+ #1#2\@@_sep: #3#4\@@_sep:
}
-\cs_new:Npn \@@_compare_back_any:ww #1#2; #3
+\cs_new:Npn \@@_compare_back_any:ww #1#2\@@_sep: #3
{
\@@_if_type_fp:NTwFw
#1 { \@@_if_type_fp:NTwFw #3 \use_i:nn \s_@@ \use_ii:nn \s_@@_stop }
@@ -206,11 +206,11 @@
:ww
\cs_end:
}
- #1#2 ; #3
+ #1#2 \@@_sep: #3
}
\cs_new:Npn \@@_bcmp:ww
- \s_@@ \@@_chk:w #1 #2 #3;
- \s_@@ \@@_chk:w #4 #5 #6;
+ \s_@@ \@@_chk:w #1 #2 #3\@@_sep:
+ \s_@@ \@@_chk:w #4 #5 #6\@@_sep:
{
\int_value:w
\if_meaning:w 3 #1 \exp_after:wN \@@_compare_nan:w \fi:
@@ -219,7 +219,7 @@
\if_meaning:w #2 #5
\if_meaning:w #1 #4
\if_meaning:w 1 #1
- \@@_compare_npos:nwnw #6; #3;
+ \@@_compare_npos:nwnw #6\@@_sep: #3\@@_sep:
\else:
0
\fi:
@@ -247,30 +247,30 @@
% and if any don't match return~$2$ (as \cs{int_value:w} |02|
% \cs{exp_stop_f:}).
% \begin{macrocode}
-\cs_new:Npn \@@_compare_back_tuple:ww #1; #2; { 2 }
-\cs_new:Npn \@@_tuple_compare_back:ww #1; #2; { 2 }
+\cs_new:Npn \@@_compare_back_tuple:ww #1\@@_sep: #2\@@_sep: { 2 }
+\cs_new:Npn \@@_tuple_compare_back:ww #1\@@_sep: #2\@@_sep: { 2 }
\cs_new:Npn \@@_tuple_compare_back_tuple:ww
- \s_@@_tuple \@@_tuple_chk:w #1;
- \s_@@_tuple \@@_tuple_chk:w #2;
+ \s_@@_tuple \@@_tuple_chk:w #1\@@_sep:
+ \s_@@_tuple \@@_tuple_chk:w #2\@@_sep:
{
\int_compare:nNnTF { \@@_array_count:n {#1} } =
{ \@@_array_count:n {#2} }
{
\int_value:w 0
\@@_tuple_compare_back_loop:w
- #1 { \s_@@ \prg_break: } ; @
- #2 { \s_@@ \prg_break: } ;
+ #1 { \s_@@ \prg_break: } \@@_sep: @
+ #2 { \s_@@ \prg_break: } \@@_sep:
\prg_break_point:
\exp_stop_f:
}
{ 2 }
}
-\cs_new:Npn \@@_tuple_compare_back_loop:w #1#2 ; #3 @ #4#5 ;
+\cs_new:Npn \@@_tuple_compare_back_loop:w #1#2 \@@_sep: #3 @ #4#5 \@@_sep:
{
\use_none:n #1
\use_none:n #4
\if_int_compare:w
- \@@_compare_back_any:ww #1 #2 ; #4 #5 ; = \c_zero_int
+ \@@_compare_back_any:ww #1 #2 \@@_sep: #4 #5 \@@_sep: = \c_zero_int
\else:
2 \exp_after:wN \prg_break:
\fi:
@@ -284,8 +284,8 @@
% \begin{macro}[EXP]{\@@_compare_significand:nnnnnnnn}
% \begin{quote}
% \cs{@@_compare_npos:nwnw}
-% \Arg{expo_1} \meta{body_1} |;|
-% \Arg{expo_2} \meta{body_2} |;|
+% \Arg{expo_1} \meta{body_1} \cs{@@_sep:}
+% \Arg{expo_2} \meta{body_2} \cs{@@_sep:}
% \end{quote}
% Within an \cs{int_value:w} \ldots{} \cs{exp_stop_f:} construction,
% this expands to $0$ if the two numbers are equal, $-1$ if the first
@@ -296,7 +296,7 @@
% first $8$ digits coincide, the next $8$ decide. Otherwise, the
% first $8$ digits are compared.
% \begin{macrocode}
-\cs_new:Npn \@@_compare_npos:nwnw #1#2; #3#4;
+\cs_new:Npn \@@_compare_npos:nwnw #1#2\@@_sep: #3#4\@@_sep:
{
\if_int_compare:w #1 = #3 \exp_stop_f:
\@@_compare_significand:nnnnnnnn #2 #4
@@ -427,20 +427,22 @@
% progress. Conversion to decimal is done just before calling the
% user's function.
% \begin{macrocode}
-\cs_new:Npn \@@_step:wwwN #1#2; #3#4; #5#6; #7
+\cs_new:Npn \@@_step:wwwN #1#2\@@_sep: #3#4\@@_sep: #5#6\@@_sep: #7
{
\@@_if_type_fp:NTwFw #1 { } \s_@@ \prg_break: \s_@@_stop
\@@_if_type_fp:NTwFw #3 { } \s_@@ \prg_break: \s_@@_stop
\@@_if_type_fp:NTwFw #5 { } \s_@@ \prg_break: \s_@@_stop
- \use_i:nnnn { \@@_step_fp:wwwN #1#2; #3#4; #5#6; #7 }
+ \use_i:nnnn
+ { \@@_step_fp:wwwN #1#2\@@_sep: #3#4\@@_sep: #5#6\@@_sep: #7 }
\prg_break_point:
\use:n
{
- \@@_error:nfff { step-tuple } { \fp_to_tl:n { #1#2 ; } }
- { \fp_to_tl:n { #3#4 ; } } { \fp_to_tl:n { #5#6 ; } }
+ \@@_error:nfff { step-tuple } { \fp_to_tl:n { #1#2 \@@_sep: } }
+ { \fp_to_tl:n { #3#4 \@@_sep: } } { \fp_to_tl:n { #5#6 \@@_sep: } }
}
}
-\cs_new:Npn \@@_step_fp:wwwN #1 ; \s_@@ \@@_chk:w #2#3#4 ; #5; #6
+\cs_new:Npn \@@_step_fp:wwwN
+ #1 \@@_sep: \s_@@ \@@_chk:w #2#3#4 \@@_sep: #5\@@_sep: #6
{
\token_if_eq_meaning:NNTF #2 1
{
@@ -456,11 +458,15 @@
}
{
\@@_error:nnfn { bad-step } { }
- { \fp_to_tl:n { \s_@@ \@@_chk:w #2#3#4 ; } } {#6}
+ { \fp_to_tl:n { \s_@@ \@@_chk:w #2#3#4 \@@_sep: } } {#6}
}
\use_none:nnnnn
}
- { #1 ; } { \c_nan_fp } { \s_@@ \@@_chk:w #2#3#4 ; } { #5 ; } #6
+ { #1 \@@_sep: }
+ { \c_nan_fp }
+ { \s_@@ \@@_chk:w #2#3#4 \@@_sep: }
+ { #5 \@@_sep: }
+ #6
}
\cs_new:Npn \@@_step:NnnnnN #1#2#3#4#5#6
{
@@ -556,8 +562,8 @@
\exp_after:wN \@@_minmax_loop:Nww \exp_after:wN -
\fi:
#2
- \s_@@ \@@_chk:w 2 #1 \s_@@_exact ;
- \s_@@ \@@_chk:w { 3 \@@_minmax_break_o:w } ;
+ \s_@@ \@@_chk:w 2 #1 \s_@@_exact \@@_sep:
+ \s_@@ \@@_chk:w { 3 \@@_minmax_break_o:w } \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -574,7 +580,7 @@
% maximum; otherwise we keep the first number. Then loop.
% \begin{macrocode}
\cs_new:Npn \@@_minmax_loop:Nww
- #1 \s_@@ \@@_chk:w #2#3; \s_@@ \@@_chk:w #4#5;
+ #1 \s_@@ \@@_chk:w #2#3\@@_sep: \s_@@ \@@_chk:w #4#5\@@_sep:
{
\if_meaning:w 3 #4
\if_meaning:w 3 #2
@@ -585,8 +591,8 @@
\else:
\if_int_compare:w
\@@_compare_back:ww
- \s_@@ \@@_chk:w #4#5;
- \s_@@ \@@_chk:w #2#3;
+ \s_@@ \@@_chk:w #4#5\@@_sep:
+ \s_@@ \@@_chk:w #2#3\@@_sep:
= #1 1 \exp_stop_f:
\@@_minmax_auxii:ww
\else:
@@ -594,8 +600,8 @@
\fi:
\fi:
\@@_minmax_loop:Nww #1
- \s_@@ \@@_chk:w #2#3;
- \s_@@ \@@_chk:w #4#5;
+ \s_@@ \@@_chk:w #2#3\@@_sep:
+ \s_@@ \@@_chk:w #4#5\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -603,9 +609,10 @@
% \begin{macro}[EXP]{\@@_minmax_auxi:ww, \@@_minmax_auxii:ww}
% Keep the first/second number, and remove the other.
% \begin{macrocode}
-\cs_new:Npn \@@_minmax_auxi:ww #1 \fi: \fi: #2 \s_@@ #3 ; \s_@@ #4;
- { \fi: \fi: #2 \s_@@ #3 ; }
-\cs_new:Npn \@@_minmax_auxii:ww #1 \fi: \fi: #2 \s_@@ #3 ;
+\cs_new:Npn \@@_minmax_auxi:ww
+ #1 \fi: \fi: #2 \s_@@ #3 \@@_sep: \s_@@ #4\@@_sep:
+ { \fi: \fi: #2 \s_@@ #3 \@@_sep: }
+\cs_new:Npn \@@_minmax_auxii:ww #1 \fi: \fi: #2 \s_@@ #3 \@@_sep:
{ \fi: \fi: #2 }
% \end{macrocode}
% \end{macro}
@@ -615,8 +622,8 @@
% to the end of the tests, close the current test with \cs{fi:}, clean
% up, and return the appropriate number with one post-expansion.
% \begin{macrocode}
-\cs_new:Npn \@@_minmax_break_o:w #1 \fi: \fi: #2 \s_@@ #3; #4;
- { \fi: \@@_exp_after_o:w \s_@@ #3; }
+\cs_new:Npn \@@_minmax_break_o:w #1 \fi: \fi: #2 \s_@@ #3\@@_sep: #4\@@_sep:
+ { \fi: \@@_exp_after_o:w \s_@@ #3\@@_sep: }
% \end{macrocode}
% \end{macro}
%
@@ -627,7 +634,7 @@
% exit the conditional, and one to please \pkg{l3fp-parse}. The first
% argument is provided by \pkg{l3fp-parse} and is ignored.
% \begin{macrocode}
-\cs_new:Npn \@@_not_o:w #1 \s_@@ \@@_chk:w #2#3; @
+\cs_new:Npn \@@_not_o:w #1 \s_@@ \@@_chk:w #2#3\@@_sep: @
{
\if_meaning:w 0 #2
\exp_after:wN \exp_after:wN \exp_after:wN \c_one_fp
@@ -652,30 +659,31 @@
\group_begin:
\char_set_catcode_letter:N &
\char_set_catcode_letter:N |
- \cs_new:Npn \@@_&_o:ww #1 \s_@@ \@@_chk:w #2#3;
+ \cs_new:Npn \@@_&_o:ww #1 \s_@@ \@@_chk:w #2#3\@@_sep:
{
\if_meaning:w 0 #2 #1
- \@@_and_return:wNw \s_@@ \@@_chk:w #2#3;
+ \@@_and_return:wNw \s_@@ \@@_chk:w #2#3\@@_sep:
\fi:
\@@_exp_after_o:w
}
- \cs_new:Npn \@@_&_tuple_o:ww #1 \s_@@ \@@_chk:w #2#3;
+ \cs_new:Npn \@@_&_tuple_o:ww #1 \s_@@ \@@_chk:w #2#3\@@_sep:
{
\if_meaning:w 0 #2 #1
- \@@_and_return:wNw \s_@@ \@@_chk:w #2#3;
+ \@@_and_return:wNw \s_@@ \@@_chk:w #2#3\@@_sep:
\fi:
\@@_exp_after_tuple_o:w
}
- \cs_new:Npn \@@_tuple_&_o:ww #1; { \@@_exp_after_o:w }
- \cs_new:Npn \@@_tuple_&_tuple_o:ww #1; { \@@_exp_after_tuple_o:w }
+ \cs_new:Npn \@@_tuple_&_o:ww #1\@@_sep: { \@@_exp_after_o:w }
+ \cs_new:Npn \@@_tuple_&_tuple_o:ww #1\@@_sep: { \@@_exp_after_tuple_o:w }
\cs_new:Npn \@@_|_o:ww { \@@_&_o:ww \else: }
\cs_new:Npn \@@_|_tuple_o:ww { \@@_&_tuple_o:ww \else: }
- \cs_new:Npn \@@_tuple_|_o:ww #1; #2; { \@@_exp_after_tuple_o:w #1; }
- \cs_new:Npn \@@_tuple_|_tuple_o:ww #1; #2;
- { \@@_exp_after_tuple_o:w #1; }
+ \cs_new:Npn \@@_tuple_|_o:ww #1\@@_sep: #2\@@_sep:
+ { \@@_exp_after_tuple_o:w #1\@@_sep: }
+ \cs_new:Npn \@@_tuple_|_tuple_o:ww #1\@@_sep: #2\@@_sep:
+ { \@@_exp_after_tuple_o:w #1\@@_sep: }
\group_end:
-\cs_new:Npn \@@_and_return:wNw #1; \fi: #2;
- { \fi: \@@_exp_after_o:w #1; }
+\cs_new:Npn \@@_and_return:wNw #1\@@_sep: \fi: #2\@@_sep:
+ { \fi: \@@_exp_after_o:w #1\@@_sep: }
% \end{macrocode}
% \end{macro}
% \end{macro}
diff --git a/macros/latex-dev/required/l3kernel/l3fp-parse.dtx b/macros/latex-dev/required/l3kernel/l3fp-parse.dtx
index 7853c40132..b7fb52e7fd 100644
--- a/macros/latex-dev/required/l3kernel/l3fp-parse.dtx
+++ b/macros/latex-dev/required/l3kernel/l3fp-parse.dtx
@@ -2,7 +2,7 @@
%
%% File: l3fp-parse.dtx
%
-% Copyright (C) 2011-2024 The LaTeX Project
+% Copyright (C) 2011-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -42,7 +42,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -71,7 +71,7 @@
%
% In this file at least, a \meta{floating point object} is a floating
% point number or tuple. This can be extended to anything that starts
-% with \cs{s_@@} or \cs{s_@@_\meta{type}} and ends with |;| with some
+% with \cs{s_@@} or \cs{s_@@_\meta{type}} and ends with \cs{@@_sep:} with some
% internal structure that depends on the \meta{type}.
%
% \begin{macro}[EXP]{\@@_parse:n}
@@ -215,12 +215,12 @@
% |\add:ww| 12345 ; 333444 ;
% \end{syntax}
% which can safely perform the addition by grabbing two arguments
-% delimited by~|;|.
+% delimited by~\cs{@@_sep:}.
%
% If we were to continue parsing the expression, then the following
% number should also be cleaned up before the next use of a binary
% operation such as |\add:ww|. Just like \cs{int_value:w} |12345|
-% \cs{exp_after:wN}~|;| expanded what follows once, we need |\add:ww|
+% \cs{exp_after:wN}~\cs{@@_sep:} expanded what follows once, we need |\add:ww|
% to do the calculation, and in the process to expand the following
% once. This is also true in our real application: all the functions of
% the form \cs[no-index]{@@_\ldots_o:ww} expand what follows once. This comes at the
@@ -643,7 +643,7 @@
% expansion. That turns out to be useful.
% \begin{macrocode}
\cs_new:Npn \@@_parse_return_semicolon:w
- #1 \fi: \@@_parse_expand:w { \fi: ; #1 }
+ #1 \fi: \@@_parse_expand:w { \fi: \@@_sep: #1 }
% \end{macrocode}
% \end{macro}
%
@@ -665,7 +665,7 @@
% stream, until meeting a non-digit, or up to a number of digits equal
% to their index. The full expansion is
% \begin{syntax}
-% \meta{digits} |;| \meta{filling 0} |;| \meta{length}
+% \meta{digits} \cs{@@_sep:} \meta{filling 0} \cs{@@_sep:} \meta{length}
% \end{syntax}
% where \meta{filling 0} is a string of zeros such that \meta{digits}
% \meta{filling 0} has the length given by the index of the function,
@@ -687,14 +687,14 @@
\@@_parse_expand:w
}
}
-\@@_tmp:w {vii} \@@_parse_digits_vi:N { 0000000 ; 7 }
-\@@_tmp:w {vi} \@@_parse_digits_v:N { 000000 ; 6 }
-\@@_tmp:w {v} \@@_parse_digits_iv:N { 00000 ; 5 }
-\@@_tmp:w {iv} \@@_parse_digits_iii:N { 0000 ; 4 }
-\@@_tmp:w {iii} \@@_parse_digits_ii:N { 000 ; 3 }
-\@@_tmp:w {ii} \@@_parse_digits_i:N { 00 ; 2 }
-\@@_tmp:w {i} \@@_parse_digits_:N { 0 ; 1 }
-\cs_new:Npn \@@_parse_digits_:N { ; ; 0 }
+\@@_tmp:w {vii} \@@_parse_digits_vi:N { 0000000 \@@_sep: 7 }
+\@@_tmp:w {vi} \@@_parse_digits_v:N { 000000 \@@_sep: 6 }
+\@@_tmp:w {v} \@@_parse_digits_iv:N { 00000 \@@_sep: 5 }
+\@@_tmp:w {iv} \@@_parse_digits_iii:N { 0000 \@@_sep: 4 }
+\@@_tmp:w {iii} \@@_parse_digits_ii:N { 000 \@@_sep: 3 }
+\@@_tmp:w {ii} \@@_parse_digits_i:N { 00 \@@_sep: 2 }
+\@@_tmp:w {i} \@@_parse_digits_:N { 0 \@@_sep: 1 }
+\cs_new:Npn \@@_parse_digits_:N { \@@_sep: \@@_sep: 0 }
% \end{macrocode}
% \end{macro}
%
@@ -874,26 +874,26 @@
\exp_after:wN \@@_parse_one_register_auxii:wwwNw
}
\exp_not:N \exp_after:wN { \exp_not:N \tex_the:D #1 }
- ; \exp_not:N \@@_parse_one_register_dim:ww
- \tl_to_str:n { pt } ; \exp_not:N \@@_parse_one_register_mu:www
- . \tl_to_str:n { pt } ; \exp_not:N \@@_parse_one_register_int:www
+ \@@_sep: \exp_not:N \@@_parse_one_register_dim:ww
+ \tl_to_str:n { pt } \@@_sep: \exp_not:N \@@_parse_one_register_mu:www
+ . \tl_to_str:n { pt } \@@_sep: \exp_not:N \@@_parse_one_register_int:www
\s_@@_stop
}
\exp_args:Nno \use:nn
{ \cs_new:Npn \@@_parse_one_register_auxii:wwwNw #1 . #2 }
- { \tl_to_str:n { pt } #3 ; #4#5 \s_@@_stop }
- { #4 #1.#2; }
+ { \tl_to_str:n { pt } #3 \@@_sep: #4#5 \s_@@_stop }
+ { #4 #1.#2\@@_sep: }
\exp_args:Nno \use:nn
{ \cs_new:Npn \@@_parse_one_register_mu:www #1 }
- { \tl_to_str:n { mu } ; #2 ; }
- { \@@_parse_one_register_dim:ww #1 ; }
-\cs_new:Npn \@@_parse_one_register_int:www #1; #2.; #3;
+ { \tl_to_str:n { mu } \@@_sep: #2 \@@_sep: }
+ { \@@_parse_one_register_dim:ww #1 \@@_sep: }
+\cs_new:Npn \@@_parse_one_register_int:www #1\@@_sep: #2.\@@_sep: #3\@@_sep:
{ \@@_parse:n { #1 e #3 } }
-\cs_new:Npn \@@_parse_one_register_dim:ww #1; #2;
+\cs_new:Npn \@@_parse_one_register_dim:ww #1\@@_sep: #2\@@_sep:
{
\exp_after:wN \@@_from_dim_test:ww
\int_value:w #2 \exp_after:wN ,
- \int_value:w \dim_to_decimal_in_sp:n { #1 pt } ;
+ \int_value:w \dim_to_decimal_in_sp:n { #1 pt } \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -942,11 +942,11 @@
\exp_after:wN \@@_parse_one_register_wd:Nw
#4 \@@_parse_expand:w e
}
-\cs_new:Npn \@@_parse_one_register_wd:Nw #1#2 ;
+\cs_new:Npn \@@_parse_one_register_wd:Nw #1#2 \@@_sep:
{
\exp_after:wN \@@_from_dim_test:ww
\exp_after:wN 0 \exp_after:wN ,
- \int_value:w \dim_to_decimal_in_sp:n { #1 #2 } ;
+ \int_value:w \dim_to_decimal_in_sp:n { #1 #2 } \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -1020,7 +1020,7 @@
% mixture of lower and upper case, so we test and use a
% differently-named control sequence.
% \begin{macrocode}
-\cs_new:Npn \@@_parse_word:Nw #1#2;
+\cs_new:Npn \@@_parse_word:Nw #1#2\@@_sep:
{
\cs_if_exist_use:cF { @@_parse_word_#2:N }
{
@@ -1184,7 +1184,7 @@
% \begin{macrocode}
\cs_new:Npn \@@_parse_zero:
{
- \exp_after:wN ; \exp_after:wN 1
+ \exp_after:wN \@@_sep: \exp_after:wN 1
\int_value:w \@@_parse_exponent:N
}
% \end{macrocode}
@@ -1220,7 +1220,7 @@
%
% \begin{macro}[rEXP]{\@@_parse_small_leading:wwNN}
% \begin{syntax}
-% \cs{@@_parse_small_leading:wwNN} |1| \meta{digits} |;| \meta{zeros} |;| \meta{number~of~zeros}
+% \cs{@@_parse_small_leading:wwNN} |1| \meta{digits} \cs{@@_sep:} \meta{zeros} \cs{@@_sep:} \meta{number~of~zeros}
% \end{syntax}
% We leave \meta{digits} \meta{zeros} in the input stream: the
% functions used to grab digits are such that this constitutes digits
@@ -1232,7 +1232,7 @@
% Otherwise put $8$~zeros in to complete the significand, then look
% for an exponent.
% \begin{macrocode}
-\cs_new:Npn \@@_parse_small_leading:wwNN 1 #1 ; #2; #3 #4
+\cs_new:Npn \@@_parse_small_leading:wwNN 1 #1 \@@_sep: #2\@@_sep: #3 #4
{
#1 #2
\exp_after:wN \@@_parse_pack_trailing:NNNNNNww
@@ -1254,7 +1254,7 @@
%
% \begin{macro}[rEXP]{\@@_parse_small_trailing:wwNN}
% \begin{syntax}
-% \cs{@@_parse_small_trailing:wwNN} |1| \meta{digits} |;| \meta{zeros} |;| \meta{number~of~zeros} \meta{next~token}
+% \cs{@@_parse_small_trailing:wwNN} |1| \meta{digits} \cs{@@_sep:} \meta{zeros} \cs{@@_sep:} \meta{number~of~zeros} \meta{next~token}
% \end{syntax}
% Leave digits $10$ to~$15$ (arguments |#1| and |#2|) in the input
% stream. If the \meta{next~token} is a digit, it is the $16$th
@@ -1264,7 +1264,7 @@
% Otherwise, there is no $16$-th digit, so we put a~$0$, and look for
% an exponent.
% \begin{macrocode}
-\cs_new:Npn \@@_parse_small_trailing:wwNN 1 #1 ; #2; #3 #4
+\cs_new:Npn \@@_parse_small_trailing:wwNN 1 #1 \@@_sep: #2\@@_sep: #3 #4
{
#1 #2
\if_int_compare:w 9 < 1 \token_to_str:N #4 \exp_stop_f:
@@ -1301,19 +1301,20 @@
% this is simple because such a carry can only occur to give rise to a
% power of~$10$.
% \begin{macrocode}
-\cs_new:Npn \@@_parse_pack_trailing:NNNNNNww #1 #2 #3#4#5#6 #7; #8 ;
+\cs_new:Npn \@@_parse_pack_trailing:NNNNNNww
+ #1 #2 #3#4#5#6 #7\@@_sep: #8 \@@_sep:
{
\if_meaning:w 2 #2 + 1 \fi:
- ; #8 + #1 ; {#3#4#5#6} {#7};
+ \@@_sep: #8 + #1 \@@_sep: {#3#4#5#6} {#7}\@@_sep:
}
-\cs_new:Npn \@@_parse_pack_leading:NNNNNww #1 #2#3#4#5 #6; #7;
+\cs_new:Npn \@@_parse_pack_leading:NNNNNww #1 #2#3#4#5 #6\@@_sep: #7\@@_sep:
{
+ #7
\if_meaning:w 2 #1 \@@_parse_pack_carry:w \fi:
- ; 0 {#2#3#4#5} {#6}
+ \@@_sep: 0 {#2#3#4#5} {#6}
}
-\cs_new:Npn \@@_parse_pack_carry:w \fi: ; 0 #1
- { \fi: + 1 ; 0 {1000} }
+\cs_new:Npn \@@_parse_pack_carry:w \fi: \@@_sep: 0 #1
+ { \fi: + 1 \@@_sep: 0 {1000} }
% \end{macrocode}
% \end{macro}
%
@@ -1344,7 +1345,7 @@
%
% \begin{macro}[rEXP]{\@@_parse_large_leading:wwNN}
% \begin{syntax}
-% \cs{@@_parse_large_leading:wwNN} |1| \meta{digits} |;| \meta{zeros} |;| \meta{number~of~zeros} \meta{next~token}
+% \cs{@@_parse_large_leading:wwNN} |1| \meta{digits} \cs{@@_sep:} \meta{zeros} \cs{@@_sep:} \meta{number~of~zeros} \meta{next~token}
% \end{syntax}
% We shift the exponent by the number of digits in~|#1|, namely the
% target number, $8$, minus the \meta{number of zeros} (number of
@@ -1357,7 +1358,7 @@
% complete the $8$~first digits, insert $8$~more, and look for an
% exponent.
% \begin{macrocode}
-\cs_new:Npn \@@_parse_large_leading:wwNN 1 #1 ; #2; #3 #4
+\cs_new:Npn \@@_parse_large_leading:wwNN 1 #1 \@@_sep: #2\@@_sep: #3 #4
{
+ \c_@@_half_prec_int - #3
\exp_after:wN \@@_parse_pack_leading:NNNNNww
@@ -1392,7 +1393,7 @@
%
% \begin{macro}[EXP]{\@@_parse_large_trailing:wwNN}
% \begin{syntax}
-% \cs{@@_parse_large_trailing:wwNN} |1| \meta{digits} |;| \meta{zeros} |;| \meta{number~of~zeros} \meta{next~token}
+% \cs{@@_parse_large_trailing:wwNN} |1| \meta{digits} \cs{@@_sep:} \meta{zeros} \cs{@@_sep:} \meta{number~of~zeros} \meta{next~token}
% \end{syntax}
% We have just read $15$~digits. If the \meta{next token} is a digit,
% then the exponent shift caused by this block of $8$~digits is~$8$,
@@ -1408,7 +1409,7 @@
% for an exponent after using the \meta{zeros} and providing a $16$-th
% digit of~$0$.
% \begin{macrocode}
-\cs_new:Npn \@@_parse_large_trailing:wwNN 1 #1 ; #2; #3 #4
+\cs_new:Npn \@@_parse_large_trailing:wwNN 1 #1 \@@_sep: #2\@@_sep: #3 #4
{
\if_int_compare:w 9 < 1 \token_to_str:N #4 \exp_stop_f:
\exp_after:wN \@@_parse_pack_trailing:NNNNNNww
@@ -1488,9 +1489,9 @@
% time, the result |0| or |1| is added to the
% surrounding integer expression.
% \begin{macrocode}
-\cs_new:Npn \@@_parse_round_after:wN #1; #2
+\cs_new:Npn \@@_parse_round_after:wN #1\@@_sep: #2
{
- + #2 \exp_after:wN ;
+ + #2 \exp_after:wN \@@_sep:
\int_value:w \@@_int_eval:w #1 + \@@_parse_exponent:N
}
% \end{macrocode}
@@ -1500,8 +1501,8 @@
% {\@@_parse_small_round:NN, \@@_parse_round_after:wN}
% Here, |#1|~is the digit that we are currently rounding (we only care
% whether it is even or odd). If |#2|~is not a digit, then fetch an
-% exponent and expand to |;|\meta{exponent} only. Otherwise, we
-% expand to |+0| or |+1|, then |;|\meta{exponent}. To
+% exponent and expand to \cs{@@_sep:}\meta{exponent} only. Otherwise, we
+% expand to |+0| or |+1|, then \cs{@@_sep:}\meta{exponent}. To
% decide which, call \cs{@@_round_s:NNNw} to know whether to round up,
% giving it as arguments a sign~$0$ (all explicit numbers are
% positive), the digit |#1|~to round, the first following digit~|#2|,
@@ -1581,7 +1582,7 @@
\fi:
\@@_parse_expand:w
}
-\cs_new:Npn \@@_parse_large_round_aux:wNN #1 ; #2 #3
+\cs_new:Npn \@@_parse_large_round_aux:wNN #1 \@@_sep: #2 #3
{
+ #2
\exp_after:wN \@@_parse_round_after:wN
@@ -1591,7 +1592,7 @@
\exp_after:wN \@@_parse_round_loop:N
\exp:w \exp_after:wN \@@_parse_expand:w
\else:
- \exp_after:wN ;
+ \exp_after:wN \@@_sep:
\exp_after:wN 0
\exp_after:wN #3
\fi:
@@ -1618,7 +1619,7 @@
% two tokens ahead completely would break the third example (unpacking
% is even worse). Indeed, in the course of reading $3.2$, \cs{c_pi_fp}
% is expanded to \cs{s_@@} \cs{@@_chk:w} |1| |0| |{-1}| |{3141}|
-% $\cdots$ |;| and \cs{s_@@} stops the expansion. Expanding two tokens
+% $\cdots$ \cs{@@_sep:} and \cs{s_@@} stops the expansion. Expanding two tokens
% ahead would then force the expansion of \cs{@@_chk:w} (despite it
% being protected), and that function tries to produce an error.
%
@@ -1636,7 +1637,7 @@
% \begin{macrocode}
\cs_new:Npn \@@_parse_exponent:Nw #1 #2 \@@_parse_expand:w
{
- \exp_after:wN ;
+ \exp_after:wN \@@_sep:
\int_value:w #2 \@@_parse_exponent:N #1
}
% \end{macrocode}
@@ -1669,7 +1670,7 @@
{
\if_int_compare:w \if_catcode:w \scan_stop: \exp_not:N #2
0 \else: `#2 \fi: > `9 \exp_stop_f:
- 0 \exp_after:wN ; \exp_after:wN #1
+ 0 \exp_after:wN \@@_sep: \exp_after:wN #1
\else:
\exp_after:wN \@@_parse_exponent_sign:N
\fi:
@@ -1708,7 +1709,7 @@
\@@_parse_exponent_keep:NTF #1
{ \@@_parse_return_semicolon:w #1 }
{
- \exp_after:wN ;
+ \exp_after:wN \@@_sep:
\exp:w
}
\fi:
@@ -1820,7 +1821,7 @@
% \begin{macro}[EXP]{\@@_parse_apply_unary_type:NNN, \@@_parse_apply_unary_error:NNw}
% In contrast to \cs{@@_parse_apply_function:NNNwN}, this checks that
% the operand |#4| is a single argument (namely there is a single
-% |;|). We use the fact that any floating point starts with a
+% \cs{@@_sep:}). We use the fact that any floating point starts with a
% \enquote{safe} token like \cs{s_@@}. If there is no argument
% produce the |fp-no-arg| error; if there are at least two produce
% |fp-multi-arg|. For the error message extract the mathematical
@@ -1834,12 +1835,12 @@
% \begin{macrocode}
\cs_new:Npn \@@_parse_apply_unary:NNNwN #1#2#3#4@#5
{
- \@@_parse_apply_unary_chk:NwNw #4 @ ; . \s_@@_stop
+ \@@_parse_apply_unary_chk:NwNw #4 @ \@@_sep: . \s_@@_stop
\@@_parse_apply_unary_type:NNN
#3 #2 #4 @
\exp:w \exp_end_continue_f:w #5 #1
}
-\cs_new:Npn \@@_parse_apply_unary_chk:NwNw #1#2 ; #3#4 \s_@@_stop
+\cs_new:Npn \@@_parse_apply_unary_chk:NwNw #1#2 \@@_sep: #3#4 \s_@@_stop
{
\if_meaning:w @ #3 \else:
\token_if_eq_meaning:NNTF . #3
@@ -2043,7 +2044,7 @@
\cs_new:cpn { @@_parse_word_#1:N }
{
\@@_exp_after_f:nw { \@@_parse_infix:NN }
- \s_@@ \@@_chk:w 10 #2 ;
+ \s_@@ \@@_chk:w 10 #2 \@@_sep:
}
}
\@@_tmp:w {pt} { {1} {1000} {0000} {0000} {0000} }
@@ -2070,7 +2071,7 @@
{
\exp_after:wN \@@_from_dim_test:ww
\exp_after:wN 0 \exp_after:wN ,
- \int_value:w \dim_to_decimal_in_sp:n { 1 #1 } \exp_after:wN ;
+ \int_value:w \dim_to_decimal_in_sp:n { 1 #1 } \exp_after:wN \@@_sep:
\exp:w \exp_end_continue_f:w \@@_parse_infix:NN
}
}
@@ -2220,7 +2221,7 @@
% according to their types, and expands once after the result.
% The |rev| version swaps its arguments before doing this.
% \begin{macrocode}
-\cs_new:Npn \@@_binary_type_o:Nww #1 #2#3 ; #4
+\cs_new:Npn \@@_binary_type_o:Nww #1 #2#3 \@@_sep: #4
{
\exp_after:wN \@@_parse_apply_binary_chk:NN
\cs:w
@@ -2231,9 +2232,9 @@
_o:ww
\cs_end:
#1
- #2 #3 ; #4
+ #2 #3 \@@_sep: #4
}
-\cs_new:Npn \@@_binary_rev_type_o:Nww #1 #2#3 ; #4#5 ;
+\cs_new:Npn \@@_binary_rev_type_o:Nww #1 #2#3 \@@_sep: #4#5 \@@_sep:
{
\exp_after:wN \@@_parse_apply_binary_chk:NN
\cs:w
@@ -2244,7 +2245,7 @@
_o:ww
\cs_end:
#1
- #4 #5 ; #2 #3 ;
+ #4 #5 \@@_sep: #2 #3 \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -2253,10 +2254,10 @@
%
% \begin{macro}[EXP]{\@@_parse_infix_after_operand:NwN}
% \begin{macrocode}
-\cs_new:Npn \@@_parse_infix_after_operand:NwN #1 #2;
+\cs_new:Npn \@@_parse_infix_after_operand:NwN #1 #2\@@_sep:
{
\@@_exp_after_f:nw { \@@_parse_infix:NN #1 }
- #2;
+ #2\@@_sep:
}
\cs_new:Npn \@@_parse_infix:NN #1 #2
{
@@ -2430,7 +2431,7 @@
\exp_after:wN #1
\exp:w \exp_end_continue_f:w
\@@_exp_after_tuple_f:nw { }
- \s_@@_tuple \@@_tuple_chk:w { #2 #4 } ;
+ \s_@@_tuple \@@_tuple_chk:w { #2 #4 } \@@_sep:
#5 #1
}
% \end{macrocode}
@@ -2688,14 +2689,14 @@
\fi:
#1 #8 #9
}
-\cs_new:Npn \@@_parse_apply_compare_aux:NNwN #1 #2 #3; #4
+\cs_new:Npn \@@_parse_apply_compare_aux:NNwN #1 #2 #3\@@_sep: #4
{
\if_meaning:w \@@_parse_compare:NNNNNNN #4
\exp_after:wN \@@_parse_continue_compare:NNwNN
\exp_after:wN #1
\exp_after:wN #2
\exp:w \exp_end_continue_f:w
- \@@_exp_after_o:w #3;
+ \@@_exp_after_o:w #3\@@_sep:
\exp:w \exp_end_continue_f:w
\else:
\exp_after:wN \@@_parse_continue:NwN
@@ -2725,7 +2726,7 @@
{
\@@_error:nffn { bad-args }
{#1}
- { \fp_to_tl:n { \s_@@_tuple \@@_tuple_chk:w {#3} ; } }
+ { \fp_to_tl:n { \s_@@_tuple \@@_tuple_chk:w {#3} \@@_sep: } }
{ }
\exp_after:wN \c_nan_fp
}
@@ -2764,11 +2765,11 @@
{
\@@_error:nffn { bad-args }
{#2}
- { \fp_to_tl:n { \s_@@_tuple \@@_tuple_chk:w {#4} ; } }
+ { \fp_to_tl:n { \s_@@_tuple \@@_tuple_chk:w {#4} \@@_sep: } }
{ }
\exp_after:wN \c_nan_fp
}
-\cs_new:Npn \@@_parse_function_one_two_aux:nnw #1#2 #3; #4
+\cs_new:Npn \@@_parse_function_one_two_aux:nnw #1#2 #3\@@_sep: #4
{
\@@_if_type_fp:NTwFw
#4 { }
@@ -2780,14 +2781,14 @@
\@@_parse_function_one_two_error_o:w
}
\s_@@_stop
- \@@_parse_function_one_two_auxii:nnw {#1} {#2} #3; #4
+ \@@_parse_function_one_two_auxii:nnw {#1} {#2} #3\@@_sep: #4
}
-\cs_new:Npn \@@_parse_function_one_two_auxii:nnw #1#2#3; #4; #5
+\cs_new:Npn \@@_parse_function_one_two_auxii:nnw #1#2#3\@@_sep: #4\@@_sep: #5
{
\if_meaning:w @ #5 \else:
\exp_after:wN \@@_parse_function_one_two_error_o:w
\fi:
- \use_ii:nn {#1} { \use_none:n #2 } #3; #4; #5
+ \use_ii:nn {#1} { \use_none:n #2 } #3\@@_sep: #4\@@_sep: #5
}
% \end{macrocode}
% \end{macro}
@@ -2798,21 +2799,21 @@
% afterwards. The code |#1| should itself expand once after its
% result.
% \begin{macrocode}
-\cs_new:Npn \@@_tuple_map_o:nw #1 \s_@@_tuple \@@_tuple_chk:w #2 ;
+\cs_new:Npn \@@_tuple_map_o:nw #1 \s_@@_tuple \@@_tuple_chk:w #2 \@@_sep:
{
\exp_after:wN \s_@@_tuple
\exp_after:wN \@@_tuple_chk:w
\exp_after:wN {
\exp:w \exp_end_continue_f:w
\@@_tuple_map_loop_o:nw {#1} #2
- { \s_@@ \prg_break: } ;
+ { \s_@@ \prg_break: } \@@_sep:
\prg_break_point:
- \exp_after:wN } \exp_after:wN ;
+ \exp_after:wN } \exp_after:wN \@@_sep:
}
-\cs_new:Npn \@@_tuple_map_loop_o:nw #1#2#3 ;
+\cs_new:Npn \@@_tuple_map_loop_o:nw #1#2#3 \@@_sep:
{
\use_none:n #2
- #1 #2 #3 ;
+ #1 #2 #3 \@@_sep:
\exp:w \exp_end_continue_f:w
\@@_tuple_map_loop_o:nw {#1}
}
@@ -2824,24 +2825,24 @@
% afterwards.
% \begin{macrocode}
\cs_new:Npn \@@_tuple_mapthread_o:nww #1
- \s_@@_tuple \@@_tuple_chk:w #2 ;
- \s_@@_tuple \@@_tuple_chk:w #3 ;
+ \s_@@_tuple \@@_tuple_chk:w #2 \@@_sep:
+ \s_@@_tuple \@@_tuple_chk:w #3 \@@_sep:
{
\exp_after:wN \s_@@_tuple
\exp_after:wN \@@_tuple_chk:w
\exp_after:wN {
\exp:w \exp_end_continue_f:w
\@@_tuple_mapthread_loop_o:nw {#1}
- #2 { \s_@@ \prg_break: } ; @
- #3 { \s_@@ \prg_break: } ;
+ #2 { \s_@@ \prg_break: } \@@_sep: @
+ #3 { \s_@@ \prg_break: } \@@_sep:
\prg_break_point:
- \exp_after:wN } \exp_after:wN ;
+ \exp_after:wN } \exp_after:wN \@@_sep:
}
-\cs_new:Npn \@@_tuple_mapthread_loop_o:nw #1#2#3 ; #4 @ #5#6 ;
+\cs_new:Npn \@@_tuple_mapthread_loop_o:nw #1#2#3 \@@_sep: #4 @ #5#6 \@@_sep:
{
\use_none:n #2
\use_none:n #5
- #1 #2 #3 ; #5 #6 ;
+ #1 #2 #3 \@@_sep: #5 #6 \@@_sep:
\exp:w \exp_end_continue_f:w
\@@_tuple_mapthread_loop_o:nw {#1} #4 @
}
diff --git a/macros/latex-dev/required/l3kernel/l3fp-random.dtx b/macros/latex-dev/required/l3kernel/l3fp-random.dtx
index ff999926ab..9ca2d3b3b2 100644
--- a/macros/latex-dev/required/l3kernel/l3fp-random.dtx
+++ b/macros/latex-dev/required/l3kernel/l3fp-random.dtx
@@ -2,7 +2,7 @@
%
%% File: l3fp-random.dtx
%
-% Copyright (C) 2016-2024 The LaTeX Project
+% Copyright (C) 2016-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -42,7 +42,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -266,13 +266,13 @@
% \begin{macro}[EXP]
% {\@@_rand_myriads:n, \@@_rand_myriads_loop:w, \@@_rand_myriads_get:w}
% Used as \cs{@@_rand_myriads:n} |{XXX}| with one letter |X|
-% (specifically) per block of four digit we want; it expands to |;|
+% (specifically) per block of four digit we want; it expands to \cs{@@_sep:}
% followed by the requested number of brace groups, each containing
% four (pseudo-random) digits. Digits are produced as a random number
% in $[10000,19999]$ for the usual reason of preserving leading zeros.
% \begin{macrocode}
\cs_new:Npn \@@_rand_myriads:n #1
- { \@@_rand_myriads_loop:w #1 \prg_break: X \prg_break_point: ; }
+ { \@@_rand_myriads_loop:w #1 \prg_break: X \prg_break_point: \@@_sep: }
\cs_new:Npn \@@_rand_myriads_loop:w #1 X
{
#1
@@ -281,7 +281,7 @@
\__kernel_randint:n { 10000 }
\@@_rand_myriads_loop:w
}
-\cs_new:Npn \@@_rand_myriads_get:w 1 #1 ; { ; {#1} }
+\cs_new:Npn \@@_rand_myriads_get:w 1 #1 \@@_sep: { \@@_sep: {#1} }
% \end{macrocode}
% \end{macro}
%
@@ -301,7 +301,7 @@
{
\exp_after:wN \@@_rand_o:w
\exp:w \exp_end_continue_f:w
- \@@_rand_myriads:n { XXXX } { 0000 } { 0000 } ; 0
+ \@@_rand_myriads:n { XXXX } { 0000 } { 0000 } \@@_sep: 0
}
{
\msg_expandable_error:nnnnn
@@ -309,7 +309,7 @@
\exp_after:wN \c_nan_fp
}
}
-\cs_new:Npn \@@_rand_o:w ;
+\cs_new:Npn \@@_rand_o:w \@@_sep:
{
\exp_after:wN \@@_sanitize:Nw
\exp_after:wN 0
@@ -360,41 +360,41 @@
{ \@@_randint_default:w \@@_randint_o:w }
}
\cs_new:Npn \@@_randint_default:w #1 { \exp_after:wN #1 \c_one_fp }
-\cs_new:Npn \@@_randint_badarg:w \s_@@ \@@_chk:w #1#2#3;
+\cs_new:Npn \@@_randint_badarg:w \s_@@ \@@_chk:w #1#2#3\@@_sep:
{
- \@@_int:wTF \s_@@ \@@_chk:w #1#2#3;
+ \@@_int:wTF \s_@@ \@@_chk:w #1#2#3\@@_sep:
{
\if_meaning:w 1 #1
\if_int_compare:w
- \@@_use_i_until_s:nw #3 ; > \c_@@_prec_int
+ \@@_use_i_until_s:nw #3 \@@_sep: > \c_@@_prec_int
\c_one_int
\fi:
\fi:
}
{ \c_one_int }
}
-\cs_new:Npn \@@_randint_o:w #1; #2; @
+\cs_new:Npn \@@_randint_o:w #1\@@_sep: #2\@@_sep: @
{
\if_case:w
- \@@_randint_badarg:w #1;
- \@@_randint_badarg:w #2;
- \if:w 1 \@@_compare_back:ww #2; #1; \c_one_int \fi:
+ \@@_randint_badarg:w #1\@@_sep:
+ \@@_randint_badarg:w #2\@@_sep:
+ \if:w 1 \@@_compare_back:ww #2\@@_sep: #1\@@_sep: \c_one_int \fi:
\c_zero_int
- \@@_randint_auxi_o:ww #1; #2;
+ \@@_randint_auxi_o:ww #1\@@_sep: #2\@@_sep:
\or:
\@@_invalid_operation_tl_o:ff
- { randint } { \@@_array_to_clist:n { #1; #2; } }
+ { randint } { \@@_array_to_clist:n { #1\@@_sep: #2\@@_sep: } }
\exp:w
\fi:
\exp_after:wN \exp_end:
}
-\cs_new:Npn \@@_randint_auxi_o:ww #1 ; #2 ; #3 \exp_end:
+\cs_new:Npn \@@_randint_auxi_o:ww #1 \@@_sep: #2 \@@_sep: #3 \exp_end:
{
\fi:
- \@@_randint_auxii:wn #2 ;
- { \@@_randint_auxii:wn #1 ; \@@_randint_auxiii_o:ww }
+ \@@_randint_auxii:wn #2 \@@_sep:
+ { \@@_randint_auxii:wn #1 \@@_sep: \@@_randint_auxiii_o:ww }
}
-\cs_new:Npn \@@_randint_auxii:wn \s_@@ \@@_chk:w #1#2#3#4 ;
+\cs_new:Npn \@@_randint_auxii:wn \s_@@ \@@_chk:w #1#2#3#4 \@@_sep:
{
\if_meaning:w 0 #1
\exp_after:wN \use_i:nn
@@ -405,7 +405,7 @@
{
\exp_after:wN \@@_ep_to_fixed:wwn
\int_value:w \@@_int_eval:w
- #3 - \c_@@_prec_int , #4 {0000} {0000} ;
+ #3 - \c_@@_prec_int , #4 {0000} {0000} \@@_sep:
{
\if_meaning:w 0 #2
\exp_after:wN \use_i:nnnn
@@ -416,22 +416,22 @@
\@@_fixed_continue:wn
}
}
-\cs_new:Npn \@@_randint_auxiii_o:ww #1 ; #2 ;
+\cs_new:Npn \@@_randint_auxiii_o:ww #1 \@@_sep: #2 \@@_sep:
{
- \@@_fixed_add:wwn #2 ;
- {0000} {0000} {0000} {0001} {0000} {0000} ;
- \@@_fixed_sub:wwn #1 ;
+ \@@_fixed_add:wwn #2 \@@_sep:
+ {0000} {0000} {0000} {0001} {0000} {0000} \@@_sep:
+ \@@_fixed_sub:wwn #1 \@@_sep:
{
\exp_after:wN \use_i:nn
\exp_after:wN \@@_fixed_mul_add:wwwn
- \exp:w \exp_end_continue_f:w \@@_rand_myriads:n { XXXXXX } ;
+ \exp:w \exp_end_continue_f:w \@@_rand_myriads:n { XXXXXX } \@@_sep:
}
- #1 ;
+ #1 \@@_sep:
\@@_randint_auxiv_o:ww
- #2 ;
- \@@_randint_auxv_o:w #1 ; @
+ #2 \@@_sep:
+ \@@_randint_auxv_o:w #1 \@@_sep: @
}
-\cs_new:Npn \@@_randint_auxiv_o:ww #1#2#3#4#5 ; #6#7#8#9
+\cs_new:Npn \@@_randint_auxiv_o:ww #1#2#3#4#5 \@@_sep: #6#7#8#9
{
\if_int_compare:w
\if_int_compare:w #1#2 > #6#7 \exp_stop_f: 1 \else:
@@ -441,7 +441,7 @@
\fi:
\@@_randint_auxv_o:w {#1}{#2}{#3}{#4}#5
}
-\cs_new:Npn \@@_randint_auxv_o:w #1#2#3#4#5 ; #6 @
+\cs_new:Npn \@@_randint_auxv_o:w #1#2#3#4#5 \@@_sep: #6 @
{
\exp_after:wN \@@_sanitize:Nw
\int_value:w
@@ -453,7 +453,7 @@
\exp_after:wN \@@_reverse_args:Nww
\fi:
\exp_after:wN \@@_fixed_sub:wwn \c_@@_one_fixed_tl
- {#1} {#2} {#3} {#4} {0000} {0000} ;
+ {#1} {#2} {#3} {#4} {0000} {0000} \@@_sep:
{
\exp_after:wN \exp_stop_f:
\int_value:w \@@_int_eval:w \c_@@_prec_int
@@ -480,16 +480,16 @@
\int_eval:n
{
\exp_after:wN \@@_randint:ww
- \int_value:w \int_eval:n {#1} \exp_after:wN ;
- \int_value:w \int_eval:n {#2} ;
+ \int_value:w \int_eval:n {#1} \exp_after:wN \@@_sep:
+ \int_value:w \int_eval:n {#2} \@@_sep:
}
}
-\cs_new:Npn \@@_randint:ww #1; #2;
+\cs_new:Npn \@@_randint:ww #1\@@_sep: #2\@@_sep:
{
\if_int_compare:w #1 > #2 \exp_stop_f:
\msg_expandable_error:nnnn
{ kernel } { randint-backward-range } {#1} {#2}
- \@@_randint:ww #2; #1;
+ \@@_randint:ww #2\@@_sep: #1\@@_sep:
\else:
\if_int_compare:w \@@_int_eval:w #2
\if_int_compare:w #1 > \c_zero_int
@@ -517,15 +517,15 @@
% }
% Any $n\in[-2^{31}+1,2^{31}-1]$ is uniquely written as
% $2^{14}n_1+n_2$ with $n_1\in[-2^{17},2^{17}-1]$ and
-% $n_2\in[0,2^{14}-1]$. Calling \cs{@@_randint_split_o:Nw} $n$ |;|
-% gives $n_1$|;| $n_2$|;| and expands the next token once. We do this
+% $n_2\in[0,2^{14}-1]$. Calling \cs{@@_randint_split_o:Nw} $n$ \cs{@@_sep:}
+% gives $n_1$\cs{@@_sep:} $n_2$\cs{@@_sep:} and expands the next token once. We do this
% for two random numbers and apply \cs{@@_randint_split_o:Nw} twice to
% fully decompose the range~$R$. One subtlety is that we compute
% $R-2^{31}=\meta{max}-\meta{min}-(2^{31}-1)\in[-2^{31}+1,2^{31}-1]$
% rather than $R$ to avoid overflow.
%
-% Then we have \cs{@@_randint_wide_aux:w} \meta{X_1}|;|\meta{X_0}|;|
-% \meta{Y_1}|;|\meta{Y_0}|;| \meta{R_2}|;|\meta{R_1}|;|\meta{R_0}|;.|
+% Then we have \cs{@@_randint_wide_aux:w} \meta{X_1}\cs{@@_sep:}\meta{X_0}\cs{@@_sep:}
+% \meta{Y_1}\cs{@@_sep:}\meta{Y_0}\cs{@@_sep:} \meta{R_2}\cs{@@_sep:}\meta{R_1}\cs{@@_sep:}\meta{R_0}|;.|
% and we apply the algorithm described earlier.
% \begin{macrocode}
\cs_new:Npn \__kernel_randint:nn #1#2
@@ -534,46 +534,49 @@
\exp_after:wN \@@_randint_wide_aux:w
\int_value:w
\exp_after:wN \@@_randint_split_o:Nw
- \tex_uniformdeviate:D 268435456 ;
+ \tex_uniformdeviate:D 268435456 \@@_sep:
\int_value:w
\exp_after:wN \@@_randint_split_o:Nw
- \tex_uniformdeviate:D 268435456 ;
+ \tex_uniformdeviate:D 268435456 \@@_sep:
\int_value:w
\exp_after:wN \@@_randint_split_o:Nw
\int_value:w \@@_int_eval:w 131072 +
\exp_after:wN \@@_randint_split_o:Nw
\int_value:w
- \__kernel_int_add:nnn {#2} { -#1 } { -\c_max_int } ;
+ \__kernel_int_add:nnn {#2} { -#1 } { -\c_max_int } \@@_sep:
.
}
-\cs_new:Npn \@@_randint_split_o:Nw #1#2 ;
+\cs_new:Npn \@@_randint_split_o:Nw #1#2 \@@_sep:
{
\if_meaning:w 0 #1
- 0 \exp_after:wN ; \int_value:w 0
+ 0 \exp_after:wN \@@_sep: \int_value:w 0
\else:
\exp_after:wN \@@_randint_split_aux:w
- \int_value:w \@@_int_eval:w (#1#2 - 8192) / 16384 ;
+ \int_value:w \@@_int_eval:w (#1#2 - 8192) / 16384 \@@_sep:
+ #1#2
\fi:
- \exp_after:wN ;
+ \exp_after:wN \@@_sep:
}
-\cs_new:Npn \@@_randint_split_aux:w #1 ;
+\cs_new:Npn \@@_randint_split_aux:w #1 \@@_sep:
{
- #1 \exp_after:wN ;
+ #1 \exp_after:wN \@@_sep:
\int_value:w \@@_int_eval:w - #1 * 16384
}
-\cs_new:Npn \@@_randint_wide_aux:w #1;#2; #3;#4; #5;#6;#7; .
+\cs_new:Npn \@@_randint_wide_aux:w
+ #1\@@_sep:#2\@@_sep: #3\@@_sep:#4\@@_sep:
+ #5\@@_sep:#6\@@_sep:#7\@@_sep: .
{
\exp_after:wN \@@_randint_wide_auxii:w
\int_value:w \@@_int_eval:w #5 * #3 + #6 * #1 +
(#5 * #4 + #6 * #3 + #7 * #1 +
(#5 * #2 + #7 * #3 +
(16384 * #6 + #7) * (16384 * #4 + #2) / 268435456) / 16384
- ) / 16384 \exp_after:wN ;
- \int_value:w \@@_int_eval:w (#5 + #6) * 16384 + #7 ;
- #1 ; #5 ;
+ ) / 16384 \exp_after:wN \@@_sep:
+ \int_value:w \@@_int_eval:w (#5 + #6) * 16384 + #7 \@@_sep:
+ #1 \@@_sep: #5 \@@_sep:
}
-\cs_new:Npn \@@_randint_wide_auxii:w #1; #2; #3; #4;
+\cs_new:Npn \@@_randint_wide_auxii:w
+ #1\@@_sep: #2\@@_sep: #3\@@_sep: #4\@@_sep:
{
\if_int_odd:w 0
\if_int_compare:w #1 = #2 \else: \exp_stop_f: \fi:
@@ -606,7 +609,7 @@
\if_int_compare:w #1 < \c_one_int
\msg_expandable_error:nnnn
{ kernel } { randint-backward-range } { 1 } {#1}
- \@@_randint:ww #1; 1;
+ \@@_randint:ww #1\@@_sep: 1\@@_sep:
\else:
\if_int_compare:w #1 > \c__kernel_randint_max_int
\__kernel_randint:nn { 1 } {#1}
diff --git a/macros/latex-dev/required/l3kernel/l3fp-round.dtx b/macros/latex-dev/required/l3kernel/l3fp-round.dtx
index 0d39b8a26a..695b43954c 100644
--- a/macros/latex-dev/required/l3kernel/l3fp-round.dtx
+++ b/macros/latex-dev/required/l3kernel/l3fp-round.dtx
@@ -2,7 +2,7 @@
%
%% File: l3fp-round.dtx
%
-% Copyright (C) 2011-2024 The LaTeX Project
+% Copyright (C) 2011-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -144,7 +144,7 @@
% \item \cs{@@_round:NNN} \meta{sign} \meta{digit_1} \meta{digit_2}
% can expand to |0\exp_stop_f:| or |1\exp_stop_f:|.
% \item \cs{@@_round_s:NNNw} \meta{sign} \meta{digit_1} \meta{digit_2}
-% \meta{more digits}|;| can expand to |0\exp_stop_f:;| or |1\exp_stop_f:;|.
+% \meta{more digits}\cs{@@_sep:} can expand to |0\exp_stop_f:;| or |1\exp_stop_f:;|.
% \item \cs{@@_round_neg:NNN} \meta{sign} \meta{digit_1} \meta{digit_2}
% can expand to |0\exp_stop_f:| or |1\exp_stop_f:|.
% \end{itemize}
@@ -267,7 +267,7 @@
%
% \begin{macro}[EXP]{\@@_round_s:NNNw}
% \begin{syntax}
-% \cs{@@_round_s:NNNw} \meta{final sign} \meta{digit} \meta{more digits} |;|
+% \cs{@@_round_s:NNNw} \meta{final sign} \meta{digit} \meta{more digits} \cs{@@_sep:}
% \end{syntax}
% Similar to \cs{@@_round:NNN}, but with an extra semicolon, this
% function expands to |0\exp_stop_f:;| if rounding $\meta{final sign}
@@ -277,7 +277,7 @@
% \cs{@@_int_eval:w} construction. The only relevant information about
% this piece is whether it is zero or not.
% \begin{macrocode}
-\cs_new:Npn \@@_round_s:NNNw #1 #2 #3 #4;
+\cs_new:Npn \@@_round_s:NNNw #1 #2 #3 #4\@@_sep:
{
\exp_after:wN \@@_round:NNN
\exp_after:wN #1
@@ -291,14 +291,14 @@
\fi:
\fi:
#3
- ;
+ \@@_sep:
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[EXP]{\@@_round_digit:Nw}
% \begin{syntax}
-% \cs{int_value:w} \cs{@@_round_digit:Nw} \meta{digit} \meta{int expr} |;|
+% \cs{int_value:w} \cs{@@_round_digit:Nw} \meta{digit} \meta{int expr} \cs{@@_sep:}
% \end{syntax}
% This function should always be called within an \cs{int_value:w}
% or \cs{@@_int_eval:w} expansion; it may add an extra
@@ -306,7 +306,7 @@
% expression should not be ended with a synonym of \tn{relax}, but
% with a semi-colon for instance.
% \begin{macrocode}
-\cs_new:Npn \@@_round_digit:Nw #1 #2;
+\cs_new:Npn \@@_round_digit:Nw #1 #2\@@_sep:
{
\if_int_odd:w \if_meaning:w 0 #1 1 \else:
\if_meaning:w 5 #1 1 \else:
@@ -427,7 +427,8 @@
% \cs{@@_round_to_nearest_ninf:NNN}, \cs{@@_round_to_nearest_pinf:NNN}
% and act accordingly.
% \begin{macrocode}
-\cs_new:Npn \@@_round:Nwww #1#2 ; #3 ; \s_@@ \@@_chk:w #4#5#6 ; #7 @
+\cs_new:Npn \@@_round:Nwww
+ #1#2 \@@_sep: #3 \@@_sep: \s_@@ \@@_chk:w #4#5#6 \@@_sep: #7 @
{
\cs_if_eq:NNTF #1 \@@_round_to_nearest:NNN
{
@@ -440,7 +441,7 @@
\if_case:w #5 \exp_stop_f: _pinf \or: \else: _ninf \fi: \fi:
:NNN
}
- #2 ; #3 ;
+ #2 \@@_sep: #3 \@@_sep:
}
{
\@@_error:nnnn { num-args } { round () } { 1 } { 3 }
@@ -488,11 +489,11 @@
% otherwise invalid as we have something like |round(1,3.14)| where
% the number of digits is not an integer.
% \begin{macrocode}
-\cs_new:Npn \@@_round:Nww #1#2 ; #3 ;
+\cs_new:Npn \@@_round:Nww #1#2 \@@_sep: #3 \@@_sep:
{
- \@@_small_int:wTF #3; { \@@_round:Nwn #1#2; }
+ \@@_small_int:wTF #3\@@_sep: { \@@_round:Nwn #1#2\@@_sep: }
{
- \if:w 3 \@@_kind:w #3 ;
+ \if:w 3 \@@_kind:w #3 \@@_sep:
\exp_after:wN \use_i:nn
\else:
\exp_after:wN \use_ii:nn
@@ -501,11 +502,11 @@
{
\@@_invalid_operation_tl_o:ff
{ \@@_round_name_from_cs:N #1 }
- { \@@_array_to_clist:n { #2; #3; } }
+ { \@@_array_to_clist:n { #2\@@_sep: #3\@@_sep: } }
}
}
}
-\cs_new:Npn \@@_round:Nwn #1 \s_@@ \@@_chk:w #2#3#4; #5
+\cs_new:Npn \@@_round:Nwn #1 \s_@@ \@@_chk:w #2#3#4\@@_sep: #5
{
\if_meaning:w 1 #2
\exp_after:wN \@@_round_normal:NwNNnw
@@ -514,14 +515,14 @@
\else:
\exp_after:wN \@@_exp_after_o:w
\fi:
- \s_@@ \@@_chk:w #2#3#4;
+ \s_@@ \@@_chk:w #2#3#4\@@_sep:
}
-\cs_new:Npn \@@_round_normal:NwNNnw #1#2 \s_@@ \@@_chk:w 1#3#4#5;
+\cs_new:Npn \@@_round_normal:NwNNnw #1#2 \s_@@ \@@_chk:w 1#3#4#5\@@_sep:
{
\@@_decimate:nNnnnn { \c_@@_prec_int - #4 - #2 }
\@@_round_normal:NnnwNNnn #5 #1 #3 {#4} {#2}
}
-\cs_new:Npn \@@_round_normal:NnnwNNnn #1#2#3#4; #5#6
+\cs_new:Npn \@@_round_normal:NnnwNNnn #1#2#3#4\@@_sep: #5#6
{
\exp_after:wN \@@_round_normal:NNwNnn
\int_value:w \@@_int_eval:w
@@ -539,7 +540,7 @@
\use_none:nnnnnnn #3
#1
\@@_int_eval_end:
- 0000 0000 0000 0000 ; #6
+ 0000 0000 0000 0000 \@@_sep: #6
}
\cs_new:Npn \@@_round_pack:Nw #1
{ \if_meaning:w 2 #1 + 1 \fi: \@@_int_eval_end: }
@@ -552,14 +553,14 @@
\@@_pack_twice_four:wNNNNNNNN
\@@_pack_twice_four:wNNNNNNNN
\@@_round_normal_end:wwNnn
- ; #2
+ \@@_sep: #2
}
-\cs_new:Npn \@@_round_normal_end:wwNnn #1;#2;#3#4#5
+\cs_new:Npn \@@_round_normal_end:wwNnn #1\@@_sep:#2\@@_sep:#3#4#5
{
\exp_after:wN \@@_exp_after_o:w \exp:w \exp_end_continue_f:w
- \@@_sanitize:Nw #3 #4 ; #1 ;
+ \@@_sanitize:Nw #3 #4 \@@_sep: #1 \@@_sep:
}
-\cs_new:Npn \@@_round_special:NwwNnn #1#2;#3;#4#5#6
+\cs_new:Npn \@@_round_special:NwwNnn #1#2\@@_sep:#3\@@_sep:#4#5#6
{
\if_meaning:w 0 #1
\@@_case_return:nw
@@ -570,12 +571,12 @@
\int_value:w \@@_int_eval:w 1
\if_meaning:w 1 #1 -#6 \else: +#5 \fi:
\fi:
- ;
+ \@@_sep:
}
-\cs_new:Npn \@@_round_special_aux:Nw #1#2;
+\cs_new:Npn \@@_round_special_aux:Nw #1#2\@@_sep:
{
\exp_after:wN \@@_exp_after_o:w \exp:w \exp_end_continue_f:w
- \@@_sanitize:Nw #1#2; {1000}{0000}{0000}{0000};
+ \@@_sanitize:Nw #1#2\@@_sep: {1000}{0000}{0000}{0000}\@@_sep:
}
% \end{macrocode}
% \end{macro}
diff --git a/macros/latex-dev/required/l3kernel/l3fp-symbolic.dtx b/macros/latex-dev/required/l3kernel/l3fp-symbolic.dtx
index 88e214f49e..a9cb0ee95e 100644
--- a/macros/latex-dev/required/l3kernel/l3fp-symbolic.dtx
+++ b/macros/latex-dev/required/l3kernel/l3fp-symbolic.dtx
@@ -42,7 +42,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -75,14 +75,14 @@
%
% Every symbolic expression has the form \cs{s_@@_symbolic}
% \cs{@@_symbolic_chk:w} \meta{operation} |,| \Arg{operands} \meta{junk}
-% |;| where the \meta{operation} is a list of \texttt{N}-type tokens,
+% \cs{@@_sep:} where the \meta{operation} is a list of \texttt{N}-type tokens,
% the \meta{operands} is an array of floating point objects, and the
% \meta{junk} is to be discarded. If the outermost operator (last to be
% evaluated) is unary, the expression has the form
% \begin{quote}
% \cs{s_@@_symbolic} \cs{@@_symbolic_chk:w} \\
% \cs{@@_types_unary:NNw} |\__fp_|\meta{op}|_o:w| \meta{token} |,| \\
-% |{| \meta{operand} |}| \meta{junk} |;|
+% |{| \meta{operand} |}| \meta{junk} \cs{@@_sep:}
% \end{quote}
% where the \meta{op} is a unary operation (|set_sign|, |cos|,
% \ldots{}), and the \meta{token} and \meta{operand} are used as
@@ -92,7 +92,7 @@
% \begin{quote}
% \cs{s_@@_symbolic} \cs{@@_symbolic_chk:w} \\
% \cs{@@_types_binary:Nww} |\__fp_|\meta{op}|_o:ww| |,| \\
-% |{| \meta{operand_1} \meta{operand_2} |}| \meta{junk} |;|
+% |{| \meta{operand_1} \meta{operand_2} |}| \meta{junk} \cs{@@_sep:}
% \end{quote}
% where the \meta{op} is an operation (|+|, |&|, \ldots{}), and
% |\__fp_|\meta{op}|_o:ww| receives the \meta{operands} as arguments.
@@ -100,7 +100,7 @@
% \begin{quote}
% \cs{s_@@_symbolic} \cs{@@_symbolic_chk:w} \\
% \cs{@@_variable_o:w} \meta{identifier} |,| \\
-% |{| |}| \meta{junk} |;|
+% |{| |}| \meta{junk} \cs{@@_sep:}
% \end{quote}
%
% Symbolic expressions are stored in a prefix form. When encountering a
@@ -141,12 +141,12 @@
% \begin{macro}{\@@_symbolic_chk:w}
% Analog of \cs{@@_chk:w} for symbolic expressions.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_symbolic_chk:w #1,#2#3;
+\cs_new_protected:Npn \@@_symbolic_chk:w #1,#2#3\@@_sep:
{
\msg_error:nne { fp } { misused-fp }
{
\@@_to_tl_dispatch:w
- \s_@@_symbolic \@@_symbolic_chk:w #1,{#2};
+ \s_@@_symbolic \@@_symbolic_chk:w #1,{#2}\@@_sep:
}
}
% \end{macrocode}
@@ -181,7 +181,7 @@
% evaluate all pieces of the expression which can be evaluated.
% \begin{macrocode}
\cs_new:Npn \@@_exp_after_symbolic_f:nw
- #1 \s_@@_symbolic \@@_symbolic_chk:w #2, #3#4;
+ #1 \s_@@_symbolic \@@_symbolic_chk:w #2, #3#4\@@_sep:
{
\exp_after:wN \@@_exp_after_symbolic_aux:w
\exp:w
@@ -193,13 +193,13 @@
\@@_exp_after_array_f:w #3 \s_@@_expr_stop
\exp_after:wN
}
- \exp_after:wN ;
+ \exp_after:wN \@@_sep:
\exp:w \exp_end_continue_f:w #1
}
-\cs_new:Npn \@@_exp_after_symbolic_aux:w #1, #2;
+\cs_new:Npn \@@_exp_after_symbolic_aux:w #1, #2\@@_sep:
{
\@@_if_has_symbolic:nTF {#2}
- { \s_@@_symbolic \@@_symbolic_chk:w #1, {#2} ; }
+ { \s_@@_symbolic \@@_symbolic_chk:w #1, {#2} \@@_sep: }
{ #1 #2 @ \prg_do_nothing: }
}
\cs_new:Npn \@@_exp_after_symbolic_loop:N #1
@@ -218,11 +218,11 @@
% \begin{macro}[EXP]{\@@_symbolic_binary_o:Nww}
% Used when applying infix operators to expressions.
% \begin{macrocode}
-\cs_new:Npn \@@_symbolic_binary_o:Nww #1 #2; #3;
+\cs_new:Npn \@@_symbolic_binary_o:Nww #1 #2\@@_sep: #3\@@_sep:
{
\@@_exp_after_symbolic_f:nw { \exp_after:wN \exp_stop_f: }
\s_@@_symbolic \@@_symbolic_chk:w
- \@@_types_binary:Nww #1 , { #2; #3; } ;
+ \@@_types_binary:Nww #1 , { #2\@@_sep: #3\@@_sep: } \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -280,11 +280,11 @@
% \begin{macro}[EXP]{\@@_symbolic_unary_o:NNw}
% Used when applying infix operators to expressions.
% \begin{macrocode}
-\cs_new:Npn \@@_symbolic_unary_o:NNw #1#2#3; @
+\cs_new:Npn \@@_symbolic_unary_o:NNw #1#2#3\@@_sep: @
{
\@@_exp_after_symbolic_f:nw { \exp_after:wN \exp_stop_f: }
\s_@@_symbolic \@@_symbolic_chk:w
- \@@_types_unary:NNw #1#2 , { #3; } ;
+ \@@_types_unary:NNw #1#2 , { #3\@@_sep: } \@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -346,11 +346,11 @@
\@@_tmp:w { decimal } { 0 } \@@_to_decimal_dispatch:w
\@@_tmp:w { int } { 0 } \@@_to_int_dispatch:w
\@@_tmp:w { scientific } { nan } \@@_to_scientific_dispatch:w
-\cs_new:Npn \@@_symbolic_convert:wnnN #1#2; #3#4#5
+\cs_new:Npn \@@_symbolic_convert:wnnN #1#2\@@_sep: #3#4#5
{
\str_if_eq:nnTF {#1} { \s_@@_symbolic }
- { \@@_invalid_operation:nnw {#3} {#4} #1#2; }
- { #5 #1#2; }
+ { \@@_invalid_operation:nnw {#3} {#4} #1#2\@@_sep: }
+ { #5 #1#2\@@_sep: }
}
% \end{macrocode}
% \end{macro}
@@ -390,7 +390,7 @@
% Converting a symbolic expression to a token list is possible.
% \begin{macrocode}
\cs_new:Npn \@@_symbolic_to_tl:w
- \s_@@_symbolic \@@_symbolic_chk:w #1#2, #3#4;
+ \s_@@_symbolic \@@_symbolic_chk:w #1#2, #3#4\@@_sep:
{
\str_case:nnTF {#1}
{
@@ -409,13 +409,13 @@
( \@@_to_tl_dispatch:w #3 )
}
}
-\cs_new:Npn \@@_symbolic_binary_to_tl:Nww #1, #2; #3; @
+\cs_new:Npn \@@_symbolic_binary_to_tl:Nww #1, #2\@@_sep: #3\@@_sep: @
{
\use:e
{
- ( \@@_to_tl_dispatch:w #2; )
+ ( \@@_to_tl_dispatch:w #2\@@_sep: )
\@@_types_cs_to_op:N #1
- ( \@@_to_tl_dispatch:w #3; )
+ ( \@@_to_tl_dispatch:w #3\@@_sep: )
}
}
\cs_new:Npn \@@_symbolic_function_to_tl:Nw #1, #2@
@@ -492,7 +492,7 @@
\token_if_eq_meaning:NNTF #2 \prg_do_nothing:
{
\s_@@_symbolic \@@_symbolic_chk:w
- \@@_variable_o:w #1 , { } ;
+ \@@_variable_o:w #1 , { } \@@_sep:
}
{
\exp_after:wN \s_@@_symbolic
@@ -502,7 +502,7 @@
\@@_exp_after_symbolic_loop:N #1
{ , \exp:w \use_none:nn }
\exp_after:wN \exp_end:
- \exp_after:wN { \exp_after:wN } \exp_after:wN ;
+ \exp_after:wN { \exp_after:wN } \exp_after:wN \@@_sep:
#2
}
}
@@ -519,7 +519,7 @@
{
\@@_exp_after_symbolic_f:nw { \@@_parse_infix:NN }
\s_@@_symbolic \@@_symbolic_chk:w
- \@@_variable_o:w #2 , { } ;
+ \@@_variable_o:w #2 , { } \@@_sep:
}
\exp_args:NNc \@@_variable_set_parsing_aux:NNn #1
{ @@_parse_word_#2:N } {#2}
diff --git a/macros/latex-dev/required/l3kernel/l3fp-traps.dtx b/macros/latex-dev/required/l3kernel/l3fp-traps.dtx
index fec48bc163..5fb3d5d08a 100644
--- a/macros/latex-dev/required/l3kernel/l3fp-traps.dtx
+++ b/macros/latex-dev/required/l3kernel/l3fp-traps.dtx
@@ -2,7 +2,7 @@
%
%% File: l3fp-traps.dtx
%
-% Copyright (C) 2011-2024 The LaTeX Project
+% Copyright (C) 2011-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -42,7 +42,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
% \maketitle
%
% \begin{documentation}
@@ -163,19 +163,21 @@
\cs_new_protected:Npn \@@_trap_invalid_operation_set:N #1
{
\exp_args:Nno \use:n
- { \cs_set:Npn \@@_invalid_operation:nnw ##1##2##3; }
+ { \cs_set:Npn \@@_invalid_operation:nnw ##1##2##3\@@_sep: }
{
#1
- \@@_error:nnfn { invalid } {##2} { \fp_to_tl:n { ##3; } } { }
+ \@@_error:nnfn { invalid } {##2} { \fp_to_tl:n { ##3\@@_sep: } } { }
\flag_ensure_raised:N \l_fp_invalid_operation_flag
##1
}
\exp_args:Nno \use:n
- { \cs_set:Npn \@@_invalid_operation_o:Nww ##1##2; ##3; }
+ { \cs_set:Npn \@@_invalid_operation_o:Nww ##1##2\@@_sep: ##3\@@_sep: }
{
#1
\@@_error:nffn { invalid-ii }
- { \fp_to_tl:n { ##2; } } { \fp_to_tl:n { ##3; } } {##1}
+ { \fp_to_tl:n { ##2\@@_sep: } }
+ { \fp_to_tl:n { ##3\@@_sep: } }
+ {##1}
\flag_ensure_raised:N \l_fp_invalid_operation_flag
\exp_after:wN \c_nan_fp
}
@@ -213,19 +215,23 @@
\cs_new_protected:Npn \@@_trap_division_by_zero_set:N #1
{
\exp_args:Nno \use:n
- { \cs_set:Npn \@@_division_by_zero_o:Nnw ##1##2##3; }
+ { \cs_set:Npn \@@_division_by_zero_o:Nnw ##1##2##3\@@_sep: }
{
#1
- \@@_error:nnfn { zero-div } {##2} { \fp_to_tl:n { ##3; } } { }
+ \@@_error:nnfn { zero-div } {##2} { \fp_to_tl:n { ##3\@@_sep: } } { }
\flag_ensure_raised:N \l_fp_division_by_zero_flag
\exp_after:wN ##1
}
\exp_args:Nno \use:n
- { \cs_set:Npn \@@_division_by_zero_o:NNww ##1##2##3; ##4; }
+ {
+ \cs_set:Npn \@@_division_by_zero_o:NNww ##1##2##3\@@_sep: ##4\@@_sep:
+ }
{
#1
\@@_error:nffn { zero-div-ii }
- { \fp_to_tl:n { ##3; } } { \fp_to_tl:n { ##4; } } {##2}
+ { \fp_to_tl:n { ##3\@@_sep: } }
+ { \fp_to_tl:n { ##4\@@_sep: } }
+ {##2}
\flag_ensure_raised:N \l_fp_division_by_zero_flag
\exp_after:wN ##1
}
@@ -281,12 +287,12 @@
\cs_new_protected:Npn \@@_trap_overflow_set:NnNn #1#2#3#4
{
\exp_args:Nno \use:n
- { \cs_set:cpn { @@_ #2 :w } \s_@@ \@@_chk:w ##1##2##3; }
+ { \cs_set:cpn { @@_ #2 :w } \s_@@ \@@_chk:w ##1##2##3\@@_sep: }
{
#1
\@@_error:nffn
{ flow \if_meaning:w 1 ##1 -to \fi: }
- { \fp_to_tl:n { \s_@@ \@@_chk:w ##1##2##3; } }
+ { \fp_to_tl:n { \s_@@ \@@_chk:w ##1##2##3\@@_sep: } }
{ \token_if_eq_meaning:NNF 0 ##2 { - } #4 }
{#2}
\flag_ensure_raised:c { l_fp_#2_flag }
@@ -310,11 +316,11 @@
% division by zero, overflow, and underflow to act silently on their
% flag.
% \begin{macrocode}
-\cs_new:Npn \@@_invalid_operation:nnw #1#2#3; { }
-\cs_new:Npn \@@_invalid_operation_o:Nww #1#2; #3; { }
+\cs_new:Npn \@@_invalid_operation:nnw #1#2#3\@@_sep: { }
+\cs_new:Npn \@@_invalid_operation_o:Nww #1#2\@@_sep: #3\@@_sep: { }
\cs_new:Npn \@@_invalid_operation_tl_o:ff #1 #2 { }
-\cs_new:Npn \@@_division_by_zero_o:Nnw #1#2#3; { }
-\cs_new:Npn \@@_division_by_zero_o:NNww #1#2#3; #4; { }
+\cs_new:Npn \@@_division_by_zero_o:Nnw #1#2#3\@@_sep: { }
+\cs_new:Npn \@@_division_by_zero_o:NNww #1#2#3\@@_sep: #4\@@_sep: { }
\cs_new:Npn \@@_overflow:w { }
\cs_new:Npn \@@_underflow:w { }
\fp_trap:nn { invalid_operation } { error }
diff --git a/macros/latex-dev/required/l3kernel/l3fp-trig.dtx b/macros/latex-dev/required/l3kernel/l3fp-trig.dtx
index 7c40c6198f..501a6bf2fa 100644
--- a/macros/latex-dev/required/l3kernel/l3fp-trig.dtx
+++ b/macros/latex-dev/required/l3kernel/l3fp-trig.dtx
@@ -2,7 +2,7 @@
%
%% File: l3fp-trig.dtx
%
-% Copyright (C) 2011-2024 The LaTeX Project
+% Copyright (C) 2011-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -42,7 +42,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -168,7 +168,7 @@
% result of the series to a floating point directly rather than taking
% its inverse, since $\sin(x) = \#3 \sin\lvert x\rvert$.
% \begin{macrocode}
-\cs_new:Npn \@@_sin_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+\cs_new:Npn \@@_sin_o:w #1 \s_@@ \@@_chk:w #2#3#4\@@_sep: @
{
\if_case:w #2 \exp_stop_f:
\@@_case_return_same_o:w
@@ -181,7 +181,7 @@
{ \@@_invalid_operation_o:fw { #1 { sin } { sind } } }
\else: \@@_case_return_same_o:w
\fi:
- \s_@@ \@@_chk:w #2 #3 #4;
+ \s_@@ \@@_chk:w #2 #3 #4\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -195,7 +195,7 @@
% sign~|0| regardless of the sign of~$x$, and with an initial octant
% of~$2$, because $\cos(x) = + \sin(\pi/2 + \lvert x\rvert)$.
% \begin{macrocode}
-\cs_new:Npn \@@_cos_o:w #1 \s_@@ \@@_chk:w #2#3; @
+\cs_new:Npn \@@_cos_o:w #1 \s_@@ \@@_chk:w #2#3\@@_sep: @
{
\if_case:w #2 \exp_stop_f:
\@@_case_return_o:Nw \c_one_fp
@@ -208,7 +208,7 @@
{ \@@_invalid_operation_o:fw { #1 { cos } { cosd } } }
\else: \@@_case_return_same_o:w
\fi:
- \s_@@ \@@_chk:w #2 #3;
+ \s_@@ \@@_chk:w #2 #3\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -225,7 +225,7 @@
% point sine to the floating point result, because $\csc(x) = \#3
% \big( \sin\lvert x\rvert\big)^{-1}$.
% \begin{macrocode}
-\cs_new:Npn \@@_csc_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+\cs_new:Npn \@@_csc_o:w #1 \s_@@ \@@_chk:w #2#3#4\@@_sep: @
{
\if_case:w #2 \exp_stop_f:
\@@_cot_zero_o:Nfw #3 { #1 { csc } { cscd } }
@@ -238,7 +238,7 @@
{ \@@_invalid_operation_o:fw { #1 { csc } { cscd } } }
\else: \@@_case_return_same_o:w
\fi:
- \s_@@ \@@_chk:w #2 #3 #4;
+ \s_@@ \@@_chk:w #2 #3 #4\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -251,7 +251,7 @@
% positive sign~$0$, a starting octant of~$2$, and inverting upon
% conversion, because $\sec(x) = + 1 / \sin(\pi/2 + \lvert x\rvert)$.
% \begin{macrocode}
-\cs_new:Npn \@@_sec_o:w #1 \s_@@ \@@_chk:w #2#3; @
+\cs_new:Npn \@@_sec_o:w #1 \s_@@ \@@_chk:w #2#3\@@_sep: @
{
\if_case:w #2 \exp_stop_f:
\@@_case_return_o:Nw \c_one_fp
@@ -264,7 +264,7 @@
{ \@@_invalid_operation_o:fw { #1 { sec } { secd } } }
\else: \@@_case_return_same_o:w
\fi:
- \s_@@ \@@_chk:w #2 #3;
+ \s_@@ \@@_chk:w #2 #3\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -278,7 +278,7 @@
% of~$1$ (this shift is somewhat arbitrary). See \cs{@@_cot_o:w} for
% an explanation of the $0$~argument.
% \begin{macrocode}
-\cs_new:Npn \@@_tan_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+\cs_new:Npn \@@_tan_o:w #1 \s_@@ \@@_chk:w #2#3#4\@@_sep: @
{
\if_case:w #2 \exp_stop_f:
\@@_case_return_same_o:w
@@ -291,7 +291,7 @@
{ \@@_invalid_operation_o:fw { #1 { tan } { tand } } }
\else: \@@_case_return_same_o:w
\fi:
- \s_@@ \@@_chk:w #2 #3 #4;
+ \s_@@ \@@_chk:w #2 #3 #4\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -308,7 +308,7 @@
% sign of the argument: the first of those indicates whether we
% compute tangent or cotangent. Those signs are eventually combined.
% \begin{macrocode}
-\cs_new:Npn \@@_cot_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+\cs_new:Npn \@@_cot_o:w #1 \s_@@ \@@_chk:w #2#3#4\@@_sep: @
{
\if_case:w #2 \exp_stop_f:
\@@_cot_zero_o:Nfw #3 { #1 { cot } { cotd } }
@@ -321,7 +321,7 @@
{ \@@_invalid_operation_o:fw { #1 { cot } { cotd } } }
\else: \@@_case_return_same_o:w
\fi:
- \s_@@ \@@_chk:w #2 #3 #4;
+ \s_@@ \@@_chk:w #2 #3 #4\@@_sep:
}
\cs_new:Npn \@@_cot_zero_o:Nfw #1#2#3 \fi:
{
@@ -362,7 +362,7 @@
% four \texttt{trig}/\texttt{trigd} auxiliaries receive the operand as
% an extended-precision number.
% \begin{macrocode}
-\cs_new:Npn \@@_trig:NNNNNwn #1#2#3#4#5 \s_@@ \@@_chk:w 1#6#7#8;
+\cs_new:Npn \@@_trig:NNNNNwn #1#2#3#4#5 \s_@@ \@@_chk:w 1#6#7#8\@@_sep:
{
\exp_after:wN #2
\exp_after:wN #3
@@ -374,7 +374,7 @@
\else:
#1 \@@_trig_small:ww \@@_trigd_small:ww
\fi:
- #7,#8{0000}{0000};
+ #7,#8{0000}{0000}\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -390,8 +390,8 @@
% an extended-precision number) rather than the fixed point number.
% The period serves to end the integer expression for the octant.
% \begin{macrocode}
-\cs_new:Npn \@@_trig_small:ww #1,#2;
- { \@@_ep_to_fixed:wwn #1,#2; . #1,#2; }
+\cs_new:Npn \@@_trig_small:ww #1,#2\@@_sep:
+ { \@@_ep_to_fixed:wwn #1,#2\@@_sep: . #1,#2\@@_sep: }
% \end{macrocode}
% \end{macro}
%
@@ -400,10 +400,10 @@
% \cs{@@_trig_small:ww} to massage it in the form appropriate for the
% \texttt{_series} auxiliary.
% \begin{macrocode}
-\cs_new:Npn \@@_trigd_small:ww #1,#2;
+\cs_new:Npn \@@_trigd_small:ww #1,#2\@@_sep:
{
\@@_ep_mul_raw:wwwwN
- -1,{1745}{3292}{5199}{4329}{5769}{2369}; #1,#2;
+ -1,{1745}{3292}{5199}{4329}{5769}{2369}\@@_sep: #1,#2\@@_sep:
\@@_trig_small:ww
}
% \end{macrocode}
@@ -444,34 +444,34 @@
% those are all~$0$ and no precision is lost (|#6| and~|#7| are
% four~$0$ each).
% \begin{macrocode}
-\cs_new:Npn \@@_trigd_large:ww #1, #2#3#4#5#6#7;
+\cs_new:Npn \@@_trigd_large:ww #1, #2#3#4#5#6#7\@@_sep:
{
\exp_after:wN \@@_pack_eight:wNNNNNNNN
\exp_after:wN \@@_pack_eight:wNNNNNNNN
\exp_after:wN \@@_pack_twice_four:wNNNNNNNN
\exp_after:wN \@@_pack_twice_four:wNNNNNNNN
\exp_after:wN \@@_trigd_large_auxi:nnnnwNNNN
- \exp_after:wN ;
+ \exp_after:wN \@@_sep:
\exp:w \exp_end_continue_f:w
\prg_replicate:nn { \int_max:nn { 22 - #1 } { 0 } } { 0 }
#2#3#4#5#6#7 0000 0000 0000 !
}
-\cs_new:Npn \@@_trigd_large_auxi:nnnnwNNNN #1#2#3#4#5; #6#7#8#9
+\cs_new:Npn \@@_trigd_large_auxi:nnnnwNNNN #1#2#3#4#5\@@_sep: #6#7#8#9
{
\exp_after:wN \@@_trigd_large_auxii:wNw
\int_value:w \@@_int_eval:w #1 + #2
- (#1 + #2 - 4) / 9 * 9 \@@_int_eval_end:
- #3;
- #4; #5{#6#7#8#9};
+ #3\@@_sep:
+ #4\@@_sep: #5{#6#7#8#9}\@@_sep:
}
-\cs_new:Npn \@@_trigd_large_auxii:wNw #1; #2#3;
+\cs_new:Npn \@@_trigd_large_auxii:wNw #1\@@_sep: #2#3\@@_sep:
{
+ (#1#2 - 4) / 9 * 2
\exp_after:wN \@@_trigd_large_auxiii:www
\int_value:w \@@_int_eval:w #1#2
- - (#1#2 - 4) / 9 * 9 \@@_int_eval_end: #3 ;
+ - (#1#2 - 4) / 9 * 9 \@@_int_eval_end: #3 \@@_sep:
}
-\cs_new:Npn \@@_trigd_large_auxiii:www #1; #2; #3!
+\cs_new:Npn \@@_trigd_large_auxiii:www #1\@@_sep: #2\@@_sep: #3!
{
\if_int_compare:w #1 < 4500 \exp_stop_f:
\exp_after:wN \@@_use_i_until_s:nw
@@ -479,8 +479,8 @@
\else:
+ 1
\fi:
- \@@_fixed_sub:wwn {9000}{0000}{0000}{0000}{0000}{0000};
- {#1}#2{0000}{0000};
+ \@@_fixed_sub:wwn {9000}{0000}{0000}{0000}{0000}{0000}\@@_sep:
+ {#1}#2{0000}{0000}\@@_sep:
{ \@@_trigd_small:ww 2, }
}
% \end{macrocode}
@@ -768,12 +768,12 @@
% between $65$ and $72$ at this point) into groups of~$4$ and the
% \texttt{auxv} auxiliary is called.
% \begin{macrocode}
-\cs_new:Npn \@@_trig_large:ww #1, #2#3#4#5#6;
+\cs_new:Npn \@@_trig_large:ww #1, #2#3#4#5#6\@@_sep:
{
\exp_after:wN \@@_trig_large_auxi:w
\int_value:w \@@_int_eval:w (#1 - 4) / 8 \exp_after:wN ,
- \int_value:w #1 , ;
- {#2}{#3}{#4}{#5} ;
+ \int_value:w #1 , \@@_sep:
+ {#2}{#3}{#4}{#5} \@@_sep:
}
\cs_new:Npn \@@_trig_large_auxi:w #1, #2,
{
@@ -818,7 +818,7 @@
\@@_pack_twice_four:wNNNNNNNN \@@_pack_twice_four:wNNNNNNNN
\@@_pack_twice_four:wNNNNNNNN \@@_pack_twice_four:wNNNNNNNN
\@@_pack_twice_four:wNNNNNNNN \@@_pack_twice_four:wNNNNNNNN
- \@@_trig_large_auxv:www ;
+ \@@_trig_large_auxv:www \@@_sep:
}
\cs_new:Npn \@@_trig_large_auxiii:w 1 { \exp_stop_f: }
% \end{macrocode}
@@ -848,7 +848,7 @@
% more step in the ladder. The last semicolon closes the ladder, and
% we return control to the \texttt{auxvii} auxiliary.
% \begin{macrocode}
-\cs_new:Npn \@@_trig_large_auxv:www #1; #2; #3;
+\cs_new:Npn \@@_trig_large_auxv:www #1\@@_sep: #2\@@_sep: #3\@@_sep:
{
\exp_after:wN \@@_use_i_until_s:nw
\exp_after:wN \@@_trig_large_auxvii:w
@@ -857,17 +857,17 @@
{ \@@_trig_large_auxvi:wnnnnnnnn }
+ \c_@@_trailing_shift_int - \c_@@_middle_shift_int
\@@_use_i_until_s:nw
- ; #3 #1 ; ;
+ \@@_sep: #3 #1 \@@_sep: \@@_sep:
}
-\cs_new:Npn \@@_trig_large_auxvi:wnnnnnnnn #1; #2#3#4#5#6#7#8#9
+\cs_new:Npn \@@_trig_large_auxvi:wnnnnnnnn #1\@@_sep: #2#3#4#5#6#7#8#9
{
\exp_after:wN \@@_trig_large_pack:NNNNNw
\int_value:w \@@_int_eval:w \c_@@_middle_shift_int
+ #2*#9 + #3*#8 + #4*#7 + #5*#6
- #1; {#2}{#3}{#4}{#5} {#7}{#8}{#9}
+ #1\@@_sep: {#2}{#3}{#4}{#5} {#7}{#8}{#9}
}
-\cs_new:Npn \@@_trig_large_pack:NNNNNw #1#2#3#4#5#6;
- { + #1#2#3#4#5 ; #6 }
+\cs_new:Npn \@@_trig_large_pack:NNNNNw #1#2#3#4#5#6\@@_sep:
+ { + #1#2#3#4#5 \@@_sep: #6 }
% \end{macrocode}
% \end{macro}
%
@@ -900,10 +900,10 @@
\cs_new:Npn \@@_trig_large_auxvii:w #1#2#3
{
\exp_after:wN \@@_trig_large_auxviii:ww
- \int_value:w \@@_int_eval:w (#1#2#3 - 62) / 125 ;
+ \int_value:w \@@_int_eval:w (#1#2#3 - 62) / 125 \@@_sep:
#1#2#3
}
-\cs_new:Npn \@@_trig_large_auxviii:ww #1;
+\cs_new:Npn \@@_trig_large_auxviii:ww #1\@@_sep:
{
+ #1
\if_int_odd:w #1 \exp_stop_f:
@@ -922,20 +922,20 @@
\prg_replicate:nn { 13 }
{ \@@_trig_large_auxx:wNNNNN }
+ \c_@@_trailing_shift_int - \c_@@_middle_shift_int
- ;
+ \@@_sep:
}
-\cs_new:Npn \@@_trig_large_auxx:wNNNNN #1; #2 #3#4#5#6
+\cs_new:Npn \@@_trig_large_auxx:wNNNNN #1\@@_sep: #2 #3#4#5#6
{
\exp_after:wN \@@_trig_large_pack:NNNNNw
\int_value:w \@@_int_eval:w \c_@@_middle_shift_int
#2 8 * #3#4#5#6
- #1; #2
+ #1\@@_sep: #2
}
-\cs_new:Npn \@@_trig_large_auxxi:w #1;
+\cs_new:Npn \@@_trig_large_auxxi:w #1\@@_sep:
{
\exp_after:wN \@@_ep_mul_raw:wwwwN
- \int_value:w \@@_int_eval:w 0 \@@_ep_to_ep_loop:N #1 ; ; !
- 0,{7853}{9816}{3397}{4483}{0961}{5661};
+ \int_value:w \@@_int_eval:w 0 \@@_ep_to_ep_loop:N #1 \@@_sep: \@@_sep: !
+ 0,{7853}{9816}{3397}{4483}{0961}{5661}\@@_sep:
\@@_trig_small:ww
}
% \end{macrocode}
@@ -975,9 +975,9 @@
% floating point number with the given sign, and \cs{@@_sanitize:Nw}
% checks for overflow and underflow.
% \begin{macrocode}
-\cs_new:Npn \@@_sin_series_o:NNwwww #1#2#3. #4;
+\cs_new:Npn \@@_sin_series_o:NNwwww #1#2#3. #4\@@_sep:
{
- \@@_fixed_mul:wwn #4; #4;
+ \@@_fixed_mul:wwn #4\@@_sep: #4\@@_sep:
{
\exp_after:wN \@@_sin_series_aux_o:NNnwww
\exp_after:wN #1
@@ -990,7 +990,7 @@
{#3}
}
}
-\cs_new:Npn \@@_sin_series_aux_o:NNnwww #1#2#3 #4; #5,#6;
+\cs_new:Npn \@@_sin_series_aux_o:NNnwww #1#2#3 #4\@@_sep: #5,#6\@@_sep:
{
\if_int_odd:w \@@_int_eval:w #3 / 2 \@@_int_eval_end:
\exp_after:wN \use_i:nn
@@ -998,29 +998,46 @@
\exp_after:wN \use_ii:nn
\fi:
{ % 1/18!
- \@@_fixed_mul_sub_back:wwwn {0000}{0000}{0000}{0001}{5619}{2070};
- #4;{0000}{0000}{0000}{0477}{9477}{3324};
- \@@_fixed_mul_sub_back:wwwn #4;{0000}{0000}{0011}{4707}{4559}{7730};
- \@@_fixed_mul_sub_back:wwwn #4;{0000}{0000}{2087}{6756}{9878}{6810};
- \@@_fixed_mul_sub_back:wwwn #4;{0000}{0027}{5573}{1922}{3985}{8907};
- \@@_fixed_mul_sub_back:wwwn #4;{0000}{2480}{1587}{3015}{8730}{1587};
- \@@_fixed_mul_sub_back:wwwn #4;{0013}{8888}{8888}{8888}{8888}{8889};
- \@@_fixed_mul_sub_back:wwwn #4;{0416}{6666}{6666}{6666}{6666}{6667};
- \@@_fixed_mul_sub_back:wwwn #4;{5000}{0000}{0000}{0000}{0000}{0000};
- \@@_fixed_mul_sub_back:wwwn#4;{10000}{0000}{0000}{0000}{0000}{0000};
+ \@@_fixed_mul_sub_back:wwwn {0000}{0000}{0000}{0001}{5619}{2070}\@@_sep:
+ #4\@@_sep:
+ {0000}{0000}{0000}{0477}{9477}{3324}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #4\@@_sep:
+ {0000}{0000}{0011}{4707}{4559}{7730}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #4\@@_sep:
+ {0000}{0000}{2087}{6756}{9878}{6810}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #4\@@_sep:
+ {0000}{0027}{5573}{1922}{3985}{8907}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #4\@@_sep:
+ {0000}{2480}{1587}{3015}{8730}{1587}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #4\@@_sep:
+ {0013}{8888}{8888}{8888}{8888}{8889}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #4\@@_sep:
+ {0416}{6666}{6666}{6666}{6666}{6667}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #4\@@_sep:
+ {5000}{0000}{0000}{0000}{0000}{0000}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn#4\@@_sep:
+ {10000}{0000}{0000}{0000}{0000}{0000}\@@_sep:
{ \@@_fixed_continue:wn 0, }
}
{ % 1/17!
- \@@_fixed_mul_sub_back:wwwn {0000}{0000}{0000}{0028}{1145}{7254};
- #4;{0000}{0000}{0000}{7647}{1637}{3182};
- \@@_fixed_mul_sub_back:wwwn #4;{0000}{0000}{0160}{5904}{3836}{8216};
- \@@_fixed_mul_sub_back:wwwn #4;{0000}{0002}{5052}{1083}{8544}{1719};
- \@@_fixed_mul_sub_back:wwwn #4;{0000}{0275}{5731}{9223}{9858}{9065};
- \@@_fixed_mul_sub_back:wwwn #4;{0001}{9841}{2698}{4126}{9841}{2698};
- \@@_fixed_mul_sub_back:wwwn #4;{0083}{3333}{3333}{3333}{3333}{3333};
- \@@_fixed_mul_sub_back:wwwn #4;{1666}{6666}{6666}{6666}{6666}{6667};
- \@@_fixed_mul_sub_back:wwwn#4;{10000}{0000}{0000}{0000}{0000}{0000};
- { \@@_ep_mul:wwwwn 0, } #5,#6;
+ \@@_fixed_mul_sub_back:wwwn {0000}{0000}{0000}{0028}{1145}{7254}\@@_sep:
+ #4\@@_sep:
+ {0000}{0000}{0000}{7647}{1637}{3182}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #4\@@_sep:
+ {0000}{0000}{0160}{5904}{3836}{8216}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #4\@@_sep:
+ {0000}{0002}{5052}{1083}{8544}{1719}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #4\@@_sep:
+ {0000}{0275}{5731}{9223}{9858}{9065}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #4\@@_sep:
+ {0001}{9841}{2698}{4126}{9841}{2698}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #4\@@_sep:
+ {0083}{3333}{3333}{3333}{3333}{3333}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #4\@@_sep:
+ {1666}{6666}{6666}{6666}{6666}{6667}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn#4\@@_sep:
+ {10000}{0000}{0000}{0000}{0000}{0000}\@@_sep:
+ { \@@_ep_mul:wwwwn 0, } #5,#6\@@_sep:
}
{
\exp_after:wN \@@_sanitize:Nw
@@ -1064,9 +1081,9 @@
% before computing the ratio. Note that this \cs{if_int_odd:w} test
% relies on the fact that the octant is at least~$1$.
% \begin{macrocode}
-\cs_new:Npn \@@_tan_series_o:NNwwww #1#2#3. #4;
+\cs_new:Npn \@@_tan_series_o:NNwwww #1#2#3. #4\@@_sep:
{
- \@@_fixed_mul:wwn #4; #4;
+ \@@_fixed_mul:wwn #4\@@_sep: #4\@@_sep:
{
\exp_after:wN \@@_tan_series_aux_o:Nnwww
\int_value:w
@@ -1077,22 +1094,32 @@
{#3}
}
}
-\cs_new:Npn \@@_tan_series_aux_o:Nnwww #1 #2 #3; #4,#5;
+\cs_new:Npn \@@_tan_series_aux_o:Nnwww #1 #2 #3\@@_sep: #4,#5\@@_sep:
{
- \@@_fixed_mul_sub_back:wwwn {0000}{0000}{1527}{3493}{0856}{7059};
- #3; {0000}{0159}{6080}{0274}{5257}{6472};
- \@@_fixed_mul_sub_back:wwwn #3; {0002}{4571}{2320}{0157}{2558}{8481};
- \@@_fixed_mul_sub_back:wwwn #3; {0115}{5830}{7533}{5397}{3168}{2147};
- \@@_fixed_mul_sub_back:wwwn #3; {1929}{8245}{6140}{3508}{7719}{2982};
- \@@_fixed_mul_sub_back:wwwn #3;{10000}{0000}{0000}{0000}{0000}{0000};
- { \@@_ep_mul:wwwwn 0, } #4,#5;
+ \@@_fixed_mul_sub_back:wwwn {0000}{0000}{1527}{3493}{0856}{7059}\@@_sep:
+ #3\@@_sep:
+ {0000}{0159}{6080}{0274}{5257}{6472}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #3\@@_sep:
+ {0002}{4571}{2320}{0157}{2558}{8481}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #3\@@_sep:
+ {0115}{5830}{7533}{5397}{3168}{2147}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #3\@@_sep:
+ {1929}{8245}{6140}{3508}{7719}{2982}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #3\@@_sep:
+ {10000}{0000}{0000}{0000}{0000}{0000}\@@_sep:
+ { \@@_ep_mul:wwwwn 0, } #4,#5\@@_sep:
{
- \@@_fixed_mul_sub_back:wwwn {0000}{0007}{0258}{0681}{9408}{4706};
- #3;{0000}{2343}{7175}{1399}{6151}{7670};
- \@@_fixed_mul_sub_back:wwwn #3;{0019}{2638}{4588}{9232}{8861}{3691};
- \@@_fixed_mul_sub_back:wwwn #3;{0536}{6357}{0691}{4344}{6852}{4252};
- \@@_fixed_mul_sub_back:wwwn #3;{5263}{1578}{9473}{6842}{1052}{6315};
- \@@_fixed_mul_sub_back:wwwn#3;{10000}{0000}{0000}{0000}{0000}{0000};
+ \@@_fixed_mul_sub_back:wwwn {0000}{0007}{0258}{0681}{9408}{4706}\@@_sep:
+ #3\@@_sep:
+ {0000}{2343}{7175}{1399}{6151}{7670}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #3\@@_sep:
+ {0019}{2638}{4588}{9232}{8861}{3691}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #3\@@_sep:
+ {0536}{6357}{0691}{4344}{6852}{4252}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn #3\@@_sep:
+ {5263}{1578}{9473}{6842}{1052}{6315}\@@_sep:
+ \@@_fixed_mul_sub_back:wwwn#3\@@_sep:
+ {10000}{0000}{0000}{0000}{0000}{0000}\@@_sep:
{
\reverse_if:N \if_int_odd:w
\@@_int_eval:w (#2 - 1) / 2 \@@_int_eval_end:
@@ -1220,7 +1247,7 @@
% \cs{@@_acotii_o:ww} simply reverses its two arguments.
% \begin{macrocode}
\cs_new:Npn \@@_atanii_o:Nww
- #1 \s_@@ \@@_chk:w #2#3#4; \s_@@ \@@_chk:w #5 #6 @
+ #1 \s_@@ \@@_chk:w #2#3#4\@@_sep: \s_@@ \@@_chk:w #5 #6 @
{
\if_meaning:w 3 #2 \@@_case_return_i_o:ww \fi:
\if_meaning:w 3 #5 \@@_case_return_ii_o:ww \fi:
@@ -1236,11 +1263,11 @@
\or: \@@_case_return:nw { \@@_atan_inf_o:NNNw #1 #3 0 }
\fi:
\@@_atan_normal_o:NNnwNnw #1
- \s_@@ \@@_chk:w #2#3#4;
+ \s_@@ \@@_chk:w #2#3#4\@@_sep:
\s_@@ \@@_chk:w #5 #6
}
-\cs_new:Npn \@@_acotii_o:Nww #1#2; #3;
- { \@@_atanii_o:Nww #1#3; #2; }
+\cs_new:Npn \@@_acotii_o:Nww #1#2\@@_sep: #3\@@_sep:
+ { \@@_atanii_o:Nww #1#3\@@_sep: #2\@@_sep: }
% \end{macrocode}
% \end{macro}
%
@@ -1257,15 +1284,15 @@
% is positive, and $[(7-|#3|)/2]\cdot\pi/4$ for negative~$x$, where
% the divisions are rounded up.
% \begin{macrocode}
-\cs_new:Npn \@@_atan_inf_o:NNNw #1#2#3 \s_@@ \@@_chk:w #4#5#6;
+\cs_new:Npn \@@_atan_inf_o:NNNw #1#2#3 \s_@@ \@@_chk:w #4#5#6\@@_sep:
{
\exp_after:wN \@@_atan_combine_o:NwwwwwN
\exp_after:wN #2
\int_value:w \@@_int_eval:w
- \if_meaning:w 2 #5 7 - \fi: #3 \exp_after:wN ;
+ \if_meaning:w 2 #5 7 - \fi: #3 \exp_after:wN \@@_sep:
\c_@@_one_fixed_tl
- {0000}{0000}{0000}{0000}{0000}{0000};
- 0,{0000}{0000}{0000}{0000}{0000}{0000}; #1
+ {0000}{0000}{0000}{0000}{0000}{0000}\@@_sep:
+ 0,{0000}{0000}{0000}{0000}{0000}{0000}\@@_sep: #1
}
% \end{macrocode}
% \end{macro}
@@ -1279,11 +1306,11 @@
% intermediate rounding errors.
% \begin{macrocode}
\cs_new_protected:Npn \@@_atan_normal_o:NNnwNnw
- #1 \s_@@ \@@_chk:w 1#2#3#4; \s_@@ \@@_chk:w 1#5#6#7;
+ #1 \s_@@ \@@_chk:w 1#2#3#4\@@_sep: \s_@@ \@@_chk:w 1#5#6#7\@@_sep:
{
\@@_atan_test_o:NwwNwwN
- #2 #3, #4{0000}{0000};
- #5 #6, #7{0000}{0000}; #1
+ #2 #3, #4{0000}{0000}\@@_sep:
+ #5 #6, #7{0000}{0000}\@@_sep: #1
}
% \end{macrocode}
% \end{macro}
@@ -1304,7 +1331,7 @@
% two numbers. The finer test with $0.41421$ is done by
% \cs{@@_atan_div:wnwwnw} after the operands have been ordered.
% \begin{macrocode}
-\cs_new:Npn \@@_atan_test_o:NwwNwwN #1#2,#3; #4#5,#6;
+\cs_new:Npn \@@_atan_test_o:NwwNwwN #1#2,#3\@@_sep: #4#5,#6\@@_sep:
{
\exp_after:wN \@@_atan_combine_o:NwwwwwN
\exp_after:wN #1
@@ -1313,11 +1340,11 @@
7 - \@@_int_eval:w
\fi:
\if_int_compare:w
- \@@_ep_compare:wwww #2,#3; #5,#6; > \c_zero_int
+ \@@_ep_compare:wwww #2,#3\@@_sep: #5,#6\@@_sep: > \c_zero_int
3 -
\exp_after:wN \@@_reverse_args:Nww
\fi:
- \@@_atan_div:wnwwnw #2,#3; #5,#6;
+ \@@_atan_div:wnwwnw #2,#3\@@_sep: #5,#6\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -1337,7 +1364,7 @@
% followed by~$z$, as a comma-delimited exponent and a fixed point
% number.
% \begin{macrocode}
-\cs_new:Npn \@@_atan_div:wnwwnw #1,#2#3; #4,#5#6;
+\cs_new:Npn \@@_atan_div:wnwwnw #1,#2#3\@@_sep: #4,#5#6\@@_sep:
{
\if_int_compare:w
\@@_int_eval:w 41421 * #5 < #2 000
@@ -1347,20 +1374,20 @@
\exp_after:wN \@@_atan_near:wwwn
\fi:
0
- \@@_ep_div:wwwwn #1,{#2}#3; #4,{#5}#6;
+ \@@_ep_div:wwwwn #1,{#2}#3\@@_sep: #4,{#5}#6\@@_sep:
\@@_atan_auxi:ww
}
\cs_new:Npn \@@_atan_near:wwwn
- 0 \@@_ep_div:wwwwn #1,#2; #3,
+ 0 \@@_ep_div:wwwwn #1,#2\@@_sep: #3,
{
1
- \@@_ep_to_fixed:wwn #1 - #3, #2;
+ \@@_ep_to_fixed:wwn #1 - #3, #2\@@_sep:
\@@_atan_near_aux:wwn
}
-\cs_new:Npn \@@_atan_near_aux:wwn #1; #2;
+\cs_new:Npn \@@_atan_near_aux:wwn #1\@@_sep: #2\@@_sep:
{
- \@@_fixed_add:wwn #1; #2;
- { \@@_fixed_sub:wwn #2; #1; { \@@_ep_div:wwwwn 0, } 0, }
+ \@@_fixed_add:wwn #1\@@_sep: #2\@@_sep:
+ { \@@_fixed_sub:wwn #2\@@_sep: #1\@@_sep: { \@@_ep_div:wwwwn 0, } 0, }
}
% \end{macrocode}
% \end{macro}
@@ -1372,16 +1399,16 @@
% call to \cs{@@_atan_Taylor_loop:www}, followed by the fixed point
% representation of~$z$ and the old representation.
% \begin{macrocode}
-\cs_new:Npn \@@_atan_auxi:ww #1,#2;
- { \@@_ep_to_fixed:wwn #1,#2; \@@_atan_auxii:w #1,#2; }
-\cs_new:Npn \@@_atan_auxii:w #1;
+\cs_new:Npn \@@_atan_auxi:ww #1,#2\@@_sep:
+ { \@@_ep_to_fixed:wwn #1,#2\@@_sep: \@@_atan_auxii:w #1,#2\@@_sep: }
+\cs_new:Npn \@@_atan_auxii:w #1\@@_sep:
{
- \@@_fixed_mul:wwn #1; #1;
+ \@@_fixed_mul:wwn #1\@@_sep: #1\@@_sep:
{
- \@@_atan_Taylor_loop:www 39 ;
- {0000}{0000}{0000}{0000}{0000}{0000} ;
+ \@@_atan_Taylor_loop:www 39 \@@_sep:
+ {0000}{0000}{0000}{0000}{0000}{0000} \@@_sep:
}
- ! #1;
+ ! #1\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -1398,22 +1425,22 @@
% computing the octant with a semicolon, and leave the result~|#2|
% afterwards.
% \begin{macrocode}
-\cs_new:Npn \@@_atan_Taylor_loop:www #1; #2; #3;
+\cs_new:Npn \@@_atan_Taylor_loop:www #1\@@_sep: #2\@@_sep: #3\@@_sep:
{
\if_int_compare:w #1 = - \c_one_int
\@@_atan_Taylor_break:w
\fi:
- \exp_after:wN \@@_fixed_div_int:wwN \c_@@_one_fixed_tl #1;
- \@@_rrot:www \@@_fixed_mul_sub_back:wwwn #2; #3;
+ \exp_after:wN \@@_fixed_div_int:wwN \c_@@_one_fixed_tl #1\@@_sep:
+ \@@_rrot:www \@@_fixed_mul_sub_back:wwwn #2\@@_sep: #3\@@_sep:
{
\exp_after:wN \@@_atan_Taylor_loop:www
- \int_value:w \@@_int_eval:w #1 - 2 ;
+ \int_value:w \@@_int_eval:w #1 - 2 \@@_sep:
}
- #3;
+ #3\@@_sep:
}
\cs_new:Npn \@@_atan_Taylor_break:w
- \fi: #1 \@@_fixed_mul_sub_back:wwwn #2; #3 !
- { \fi: ; #2 ; }
+ \fi: #1 \@@_fixed_mul_sub_back:wwwn #2\@@_sep: #3 !
+ { \fi: \@@_sep: #2 \@@_sep: }
% \end{macrocode}
% \end{macro}
%
@@ -1442,7 +1469,8 @@
% both cases, convert to a floating point with
% \cs{@@_fixed_to_float_o:wN}.
% \begin{macrocode}
-\cs_new:Npn \@@_atan_combine_o:NwwwwwN #1 #2; #3; #4; #5,#6; #7
+\cs_new:Npn \@@_atan_combine_o:NwwwwwN
+ #1 #2\@@_sep: #3\@@_sep: #4\@@_sep: #5,#6\@@_sep: #7
{
\exp_after:wN \@@_sanitize:Nw
\exp_after:wN #1
@@ -1452,22 +1480,22 @@
\else:
\exp_after:wN \use_ii:nn
\fi:
- { #5 \@@_fixed_mul:wwn #3; #6; }
+ { #5 \@@_fixed_mul:wwn #3\@@_sep: #6\@@_sep: }
{
- \@@_fixed_mul:wwn #3; #4;
+ \@@_fixed_mul:wwn #3\@@_sep: #4\@@_sep:
{
\exp_after:wN \@@_atan_combine_aux:ww
- \int_value:w \@@_int_eval:w #2 / 2 ; #2;
+ \int_value:w \@@_int_eval:w #2 / 2 \@@_sep: #2\@@_sep:
}
}
{ #7 \@@_fixed_to_float_o:wN \@@_fixed_to_float_rad_o:wN }
#1
}
-\cs_new:Npn \@@_atan_combine_aux:ww #1; #2;
+\cs_new:Npn \@@_atan_combine_aux:ww #1\@@_sep: #2\@@_sep:
{
\@@_fixed_mul_short:wwn
- {7853}{9816}{3397}{4483}{0961}{5661};
- {#1}{0000}{0000};
+ {7853}{9816}{3397}{4483}{0961}{5661}\@@_sep:
+ {#1}{0000}{0000}\@@_sep:
{
\if_int_odd:w #2 \exp_stop_f:
\exp_after:wN \@@_fixed_sub:wwn
@@ -1491,7 +1519,7 @@
% about what function is being performed (for \enquote{invalid operation}
% exceptions).
% \begin{macrocode}
-\cs_new:Npn \@@_asin_o:w #1 \s_@@ \@@_chk:w #2#3; @
+\cs_new:Npn \@@_asin_o:w #1 \s_@@ \@@_chk:w #2#3\@@_sep: @
{
\if_case:w #2 \exp_stop_f:
\@@_case_return_same_o:w
@@ -1504,7 +1532,7 @@
\else:
\@@_case_return_same_o:w
\fi:
- \s_@@ \@@_chk:w #2 #3;
+ \s_@@ \@@_chk:w #2 #3\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -1517,7 +1545,7 @@
% \texttt{acos} or \texttt{acosd}, and preparing to swap some
% arguments down the line.
% \begin{macrocode}
-\cs_new:Npn \@@_acos_o:w #1 \s_@@ \@@_chk:w #2#3; @
+\cs_new:Npn \@@_acos_o:w #1 \s_@@ \@@_chk:w #2#3\@@_sep: @
{
\if_case:w #2 \exp_stop_f:
\@@_case_use:nw { \@@_atan_inf_o:NNNw #1 0 4 }
@@ -1533,7 +1561,7 @@
\else:
\@@_case_return_same_o:w
\fi:
- \s_@@ \@@_chk:w #2 #3;
+ \s_@@ \@@_chk:w #2 #3\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -1550,7 +1578,7 @@
% outside the domain of arcsine or arccosine.
% \begin{macrocode}
\cs_new:Npn \@@_asin_normal_o:NfwNnnnnw
- #1#2#3 \s_@@ \@@_chk:w 1#4#5#6#7#8#9;
+ #1#2#3 \s_@@ \@@_chk:w 1#4#5#6#7#8#9\@@_sep:
{
\if_int_compare:w #5 < \c_one_int
\exp_after:wN \@@_use_none_until_s:w
@@ -1560,9 +1588,9 @@
\fi:
\@@_use_i:ww
\@@_invalid_operation_o:fw {#2}
- \s_@@ \@@_chk:w 1#4{#5}{#6}{#7}{#8}{#9};
+ \s_@@ \@@_chk:w 1#4{#5}{#6}{#7}{#8}{#9}\@@_sep:
\@@_asin_auxi_o:NnNww
- #1 {#3} #4 #5,{#6}{#7}{#8}{#9}{0000}{0000};
+ #1 {#3} #4 #5,{#6}{#7}{#8}{#9}{0000}{0000}\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -1585,21 +1613,21 @@
% function requires normalized arguments, hence the need for
% \texttt{ep_to_ep} and \texttt{continue} after \texttt{ep_mul}.
% \begin{macrocode}
-\cs_new:Npn \@@_asin_auxi_o:NnNww #1#2#3#4,#5;
+\cs_new:Npn \@@_asin_auxi_o:NnNww #1#2#3#4,#5\@@_sep:
{
- \@@_ep_to_fixed:wwn #4,#5;
+ \@@_ep_to_fixed:wwn #4,#5\@@_sep:
\@@_asin_isqrt:wn
- \@@_ep_mul:wwwwn #4,#5;
+ \@@_ep_mul:wwwwn #4,#5\@@_sep:
\@@_ep_to_ep:wwN
\@@_fixed_continue:wn
{ #2 \@@_atan_test_o:NwwNwwN #3 }
- 0 1,{1000}{0000}{0000}{0000}{0000}{0000}; #1
+ 0 1,{1000}{0000}{0000}{0000}{0000}{0000}\@@_sep: #1
}
-\cs_new:Npn \@@_asin_isqrt:wn #1;
+\cs_new:Npn \@@_asin_isqrt:wn #1\@@_sep:
{
- \exp_after:wN \@@_fixed_sub:wwn \c_@@_one_fixed_tl #1;
+ \exp_after:wN \@@_fixed_sub:wwn \c_@@_one_fixed_tl #1\@@_sep:
{
- \@@_fixed_add_one:wN #1;
+ \@@_fixed_add_one:wN #1\@@_sep:
\@@_fixed_continue:wn { \@@_ep_mul:wwwwn 0, } 0,
}
\@@_ep_isqrt:wwn
@@ -1619,7 +1647,7 @@
% tests, keeping the function name (\texttt{acsc} or \texttt{acscd})
% as an argument for invalid operation exceptions.
% \begin{macrocode}
-\cs_new:Npn \@@_acsc_o:w #1 \s_@@ \@@_chk:w #2#3#4; @
+\cs_new:Npn \@@_acsc_o:w #1 \s_@@ \@@_chk:w #2#3#4\@@_sep: @
{
\if_case:w \if_meaning:w 2 #2 #3 \fi: #2 \exp_stop_f:
\@@_case_use:nw
@@ -1630,7 +1658,7 @@
\or: \@@_case_return_same_o:w
\else: \@@_case_return_o:Nw \c_minus_zero_fp
\fi:
- \s_@@ \@@_chk:w #2 #3 #4;
+ \s_@@ \@@_chk:w #2 #3 #4\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -1644,7 +1672,7 @@
% \cs{@@_reverse_args:Nww} following precisely that appearing in
% \cs{@@_acos_o:w}.
% \begin{macrocode}
-\cs_new:Npn \@@_asec_o:w #1 \s_@@ \@@_chk:w #2#3; @
+\cs_new:Npn \@@_asec_o:w #1 \s_@@ \@@_chk:w #2#3\@@_sep: @
{
\if_case:w #2 \exp_stop_f:
\@@_case_use:nw
@@ -1658,7 +1686,7 @@
\or: \@@_case_use:nw { \@@_atan_inf_o:NNNw #1 0 4 }
\else: \@@_case_return_same_o:w
\fi:
- \s_@@ \@@_chk:w #2 #3;
+ \s_@@ \@@_chk:w #2 #3\@@_sep:
}
% \end{macrocode}
% \end{macro}
@@ -1672,17 +1700,17 @@
% $\operatorname{acsc}(x)=\operatorname{asin}(1/x)$ and
% $\operatorname{asec}(x)=\operatorname{acos}(1/x)$.
% \begin{macrocode}
-\cs_new:Npn \@@_acsc_normal_o:NfwNnw #1#2#3 \s_@@ \@@_chk:w 1#4#5#6;
+\cs_new:Npn \@@_acsc_normal_o:NfwNnw #1#2#3 \s_@@ \@@_chk:w 1#4#5#6\@@_sep:
{
\int_compare:nNnTF {#5} < 1
{
\@@_invalid_operation_o:fw {#2}
- \s_@@ \@@_chk:w 1#4{#5}#6;
+ \s_@@ \@@_chk:w 1#4{#5}#6\@@_sep:
}
{
\@@_ep_div:wwwwn
- 1,{1000}{0000}{0000}{0000}{0000}{0000};
- #5,#6{0000}{0000};
+ 1,{1000}{0000}{0000}{0000}{0000}{0000}\@@_sep:
+ #5,#6{0000}{0000}\@@_sep:
{ \@@_asin_auxi_o:NnNww #1 {#3} #4 }
}
}
diff --git a/macros/latex-dev/required/l3kernel/l3fp-types.dtx b/macros/latex-dev/required/l3kernel/l3fp-types.dtx
index e9269e1f03..613890919f 100644
--- a/macros/latex-dev/required/l3kernel/l3fp-types.dtx
+++ b/macros/latex-dev/required/l3kernel/l3fp-types.dtx
@@ -42,7 +42,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -153,7 +153,7 @@
\exp_last_unbraced:Nf \@@_types_binary_auxi:Nww
{ \@@_types_cs_to_op:N #1 }
}
-\cs_new:Npn \@@_types_binary_auxi:Nww #1#2#3; #4#5; @
+\cs_new:Npn \@@_types_binary_auxi:Nww #1#2#3\@@_sep: #4#5\@@_sep: @
{
\exp_after:wN \@@_types_binary_auxii:NNww
\cs:w
@@ -163,7 +163,7 @@
\@@_type_from_scan:N #4
_o:ww
\cs_end:
- #1 #2#3; #4#5;
+ #1 #2#3\@@_sep: #4#5\@@_sep:
}
\cs_new:Npn \@@_types_binary_auxii:NNww #1#2
{
diff --git a/macros/latex-dev/required/l3kernel/l3fp.dtx b/macros/latex-dev/required/l3kernel/l3fp.dtx
index d273b057ea..045f66200a 100644
--- a/macros/latex-dev/required/l3kernel/l3fp.dtx
+++ b/macros/latex-dev/required/l3kernel/l3fp.dtx
@@ -2,7 +2,7 @@
%
%% File: l3fp.dtx
%
-% Copyright (C) 2011-2024 The LaTeX Project
+% Copyright (C) 2011-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -49,7 +49,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -59,8 +59,8 @@
% separate exponent. The module implements expandably a wide set of
% arithmetic, trigonometric, and other operations on decimal floating point
% numbers, to be used within floating point expressions. \emph{Floating point
-% expressions} (\enquote{\meta{fp expr}}) support the following operations with their usual
-% precedence.
+% expressions} (\enquote{\meta{fp expr}}) support the following operations with
+% their usual precedence.
% \begin{itemize}
% \item Basic arithmetic: addition $x+y$, subtraction $x-y$,
% multiplication $x*y$, division $x/y$, square root~$\sqrt{x}$,
@@ -108,7 +108,8 @@
% towards $+\infty$ if $t>0$ and towards $-\infty$ if $t<0$.
% \end{itemize}
% And \emph{(not yet)} modulo, and \enquote{quantize}.
-% \item Random numbers: $\mathop{rand}()$, $\mathop{randint}(m,n)$.
+% \item Random numbers: $\operatorname{rand}()$,
+% $\operatorname{randint}(m,n)$.
% \item Constants: \texttt{pi}, \texttt{deg} (one degree in radians).
% \item Dimensions, automatically expressed in points, \emph{e.g.},
% \texttt{pc} is~$12$.
@@ -124,9 +125,9 @@
% as |1.234e-34|, or |-.0001|), or as a stored floating point variable,
% which is automatically replaced by its current value.
% A \enquote{floating point} is a floating point number or a tuple thereof. See
-% section~\ref{sec:l3fp:fp-floats} for a description of what a floating point is,
-% section~\ref{sec:l3fp:fp-precedence} for details about how an expression is
-% parsed, and section~\ref{sec:l3fp:fp-operations} to know what the various
+% section~\ref{sec:l3fp:fp-floats} for a description of what a floating point
+% is, section~\ref{sec:l3fp:fp-precedence} for details about how an expression
+% is parsed, and section~\ref{sec:l3fp:fp-operations} to know what the various
% operations do. Some operations may raise exceptions (error messages),
% described in section~\ref{sec:l3fp:fp-exceptions}.
%
@@ -198,7 +199,10 @@
% \section{Setting floating point variables}
%
% \begin{function}[updated = 2012-05-08, tested = m3fp002]
-% {\fp_set:Nn, \fp_set:cn, \fp_gset:Nn, \fp_gset:cn}
+% {
+% \fp_set:Nn, \fp_set:cn, \fp_set:NV, \fp_set:cV,
+% \fp_gset:Nn, \fp_gset:cn, \fp_gset:NV, \fp_gset:cV
+% }
% \begin{syntax}
% \cs{fp_set:Nn} \meta{fp~var} \Arg{fp expr}
% \end{syntax}
@@ -254,7 +258,8 @@
% integers are expressed without a decimal separator. The values
% $\pm\infty$ and \nan{} trigger an \enquote{invalid operation}
% exception.
-% For a tuple, each item is converted using \cs{fp_eval:n} and they are combined as
+% For a tuple, each item is converted using \cs{fp_eval:n} and they are
+% combined as
% |(|\meta{fp_1}\verb*|, |\meta{fp_2}\verb*|, |\ldots{}\meta{fp_n}|)|
% if $n>1$ and |(|\meta{fp_1}|,)| or |()| for fewer items.
% This function is identical to \cs{fp_to_decimal:n}.
@@ -285,7 +290,8 @@
% integers are expressed without a decimal separator. The values
% $\pm\infty$ and~\nan{} trigger an \enquote{invalid operation}
% exception.
-% For a tuple, each item is converted using \cs{fp_to_decimal:n} and they are combined as
+% For a tuple, each item is converted using \cs{fp_to_decimal:n} and they are
+% combined as
% |(|\meta{fp_1}\verb*|, |\meta{fp_2}\verb*|, |\ldots{}\meta{fp_n}|)|
% if $n>1$ and |(|\meta{fp_1}|,)| or |()| for fewer items.
% \end{function}
@@ -337,7 +343,8 @@
% The values $\pm\infty$ and~\nan{} trigger an \enquote{invalid
% operation} exception. Normal category codes apply: thus the |e| is
% category code~$11$ (a letter).
-% For a tuple, each item is converted using \cs{fp_to_scientific:n} and they are combined as
+% For a tuple, each item is converted using \cs{fp_to_scientific:n} and they
+% are combined as
% |(|\meta{fp_1}\verb*|, |\meta{fp_2}\verb*|, |\ldots{}\meta{fp_n}|)|
% if $n>1$ and |(|\meta{fp_1}|,)| or |()| for fewer items.
% \end{function}
@@ -361,7 +368,8 @@
% |0|, |-0|, \texttt{inf}, \texttt{-inf}, and~\texttt{nan}
% respectively. Normal category codes apply and thus \texttt{inf} or
% \texttt{nan}, if produced, are made up of letters.
-% For a tuple, each item is converted using \cs{fp_to_tl:n} and they are combined as
+% For a tuple, each item is converted using \cs{fp_to_tl:n} and they are
+% combined as
% |(|\meta{fp_1}\verb*|, |\meta{fp_2}\verb*|, |\ldots{}\meta{fp_n}|)|
% if $n>1$ and |(|\meta{fp_1}|,)| or |()| for fewer items.
% \end{function}
@@ -377,7 +385,8 @@
% exponent. Non-significant trailing zeros are trimmed. Integers are
% expressed without a decimal separator. The values $\pm\infty$
% and~\nan{} trigger an \enquote{invalid operation} exception.
-% For a tuple, each item is converted using \cs{fp_to_decimal:n} and they are combined as
+% For a tuple, each item is converted using \cs{fp_to_decimal:n} and they are
+% combined as
% |(|\meta{fp_1}\verb*|, |\meta{fp_2}\verb*|, |\ldots{}\meta{fp_n}|)|
% if $n>1$ and |(|\meta{fp_1}|,)| or |()| for fewer items.
% This function is identical to \cs{fp_to_decimal:N}.
@@ -773,9 +782,9 @@
% The result may contain other functions, which are
% then replaced by their results if they have any. For instance,
% \begin{quote}
-% \cs{fp_new_function:n} |{ foo }| \\
+% \cs{fp_new_function:n} |{ npow }| \\
% \cs{fp_set_function:nnn} |{ npow } { a,b } { a**b }| \\
-% \cs{fp_show:n} |{ npow(16,0.25) } }|
+% \cs{fp_show:n} |{ npow(16,0.25) }|
% \end{quote}
% shows |2|. The names of the \meta{vars} must
% consist entirely of Latin letters |[a-zA-Z]|, but are otherwise not
@@ -904,7 +913,6 @@
% the \TeX{} run and display some information about the current
% operation in the terminal.
% \end{itemize}
-% \emph{This function is experimental, and may be altered or removed.}
% \end{function}
%
% \begin{variable}
@@ -993,7 +1001,8 @@
% valid floating point numbers. Note that the latter could be mistaken
% with the difference of \enquote{\texttt{e}} and $1$. To avoid
% confusions, the base of natural logarithms cannot be input as |e| and
-% should be input as \texttt{exp(1)} or \cs[module = fp]{c_e_fp} (which is faster).
+% should be input as \texttt{exp(1)} or \cs[module = fp]{c_e_fp} (which is
+% faster).
%
% Special numbers are input as follows:
% \begin{itemize}
@@ -1022,7 +1031,8 @@
% \item Unary |+|, |-|, |!|.
% \item Implicit multiplication by juxtaposition (\texttt{2pi})
% when neither factor is in parentheses.
-% \item Binary |*| and |/|, implicit multiplication by juxtaposition with parentheses (for instance \texttt{3(4+5)}).
+% \item Binary |*| and |/|, implicit multiplication by juxtaposition with
+% parentheses (for instance \texttt{3(4+5)}).
% \item Binary |+| and |-|.
% \item Comparisons |>=|, |!=|, |<?|, \emph{etc}.
% \item Logical \texttt{and}, denoted by |&&|.
@@ -1059,9 +1069,10 @@
% \cs{fp_eval:n} \{ \meta{operand_1} |?| \meta{operand_2} |:| \meta{operand_3} \}
% \end{syntax}
% The ternary operator |?:| results in \meta{operand_2} if
-% \meta{operand_1} is true (not $\pm 0$), and \meta{operand_3} if \meta{operand_1}
-% is false ($\pm 0$). All three \meta{operands} are evaluated in all
-% cases; they may be tuples. The operator is right associative, hence
+% \meta{operand_1} is true (not $\pm 0$), and \meta{operand_3} if
+% \meta{operand_1} is false ($\pm 0$). All three \meta{operands} are
+% evaluated in all cases; they may be tuples. The operator is right
+% associative, hence
% \begin{verbatim}
% \fp_eval:n
% {
@@ -1260,11 +1271,11 @@
% \cs{fp_eval:n} \{ |round| |(| \meta{fp expr_1} , \meta{fp expr_2} , \meta{fp expr_3} |)| \}
% \end{syntax}
% Only |round| accepts a third argument.
-% Evaluates $\meta{fp expr_1}=x$ and $\meta{fp expr_2}=n$ and $\meta{fp expr_3}=t$ then rounds
-% $x$~to $n$~places. If $n$~is an integer, this rounds~$x$ to a
-% multiple of~$10^{-n}$; if $n=+\infty$, this always yields~$x$; if
-% $n=-\infty$, this yields one of $\pm 0$, $\pm\infty$, or~\nan{}; if
-% $n=\nan{}$, this yields \nan{}; if
+% Evaluates $\meta{fp expr_1}=x$ and $\meta{fp expr_2}=n$ and $\meta{fp
+% expr_3}=t$ then rounds $x$~to $n$~places. If $n$~is an integer, this
+% rounds~$x$ to a multiple of~$10^{-n}$; if $n=+\infty$, this always
+% yields~$x$; if $n=-\infty$, this yields one of $\pm 0$, $\pm\infty$,
+% or~\nan{}; if $n=\nan{}$, this yields \nan{}; if
% $n$~is neither $\pm\infty$ nor an integer, then an \enquote{invalid
% operation} exception is raised. When \meta{fp expr_2} is omitted,
% $n=0$, \emph{i.e.}, \meta{fp expr_1} is rounded to an integer. The
@@ -1275,8 +1286,8 @@
% as follows. If $t$ is \texttt{nan} (or not given) the even
% multiple is chosen (\enquote{ties to even}), if $t=\pm 0$ the
% multiple closest to $0$ is chosen (\enquote{ties to zero}),
-% if $t$ is positive/negative the multiple closest to $\infty$/$-\infty$ is chosen
-% (\enquote{ties towards positive/negative infinity}).
+% if $t$ is positive/negative the multiple closest to $\infty$/$-\infty$
+% is chosen (\enquote{ties towards positive/negative infinity}).
% \item |floor| yields the largest
% multiple of~$10^{-n}$ smaller or equal to~$x$ (\enquote{round
% towards negative infinity});
@@ -1457,8 +1468,8 @@
% \cs{fp_eval:n} \{ |sqrt(| \meta{fp expr} |)| \}
% \end{syntax}
% Computes the square root of the \meta{fp expr}. The \enquote{invalid
-% operation} is raised when the \meta{fp expr} is negative or is a tuple; no other
-% exception can occur. Special values yield $\sqrt{-0} = -0$,
+% operation} is raised when the \meta{fp expr} is negative or is a tuple; no
+% other exception can occur. Special values yield $\sqrt{-0} = -0$,
% $\sqrt{+0} = +0$, $\sqrt{+\infty} = +\infty$ and
% $\sqrt{\text{\nan{}}}=\text{\nan{}}$.
% \end{function}
@@ -1500,8 +1511,9 @@
%
% \begin{variable}[tested = m3fp-parse001]{inf, nan}
% The special values $+\infty$, $-\infty$, and \nan{} are represented
-% as \texttt{inf}, \texttt{-inf} and \texttt{nan} (see \cs[module = fp]{c_inf_fp},
-% \cs[module = fp]{c_minus_inf_fp} and \cs[module = fp]{c_nan_fp}).
+% as \texttt{inf}, \texttt{-inf} and \texttt{nan} (see
+% \cs[module = fp]{c_inf_fp}, \cs[module = fp]{c_minus_inf_fp} and
+% \cs[module = fp]{c_nan_fp}).
% \end{variable}
%
% \begin{variable}[tested = m3fp-parse001]{pi}
diff --git a/macros/latex-dev/required/l3kernel/l3fparray.dtx b/macros/latex-dev/required/l3kernel/l3fparray.dtx
index f48de27af3..642e75c659 100644
--- a/macros/latex-dev/required/l3kernel/l3fparray.dtx
+++ b/macros/latex-dev/required/l3kernel/l3fparray.dtx
@@ -2,7 +2,7 @@
%
%% File: l3fparray.dtx
%
-% Copyright (C) 2018-2024 The LaTeX Project
+% Copyright (C) 2018-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -63,7 +63,7 @@
% \cs{fparray_new:Nn} \meta{fparray~var} \Arg{size}
% \end{syntax}
% Evaluates the integer expression \meta{size} and allocates an
-% \meta{floating point array variable} with that number of (zero)
+% \meta{fparray var} with that number of (zero)
% entries. The variable name should start with |\g_| because
% assignments are always global.
% \end{function}
@@ -72,7 +72,7 @@
% \begin{syntax}
% \cs{fparray_gzero:N} \meta{fparray~var}
% \end{syntax}
-% Sets all entries of the \meta{floating point array variable} to
+% Sets all entries of the \meta{fparray var} to
% $+0$. Assignments are always global.
% \end{function}
%
@@ -83,7 +83,7 @@
% \cs{fparray_gset:Nnn} \meta{fparray~var} \Arg{position} \Arg{value}
% \end{syntax}
% Stores the result of evaluating the floating point expression
-% \meta{value} into the \meta{floating point array variable} at the
+% \meta{value} into the \meta{fparray var} at the
% (integer expression) \meta{position}. If the \meta{position} is not
% between $1$ and the \cs{fparray_count:N}, an error occurs.
% Assignments are always global.
@@ -95,8 +95,8 @@
% \begin{syntax}
% \cs{fparray_count:N} \meta{fparray~var}
% \end{syntax}
-% Expands to the number of entries in the \meta{floating point array
-% variable}. This is performed in constant time.
+% Expands to the number of entries in the \meta{fparray
+% var}. This is performed in constant time.
% \end{function}
%
% \section{Using a single entry}
@@ -111,7 +111,7 @@
% \end{syntax}
% Applies \cs{fp_use:N} or \cs{fp_to_tl:N} (respectively) to the
% floating point entry stored at the (integer expression)
-% \meta{position} in the \meta{floating point array variable}. If the
+% \meta{position} in the \meta{fparray var}. If the
% \meta{position} is not between $1$ and the
% \cs{fparray_count:N} \meta{fparray~var}, an error occurs.
% \end{function}
@@ -266,25 +266,25 @@
\exp_after:wN \@@_array_gset:NNNNww
\exp_after:wN #1
\exp_after:wN #1
- \int_value:w \int_eval:n {#2} \exp_after:wN ;
+ \int_value:w \int_eval:n {#2} \exp_after:wN \@@_sep:
\exp:w \exp_end_continue_f:w \@@_parse:n {#3}
}
\cs_generate_variant:Nn \fparray_gset:Nnn { c }
-\cs_new_protected:Npn \@@_array_gset:NNNNww #1#2#3#4#5 ; #6 ;
+\cs_new_protected:Npn \@@_array_gset:NNNNww #1#2#3#4#5 \@@_sep: #6 \@@_sep:
{
\@@_array_bounds:NNnTF \msg_error:nneee #4 {#5}
{
\exp_after:wN \@@_change_func_type:NNN
- \@@_use_i_until_s:nw #6 ;
+ \@@_use_i_until_s:nw #6 \@@_sep:
\@@_array_gset:w
\@@_array_gset_recover:Nw
- #6 ; {#5} #1 #2 #3
+ #6 \@@_sep: {#5} #1 #2 #3
}
{ }
}
-\cs_new_protected:Npn \@@_array_gset_recover:Nw #1#2 ;
+\cs_new_protected:Npn \@@_array_gset_recover:Nw #1#2 \@@_sep:
{
- \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 ; } } { } { }
+ \@@_error:nffn { unknown-type } { \tl_to_str:n { #2 \@@_sep: } } { } { }
\exp_after:wN #1 \c_nan_fp
}
\cs_new_protected:Npn \@@_array_gset:w \s_@@ \@@_chk:w #1#2
@@ -298,7 +298,7 @@
\s_@@ \@@_chk:w #1 #2
}
\cs_new_protected:Npn \@@_array_gset_normal:w
- \s_@@ \@@_chk:w 1 #1 #2 #3#4#5 ; #6#7#8#9
+ \s_@@ \@@_chk:w 1 #1 #2 #3#4#5 \@@_sep: #6#7#8#9
{
\__kernel_intarray_gset:Nnn #7 {#6} {#2}
\__kernel_intarray_gset:Nnn #8 {#6}
@@ -354,7 +354,7 @@
{
\exp_after:wN \@@_array_item:NwN
\exp_after:wN #1
- \int_value:w \int_eval:n {#2} ;
+ \int_value:w \int_eval:n {#2} \@@_sep:
\@@_to_decimal:w
}
\cs_generate_variant:Nn \fparray_item:Nn { c }
@@ -362,11 +362,11 @@
{
\exp_after:wN \@@_array_item:NwN
\exp_after:wN #1
- \int_value:w \int_eval:n {#2} ;
+ \int_value:w \int_eval:n {#2} \@@_sep:
\@@_to_tl:w
}
\cs_generate_variant:Nn \fparray_item_to_tl:Nn { c }
-\cs_new:Npn \@@_array_item:NwN #1#2 ; #3
+\cs_new:Npn \@@_array_item:NwN #1#2 \@@_sep: #3
{
\@@_array_bounds:NNnTF \msg_expandable_error:nnfff #1 {#2}
{ \exp_after:wN \@@_array_item:NNNnN #1 {#2} #3 }
@@ -375,22 +375,22 @@
\cs_new:Npn \@@_array_item:NNNnN #1#2#3#4
{
\exp_after:wN \@@_array_item:N
- \int_value:w \__kernel_intarray_item:Nn #2 {#4} \exp_after:wN ;
- \int_value:w \__kernel_intarray_item:Nn #3 {#4} \exp_after:wN ;
- \int_value:w \__kernel_intarray_item:Nn #1 {#4} ;
+ \int_value:w \__kernel_intarray_item:Nn #2 {#4} \exp_after:wN \@@_sep:
+ \int_value:w \__kernel_intarray_item:Nn #3 {#4} \exp_after:wN \@@_sep:
+ \int_value:w \__kernel_intarray_item:Nn #1 {#4} \@@_sep:
}
\cs_new:Npn \@@_array_item:N #1
{
\if_meaning:w 0 #1 \exp_after:wN \@@_array_item_special:w \fi:
\@@_array_item:w #1
}
-\cs_new:Npn \@@_array_item:w #1 #2#3#4#5 #6 ; 1 #7 ;
+\cs_new:Npn \@@_array_item:w #1 #2#3#4#5 #6 \@@_sep: 1 #7 \@@_sep:
{
\exp_after:wN \@@_array_item_normal:w
\int_value:w \if_meaning:w #1 1 0 \else: 2 \fi: \exp_stop_f:
- #7 ; {#2#3#4#5} {#6} ;
+ #7 \@@_sep: {#2#3#4#5} {#6} \@@_sep:
}
-\cs_new:Npn \@@_array_item_special:w #1 ; #2 ; #3 ; #4
+\cs_new:Npn \@@_array_item_special:w #1 \@@_sep: #2 \@@_sep: #3 \@@_sep: #4
{
\exp_after:wN #4
\exp:w \exp_end_continue_f:w
@@ -402,8 +402,9 @@
\else: \exp_after:wN \c_minus_inf_fp
\fi:
}
-\cs_new:Npn \@@_array_item_normal:w #1 #2#3#4#5 #6 ; #7 ; #8 ; #9
- { #9 \s_@@ \@@_chk:w 1 #1 {#8} #7 {#2#3#4#5} {#6} ; }
+\cs_new:Npn \@@_array_item_normal:w
+ #1 #2#3#4#5 #6 \@@_sep: #7 \@@_sep: #8 \@@_sep: #9
+ { #9 \s_@@ \@@_chk:w 1 #1 {#8} #7 {#2#3#4#5} {#6} \@@_sep: }
% \end{macrocode}
% \end{macro}
% \end{macro}
diff --git a/macros/latex-dev/required/l3kernel/l3int.dtx b/macros/latex-dev/required/l3kernel/l3int.dtx
index 5d437910c1..120a1b4630 100644
--- a/macros/latex-dev/required/l3kernel/l3int.dtx
+++ b/macros/latex-dev/required/l3kernel/l3int.dtx
@@ -2,7 +2,7 @@
%
%% File: l3int.dtx
%
-% Copyright (C) 1990-2024 The LaTeX Project
+% Copyright (C) 1990-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -100,21 +100,6 @@
% restricted-expandable functions can both be used, and \cs{exp_not:n}
% and its variants have no effect while \cs{exp_not:N} may incorrectly
% interrupt the expression.
-% \begin{texnote}
-% Exactly two expansions are needed to evaluate \cs{int_eval:n}.
-% The result is \emph{not} an \meta{internal integer}, and therefore
-% should be terminated by a space if used in \cs{int_value:w} or in
-% a \TeX{}-style integer assignment.
-%
-% As all \TeX{} integers, integer operands can also be:
-% \tn{value}\Arg{\LaTeXe{} counter}; dimension or skip variables,
-% converted to integers in~\texttt{sp}; the character code of some
-% character given as \texttt{`}\meta{char} or
-% \texttt{`\textbackslash}\meta{char}; octal numbers given as
-% \texttt{'} followed by digits from \texttt{0} to \texttt{7}; or
-% hexadecimal numbers given as |"| followed by digits and upper case
-% letters from \texttt{A} to~\texttt{F}.
-% \end{texnote}
%
% \begin{function}[EXP]{\int_eval:n}
% \begin{syntax}
@@ -124,43 +109,7 @@
% input stream as an integer denotation: for positive results an
% explicit sequence of decimal digits not starting with~\texttt{0},
% for negative results \texttt{-}~followed by such a sequence, and
-% \texttt{0}~for zero. The \meta{int expr} should consist,
-% after expansion, of \texttt{+}, \texttt{-}, \texttt{*}, \texttt{/},
-% \texttt{(}, \texttt{)} and of course integer operands. The result
-% is calculated by applying standard mathematical rules with the
-% following peculiarities:
-% \begin{itemize}
-% \item \texttt{/} denotes division rounded to the closest integer with
-% ties rounded away from zero;
-% \item there is an error and the overall expression evaluates to zero
-% whenever the absolute value of any intermediate result exceeds
-% $2^{31}-1$, except in the case of scaling operations
-% $a$\texttt{*}$b$\texttt{/}$c$, for which $a$\texttt{*}$b$ may be
-% arbitrarily large;
-% \item parentheses may not appear after unary \texttt{+} or
-% \texttt{-}, namely placing \texttt{+(} or \texttt{-(} at the start
-% of an expression or after \texttt{+}, \texttt{-}, \texttt{*},
-% \texttt{/} or~\texttt{(} leads to an error.
-% \end{itemize}
-% Each integer operand can be either an integer variable (with no need
-% for \cs{int_use:N}) or an integer denotation. For example both
-% \begin{verbatim}
-% \int_eval:n { 5 + 4 * 3 - ( 3 + 4 * 5 ) }
-% \end{verbatim}
-% and
-% \begin{verbatim}
-% \tl_new:N \l_my_tl
-% \tl_set:Nn \l_my_tl { 5 }
-% \int_new:N \l_my_int
-% \int_set:Nn \l_my_int { 4 }
-% \int_eval:n { \l_my_tl + \l_my_int * 3 - ( 3 + 4 * 5 ) }
-% \end{verbatim}
-% evaluate to $-6$ because \cs[no-index]{l_my_tl} expands to the
-% integer denotation~|5|. As the \meta{int expr} is fully
-% expanded from left to right during evaluation, fully expandable and
-% restricted-expandable functions can both be used, and \cs{exp_not:n}
-% and its variants have no effect while \cs{exp_not:N} may incorrectly
-% interrupt the expression.
+% \texttt{0}~for zero.
% \begin{texnote}
% Exactly two expansions are needed to evaluate \cs{int_eval:n}.
% The result is \emph{not} an \meta{internal integer}, and therefore
@@ -313,11 +262,11 @@
% \begin{function}[EXP, pTF, added=2012-03-03]
% {\int_if_exist:N, \int_if_exist:c}
% \begin{syntax}
-% \cs{int_if_exist_p:N} \meta{int}
-% \cs{int_if_exist:NTF} \meta{int} \Arg{true code} \Arg{false code}
+% \cs{int_if_exist_p:N} \meta{integer}
+% \cs{int_if_exist:NTF} \meta{integer} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests whether the \meta{int} is currently defined. This does not
-% check that the \meta{int} really is an integer variable.
+% Tests whether the \meta{integer} is currently defined. This does not
+% check that the \meta{integer} really is an integer variable.
% \end{function}
%
% \section{Setting and incrementing integers}
@@ -346,7 +295,10 @@
% \end{function}
%
% \begin{function}[updated = 2011-10-22]
-% {\int_set:Nn, \int_set:cn, \int_gset:Nn, \int_gset:cn}
+% {
+% \int_set:Nn, \int_set:cn, \int_set:NV, \int_set:cV,
+% \int_gset:Nn, \int_gset:cn, \int_gset:NV, \int_gset:cV
+% }
% \begin{syntax}
% \cs{int_set:Nn} \meta{integer} \Arg{int expr}
% \end{syntax}
@@ -355,6 +307,37 @@
% \cs{int_eval:n}).
% \end{function}
%
+% \begin{function}[added = 2024-12-08]
+% {
+% \int_set_regex_count:Nnn, \int_set_regex_count:cnn,
+% \int_set_regex_count:NNn, \int_set_regex_count:cNn,
+% \int_gset_regex_count:Nnn, \int_gset_regex_count:cnn,
+% \int_gset_regex_count:NNn, \int_gset_regex_count:cNn,
+% }
+% \begin{syntax}
+% \cs{int_set_regex_count:Nnn} \meta{integer} \Arg{regex} \Arg{token list}
+% \cs{int_set_regex_count:NNn} \meta{integer} \meta{regex~var} \Arg{token list}
+% \end{syntax}
+% Sets \meta{integer} equal to the number of times
+% \meta{regular expression} appears in \meta{token list}.
+% The search starts by finding the left-most longest match,
+% respecting greedy and lazy (non-greedy) operators. Then the search
+% starts again from the character following the last character
+% of the previous match, until reaching the end of the token list.
+% Infinite loops are prevented in the case where the regular expression
+% can match an empty token list: then we count one match between each
+% pair of characters.
+% For instance,
+% \begin{verbatim}
+% \int_set_regex_count:Nnn \l_foo_int { (b+|c) } { abbababcbb }
+% \end{verbatim}
+% results in \cs[no-index]{l_foo_int} taking the value $5$.
+% Theses are alternative names for \cs{regex_count:nnN} and friends,
+% with arguments re-ordered for \meta{integer} setting;
+% see \pkg{l3regex} chapter for more details of the \meta{regex}
+% format.
+% \end{function}
+%
% \begin{function}[updated = 2011-10-22]
% {\int_sub:Nn, \int_sub:cn, \int_gsub:Nn, \int_gsub:cn}
% \begin{syntax}
@@ -462,7 +445,8 @@
% \end{syntax}
% This function evaluates the \meta{test int expr} and
% compares this in turn to each of the
-% \meta{int expr cases}. If the two are equal then the
+% \meta{int expr case}s until a match is found.
+% If the two are equal then the
% associated \meta{code} is left in the input stream
% and other cases are discarded. If any of the
% cases are matched, the \meta{true code} is also inserted into the
@@ -481,6 +465,10 @@
% { No idea! }
% \end{verbatim}
% leaves \enquote{\texttt{Medium}} in the input stream.
+% Since evaluation of the test expressions stops at the first
+% successful case, the order of possible matches should normally
+% be that the most likely are earlier: this will reduce the average
+% steps required to complete expansion.
% \end{function}
%
% \begin{function}[EXP,pTF]{\int_if_even:n, \int_if_odd:n}
@@ -641,6 +629,32 @@
% $1$. These functions are provided as simple short-cuts for code clarity.
% \end{function}
%
+% \begin{function}[added = 2025-01-13, rEXP]
+% {\int_step_tokens:nn, \int_step_tokens:nnn, \int_step_tokens:nnnn}
+% \begin{syntax}
+% \cs{int_step_tokens:nn} \Arg{final value} \Arg{code}
+% \cs{int_step_tokens:nnn} \Arg{initial value} \Arg{final value} \Arg{code}
+% \cs{int_step_tokens:nnnn} \Arg{initial value} \Arg{step} \Arg{final value} \Arg{code}
+% \end{syntax}
+% This function works just like \cs{int_step_function:nnnN} but
+% instead of mapping a single function to each stepped \meta{value}
+% between \meta{initial value} and \meta{final value} this maps
+% the multiple tokens in \meta{code}, so that it gets the current
+% \meta{value} as a braced argument following it. For instance
+% \begin{verbatim}
+% \cs_set:Npn \my_product:nn #1#2
+% { $#1 \times #2 = \int_eval:n { #1 * #2 }$ \quad }
+% \int_step_tokens:nnnn { 1 } { 1 } { 4 } { \my_product:nn { 2 } }
+% \end{verbatim}
+% would print
+% \begin{quote}
+% $2 \times 1 = 2$ \quad
+% $2 \times 2 = 4$ \quad
+% $2 \times 3 = 6$ \quad
+% $2 \times 4 = 8$ \quad
+% \end{quote}
+% \end{function}
+%
% \begin{function}[added = 2012-06-04, updated = 2018-04-22]
% {\int_step_inline:nn, \int_step_inline:nnn, \int_step_inline:nnnn}
% \begin{syntax}
@@ -1168,6 +1182,13 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\@@_sep:}
+% See comments in \texttt{l3fp-aux.dtx} for this idea.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_sep: \tex_right:D
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}[EXP]{\int_sign:n, \@@_sign:Nw}
% See \cs{int_abs:n}. Evaluate the expression once (and when
% debugging is enabled, check that the expression is well-formed),
@@ -1179,10 +1200,10 @@
\cs_new:Npn \int_sign:n #1
{
\int_value:w \exp_after:wN \@@_sign:Nw
- \int_value:w \@@_eval:w #1 \@@_eval_end: ;
+ \int_value:w \@@_eval:w #1 \@@_eval_end: \@@_sep:
\exp_stop_f:
}
-\cs_new:Npn \@@_sign:Nw #1#2 ;
+\cs_new:Npn \@@_sign:Nw #1#2 \@@_sep:
{
\if_meaning:w 0 #1
0
@@ -1216,20 +1237,20 @@
\cs_new:Npn \int_max:nn #1#2
{
\int_value:w \exp_after:wN \@@_maxmin:wwN
- \int_value:w \@@_eval:w #1 \exp_after:wN ;
- \int_value:w \@@_eval:w #2 ;
+ \int_value:w \@@_eval:w #1 \exp_after:wN \@@_sep:
+ \int_value:w \@@_eval:w #2 \@@_sep:
>
\exp_stop_f:
}
\cs_new:Npn \int_min:nn #1#2
{
\int_value:w \exp_after:wN \@@_maxmin:wwN
- \int_value:w \@@_eval:w #1 \exp_after:wN ;
- \int_value:w \@@_eval:w #2 ;
+ \int_value:w \@@_eval:w #1 \exp_after:wN \@@_sep:
+ \int_value:w \@@_eval:w #2 \@@_sep:
<
\exp_stop_f:
}
-\cs_new:Npn \@@_maxmin:wwN #1 ; #2 ; #3
+\cs_new:Npn \@@_maxmin:wwN #1 \@@_sep: #2 \@@_sep: #3
{
\if_int_compare:w #1 #3 #2 ~
#1
@@ -1269,11 +1290,11 @@
{
\int_value:w \@@_eval:w
\exp_after:wN \@@_div_truncate:NwNw
- \int_value:w \@@_eval:w #1 \exp_after:wN ;
- \int_value:w \@@_eval:w #2 ;
+ \int_value:w \@@_eval:w #1 \exp_after:wN \@@_sep:
+ \int_value:w \@@_eval:w #2 \@@_sep:
\@@_eval_end:
}
-\cs_new:Npn \@@_div_truncate:NwNw #1#2; #3#4;
+\cs_new:Npn \@@_div_truncate:NwNw #1#2 \@@_sep: #3#4 \@@_sep:
{
\if_meaning:w 0 #1
0
@@ -1297,12 +1318,12 @@
\cs_new:Npn \int_mod:nn #1#2
{
\int_value:w \@@_eval:w \exp_after:wN \@@_mod:ww
- \int_value:w \@@_eval:w #1 \exp_after:wN ;
- \int_value:w \@@_eval:w #2 ;
+ \int_value:w \@@_eval:w #1 \exp_after:wN \@@_sep:
+ \int_value:w \@@_eval:w #2 \@@_sep:
\@@_eval_end:
}
-\cs_new:Npn \@@_mod:ww #1; #2;
- { #1 - ( \@@_div_truncate:NwNw #1 ; #2 ; ) * #2 }
+\cs_new:Npn \@@_mod:ww #1 \@@_sep: #2 \@@_sep:
+ { #1 - ( \@@_div_truncate:NwNw #1 \@@_sep: #2 \@@_sep: ) * #2 }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1519,9 +1540,9 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\int_set:Nn, \int_set:cn}
+% \begin{macro}{\int_set:Nn, \int_set:cn, \int_set:NV, \int_set:cV}
% \UnitTested
-% \begin{macro}{\int_gset:Nn, \int_gset:cn}
+% \begin{macro}{\int_gset:Nn, \int_gset:cn, \int_gset:NV, \int_gset:cV}
% \UnitTested
% As integers are register-based \TeX{} issues an error
% if they are not defined. While the |=| sign is optional, this
@@ -1532,8 +1553,47 @@
{ #1 = \@@_eval:w #2 \@@_eval_end: }
\cs_new_protected:Npn \int_gset:Nn #1#2
{ \tex_global:D #1 = \@@_eval:w #2 \@@_eval_end: }
-\cs_generate_variant:Nn \int_set:Nn { c }
-\cs_generate_variant:Nn \int_gset:Nn { c }
+\cs_generate_variant:Nn \int_set:Nn { NV , c , cV }
+\cs_generate_variant:Nn \int_gset:Nn { NV , c , cV }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \int_set_regex_count:Nnn, \int_set_regex_count:cnn,
+% \int_gset_regex_count:Nnn, \int_gset_regex_count:cnn
+% }
+% \begin{macro}
+% {
+% \int_set_regex_count:NNn, \int_set_regex_count:cNn,
+% \int_gset_regex_count:NNn, \int_set_gregex_count:cNn
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \int_set_regex_count:Nnn #1#2#3
+ { \regex_count:nnN {#2} {#3} #1 }
+\cs_generate_variant:Nn \int_set_regex_count:Nnn { c }
+\cs_new_protected:Npn \int_gset_regex_count:Nnn #1#2#3
+ {
+ \group_begin:
+ \int_set_eq:NN \l_@@_internal_a_int #1
+ \regex_count:nnN {#2} {#3} \l_@@_internal_a_int
+ \int_gset_eq:NN #1 \l_@@_internal_a_int
+ \group_end:
+ }
+\cs_generate_variant:Nn \int_gset_regex_count:Nnn { c }
+\cs_new_protected:Npn \int_set_regex_count:NNn #1#2#3
+ { \regex_count:NnN #2 {#3} #1 }
+\cs_generate_variant:Nn \int_set_regex_count:Nnn { c }
+\cs_new_protected:Npn \int_gset_regex_count:NNn #1#2#3
+ {
+ \group_begin:
+ \int_set_eq:NN \l_@@_internal_a_int #1
+ \regex_count:NnN #2 {#3} \l_@@_internal_a_int
+ \int_gset_eq:NN #1 \l_@@_internal_a_int
+ \group_end:
+ }
+\cs_generate_variant:Nn \int_gset_regex_count:NNn { c }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1917,7 +1977,7 @@
% \subsection{Integer step functions}
%
% \begin{macro}{\int_step_function:nnnN}
-% \begin{macro}{\@@_step:wwwN, \@@_step:NwnnN}
+% \begin{macro}{\@@_step:w, \@@_step:Nw}
% \begin{macro}{\int_step_function:nN}
% \begin{macro}{\int_step_function:nnN}
% Before all else, evaluate the initial value, step, and final value.
@@ -1925,51 +1985,70 @@
% of the steps. After that, do the function for the start value then
% step and loop around. It would be more symmetrical to test for a
% step size of zero before checking the sign, but we optimize for the
-% most frequent case (positive step).
+% most frequent case (positive step). And since when we're doing the
+% test the step size is the result of \cs{@@_eval:w} we know that only
+% the value $0$ has a leading token |0| which we can use for a faster
+% test than \cs{int_compare:nNnTF}.
% \begin{macrocode}
\cs_new:Npn \int_step_function:nnnN #1#2#3
{
- \exp_after:wN \@@_step:wwwN
- \int_value:w \@@_eval:w #1 \exp_after:wN ;
- \int_value:w \@@_eval:w #2 \exp_after:wN ;
- \int_value:w \@@_eval:w #3 ;
+ \exp_after:wN \@@_step:w
+ \int_value:w \@@_eval:w #1 \exp_after:wN \@@_sep:
+ \int_value:w \@@_eval:w #2 \exp_after:wN \@@_sep:
+ \int_value:w \@@_eval:w #3 \@@_sep:
}
-\cs_new:Npn \@@_step:wwwN #1; #2; #3; #4
+\cs_new:Npn \@@_step:w #1 \@@_sep: #2 \@@_sep: #3 \@@_sep: #4
{
\int_compare:nNnTF {#2} > \c_zero_int
- { \@@_step:NwnnN > }
+ { \@@_step:Nw > }
{
- \int_compare:nNnTF {#2} = \c_zero_int
+ \if_meaning:w 0 #2
+ \exp_after:wN \use_ii:nn
+ \fi:
+ \use_none:n
{
\msg_expandable_error:nnn
{ kernel } { zero-step } {#4}
\prg_break:
}
- { \@@_step:NwnnN < }
+ \@@_step:Nw <
}
- #1 ; {#2} {#3} #4
+ #1 \@@_sep: {#2} {#3} {#4}
\prg_break_point:
}
-\cs_new:Npn \@@_step:NwnnN #1#2 ; #3#4#5
+\cs_new:Npn \@@_step:Nw #1#2 \@@_sep: #3#4#5
{
\if_int_compare:w #2 #1 #4 \exp_stop_f:
\prg_break:n
\fi:
#5 {#2}
- \exp_after:wN \@@_step:NwnnN
+ \exp_after:wN \@@_step:Nw
\exp_after:wN #1
- \int_value:w \@@_eval:w #2 + #3 ; {#3} {#4} #5
+ \int_value:w \@@_eval:w #2 + #3 \@@_sep: {#3} {#4} {#5}
}
\cs_new:Npn \int_step_function:nN
- { \int_step_function:nnnN { 1 } { 1 } }
+ { \int_step_function:nnnN \c_one_int \c_one_int }
\cs_new:Npn \int_step_function:nnN #1
- { \int_step_function:nnnN {#1} { 1 } }
+ { \int_step_function:nnnN {#1} \c_one_int }
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
+% \begin{macro}
+% {\int_step_tokens:nn, \int_step_tokens:nnn, \int_step_tokens:nnnn}
+% Because the internals \cs{@@_step:wwwn} and \cs{@@_step:Nwnnn} are
+% defined in such a way that they work with both a single token or a
+% braced group of tokens these are really the same as the |function|
+% variants.
+% \begin{macrocode}
+\cs_new_eq:NN \int_step_tokens:nn \int_step_function:nN
+\cs_new_eq:NN \int_step_tokens:nnn \int_step_function:nnN
+\cs_new_eq:NN \int_step_tokens:nnnn \int_step_function:nnnN
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\int_step_inline:nn, \int_step_inline:nnn, \int_step_inline:nnnn}
% \begin{macro}{\int_step_variable:nNn, \int_step_variable:nnNn, \int_step_variable:nnnNn}
% \UnitTested
diff --git a/macros/latex-dev/required/l3kernel/l3intarray.dtx b/macros/latex-dev/required/l3kernel/l3intarray.dtx
index aa49275e78..94b979956f 100644
--- a/macros/latex-dev/required/l3kernel/l3intarray.dtx
+++ b/macros/latex-dev/required/l3kernel/l3intarray.dtx
@@ -2,7 +2,7 @@
%
%% File: l3intarray.dtx
%
-% Copyright (C) 2017-2024 The LaTeX Project
+% Copyright (C) 2017-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -79,7 +79,7 @@
% \begin{function}[added = 2018-05-04]
% {\intarray_const_from_clist:Nn, \intarray_const_from_clist:cn}
% \begin{syntax}
-% \cs{intarray_const_from_clist:Nn} \meta{intarray~var} \meta{int expr clist}
+% \cs{intarray_const_from_clist:Nn} \meta{intarray~var} \Arg{int expr clist}
% \end{syntax}
% Creates a new constant \meta{integer array variable} or raises an
% error if the name is already taken. The \meta{integer array
diff --git a/macros/latex-dev/required/l3kernel/l3kernel-functions.dtx b/macros/latex-dev/required/l3kernel/l3kernel-functions.dtx
index c3bb838acf..7d38f4a22e 100644
--- a/macros/latex-dev/required/l3kernel/l3kernel-functions.dtx
+++ b/macros/latex-dev/required/l3kernel/l3kernel-functions.dtx
@@ -2,7 +2,7 @@
%
%% File: l3kernel-functions.dtx
%
-% Copyright (C) 2018-2024 The LaTeX Project
+% Copyright (C) 2018-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
diff --git a/macros/latex-dev/required/l3kernel/l3keys.dtx b/macros/latex-dev/required/l3kernel/l3keys.dtx
index 13772d1781..93c08eb9fa 100644
--- a/macros/latex-dev/required/l3kernel/l3keys.dtx
+++ b/macros/latex-dev/required/l3kernel/l3keys.dtx
@@ -2,7 +2,7 @@
%
%% File: l3keys.dtx
%
-% Copyright (C) 2006-2024 The LaTeX Project
+% Copyright (C) 2006-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -184,12 +184,13 @@
% \begin{function}[updated = 2013-07-08]
% {.bool_set:N, .bool_set:c, .bool_gset:N, .bool_gset:c}
% \begin{syntax}
-% \meta{key} .bool_set:N = \meta{boolean variable}
+% \meta{key} .bool_set:N = \meta{boolean}
% \end{syntax}
-% Defines \meta{key} to set \meta{boolean variable} to \meta{value} (which
-% must be either \enquote{\texttt{true}} or \enquote{\texttt{false}}). If the variable
-% does not exist, it will be created globally at the point that
-% the key is set up.
+% Defines \meta{key} to set \meta{boolean} to \meta{value}. If the
+% \meta{value} is given, it must be one either \enquote{\texttt{true}} or
+% \enquote{\texttt{false}}); it may be omitted, which is equivalent to
+% \texttt{true}. If the variable does not exist, it will be created globally
+% at the point that the key is set up.
% \end{function}
%
% \begin{function}[added = 2011-08-28, updated = 2013-07-08]
@@ -198,12 +199,12 @@
% .bool_gset_inverse:N, .bool_gset_inverse:c
% }
% \begin{syntax}
-% \meta{key} .bool_set_inverse:N = \meta{boolean variable}
+% \meta{key} .bool_set_inverse:N = \meta{boolean}
% \end{syntax}
-% Defines \meta{key} to set \meta{boolean variable} to the logical
+% Defines \meta{key} to set \meta{boolean} to the logical
% inverse of \meta{value} (which must be either \enquote{\texttt{true}} or
% \enquote{\texttt{false}}).
-% If the \meta{boolean variable} does not exist, it will be created globally
+% If the \meta{boolean} does not exist, it will be created globally
% at the point that the key is set up.
% \end{function}
%
@@ -310,9 +311,9 @@
% \begin{function}[updated = 2020-01-17]
% {.fp_set:N, .fp_set:c, .fp_gset:N, .fp_gset:c}
% \begin{syntax}
-% \meta{key} .fp_set:N = \meta{floating point}
+% \meta{key} .fp_set:N = \meta{fp var}
% \end{syntax}
-% Defines \meta{key} to set \meta{floating point} to \meta{value}
+% Defines \meta{key} to set \meta{fp var} to \meta{value}
% (which must a floating point expression). If the variable does not exist,
% it is created globally at the point that the key is set up. The key will
% require a value at point-of-use unless a default is set.
@@ -367,7 +368,7 @@
% \meta{key} .initial:n = \Arg{value}
% \end{syntax}
% Initialises the \meta{key} with the \meta{value}, equivalent to
-% \begin{quote}
+% \begin{quote}\ttfamily
% \cs{keys_set:nn} \Arg{module} \{ \meta{key} = \meta{value} \}
% \end{quote}
% \end{function}
@@ -500,9 +501,9 @@
%
% \begin{function}{.tl_set:N, .tl_set:c, .tl_gset:N, .tl_gset:c}
% \begin{syntax}
-% \meta{key} .tl_set:N = \meta{token list variable}
+% \meta{key} .tl_set:N = \meta{tl~var}
% \end{syntax}
-% Defines \meta{key} to set \meta{token list variable} to \meta{value}.
+% Defines \meta{key} to set \meta{tl~var} to \meta{value}.
% If the variable does not exist, it is created globally
% at the point that the key is set up.
% \end{function}
@@ -510,9 +511,9 @@
% \begin{function}[added = 2023-09-18]
% {.tl_set_e:N, .tl_set_e:c, .tl_gset_e:N, .tl_gset_e:c}
% \begin{syntax}
-% \meta{key} .tl_set_e:N = \meta{token list variable}
+% \meta{key} .tl_set_e:N = \meta{tl~var}
% \end{syntax}
-% Defines \meta{key} to set \meta{token list variable} to \meta{value},
+% Defines \meta{key} to set \meta{tl~var} to \meta{value},
% which will be subjected to an \texttt{e}-type expansion
% (\emph{i.e.}~using \cs{tl_set:Ne}). If the variable does not exist,
% it is created globally at the point that the key is set up.
@@ -649,15 +650,13 @@
% { key } % Name of choice key
% { choice-a , choice-b , choice-c } % Valid choices
% { \exp_not:n {#1} } % Invalid choice given
-% %
-% %
% }
% \end{verbatim}
%
% Multiple choices are created in a very similar manner to mutually-exclusive
% choices, using the properties \texttt{.multichoice:} and
% \texttt{.multichoices:nn}. As with mutually exclusive choices, multiple
-% choices are define as sub-keys. Thus both
+% choices are defined as sub-keys. Thus both
% \begin{verbatim}
% \keys_define:nn { mymodule }
% {
@@ -923,7 +922,7 @@
% The correct list is returned by nested calls.
% \end{function}
%
-% \section{Digesting keys}
+% \section{Precompiling keys}
%
% \begin{function}[added = 2022-03-09]{\keys_precompile:nnN}
% \begin{syntax}
@@ -933,6 +932,14 @@
% resulting code for those which set variables or functions into the
% \meta{tl~var}. Thus this function \enquote{precompiles} the keyval list into
% a set of results which can be applied rapidly.
+%
+% It is important to note that when precompiling keys, no expansion of variables
+% takes place. This means that any key setting which simply stores variable names,
+% rather than variable values, may not work correctly. Most notably, any
+% key setting which uses key status variables (\cs{l_keys_key_str}, etc.)
+% will yield unpredictable outcomes. As such, keys
+% intended to be precompiled should fully expand any values at the point of
+% setting.
% \end{function}
%
% \section{Utility functions for keys}
@@ -1804,25 +1811,34 @@
% \subsection{The key defining mechanism}
%
% \begin{macro}{\keys_define:nn, \keys_define:ne, \keys_define:nx}
-% \begin{macro}{\@@_define:nnn, \@@_define:onn}
% The public function for definitions is just a wrapper for the lower
% level mechanism, more or less. The outer function is designed to
% keep a track of the current module, to allow safe nesting. The module is set
% removing any leading |/| (which is not needed here).
% \begin{macrocode}
-\cs_new_protected:Npn \keys_define:nn
- { \@@_define:onn \l_@@_module_str }
-\cs_generate_variant:Nn \keys_define:nn { ne , nx }
-\cs_new_protected:Npn \@@_define:nnn #1#2#3
+\cs_new_protected:Npn \keys_define:nn #1#2
{
- \str_set:Ne \l_@@_module_str { \@@_trim_spaces:n {#2} }
- \keyval_parse:NNn \@@_define:n \@@_define:nn {#3}
- \str_set:Nn \l_@@_module_str {#1}
+ \use:e
+ {
+ \exp_not:n
+ {
+ \str_set:Ne \l_@@_module_str { \@@_trim_spaces:n {#1} }
+ \keyval_parse:NNn \@@_define:n \@@_define:nn {#2}
+ }
+ \@@_reset_var:N \l_@@_module_str
+ \@@_reset_var:N \l_@@_inherit_str
+ \@@_reset_var:N \l_keys_choice_tl
+ \@@_reset_var:N \l_keys_key_tl
+ \@@_reset_var:N \l_keys_key_str
+ \@@_reset_var:N \l_keys_path_tl
+ \@@_reset_var:N \l_keys_path_str
+ \@@_reset_var:N \l_keys_value_tl
+ \int_set:Nn \l_keys_choice_int { \int_use:N \l_keys_choice_int }
+ }
}
-\cs_generate_variant:Nn \@@_define:nnn { o }
+\cs_generate_variant:Nn \keys_define:nn { ne , nx }
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
% \begin{macro}{\@@_define:n}
% \begin{macro}{\@@_define:nn}
@@ -1926,19 +1942,21 @@
% \end{macro}
%
% \begin{macro}{\@@_define_code:n}
+% \begin{macro}[EXP]{\@@_define_code:nnn}
% \begin{macro}[EXP]{\@@_define_code:w}
% Two possible cases. If there is a value for the key, then just use
% the function. If not, then a check to make sure there is no need for
% a value with the property. If there should be one then complain,
-% otherwise execute it. There is no need to check for a |:| as if it
-% was missing the earlier tests would have failed.
+% otherwise execute it. For a \LaTeXe{} property like |.code| which
+% doesn't contain a |:|, treat it as having arity 1 and pass the
+% (empty) value to it.
% \begin{macrocode}
\cs_new_protected:Npn \@@_define_code:n #1
{
\bool_if:NTF \l_@@_no_value_bool
{
- \exp_after:wN \@@_define_code:w
- \l_@@_property_str \s_@@_stop
+ \@@_define_code:nnn
+ { \use:c { \c_@@_props_root_str \l_@@_property_str } {#1} }
{ \use:c { \c_@@_props_root_str \l_@@_property_str } }
{
\msg_error:nnee { keys } { property-requires-value }
@@ -1947,12 +1965,31 @@
}
{ \use:c { \c_@@_props_root_str \l_@@_property_str } {#1} }
}
-\exp_last_unbraced:NNNNo
- \cs_new:Npn \@@_define_code:w #1 \c_colon_str #2 \s_@@_stop
- { \tl_if_empty:nTF {#2} }
+\cs_new:Npe \@@_define_code:nnn
+ {
+ \exp_not:N \exp_after:wN \exp_not:N \@@_define_code:w
+ \exp_not:N \l_@@_property_str
+ \c_colon_str \c_colon_str
+ \exp_not:N \s_@@_stop
+ }
+\use:e
+ {
+ \cs_new:Npn \exp_not:N \@@_define_code:w
+ #1 \c_colon_str #2 \c_colon_str #3 \exp_not:N \s_@@_stop
+ }
+ {
+ \tl_if_empty:nTF {#3}
+ { \use_i:nnn }
+ {
+ \tl_if_empty:nTF {#2}
+ { \use_ii:nnn }
+ { \use_iii:nnn }
+ }
+ }
% \end{macrocode}
% \end{macro}
% \end{macro}
+% \end{macro}
%
% \subsection{Turning properties into actions}
%
@@ -2221,14 +2258,8 @@
% function is used here as a meta key should respect the prevailing
% filtering, etc.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_meta_make:n #1
- {
- \exp_args:NVo \@@_cmd_set_direct:nn \l_keys_path_str
- {
- \exp_after:wN \@@_set:nn \exp_after:wN
- { \l_@@_module_str } {#1}
- }
- }
+\cs_new_protected:Npn \@@_meta_make:n
+ { \exp_args:NV \@@_meta_make:nn \l_@@_module_str }
\cs_new_protected:Npn \@@_meta_make:nn #1#2
{
\exp_args:NV \@@_cmd_set_direct:nn
@@ -2813,7 +2844,6 @@
% \subsection{Setting keys}
%
% \begin{macro}{\@@_set:nnnnNn}
-% \begin{macro}{\@@_set:nnnnnnnNn}
% \begin{macro}[EXP]{\@@_reset_bool:N, \@@_reset_var:N}
% \begin{macro}{\@@_set:nn}
% \begin{macro}{\@@_set:nnn}
@@ -2830,33 +2860,34 @@
% \item The code to set up the correct selection approach
% \end{enumerate}
% \begin{macrocode}
-\cs_new_protected:Npn \@@_set:nnnnNn
- {
- \exp_args:Nooo \@@_set:nnnnnnnNn
- \l_@@_unused_clist
- \l_@@_selective_clist
- \l_@@_relative_tl
- }
-\cs_new_protected:Npn \@@_set:nnnnnnnNn #1#2#3#4#5#6#7#8#9
+\cs_new_protected:Npn \@@_set:nnnnNn #1#2#3#4#5#6
{
- \clist_clear:N \l_@@_unused_clist
- \clist_set:Ne \l_@@_selective_clist { \tl_to_str:n {#5} }
- \tl_set:Nn \l_@@_relative_tl {#7}
\use:e
{
\exp_not:n
{
- #9
- \@@_set:nn {#4} {#6}
+ \clist_clear:N \l_@@_unused_clist
+ \clist_set:Ne \l_@@_selective_clist { \tl_to_str:n {#2} }
+ \tl_set:Nn \l_@@_relative_tl {#4}
+ #6
+ \@@_set:nn {#1} {#3}
+ \clist_set_eq:NN #5 \l_@@_unused_clist
}
\@@_reset_bool:N \l_@@_only_known_bool
\@@_reset_bool:N \l_@@_exclude_bool
\@@_reset_bool:N \l_@@_selective_bool
+ \@@_reset_var:N \l_@@_unused_clist
+ \@@_reset_var:N \l_@@_selective_clist
+ \@@_reset_var:N \l_@@_relative_tl
+ \@@_reset_var:N \l_@@_inherit_str
+ \@@_reset_var:N \l_keys_choice_tl
+ \@@_reset_var:N \l_keys_key_tl
+ \@@_reset_var:N \l_keys_key_str
+ \@@_reset_var:N \l_keys_path_tl
+ \@@_reset_var:N \l_keys_path_str
+ \@@_reset_var:N \l_keys_value_tl
+ \int_set:Nn \l_keys_choice_int { \int_use:N \l_keys_choice_int }
}
- \clist_set_eq:NN #8 \l_@@_unused_clist
- \__kernel_tl_set:Nx \l_@@_unused_clist { \exp_not:n {#1} }
- \__kernel_tl_set:Nx \l_@@_selective_clist {#2}
- \__kernel_tl_set:Nx \l_@@_relative_tl { \exp_not:n {#3} }
}
\cs_new:Npn \@@_reset_bool:N #1
{
@@ -2864,6 +2895,12 @@
{ bool_set_ \bool_if:NTF #1 { true } { false } :N }
\exp_not:N #1
}
+\cs_new:Npn \@@_reset_var:N #1
+ {
+ \exp_not:n
+ { \__kernel_tl_set:Nx #1 }
+ { \exp_not:N \exp_not:n { \exp_not:o { #1 } } }
+ }
\cs_new_protected:Npn \@@_set:nn #1#2
{ \exp_args:No \@@_set:nnn \l_@@_module_str {#1} {#2} }
\cs_new_protected:Npn \@@_set:nnn #1#2#3
@@ -2877,7 +2914,6 @@
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
%
% \begin{macro}
% {
diff --git a/macros/latex-dev/required/l3kernel/l3legacy.dtx b/macros/latex-dev/required/l3kernel/l3legacy.dtx
index 4cfce5c5f1..1f5d582164 100644
--- a/macros/latex-dev/required/l3kernel/l3legacy.dtx
+++ b/macros/latex-dev/required/l3kernel/l3legacy.dtx
@@ -2,7 +2,7 @@
%
%% File: l3legacy.dtx
%
-% Copyright (C) 2019-2024 The LaTeX Project
+% Copyright (C) 2019-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
diff --git a/macros/latex-dev/required/l3kernel/l3luatex.dtx b/macros/latex-dev/required/l3kernel/l3luatex.dtx
index eb10d5aecc..0e6f1b5967 100644
--- a/macros/latex-dev/required/l3kernel/l3luatex.dtx
+++ b/macros/latex-dev/required/l3kernel/l3luatex.dtx
@@ -2,7 +2,7 @@
%
%% File: l3luatex.dtx
%
-% Copyright (C) 2010-2024 The LaTeX Project
+% Copyright (C) 2010-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -123,7 +123,7 @@
%
% \cs{lua_now:n} passes its \Arg{token list} argument to the Lua interpreter
% as a single line, with characters interpreted under the current catcode
-% regime. These two facts mean that \cs{lua_now:n} rarely behaves as expected
+% régime. These two facts mean that \cs{lua_now:n} rarely behaves as expected
% for larger pieces of code. Therefore, package authors should \textbf{not}
% write significant amounts of Lua code in the arguments to \cs{lua_now:n}.
% Instead, it is strongly recommended that they write the majorty of their Lua
@@ -567,7 +567,7 @@ ltxutils.filesize = filesize
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[int]{luadef}
+% \begin{macro}[int]{luacmd}
% An internal function for defining control sequences form Lua which behave
% like primitives. This acts as a wrapper around |token.set_lua| which accepts
% a function instead of an index into the functions table.
diff --git a/macros/latex-dev/required/l3kernel/l3msg.dtx b/macros/latex-dev/required/l3kernel/l3msg.dtx
index e901b07c06..817a77e6e9 100644
--- a/macros/latex-dev/required/l3kernel/l3msg.dtx
+++ b/macros/latex-dev/required/l3kernel/l3msg.dtx
@@ -2,7 +2,7 @@
%
%% File: l3msg.dtx
%
-% Copyright (C) 2009-2024 The LaTeX Project
+% Copyright (C) 2009-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -587,8 +587,8 @@
% \begin{function}[EXP, added = 2017-12-04]
% {\msg_show_item:n, \msg_show_item_unbraced:n, \msg_show_item:nn, \msg_show_item_unbraced:nn}
% \begin{syntax}
-% \cs{seq_map_function:NN} \meta{seq} \cs{msg_show_item:n}
-% \cs{prop_map_function:NN} \meta{prop} \cs{msg_show_item:nn}
+% \cs{seq_map_function:NN} \meta{seq var} \cs{msg_show_item:n}
+% \cs{prop_map_function:NN} \meta{property list} \cs{msg_show_item:nn}
% \end{syntax}
% Used in the text of messages for \cs{msg_show:nnnnnn} to show or log
% a list of items or key--value pairs. The output of
@@ -647,7 +647,7 @@
% \end{syntax}
% Issues an \enquote{Undefined error} message from \TeX{} itself
% using the undefined control sequence \cs{???} then prints
-% \enquote{! \meta{module}: }\meta{error message}, which should be
+% \enquote{! \meta{module}: \meta{error message}}, which should be
% short. With default settings, anything beyond approximately $60$
% characters long (or bytes in some engines) is cropped. A leading
% space might be removed as well.
@@ -2088,6 +2088,13 @@
}
\msg_new:nnn { kernel } { randint-backward-range }
{ Wrong~order~of~bounds~in~\iow_char:N\\int_rand:nn{#1}{#2}. }
+\msg_new:nnnn { kernel } { conditional-base-undefined }
+ { Undefined~conditional~base~function~'#1'. }
+ {
+ \c_@@_coding_error_text_tl
+ LaTeX~has~been~asked~to~define~a~variant~of~the~conditional~'#1',~
+ but~the~latter~is~not~defined.
+ }
\msg_new:nnnn { kernel } { conditional-form-unknown }
{ Conditional~form~'#1'~for~function~'#2'~unknown. }
{
diff --git a/macros/latex-dev/required/l3kernel/l3names.dtx b/macros/latex-dev/required/l3kernel/l3names.dtx
index 5cdd1361e3..cf38ee9254 100644
--- a/macros/latex-dev/required/l3kernel/l3names.dtx
+++ b/macros/latex-dev/required/l3kernel/l3names.dtx
@@ -2,7 +2,7 @@
%
%% File: l3names.dtx
%
-% Copyright (C) 1990-2024 The LaTeX Project
+% Copyright (C) 1990-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -580,7 +580,6 @@
\@@_primitive:NN \pdfoutline \tex_pdfoutline:D
\@@_primitive:NN \pdfoutput \tex_pdfoutput:D
\@@_primitive:NN \pdfpageattr \tex_pdfpageattr:D
- \@@_primitive:NN \pdfpagesattr \tex_pdfpagesattr:D
\@@_primitive:NN \pdfpagebox \tex_pdfpagebox:D
\@@_primitive:NN \pdfpageref \tex_pdfpageref:D
\@@_primitive:NN \pdfpageresources \tex_pdfpageresources:D
@@ -1242,13 +1241,11 @@
% \end{macrocode}
% Primitives from \upTeX{}.
% \begin{macrocode}
- \@@_primitive:NN \currentcjktoken \tex_currentcjktoken:D
\@@_primitive:NN \disablecjktoken \tex_disablecjktoken:D
\@@_primitive:NN \enablecjktoken \tex_enablecjktoken:D
\@@_primitive:NN \forcecjktoken \tex_forcecjktoken:D
\@@_primitive:NN \kchar \tex_kchar:D
\@@_primitive:NN \kchardef \tex_kchardef:D
- \@@_primitive:NN \kuten \tex_kuten:D
\@@_primitive:NN \uptexrevision \tex_uptexrevision:D
\@@_primitive:NN \uptexversion \tex_uptexversion:D
% \end{macrocode}
diff --git a/macros/latex-dev/required/l3kernel/l3news.pdf b/macros/latex-dev/required/l3kernel/l3news.pdf
index d7871cb0de..b9e9d76f27 100644
--- a/macros/latex-dev/required/l3kernel/l3news.pdf
+++ b/macros/latex-dev/required/l3kernel/l3news.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news01.pdf b/macros/latex-dev/required/l3kernel/l3news01.pdf
index 321b592182..2aa53611ae 100644
--- a/macros/latex-dev/required/l3kernel/l3news01.pdf
+++ b/macros/latex-dev/required/l3kernel/l3news01.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news02.pdf b/macros/latex-dev/required/l3kernel/l3news02.pdf
index 1513a85c9d..54b7b0f80e 100644
--- a/macros/latex-dev/required/l3kernel/l3news02.pdf
+++ b/macros/latex-dev/required/l3kernel/l3news02.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news03.pdf b/macros/latex-dev/required/l3kernel/l3news03.pdf
index cb710d3c6b..51f28a78c7 100644
--- a/macros/latex-dev/required/l3kernel/l3news03.pdf
+++ b/macros/latex-dev/required/l3kernel/l3news03.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news04.pdf b/macros/latex-dev/required/l3kernel/l3news04.pdf
index 4888017e80..432b719c76 100644
--- a/macros/latex-dev/required/l3kernel/l3news04.pdf
+++ b/macros/latex-dev/required/l3kernel/l3news04.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news05.pdf b/macros/latex-dev/required/l3kernel/l3news05.pdf
index 6e6edba022..20ff1c692c 100644
--- a/macros/latex-dev/required/l3kernel/l3news05.pdf
+++ b/macros/latex-dev/required/l3kernel/l3news05.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news06.pdf b/macros/latex-dev/required/l3kernel/l3news06.pdf
index 66fb74bfae..2065bd5091 100644
--- a/macros/latex-dev/required/l3kernel/l3news06.pdf
+++ b/macros/latex-dev/required/l3kernel/l3news06.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news07.pdf b/macros/latex-dev/required/l3kernel/l3news07.pdf
index 55613b539c..b1273d677a 100644
--- a/macros/latex-dev/required/l3kernel/l3news07.pdf
+++ b/macros/latex-dev/required/l3kernel/l3news07.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news08.pdf b/macros/latex-dev/required/l3kernel/l3news08.pdf
index 125807c5c6..addebdad41 100644
--- a/macros/latex-dev/required/l3kernel/l3news08.pdf
+++ b/macros/latex-dev/required/l3kernel/l3news08.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news09.pdf b/macros/latex-dev/required/l3kernel/l3news09.pdf
index bb16f50cb7..9a5d6cc172 100644
--- a/macros/latex-dev/required/l3kernel/l3news09.pdf
+++ b/macros/latex-dev/required/l3kernel/l3news09.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news10.pdf b/macros/latex-dev/required/l3kernel/l3news10.pdf
index 60a66c3c10..ba8892ee26 100644
--- a/macros/latex-dev/required/l3kernel/l3news10.pdf
+++ b/macros/latex-dev/required/l3kernel/l3news10.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news11.pdf b/macros/latex-dev/required/l3kernel/l3news11.pdf
index 7ee423465c..d5dc86b58b 100644
--- a/macros/latex-dev/required/l3kernel/l3news11.pdf
+++ b/macros/latex-dev/required/l3kernel/l3news11.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3news12.pdf b/macros/latex-dev/required/l3kernel/l3news12.pdf
index c07be30ab5..5a2efedcc6 100644
--- a/macros/latex-dev/required/l3kernel/l3news12.pdf
+++ b/macros/latex-dev/required/l3kernel/l3news12.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3pdf.dtx b/macros/latex-dev/required/l3kernel/l3pdf.dtx
index 55f49476e3..b9f18324ef 100644
--- a/macros/latex-dev/required/l3kernel/l3pdf.dtx
+++ b/macros/latex-dev/required/l3kernel/l3pdf.dtx
@@ -2,7 +2,7 @@
%
%% File: l3pdf.dtx
%
-% Copyright(C) 2019-2024 The LaTeX Project
+% Copyright(C) 2019-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -70,8 +70,8 @@
% \cs{pdf_object_write:nnn} \Arg{object} \Arg{type} \Arg{content}
% \end{syntax}
% Writes the \meta{content} as content of the \meta{object}. Depending on the
-% \meta{type} declared for the object, the format required for the
-% \meta{data} will vary
+% \meta{type} declared for the object, the format required for
+% \meta{content} will vary:
% \begin{itemize}
% \item[\texttt{array}] A space-separated list of values
% \item[\texttt{dict}] Key--value pairs in the form
@@ -112,7 +112,7 @@
%
% \begin{function}[added = 2024-04-01]{\pdf_object_new_indexed:nn}
% \begin{syntax}
-% \cs{pdf_object_new_indexed:nn} \Arg{class} \Arg{index}
+% \cs{pdf_object_new_indexed:nn} \Arg{class} \Arg{index}
% \end{syntax}
% Declares a PDF object of \meta{class} and \meta{index}. The object may be
% referenced from this point on, and written later using
@@ -122,7 +122,7 @@
% \begin{function}[added = 2024-04-01]
% {\pdf_object_write_indexed:nnnn, \pdf_object_write_indexed:nnne}
% \begin{syntax}
-% \cs{pdf_object_write_indexed:nnnn} \Arg{class} \Arg{index} \Arg{type} \Arg{content}
+% \cs{pdf_object_write_indexed:nnnn} \Arg{class} \Arg{index} \Arg{type} \Arg{content}
% \end{syntax}
% Writes the \meta{content} as content of the object of \meta{class} and
% \meta{index}. Depending on the
@@ -159,7 +159,7 @@
% \cs{pdf_object_unnamed_write:nn} \Arg{type} \Arg{content}
% \end{syntax}
% Writes the \meta{content} as content of an anonymous object. Depending on the
-% \meta{type}, the format required for the \meta{data} will vary
+% \meta{type}, the format required for \meta{content} will vary:
% \begin{itemize}
% \item[\texttt{array}] A space-separated list of values
% \item[\texttt{dict}] Key--value pairs in the form
@@ -192,11 +192,11 @@
%
% \begin{function}[pTF, EXP, added = 2021-02-10]{\pdf_version_compare:Nn}
% \begin{syntax}
-% \cs{pdf_version_compare_p:Nn} \meta{comparator} \Arg{version}
-% \cs{pdf_version_compare:NnTF} \meta{comparator} \Arg{version} \Arg{true code} \Arg{false code}
+% \cs{pdf_version_compare_p:Nn} \meta{relation} \Arg{version}
+% \cs{pdf_version_compare:NnTF} \meta{relation} \Arg{version} \Arg{true code} \Arg{false code}
% \end{syntax}
% Compares the version of the PDF being created with the \meta{version}
-% string specified, using the \meta{comparator}. Either the \meta{true code}
+% string specified, using the \meta{relation}. Either the \meta{true code}
% or \meta{false code} will be left in the output stream.
% \end{function}
%
@@ -251,9 +251,9 @@
%
% \section{Destinations}
%
-% Destinations are the places a link jumped too.
-% Unlike the name may suggest they don't described
-% an exact location in the PDF. Instead a destination contains a reference to
+% Destinations are the places a link jumped to.
+% Unlike the name may suggest, they don't describe
+% an exact location in the PDF. Instead, a destination contains a reference to
% a page along with an instruction how to display this page.
% The normally used \enquote{XYZ \textit{top left zoom}} for example instructs
% the viewer to show the page with the given \textit{zoom} and
diff --git a/macros/latex-dev/required/l3kernel/l3prefixes.csv b/macros/latex-dev/required/l3kernel/l3prefixes.csv
index e85412b9d8..4fad000211 100644
--- a/macros/latex-dev/required/l3kernel/l3prefixes.csv
+++ b/macros/latex-dev/required/l3kernel/l3prefixes.csv
@@ -26,6 +26,7 @@ block,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https:
bool,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
box,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
bxjh,BXjaholiday,Takuto Asakura,https://github.com/wtsnjp/BXjaholiday,https://github.com/wtsnjp/BXjaholiday.git,https://github.com/wtsnjp/BXjaholiday/issues,2018-02-02,2019-02-02,
+cal,spath3,Andrew Stacey,https://github.com/loopspace/spath3,https://github.com/loopspace/spath3.git,https://github.com/loopspace/spath3/issues,2024-07-18,2024-07-18,
cascade,cascade,F. Pantigny,,,,2020-07-21,2020-07-21,
catcode,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
cctab,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-28,2012-09-28,
@@ -74,10 +75,12 @@ emoji,emoji,Xiangdong Zeng,https://github.com/stone-zeng/latex-emoji,https://git
emojicite,emojicite,Leon Sixt,https://github.com/berleon/emojicite,https://github.com/berleon/emojicite.git,https://github.com/berleon/emojicite/issues/,2020-04-14,2020-04-20,
empty,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
enotez,enotez,Clemens Niederberger,https://github.com/cgnieder/enotez/,https://github.com/cgnieder/enotez.git,https://github.com/cgnieder/enotez/issues,2013-03-16,2020-04-14,
+enumext,enumext,Pablo González,https://github.com/pablgonz/enumext,git@github.com:pablgonz/enumext.git,https://github.com/pablgonz/enumext/issues,2024-11-18,2024-11-18,
etex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
etl,etl,Jonathan P. Spratte,https://github.com/Skillmon/ltx_etl,git@github.com:Skillmon/ltx_etl.git,https://github.com/Skillmon/ltx_etl/issues,2021-08-16,2021-08-16,
exp,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
expl,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+expltools,expltools,Vít Starý Novotný,https://github.com/witiko/expltools/,https://github.com/witiko/expltools.git,https://github.com/witiko/expltools/issues,2024-06-26,2024-06-26,Development tools for expl3 programmers
exsheets,exsheets,Clemens Niederberger,https://bitbucket.org/cgnieder/exsheets/,git@bitbucket.org:cgnieder/exsheets.git,https://bitbucket.org/cgnieder/exsheets/issues,2013-03-16,2013-03-16,
extblx,biblatex-ext,Moritz Wemheuer,https://github.com/moewew/biblatex-ext/,https://github.com/moewew/biblatex-ext.git,https://github.com/moewew/biblatex-ext/issues,2020-02-09,2020-02-09,
exwf,exwrapfig,Takuto Asakura,https://github.com/wtsnjp/exwrapfig,https://github.com/wtsnjp/exwrapfig.git,https://github.com/wtsnjp/exwrapfig/issues,2018-06-07,2018-06-07,
@@ -132,9 +135,11 @@ job,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https:/
jsonparse,jsonparse,Jasper Habicht,https://github.com/jasperhabicht/jsonparse,https://github.com/jasperhabicht/jsonparse/jsponsparse.git,https://github.com/jasperhabicht/jsonparse/issues,2024-04-14,2024-04-14,
kernel,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
keys,"l3kernel,l3keys2e,ltkeys",The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+keythms,keytheorems,Matthew Bertucci,https://github.com/mbertucci47/keytheorems,https://github.com/mbertucci47/keytheorems,https://github.com/mbertucci47/keytheorems/issues,2024-09-10,2024-09-10,
keyval,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
kgl,kantlipsum,Enrico Gregorio,,,,2013-03-16,2013-03-16,
kivitendo,"kiviletter, kivitables",Marei Peischl for Kivitendo,https://www.kivitendo.de/,https://github.com/kivitendo/kivitendo-erp,https://forum.kivitendo.de/,2021-05-28,2021-05-28,
+knot,spath3,Andrew Stacey,https://github.com/loopspace/spath3,https://github.com/loopspace/spath3.git,https://github.com/loopspace/spath3/issues,2024-07-18,2024-07-18,
langsci,langscibook,Language Science Press,https://langsci-press.org,https://github.com/langsci/langscibook,https://github.com/langsci/langscibook/issues,2021-07-20,2021-07-21,
left,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
liftarm,liftarm,Matthias Floré,,,,2024-05-25,2024-05-25,
@@ -160,6 +165,7 @@ minibox,minibox,Will Robertson,,https://github.com/wspr/will2e.git,https://githu
minus,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
mix,media9,Alexander Grahn,,https://gitlab.com/agrahn/media9,https://gitlab.com/agrahn/media9/issues,2013-01-18,2020-04-15,
mode,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
+moremath,moremath,Marcel Ilg,https://github.com/Mister00X/moremath,https://github.com/Mister00X/moremath.git,https://github.com/Mister00X/moremath/issues,2024-07-27,2024-07-27,
morewrites,morewrites,Bruno Le Floch,https://github.com/blefloch/latex-morewrites,https://github.com/blefloch/latex-morewrites.git,https://github.com/blefloch/latex-morewrites/issues,2013-03-16,2015-09-22,
msg,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
msvg,media4svg,Alexander Grahn,,https://gitlab.com/agrahn/media4svg,https://gitlab.com/agrahn/media4svg/issues,2020-04-15,2020-04-15,
@@ -201,6 +207,7 @@ piton,piton,François Pantigny,,,,29/09/2022,29/09/2022,
pkgploader,pkgploader,Michiel Helvensteijn,,,,2014-02-05,2014-02-05,
platex,platex,Japanese TeX Development Community,https://github.com/texjporg/platex,https://github.com/texjporg/platex.git,https://github.com/texjporg/platex/issues,2020-09-30,2020-09-30,
polyglossia,polyglossia,Arthur Reutenauer,https://www.polyglossia.org/,https://github.com/reutenauer/polyglossia,https://github.com/reutenauer/polyglossia/issues,2019-09-03,,
+polyomino,polyomino,Matthias Floré,,,,2024-09-05,2024-09-05,
postnotes,postnotes,gusbrs,https://github.com/gusbrs/postnotes,https://github.com/gusbrs/postnotes.git,https://github.com/gusbrs/postnotes/issues,2022-04-23,2022-04-23,
prelim,prelim2e,Marei Peischl,https://github.com/TeXhackse/prelim2e,https://github.com/TeXhackse/prelim2e.git,https://github.com/TeXhackse/prelim2e/issues,2020-11-24,2020-11-24,
prg,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
@@ -210,6 +217,7 @@ property,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,htt
pseudo,pseudo,Magnus Lie Hetland,https://github.com/mlhetland/pseudo.sty,https://github.com/mlhetland/pseudo.sty.git,https://github.com/mlhetland/pseudo.sty/issues,2019-06-24,2019-06-24,
ptex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2015-07-28,2015-07-28,
ptxcd,ptxcd,Marei Peischl,,,,2020-07-27,2020-07-27,Used for specific corporate design templates
+ptxtools,"depp, ptxtools",Marei Peischl,https://gitlab.com/islandoftex/texmf/depp,https://gitlab.com/islandoftex/texmf/depp.git,https://gitlab.com/islandoftex/texmf/depp,2024-07-09,2024-07-09,
qrbill,qrbill,Marei Peischl,https://github.com/peiTeX/qrbill,https://github.com/peiTeX/qrbill.git,https://github.com/peiTeX/qrbill/issues,2020-06-27,2020-06-27,
quark,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
rainbow,beamertheme-rainbow,samcarter,https://github.com/samcarter/beamertheme-rainbow,https://github.com/samcarter/beamertheme-rainbow,https://github.com/samcarter/beamertheme-rainbow/issues,2023-07-04,2023-07-04,
@@ -224,6 +232,7 @@ rivbook,rivbook,Julien Rivaud,,,,2018-06-13,2018-06-14,
rivmath,rivmath,Julien Rivaud,,,,2018-06-13,2018-06-13,
rpgicons,rpgicons,Jasper Habicht,https://github.com/jasperhabicht/rpgicons,https://github.com/jasperhabicht/rpgicons/rpgicons.git,https://github.com/jasperhabicht/rpgicons/issues,2024-04-29,2024-04-29,
sanuml,sanitize-umlaut,Thomas F. Sturm,https://github.com/T-F-S/sanitize-umlaut,https://github.com/T-F-S/sanitize-umlaut.git,https://github.com/T-F-S/sanitize-umlaut/issues,2022-07-19,2022-07-19,
+scaletextbullet,scaletextbullet,Oliver Beery,https://github.com/beeryoliver/scaletextbullet,https://github.com/beeryoliver/scaletextbullet/scaletextbullet.git,https://github.com/beeryoliver/scaletextbullet/issues,2024-11-15,2024-11-15,
scan,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
schulma,schulmathematik,Keno Wehr,https://ctan.org/pkg/schulmathematik,,,2021-08-23,2021-08-23,
scontents,scontents,Pablo González,https://github.com/pablgonz/scontents,git@github.com:pablgonz/scontents.git,https://github.com/pablgonz/scontents/issues,2019-12-05,2019-12-05,
@@ -239,6 +248,7 @@ slcd,se2thesis,Stephan Lukasczyk,https://github.com/se2p/se2thesis,https://githu
socket,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex2e.git,https://github.com/latex3/latex2e/issues,2023-10-17,2023-10-17,
sort,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2017-02-13,
space,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
+spath,spath3,Andrew Stacey,https://github.com/loopspace/spath3,https://github.com/loopspace/spath3.git,https://github.com/loopspace/spath3/issues,2024-07-18,2024-07-18,
starray,starray,Alceu Frigeri,https://github.com/alceu-frigeri/starray,https://github.com/alceu-frigeri/starray,https://github.com/alceu-frigeri/starray/issues,2023-05-15,2023-05-15,
statistics,statistics,Julien Rivaud,https://gitlab.com/frnchfrgg-latex/statistics,https://gitlab.com/frnchfrgg-latex/statistics.git,https://gitlab.com/frnchfrgg-latex/statistics/issues,2018-06-25,2018-06-25,
stm,lt3-stm,CV Radhakrishnan,http://www.cvr.cc/,,,2014-02-26,2014-02-26,
@@ -258,6 +268,7 @@ tex,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https:/
text,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2020-01-15,2020-01-15,
tikzfill,tikzfill,Thomas F. Sturm,https://github.com/T-F-S/tikzfill,https://github.com/T-F-S/tikzfill.git,https://github.com/T-F-S/tikzfill/issues,2022-07-19,2022-07-19,
tikzlings,tikzlings,samcarter,https://github.com/samcarter/tikzlings,git@github.com:samcarter/tikzlings.git,https://github.com/samcarter/tikzlings/issues,2023-02-17,2023-02-17,
+tikzspath,spath3,Andrew Stacey,https://github.com/loopspace/spath3,https://github.com/loopspace/spath3.git,https://github.com/loopspace/spath3/issues,2024-07-18,2024-07-18,
tikzsymbols,tikzsymbols,Ben Vitecek,https://github.com/Vidabe/tikzsymbols,https://github.com/Vidabe/tikzsymbols.git,https://github.com/Vidabe/tikzsymbols/issues,2018-09-26,2018-09-26,
tilde,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
tl,"l3kernel,l3tl-build",The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
@@ -288,6 +299,7 @@ xmarks,latex2e,The LaTeX Project,https://www.latex-project.org/latex3.html,https
xparse,xparse,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
xpatch,"regexpatch,xpatch",Enrico Gregorio,,,,2013-03-16,2013-03-16,
xpeek,xpeek,Joel C. Salomon,,,,2013-03-16,2013-03-16,
+xpg,polyglossia,Jürgen Spitzmüller,https://github.com/reutenauer/polyglossia/,https://github.com/reutenauer/polyglossia/,https://github.com/reutenauer/polyglossia/issues,2024-07-02,2024-07-02,
xpinyin,xpinyin,Qing Lee,https://github.com/CTeX-org/ctex-kit,https://github.com/CTeX-org/ctex-kit.git,https://github.com/CTeX-org/ctex-kit/issues,2013-03-16,2013-05-26,
xsb,xsavebox,Alexander Grahn,,https://gitlab.com/agrahn/xsavebox,https://gitlab.com/agrahn/xsavebox/issues,2016-02-26,2020-04-15,
xsim,xsim,Clemens Niederberger,https://github.com/cgnieder/xsim/,https://github.com/cgnieder/xsim.git,https://github.com/cgnieder/xsim/issues,2020-04-14,2020-04-14,
@@ -299,4 +311,5 @@ zhnum,zhnumber,Qing Lee,https://github.com/CTeX-org/ctex-kit,https://github.com/
zrefcheck,zref-check,gusbrs,https://github.com/gusbrs/zref-check,https://github.com/gusbrs/zref-check,https://github.com/gusbrs/zref-check/issues,2021-08-05,2021-08-05,
zrefclever,zref-clever,gusbrs,https://github.com/gusbrs/zref-clever,https://github.com/gusbrs/zref-clever,https://github.com/gusbrs/zref-clever/issues,2021-11-29,2021-11-29,
zrefvario,zref-vario,gusbrs,https://github.com/gusbrs/zref-vario,https://github.com/gusbrs/zref-vario,https://github.com/gusbrs/zref-vario/issues,2022-02-02,2022-02-02,
+zugferd,zugferd,Marei Peischl,https://github.com/TeXhackse/LaTeX-ZUGFeRD,https://github.com/TeXhackse/LaTeX-ZUGFeRD.git,https://github.com/TeXhackse/LaTeX-ZUGFeRD/issues,2024-07-09,2024-07-09,
zxjt,zxjatype,Takayuki Yato,,,,2013-03-16,2013-03-16,
diff --git a/macros/latex-dev/required/l3kernel/l3prefixes.pdf b/macros/latex-dev/required/l3kernel/l3prefixes.pdf
index 259b86e94a..cd19a38487 100644
--- a/macros/latex-dev/required/l3kernel/l3prefixes.pdf
+++ b/macros/latex-dev/required/l3kernel/l3prefixes.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3prg.dtx b/macros/latex-dev/required/l3kernel/l3prg.dtx
index bec4e3a712..01fcec07cf 100644
--- a/macros/latex-dev/required/l3kernel/l3prg.dtx
+++ b/macros/latex-dev/required/l3kernel/l3prg.dtx
@@ -2,7 +2,7 @@
%
%% File: l3prg.dtx
%
-% Copyright (C) 2005-2024 The LaTeX Project
+% Copyright (C) 2005-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -79,41 +79,28 @@
% \begin{function}[updated = 2022-11-01]
% {
% \prg_new_conditional:Npnn, \prg_set_conditional:Npnn, \prg_gset_conditional:Npnn,
-% \prg_new_conditional:Nnn, \prg_set_conditional:Nnn, \prg_gset_conditional:Nnn
+% \prg_new_protected_conditional:Npnn, \prg_set_protected_conditional:Npnn, \prg_gset_protected_conditional:Npnn,
+% \prg_new_conditional:Nnn, \prg_set_conditional:Nnn, \prg_gset_conditional:Nnn,
+% \prg_new_protected_conditional:Nnn, \prg_set_protected_conditional:Nnn, \prg_gset_protected_conditional:Nnn
% }
% \begin{syntax}
% \cs{prg_new_conditional:Npnn} \cs[no-index]{\meta{name}:\meta{arg spec}} \meta{parameters} \Arg{conditions} \Arg{code} \\
% \cs{prg_new_conditional:Nnn} \cs[no-index]{\meta{name}:\meta{arg spec}} \Arg{conditions} \Arg{code}
% \end{syntax}
% These functions create a family of conditionals using the same
-% \Arg{code} to perform the test created. Those conditionals are
-% expandable if \meta{code} is. The \texttt{new} versions check
+% \meta{code} to perform the test created. Those non-protected
+% conditionals are expandable if \meta{code} is.
+% The \texttt{new} versions check
% for existing definitions and perform assignments globally
% (\emph{cf.}~\cs{cs_new:Npn}) whereas the \texttt{set} versions do no
% check and perform assignments locally (\emph{cf.}~\cs{cs_set:Npn}).
% The conditionals created are dependent on the comma-separated list
-% of \meta{conditions}, which should be one or more of \texttt{p},
-% \texttt{T}, \texttt{F} and \texttt{TF}.
-% \end{function}
-%
-% \begin{function}[updated = 2012-02-06]
-% {
-% \prg_new_protected_conditional:Npnn, \prg_set_protected_conditional:Npnn, \prg_gset_protected_conditional:Npnn,
-% \prg_new_protected_conditional:Nnn, \prg_set_protected_conditional:Nnn, \prg_gset_protected_conditional:Nnn
-% }
-% \begin{syntax}
-% \cs{prg_new_protected_conditional:Npnn} \cs[no-index]{\meta{name}:\meta{arg spec}} \meta{parameters} \Arg{conditions} \Arg{code} \\
-% \cs{prg_new_protected_conditional:Nnn} \cs[no-index]{\meta{name}:\meta{arg spec}} \Arg{conditions} \Arg{code}
-% \end{syntax}
-% These functions create a family of protected conditionals using the
-% same \Arg{code} to perform the test created. The \meta{code} does
-% not need to be expandable. The \texttt{new} version check for
-% existing definitions and perform assignments globally
-% (\emph{cf.}~\cs{cs_new:Npn}) whereas the \texttt{set} version do
-% not (\emph{cf.}~\cs{cs_set:Npn}). The conditionals created are
-% depended on the comma-separated list of \meta{conditions}, which
-% should be one or more of \texttt{T}, \texttt{F} and \texttt{TF} (not
-% \texttt{p}).
+% of \meta{conditions}, which should be one or more of
+% \texttt{T}, \texttt{F} and \texttt{TF}, and for non-protected conditionals
+% \texttt{p}.
+% For public conditionals, a full set of forms should be provided:
+% this contrasts with strictly internal conditionals, where only the
+% required subset need be defined.
% \end{function}
%
% The conditionals are defined by \cs{prg_new_conditional:Npnn} and
@@ -182,7 +169,7 @@
% \prg_gset_eq_conditional:NNn
% }
% \begin{syntax}
-% \cs{prg_new_eq_conditional:NNn} \cs[no-index]{\meta{name_1}:\meta{arg spec_1}} \cs[no-index]{\meta{name_2}:\meta{arg spec_2}} \Arg{conditions}
+% \cs{prg_new_eq_conditional:NNn} \cs[no-index]{\meta{name_1}:\meta{arg spec}} \cs[no-index]{\meta{name_2}:\meta{arg spec}} \Arg{conditions}
% \end{syntax}
% These functions copy a family of conditionals. The \texttt{new} version
% checks for existing definitions (\emph{cf.}~\cs{cs_new_eq:NN}) whereas
@@ -338,7 +325,7 @@
% {\bool_to_str:N, \bool_to_str:c, \bool_to_str:n}
% \begin{syntax}
% \cs{bool_to_str:N} \meta{boolean}
-% \cs{bool_to_str:n} \meta{boolean expression}
+% \cs{bool_to_str:n} \Arg{boolean expression}
% \end{syntax}
% Expands to the string \texttt{true} or \texttt{false} depending on
% the logical truth of the \meta{boolean} or \meta{boolean
@@ -664,7 +651,7 @@
% ~~\Arg{true code}
% ~~\Arg{false code}
% \end{syntax}
-% Evaluates in turn each of the \meta{boolean expression cases} until
+% Evaluates in turn each of the \meta{boolean expression case}s until
% the first one that evaluates to \texttt{true}.
% The \meta{code} associated to this first case is left in the input
% stream, followed by the \meta{true code}, and other cases are
diff --git a/macros/latex-dev/required/l3kernel/l3prop.dtx b/macros/latex-dev/required/l3kernel/l3prop.dtx
index 21b8d03dd6..e2dd1f5bff 100644
--- a/macros/latex-dev/required/l3kernel/l3prop.dtx
+++ b/macros/latex-dev/required/l3kernel/l3prop.dtx
@@ -2,7 +2,7 @@
%
%% File: l3prop.dtx
%
-% Copyright (C) 1990-2024 The LaTeX Project
+% Copyright (C) 1990-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -181,11 +181,11 @@
% \prop_gset_from_keyval:Nn, \prop_gset_from_keyval:cn,
% }
% \begin{syntax}
-% \cs{prop_set_from_keyval:Nn} \meta{property list}
-% \{
-% \meta{key1} |=| \meta{value1} |,|
-% \meta{key2} |=| \meta{value2} |,| \ldots{}
-% \}
+% \cs{prop_set_from_keyval:Nn} \meta{property list} \\
+% ~~\{ \\
+% ~~~~\meta{key_1} |=| \meta{value_1} |,| \\
+% ~~~~\meta{key_2} |=| \meta{value_2} |,| \ldots{} \\
+% ~~\}
% \end{syntax}
% Sets \meta{property list} to contain key--value pairs given in the second
% argument. If duplicate keys appear only the last of the values is kept.
@@ -205,11 +205,11 @@
% \begin{function}[added = 2017-11-28, updated = 2021-11-07]
% {\prop_const_from_keyval:Nn, \prop_const_from_keyval:cn}
% \begin{syntax}
-% \cs{prop_const_from_keyval:Nn} \meta{property list}
-% \{
-% \meta{key1} |=| \meta{value1} |,|
-% \meta{key2} |=| \meta{value2} |,| \ldots{}
-% \}
+% \cs{prop_const_from_keyval:Nn} \meta{property list} \\
+% ~~\{ \\
+% ~~~~\meta{key_1} |=| \meta{value_1} |,| \\
+% ~~~~\meta{key_2} |=| \meta{value_2} |,| \ldots{} \\
+% ~~\}
% \end{syntax}
% Creates a new constant \enquote{flat} \meta{property list} or raises
% an error if the
@@ -224,15 +224,15 @@
% \begin{function}[added = 2024-02-12]
% {\prop_const_linked_from_keyval:Nn, \prop_const_linked_from_keyval:cn}
% \begin{syntax}
-% \cs{prop_const_linked_from_keyval:Nn} \meta{prop~var}
-% \{
-% \meta{key1} |=| \meta{value1} |,|
-% \meta{key2} |=| \meta{value2} |,| \ldots{}
-% \}
+% \cs{prop_const_linked_from_keyval:Nn} \meta{property list} \\
+% ~~\{ \\
+% ~~~~\meta{key_1} |=| \meta{value_1} |,| \\
+% ~~~~\meta{key_2} |=| \meta{value_2} |,| \ldots{} \\
+% ~~\}
% \end{syntax}
-% Creates a new constant \enquote{linked} \meta{prop~var} or raises an
+% Creates a new constant \enquote{linked} \meta{property list} or raises an
% error if the
-% name is already taken. The \meta{prop~var} is set globally to
+% name is already taken. The \meta{property list} is set globally to
% contain key--value pairs given in the second argument, processed in
% the way described for \cs{prop_set_from_keyval:Nn}. If duplicate
% keys appear only the last of the values is kept.
@@ -332,7 +332,7 @@
% \prop_gconcat:NNN, \prop_gconcat:ccc
% }
% \begin{syntax}
-% \cs{prop_concat:NNN} \meta{property list_1} \meta{property list_2} \meta{property list3}
+% \cs{prop_concat:NNN} \meta{property list_1} \meta{property list_2} \meta{property list_3}
% \end{syntax}
% Combines the key--value pairs of \meta{property list_2} and
% \meta{property list_3}, and saves the result in \meta{property list_1}. If a
@@ -347,11 +347,11 @@
% \prop_gput_from_keyval:Nn, \prop_gput_from_keyval:cn,
% }
% \begin{syntax}
-% \cs{prop_put_from_keyval:Nn} \meta{property list}
-% \{
-% \meta{key1} |=| \meta{value1} |,|
-% \meta{key2} |=| \meta{value2} |,| \ldots{}
-% \}
+% \cs{prop_put_from_keyval:Nn} \meta{property list} \\
+% ~~\{ \\
+% ~~~~\meta{key_1} |=| \meta{value_1} |,| \\
+% ~~~~\meta{key_2} |=| \meta{value_2} |,| \ldots{} \\
+% ~~\}
% \end{syntax}
% Updates the \meta{property list} by adding entries for each key--value
% pair given in the second argument. The addition is done through
@@ -384,11 +384,11 @@
% \cs{prop_get:NnN} \meta{property list} \Arg{key} \meta{tl var}
% \end{syntax}
% Recovers the \meta{value} stored with \meta{key} from the
-% \meta{property list}, and places this in the \meta{token list
-% variable}. If the \meta{key} is not found in the
-% \meta{property list} then the \meta{token list variable} is set
-% to the special marker \cs{q_no_value}. The \meta{token list
-% variable} is set within the current \TeX{} group. See also
+% \meta{property list}, and places this in the \meta{tl
+% var}. If the \meta{key} is not found in the
+% \meta{property list} then the \meta{tl~var} is set
+% to the special marker \cs{q_no_value}. The \meta{tl
+% var} is set within the current \TeX{} group. See also
% \cs{prop_get:NnNTF}.
% \end{function}
%
@@ -403,9 +403,9 @@
% \cs{prop_pop:NnN} \meta{property list} \Arg{key} \meta{tl var}
% \end{syntax}
% Recovers the \meta{value} stored with \meta{key} from the
-% \meta{property list}, and places this in the \meta{token list
-% variable}. If the \meta{key} is not found in the
-% \meta{property list} then the \meta{token list variable} is set
+% \meta{property list}, and places this in the \meta{tl
+% var}. If the \meta{key} is not found in the
+% \meta{property list} then the \meta{tl~var} is set
% to the special marker \cs{q_no_value}. The \meta{key} and
% \meta{value} are then deleted from the property list. Both
% assignments are local. See also \cs{prop_pop:NnNTF}.
@@ -422,13 +422,13 @@
% \cs{prop_gpop:NnN} \meta{property list} \Arg{key} \meta{tl var}
% \end{syntax}
% Recovers the \meta{value} stored with \meta{key} from the
-% \meta{property list}, and places this in the \meta{token list
-% variable}. If the \meta{key} is not found in the
-% \meta{property list} then the \meta{token list variable} is set
+% \meta{property list}, and places this in the \meta{tl
+% var}. If the \meta{key} is not found in the
+% \meta{property list} then the \meta{tl~var} is set
% to the special marker \cs{q_no_value}. The \meta{key} and
% \meta{value} are then deleted from the property list.
% The \meta{property list} is modified globally, while the assignment of
-% the \meta{token list variable} is local. See also \cs{prop_gpop:NnNTF}.
+% the \meta{tl~var} is local. See also \cs{prop_gpop:NnNTF}.
% \end{function}
%
% \begin{function}[EXP, added = 2014-07-17]
@@ -553,17 +553,17 @@
% \prop_get:cnc
% }
% \begin{syntax}
-% \cs{prop_get:NnNTF} \meta{property list} \Arg{key} \meta{token list variable} \\
+% \cs{prop_get:NnNTF} \meta{property list} \Arg{key} \meta{tl~var} \\
% ~~\Arg{true code} \Arg{false code}
% \end{syntax}
% If the \meta{key} is not present in the \meta{property list}, leaves
% the \meta{false code} in the input stream. The value of the
-% \meta{token list variable} is not defined in this case and should
+% \meta{tl~var} is not defined in this case and should
% not be relied upon. If the \meta{key} is present in the
% \meta{property list}, stores the corresponding \meta{value} in the
-% \meta{token list variable} without removing it from the
+% \meta{tl~var} without removing it from the
% \meta{property list}, then leaves the \meta{true code} in the input
-% stream. The \meta{token list variable} is assigned locally.
+% stream. The \meta{tl~var} is assigned locally.
% \end{function}
%
% \begin{function}[TF, added = 2011-08-18, updated = 2012-05-19]
@@ -574,17 +574,17 @@
% \prop_pop:coN
% }
% \begin{syntax}
-% \cs{prop_pop:NnNTF} \meta{property list} \Arg{key} \meta{token list variable} \\
+% \cs{prop_pop:NnNTF} \meta{property list} \Arg{key} \meta{tl~var} \\
% ~~\Arg{true code} \Arg{false code}
% \end{syntax}
% If the \meta{key} is not present in the \meta{property list}, leaves
% the \meta{false code} in the input stream. The value of the
-% \meta{token list variable} is not defined in this case and should
+% \meta{tl~var} is not defined in this case and should
% not be relied upon. If the \meta{key} is present in
% the \meta{property list}, pops the corresponding \meta{value}
-% in the \meta{token list variable}, \emph{i.e.}~removes the item from
+% in the \meta{tl~var}, \emph{i.e.}~removes the item from
% the \meta{property list}.
-% Both the \meta{property list} and the \meta{token list variable}
+% Both the \meta{property list} and the \meta{tl~var}
% are assigned locally.
% \end{function}
%
@@ -596,18 +596,18 @@
% \prop_gpop:coN
% }
% \begin{syntax}
-% \cs{prop_gpop:NnNTF} \meta{property list} \Arg{key} \meta{token list variable} \\
+% \cs{prop_gpop:NnNTF} \meta{property list} \Arg{key} \meta{tl~var} \\
% ~~\Arg{true code} \Arg{false code}
% \end{syntax}
% If the \meta{key} is not present in the \meta{property list}, leaves
% the \meta{false code} in the input stream. The value of the
-% \meta{token list variable} is not defined in this case and should
+% \meta{tl~var} is not defined in this case and should
% not be relied upon. If the \meta{key} is present in
% the \meta{property list}, pops the corresponding \meta{value}
-% in the \meta{token list variable}, \emph{i.e.}~removes the item from
+% in the \meta{tl~var}, \emph{i.e.}~removes the item from
% the \meta{property list}.
% The \meta{property list} is modified globally, while the
-% \meta{token list variable} is assigned locally.
+% \meta{tl~var} is assigned locally.
% \end{function}
%
% \section{Mapping over property lists}
@@ -1724,7 +1724,7 @@
\exp_after:wN { \tl_to_str:n {#2} }
}
}
- { \exp_after:wN \@@_get_linked:w #1 {#2} \use:n { } { } }
+ { \exp_after:wN \@@_get_linked:w #1 {#2} \exp_not:n { } { } }
}
\cs_new:Npn \@@_item:nnn #1#2#3
{
diff --git a/macros/latex-dev/required/l3kernel/l3quark.dtx b/macros/latex-dev/required/l3kernel/l3quark.dtx
index 136596a3fe..9b90b606f7 100644
--- a/macros/latex-dev/required/l3kernel/l3quark.dtx
+++ b/macros/latex-dev/required/l3kernel/l3quark.dtx
@@ -2,7 +2,7 @@
%
%% File: l3quark.dtx
%
-% Copyright (C) 1990-2024 The LaTeX Project
+% Copyright (C) 1990-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -32,7 +32,7 @@
%
% \title{^^A
% The \pkg{l3quark} module\\ Quarks and scan marks^^A
-% }
+% }\ifdefined\thechapter\label{sec:l3quarks}\fi
%
% \author{^^A
% The \LaTeX{} Project\thanks
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
diff --git a/macros/latex-dev/required/l3kernel/l3regex.dtx b/macros/latex-dev/required/l3kernel/l3regex.dtx
index 6ca9c8eeed..868f695f3c 100644
--- a/macros/latex-dev/required/l3kernel/l3regex.dtx
+++ b/macros/latex-dev/required/l3kernel/l3regex.dtx
@@ -2,7 +2,7 @@
%
%% File: l3regex.dtx
%
-% Copyright (C) 2011-2024 The LaTeX Project
+% Copyright (C) 2011-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -469,12 +469,12 @@
% the same category codes as in the original token list.
%
% By default, the category code of characters inserted by the
-% replacement are determined by the prevailing category code regime at
+% replacement are determined by the prevailing category code régime at
% the time where the replacement is made, with two exceptions:
% \begin{itemize}
% \item space characters (with character code $32$) inserted with
% \verb*|\ | or |\x20| or |\x{20}| have category code~$10$ regardless
-% of the prevailing category code regime;
+% of the prevailing category code régime;
% \item if the category code would be $0$~(escape), $5$~(newline),
% $9$~(ignore), $14$~(comment) or $15$~(invalid), it is replaced by
% $12$~(other) instead.
@@ -541,7 +541,7 @@
% \begin{syntax}
% \cs{regex_set:Nn} \meta{regex~var} \Arg{regex}
% \end{syntax}
-% Stores a compiled version of the \meta{regular expression} in the
+% Stores a compiled version of the \meta{regex} in the
% \meta{regex~var}. The assignment is local for \cs{regex_set:Nn} and
% global for \cs{regex_gset:Nn}. For instance, this function can be
% used as
@@ -557,7 +557,7 @@
% \end{syntax}
% Creates a new constant \meta{regex~var} or raises an error if the name
% is already taken. The value of the \meta{regex~var} is set
-% globally to the compiled version of the \meta{regular expression}.
+% globally to the compiled version of the \meta{regex}.
% \end{function}
%
% \begin{function}[added = 2021-04-26, updated = 2021-04-29]
@@ -595,7 +595,7 @@
% \begin{syntax}
% \cs{regex_match:nnTF} \Arg{regex} \Arg{token list} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests whether the \meta{regular expression} matches any part
+% Tests whether the \meta{regex} matches any part
% of the \meta{token list}. For instance,
% \begin{verbatim}
% \regex_match:nnTF { b [cde]* } { abecdcx } { TRUE } { FALSE }
@@ -610,11 +610,11 @@
% \regex_count:NnN, \regex_count:NVN
% }
% \begin{syntax}
-% \cs{regex_count:nnN} \Arg{regex} \Arg{token list} \meta{int var}
+% \cs{regex_count:nnN} \Arg{regex} \Arg{token list} \meta{integer}
% \end{syntax}
-% Sets \meta{int var} within the current \TeX{} group level
+% Sets \meta{integer} within the current \TeX{} group level
% equal to the number of times
-% \meta{regular expression} appears in \meta{token list}.
+% \meta{regex} appears in \meta{token list}.
% The search starts by finding the left-most longest match,
% respecting greedy and lazy (non-greedy) operators. Then the search
% starts again from the character following the last character
@@ -643,7 +643,7 @@
% \end{syntax}
% Determines which of the \meta{regular expressions} matches at the
% earliest point in the \meta{token list}, and leaves the
-% corresponding \meta{code_i} followed by the \meta{true code} in the
+% corresponding \meta{code} followed by the \meta{true code} in the
% input stream. If several \meta{regex} match starting at the same
% point, then the first one in the list is selected and the others are
% discarded. If none of the \meta{regex} match, the \meta{false code}
@@ -673,7 +673,7 @@
% \cs{regex_extract_once:nnN} \Arg{regex} \Arg{token list} \meta{seq~var}
% \cs{regex_extract_once:nnNTF} \Arg{regex} \Arg{token list} \meta{seq~var} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Finds the first match of the \meta{regular expression} in the
+% Finds the first match of the \meta{regex} in the
% \meta{token list}. If it exists, the match is stored as the first
% item of the \meta{seq~var}, and further items are the contents of
% capturing groups, in the order of their opening parenthesis. The
@@ -707,7 +707,7 @@
% \cs{regex_extract_all:nnN} \Arg{regex} \Arg{token list} \meta{seq~var}
% \cs{regex_extract_all:nnNTF} \Arg{regex} \Arg{token list} \meta{seq~var} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Finds all matches of the \meta{regular expression}
+% Finds all matches of the \meta{regex}
% in the \meta{token list}, and stores all the submatch information
% in a single sequence (concatenating the results of
% multiple \cs{regex_extract_once:nnN} calls).
@@ -731,15 +731,15 @@
% \regex_split:NnN, \regex_split:NVN,
% }
% \begin{syntax}
-% \cs{regex_split:nnN} \Arg{regular expression} \Arg{token list} \meta{seq~var}
-% \cs{regex_split:nnNTF} \Arg{regular expression} \Arg{token list} \meta{seq~var} \Arg{true code} \Arg{false code}
+% \cs{regex_split:nnN} \Arg{regex} \Arg{token list} \meta{seq~var}
+% \cs{regex_split:nnNTF} \Arg{regex} \Arg{token list} \meta{seq~var} \Arg{true code} \Arg{false code}
% \end{syntax}
% Splits the \meta{token list} into a sequence of parts, delimited by
-% matches of the \meta{regular expression}. If the \meta{regular expression}
+% matches of the \meta{regex}. If the \meta{regex}
% has capturing groups, then the token lists that they match are stored as
% items of the sequence as well. The assignment to \meta{seq~var} is local.
% If no match is found the resulting \meta{seq~var} has the
-% \meta{token list} as its sole item. If the \meta{regular expression}
+% \meta{token list} as its sole item. If the \meta{regex}
% matches the empty token list, then the \meta{token list} is split
% into single tokens.
% The testing versions insert the \meta{true code} into the input
@@ -763,10 +763,10 @@
% \regex_replace_once:NnN,\regex_replace_once:NVN
% }
% \begin{syntax}
-% \cs{regex_replace_once:nnN} \Arg{regular expression} \Arg{replacement} \meta{tl~var}
-% \cs{regex_replace_once:nnNTF} \Arg{regular expression} \Arg{replacement} \meta{tl~var} \Arg{true code} \Arg{false code}
+% \cs{regex_replace_once:nnN} \Arg{regex} \Arg{replacement} \meta{tl~var}
+% \cs{regex_replace_once:nnNTF} \Arg{regex} \Arg{replacement} \meta{tl~var} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Searches for the \meta{regular expression} in the contents of the
+% Searches for the \meta{regex} in the contents of the
% \meta{tl~var} and replaces the first match with the
% \meta{replacement}. In the \meta{replacement},
% |\0| represents the full match, |\1| represent the contents of the
@@ -780,10 +780,10 @@
% \regex_replace_all:NnN,\regex_replace_all:NVN
% }
% \begin{syntax}
-% \cs{regex_replace_all:nnN} \Arg{regular expression} \Arg{replacement} \meta{tl~var}
-% \cs{regex_replace_all:nnNTF} \Arg{regular expression} \Arg{replacement} \meta{tl~var} \Arg{true code} \Arg{false code}
+% \cs{regex_replace_all:nnN} \Arg{regex} \Arg{replacement} \meta{tl~var}
+% \cs{regex_replace_all:nnNTF} \Arg{regex} \Arg{replacement} \meta{tl~var} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Replaces all occurrences of the \meta{regular expression} in the
+% Replaces all occurrences of the \meta{regex} in the
% contents of the \meta{tl~var}
% by the \meta{replacement}, where |\0| represents
% the full match, |\1| represent the contents of the first capturing
@@ -804,8 +804,8 @@
% ~~\Arg{true code} \Arg{false code}
% \end{syntax}
% Replaces the earliest match of the regular expression
-% "(?|"\meta{regex_1}"|"\dots"|"\meta{regex_n}")" in the \meta{token
-% list variable} by the \meta{replacement} corresponding to which
+% "(?|"\meta{regex_1}"|"\dots"|"\meta{regex_n}")" in the
+% \meta{tl var} by the \meta{replacement} corresponding to which
% \meta{regex_i} matched, then leaves the \meta{true code} in the
% input stream. If none of the \meta{regex} match, then the
% \meta{tl~var} is not modified, and the \meta{false code} is left in
@@ -5970,8 +5970,8 @@
% corresponding to the initial value of
% \cs{l_@@_replacement_category_tl}.
% The argument |#1| is a single character (including the case of a catcode-other space).
-% In case no specific catcode is requested, we taked into account the
-% current catcode regime (at the time the replacement is performed)
+% In case no specific catcode is requested, we take into account the
+% current catcode régime (at the time the replacement is performed)
% as much as reasonable, with all impossible catcodes (escape,
% newline, etc.) being mapped to \enquote{other}.
% \begin{macrocode}
diff --git a/macros/latex-dev/required/l3kernel/l3seq.dtx b/macros/latex-dev/required/l3kernel/l3seq.dtx
index 38fc9471a9..b882319b44 100644
--- a/macros/latex-dev/required/l3kernel/l3seq.dtx
+++ b/macros/latex-dev/required/l3kernel/l3seq.dtx
@@ -2,7 +2,7 @@
%
%% File: l3seq.dtx
%
-% Copyright (C) 1990-2024 The LaTeX Project
+% Copyright (C) 1990-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -108,10 +108,10 @@
% \seq_gset_from_clist:Nn, \seq_gset_from_clist:cn
% }
% \begin{syntax}
-% \cs{seq_set_from_clist:NN} \meta{seq~var} \meta{comma-list}
+% \cs{seq_set_from_clist:NN} \meta{seq~var} \meta{clist~var}
% \end{syntax}
-% Converts the data in the \meta{comma list} into a \meta{seq~var}:
-% the original \meta{comma list} is unchanged.
+% Converts the data in the \meta{clist~var} into a \meta{seq~var}:
+% the original \meta{clist~var} is unchanged.
% \end{function}
%
% \begin{function}[added = 2017-11-28]
@@ -145,9 +145,9 @@
% \cs{seq_set_split:Nnn}, and can be removed afterwards using
% \cs{seq_remove_all:Nn} \meta{seq~var} |{}|.
% The \meta{delimiter} may not contain |{|, |}| or |#|
-% (assuming \TeX{}'s normal category code r\'egime).
+% (assuming \TeX{}'s normal category code régime).
% If the \meta{delimiter} is empty, the \meta{token list} is split
-% into \meta{items} as a \meta{token list}.
+% into \meta{items} as described for \cs{tl_map_function:nN}.
% See also \cs{seq_set_split_keep_spaces:Nnn}, which omits space stripping.
% \end{function}
%
@@ -167,9 +167,10 @@
% \cs{seq_set_split_keep_spaces:Nnn}, and can be removed afterwards using
% \cs{seq_remove_all:Nn} \meta{seq~var} |{}|.
% The \meta{delimiter} may not contain |{|, |}| or |#|
-% (assuming \TeX{}'s normal category code r\'egime).
+% (assuming \TeX{}'s normal category code régime).
% If the \meta{delimiter} is empty, the \meta{token list} is split
-% into \meta{items} as a \meta{token list}.
+% into \meta{items} as described for \cs{tl_map_function:nN}; note in this
+% case spaces will \emph{not} be preserved.
% See also \cs{seq_set_split:Nnn}, which removes spaces around the delimiters.
% \end{function}
%
@@ -189,6 +190,81 @@
% \end{texnote}
% \end{function}
%
+% \begin{function}[added = 2024-12-08]
+% {
+% \seq_set_regex_extract_once:Nnn, \seq_set_regex_extract_once:cnn,
+% \seq_set_regex_extract_once:NNn, \seq_set_regex_extract_once:cNn,
+% \seq_gset_regex_extract_once:Nnn, \seq_gset_regex_extract_once:cnn,
+% \seq_gset_regex_extract_once:NNn, \seq_gset_regex_extract_once:cNn,
+% }
+% \begin{syntax}
+% \cs{seq_set_regex_extract_once:Nnn} \meta{seq~var} \Arg{regex} \Arg{token list}
+% \cs{seq_set_regex_extract_once:NNn} \meta{seq~var} \meta{regex~var} \Arg{token list}
+% \end{syntax}
+% Finds the first match of the \meta{regex} in the
+% \meta{token list}. If it exists, the match is stored as the first
+% item of the \meta{seq~var}, and further items are the contents of
+% capturing groups, in the order of their opening parenthesis.
+% If there is no match, the \meta{seq~var} is cleared.
+% Theses are alternative names for \cs{regex_extract_once:nnN} and friends,
+% with arguments re-ordered for \meta{seq~var} setting;
+% see \pkg{l3regex} chapter for more details of the \meta{regex}
+% format.
+% \end{function}
+%
+% \begin{function}[added = 2024-12-08]
+% {
+% \seq_set_regex_extract_all:Nnn, \seq_set_regex_extract_all:cnn,
+% \seq_set_regex_extract_all:NNn, \seq_set_regex_extract_all:cNn,
+% \seq_gset_regex_extract_all:Nnn, \seq_gset_regex_extract_all:cnn,
+% \seq_gset_regex_extract_all:NNn, \seq_gset_regex_extract_all:cNn,
+% }
+% \begin{syntax}
+% \cs{seq_set_regex_extract_all:Nnn} \meta{seq~var} \Arg{regex} \Arg{token list}
+% \cs{seq_set_regex_extract_all:NNn} \meta{seq~var} \meta{regex~var} \Arg{token list}
+% \end{syntax}
+% Finds all matches of the \meta{regex} in the
+% \meta{token list}, and stores all the submatch information
+% in a single sequence (concatenating the results of
+% multiple \cs{seq_set_regex_extract_all:Nnn} calls).
+% If there is no match, the \meta{seq~var} is cleared.
+% Theses are alternative names for \cs{regex_extract_all:nnN} and friends,
+% with arguments re-ordered for \meta{seq~var} setting;
+% see \pkg{l3regex} chapter for more details of the \meta{regex}
+% format.
+% \end{function}
+%
+% \begin{function}[added = 2024-12-08]
+% {
+% \seq_set_regex_split:Nnn, \seq_set_regex_split:cnn,
+% \seq_set_regex_split:NNn, \seq_set_regex_split:cNn,
+% \seq_gset_regex_split:Nnn, \seq_gset_regex_split:cnn,
+% \seq_gset_regex_split:NNn, \seq_gset_regex_split:cNn,
+% }
+% \begin{syntax}
+% \cs{seq_set_regex_split:Nnn} \meta{seq~var} \Arg{regex} \Arg{token list}
+% \cs{seq_set_regex_split:NNn} \meta{seq~var} \meta{regex~var} \Arg{token list}
+% \end{syntax}
+% Splits the \meta{token list} into a sequence of parts, delimited by
+% matches of the \meta{regular expression}. If the \meta{regular expression}
+% has capturing groups, then the token lists that they match are stored as
+% items of the sequence as well.
+% If no match is found the resulting \meta{seq~var} has the
+% \meta{token list} as its sole item. If the \meta{regular expression}
+% matches the empty token list, then the \meta{token list} is split
+% into single tokens.
+% For example, after
+% \begin{verbatim}
+% \seq_set_regex_split:Nnn \l_path_seq { / } { the/path/for/this/file.tex }
+% \end{verbatim}
+% the sequence |\l_path_seq| contains the items |{the}|, |{path}|,
+% |{for}|, |{this}|, and |{file.tex}|.
+% Theses are alternative names for \cs{regex_split:nnN} and friends,
+% with arguments re-ordered for \meta{seq~var} setting;
+% see \pkg{l3regex} chapter for more details of the \meta{regex}
+% format.
+% \end{function}
+%
% \begin{function}
% {\seq_concat:NNN, \seq_concat:ccc, \seq_gconcat:NNN, \seq_gconcat:ccc}
% \begin{syntax}
@@ -249,78 +325,78 @@
% For implementation reasons, the actions at the left of the sequence are
% faster than those acting on the right. These functions all assign the
% recovered material locally, \emph{i.e.}~setting the
-% \meta{token list variable} used with \cs{tl_set:Nn} and \emph{never}
+% \meta{tl~var} used with \cs{tl_set:Nn} and \emph{never}
% \cs{tl_gset:Nn}.
%
% \begin{function}[updated = 2012-05-14]{\seq_get_left:NN, \seq_get_left:cN}
% \begin{syntax}
-% \cs{seq_get_left:NN} \meta{seq~var} \meta{token list variable}
+% \cs{seq_get_left:NN} \meta{seq~var} \meta{tl~var}
% \end{syntax}
% Stores the left-most item from a \meta{seq~var} in the
-% \meta{token list variable} without removing it from the
-% \meta{seq~var}. The \meta{token list variable} is assigned locally.
-% If \meta{seq~var} is empty the \meta{token list variable}
+% \meta{tl~var} without removing it from the
+% \meta{seq~var}. The \meta{tl~var} is assigned locally.
+% If \meta{seq~var} is empty the \meta{tl~var}
% is set to the special marker \cs{q_no_value}.
% \end{function}
%
% \begin{function}[updated = 2012-05-19]{\seq_get_right:NN, \seq_get_right:cN}
% \begin{syntax}
-% \cs{seq_get_right:NN} \meta{seq~var} \meta{token list variable}
+% \cs{seq_get_right:NN} \meta{seq~var} \meta{tl~var}
% \end{syntax}
% Stores the right-most item from a \meta{seq~var} in the
-% \meta{token list variable} without removing it from the
-% \meta{seq~var}. The \meta{token list variable} is assigned locally.
-% If \meta{seq~var} is empty the \meta{token list variable}
+% \meta{tl~var} without removing it from the
+% \meta{seq~var}. The \meta{tl~var} is assigned locally.
+% If \meta{seq~var} is empty the \meta{tl~var}
% is set to the special marker \cs{q_no_value}.
% \end{function}
%
% \begin{function}[updated = 2012-05-14]{\seq_pop_left:NN, \seq_pop_left:cN}
% \begin{syntax}
-% \cs{seq_pop_left:NN} \meta{seq~var} \meta{token list variable}
+% \cs{seq_pop_left:NN} \meta{seq~var} \meta{tl~var}
% \end{syntax}
% Pops the left-most item from a \meta{seq~var} into the
-% \meta{token list variable}, \emph{i.e.}~removes the item from the
-% sequence and stores it in the \meta{token list variable}.
+% \meta{tl~var}, \emph{i.e.}~removes the item from the
+% sequence and stores it in the \meta{tl~var}.
% Both of the variables are assigned locally. If \meta{seq~var} is
-% empty the \meta{token list variable} is set to
+% empty the \meta{tl~var} is set to
% the special marker \cs{q_no_value}.
% \end{function}
%
% \begin{function}[updated = 2012-05-14]{\seq_gpop_left:NN, \seq_gpop_left:cN}
% \begin{syntax}
-% \cs{seq_gpop_left:NN} \meta{seq~var} \meta{token list variable}
+% \cs{seq_gpop_left:NN} \meta{seq~var} \meta{tl~var}
% \end{syntax}
% Pops the left-most item from a \meta{seq~var} into the
-% \meta{token list variable}, \emph{i.e.}~removes the item from the
-% sequence and stores it in the \meta{token list variable}.
+% \meta{tl~var}, \emph{i.e.}~removes the item from the
+% sequence and stores it in the \meta{tl~var}.
% The \meta{seq~var} is modified globally, while the assignment of
-% the \meta{token list variable} is local.
-% If \meta{seq~var} is empty the \meta{token list variable} is set to
+% the \meta{tl~var} is local.
+% If \meta{seq~var} is empty the \meta{tl~var} is set to
% the special marker \cs{q_no_value}.
% \end{function}
%
% \begin{function}[updated = 2012-05-19]{\seq_pop_right:NN, \seq_pop_right:cN}
% \begin{syntax}
-% \cs{seq_pop_right:NN} \meta{seq~var} \meta{token list variable}
+% \cs{seq_pop_right:NN} \meta{seq~var} \meta{tl~var}
% \end{syntax}
% Pops the right-most item from a \meta{seq~var} into the
-% \meta{token list variable}, \emph{i.e.}~removes the item from the
-% sequence and stores it in the \meta{token list variable}.
+% \meta{tl~var}, \emph{i.e.}~removes the item from the
+% sequence and stores it in the \meta{tl~var}.
% Both of the variables are assigned locally. If \meta{seq~var} is
-% empty the \meta{token list variable} is set to
+% empty the \meta{tl~var} is set to
% the special marker \cs{q_no_value}.
% \end{function}
%
% \begin{function}[updated = 2012-05-19]{\seq_gpop_right:NN, \seq_gpop_right:cN}
% \begin{syntax}
-% \cs{seq_gpop_right:NN} \meta{seq~var} \meta{token list variable}
+% \cs{seq_gpop_right:NN} \meta{seq~var} \meta{tl~var}
% \end{syntax}
% Pops the right-most item from a \meta{seq~var} into the
-% \meta{token list variable}, \emph{i.e.}~removes the item from the
-% sequence and stores it in the \meta{token list variable}.
+% \meta{tl~var}, \emph{i.e.}~removes the item from the
+% sequence and stores it in the \meta{tl~var}.
% The \meta{seq~var} is modified globally, while the assignment of
-% the \meta{token list variable} is local.
-% If \meta{seq~var} is empty the \meta{token list variable} is set to
+% the \meta{tl~var} is local.
+% If \meta{seq~var} is empty the \meta{tl~var} is set to
% the special marker \cs{q_no_value}.
% \end{function}
%
@@ -371,92 +447,92 @@
% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]
% {\seq_get_left:NN, \seq_get_left:cN}
% \begin{syntax}
-% \cs{seq_get_left:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{seq_get_left:NNTF} \meta{seq~var} \meta{tl~var} \Arg{true code} \Arg{false code}
% \end{syntax}
% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
-% input stream. The value of the \meta{token list variable} is
+% input stream. The value of the \meta{tl~var} is
% not defined in this case and should not be relied upon. If the
% \meta{seq~var} is non-empty, stores the left-most item from the
% \meta{seq~var}
-% in the \meta{token list variable} without removing it from the
+% in the \meta{tl~var} without removing it from the
% \meta{seq~var}, then leaves the \meta{true code} in the input stream.
-% The \meta{token list variable} is assigned locally.
+% The \meta{tl~var} is assigned locally.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-19]
% {\seq_get_right:NN, \seq_get_right:cN}
% \begin{syntax}
-% \cs{seq_get_right:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{seq_get_right:NNTF} \meta{seq~var} \meta{tl~var} \Arg{true code} \Arg{false code}
% \end{syntax}
% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
-% input stream. The value of the \meta{token list variable} is
+% input stream. The value of the \meta{tl~var} is
% not defined in this case and should not be relied upon. If the
% \meta{seq~var} is non-empty, stores the right-most item from the
% \meta{seq~var}
-% in the \meta{token list variable} without removing it from the
+% in the \meta{tl~var} without removing it from the
% \meta{seq~var}, then leaves the \meta{true code} in the input stream.
-% The \meta{token list variable} is assigned locally.
+% The \meta{tl~var} is assigned locally.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]
% {\seq_pop_left:NN, \seq_pop_left:cN}
% \begin{syntax}
-% \cs{seq_pop_left:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{seq_pop_left:NNTF} \meta{seq~var} \meta{tl~var} \Arg{true code} \Arg{false code}
% \end{syntax}
% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
-% input stream. The value of the \meta{token list variable} is
+% input stream. The value of the \meta{tl~var} is
% not defined in this case and should not be relied upon. If the
% \meta{seq~var} is non-empty, pops the left-most item from the
% \meta{seq~var}
-% in the \meta{token list variable}, \emph{i.e.}~removes the item from the
+% in the \meta{tl~var}, \emph{i.e.}~removes the item from the
% \meta{seq~var}, then leaves the \meta{true code} in the input stream.
-% Both the \meta{seq~var} and the \meta{token list variable} are assigned
+% Both the \meta{seq~var} and the \meta{tl~var} are assigned
% locally.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]
% {\seq_gpop_left:NN, \seq_gpop_left:cN}
% \begin{syntax}
-% \cs{seq_gpop_left:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{seq_gpop_left:NNTF} \meta{seq~var} \meta{tl~var} \Arg{true code} \Arg{false code}
% \end{syntax}
% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
-% input stream. The value of the \meta{token list variable} is
+% input stream. The value of the \meta{tl~var} is
% not defined in this case and should not be relied upon. If the
% \meta{seq~var} is non-empty, pops the left-most item from the \meta{seq~var}
-% in the \meta{token list variable}, \emph{i.e.}~removes the item from the
+% in the \meta{tl~var}, \emph{i.e.}~removes the item from the
% \meta{seq~var}, then leaves the \meta{true code} in the input stream.
-% The \meta{seq~var} is modified globally, while the \meta{token list variable}
+% The \meta{seq~var} is modified globally, while the \meta{tl~var}
% is assigned locally.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-19]
% {\seq_pop_right:NN, \seq_pop_right:cN}
% \begin{syntax}
-% \cs{seq_pop_right:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{seq_pop_right:NNTF} \meta{seq~var} \meta{tl~var} \Arg{true code} \Arg{false code}
% \end{syntax}
% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
-% input stream. The value of the \meta{token list variable} is
+% input stream. The value of the \meta{tl~var} is
% not defined in this case and should not be relied upon. If the
% \meta{seq~var} is non-empty, pops the right-most item from the \meta{seq~var}
-% in the \meta{token list variable}, \emph{i.e.}~removes the item from the
+% in the \meta{tl~var}, \emph{i.e.}~removes the item from the
% \meta{seq~var}, then leaves the \meta{true code} in the input stream.
-% Both the \meta{seq~var} and the \meta{token list variable} are assigned
+% Both the \meta{seq~var} and the \meta{tl~var} are assigned
% locally.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-19]
% {\seq_gpop_right:NN, \seq_gpop_right:cN}
% \begin{syntax}
-% \cs{seq_gpop_right:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{seq_gpop_right:NNTF} \meta{seq~var} \meta{tl~var} \Arg{true code} \Arg{false code}
% \end{syntax}
% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
-% input stream. The value of the \meta{token list variable} is
+% input stream. The value of the \meta{tl~var} is
% not defined in this case and should not be relied upon. If the
% \meta{seq~var} is non-empty, pops the right-most item from the \meta{seq~var}
-% in the \meta{token list variable}, \emph{i.e.}~removes the item from the
+% in the \meta{tl~var}, \emph{i.e.}~removes the item from the
% \meta{seq~var}, then leaves the \meta{true code} in the input stream.
% The \meta{seq~var} is modified globally, while the
-% \meta{token list variable} is assigned locally.
+% \meta{tl~var} is assigned locally.
% \end{function}
%
% \section{Modifying sequences}
@@ -672,10 +748,10 @@
% \seq_map_pairwise_function:cNN, \seq_map_pairwise_function:ccN
% }
% \begin{syntax}
-% \cs{seq_map_pairwise_function:NNN} \meta{seq_1} \meta{seq_2} \meta{function}
+% \cs{seq_map_pairwise_function:NNN} \meta{seq var_1} \meta{seq var_2} \meta{function}
% \end{syntax}
% Applies \meta{function} to every pair of items
-% \meta{seq_1-item}--\meta{seq_2-item} from the two sequences, returning
+% \meta{seq var_1-item}--\meta{seq var_2-item} from the two sequences, returning
% items from both sequences from left to right. The \meta{function}
% receives two \texttt{n}-type arguments for each iteration. The mapping
% terminates when
@@ -747,7 +823,7 @@
% Applies \meta{inline function} to every \meta{item} stored
% within the \meta{seq~var_2}. The \meta{inline function} should
% consist of code which will receive the \meta{item} as |#1|.
-% The sequence resulting applying \meta{inline function} to each
+% The sequence resulting from applying \meta{inline function} to each
% \meta{item} is assigned to \meta{seq~var_1}.
% \begin{texnote}
% Contrarily to other mapping functions, \cs{seq_map_break:} cannot
@@ -852,72 +928,72 @@
%
% \begin{function}[updated = 2012-05-14]{\seq_get:NN, \seq_get:cN}
% \begin{syntax}
-% \cs{seq_get:NN} \meta{seq~var} \meta{token list variable}
+% \cs{seq_get:NN} \meta{seq~var} \meta{tl~var}
% \end{syntax}
% Reads the top item from a \meta{seq~var} into the
-% \meta{token list variable} without removing it from the
-% \meta{seq~var}. The \meta{token list variable} is assigned locally.
-% If \meta{seq~var} is empty the \meta{token list variable} is set to
+% \meta{tl~var} without removing it from the
+% \meta{seq~var}. The \meta{tl~var} is assigned locally.
+% If \meta{seq~var} is empty the \meta{tl~var} is set to
% the special marker \cs{q_no_value}.
% \end{function}
%
% \begin{function}[updated = 2012-05-14]{\seq_pop:NN, \seq_pop:cN}
% \begin{syntax}
-% \cs{seq_pop:NN} \meta{seq~var} \meta{token list variable}
+% \cs{seq_pop:NN} \meta{seq~var} \meta{tl~var}
% \end{syntax}
% Pops the top item from a \meta{seq~var} into the
-% \meta{token list variable}. Both of the variables are assigned
-% locally. If \meta{seq~var} is empty the \meta{token list variable}
+% \meta{tl~var}. Both of the variables are assigned
+% locally. If \meta{seq~var} is empty the \meta{tl~var}
% is set to the special marker \cs{q_no_value}.
% \end{function}
%
% \begin{function}[updated = 2012-05-14]{\seq_gpop:NN, \seq_gpop:cN}
% \begin{syntax}
-% \cs{seq_gpop:NN} \meta{seq~var} \meta{token list variable}
+% \cs{seq_gpop:NN} \meta{seq~var} \meta{tl~var}
% \end{syntax}
% Pops the top item from a \meta{seq~var} into the
-% \meta{token list variable}. The \meta{seq~var} is modified globally,
-% while the \meta{token list variable} is assigned locally. If
-% \meta{seq~var} is empty the \meta{token list variable} is set to
+% \meta{tl~var}. The \meta{seq~var} is modified globally,
+% while the \meta{tl~var} is assigned locally. If
+% \meta{seq~var} is empty the \meta{tl~var} is set to
% the special marker \cs{q_no_value}.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]{\seq_get:NN, \seq_get:cN}
% \begin{syntax}
-% \cs{seq_get:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{seq_get:NNTF} \meta{seq~var} \meta{tl~var} \Arg{true code} \Arg{false code}
% \end{syntax}
% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
-% input stream. The value of the \meta{token list variable} is
+% input stream. The value of the \meta{tl~var} is
% not defined in this case and should not be relied upon. If the
% \meta{seq~var} is non-empty, stores the top item from a
-% \meta{seq~var} in the \meta{token list variable} without removing it from
-% the \meta{seq~var}. The \meta{token list variable} is assigned locally.
+% \meta{seq~var} in the \meta{tl~var} without removing it from
+% the \meta{seq~var}. The \meta{tl~var} is assigned locally.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]{\seq_pop:NN, \seq_pop:cN}
% \begin{syntax}
-% \cs{seq_pop:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{seq_pop:NNTF} \meta{seq~var} \meta{tl~var} \Arg{true code} \Arg{false code}
% \end{syntax}
% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
-% input stream. The value of the \meta{token list variable} is
+% input stream. The value of the \meta{tl~var} is
% not defined in this case and should not be relied upon. If the
% \meta{seq~var} is non-empty, pops the top item from the
-% \meta{seq~var} in the \meta{token list variable}, \emph{i.e.}~removes the
+% \meta{seq~var} in the \meta{tl~var}, \emph{i.e.}~removes the
% item from the \meta{seq~var}. Both the \meta{seq~var} and the
-% \meta{token list variable} are assigned locally.
+% \meta{tl~var} are assigned locally.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]{\seq_gpop:NN, \seq_gpop:cN}
% \begin{syntax}
-% \cs{seq_gpop:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{seq_gpop:NNTF} \meta{seq~var} \meta{tl~var} \Arg{true code} \Arg{false code}
% \end{syntax}
% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
-% input stream. The value of the \meta{token list variable} is
+% input stream. The value of the \meta{tl~var} is
% not defined in this case and should not be relied upon. If the
% \meta{seq~var} is non-empty, pops the top item from the \meta{seq~var}
-% in the \meta{token list variable}, \emph{i.e.}~removes the item from the
+% in the \meta{tl~var}, \emph{i.e.}~removes the item from the
% \meta{seq~var}. The \meta{seq~var} is modified globally, while the
-% \meta{token list variable} is assigned locally.
+% \meta{tl~var} is assigned locally.
% \end{function}
%
% \begin{function}
@@ -1325,12 +1401,12 @@
% is a repetition of the pattern
% \cs{@@_set_split:Nw} \cs{prg_do_nothing:}
% \meta{item with spaces} \cs{@@_set_split_end:}.
-% Then, \texttt{e}-expansion causes \cs{@@_set_split:Nw}
+% Then, \texttt{x}-expansion causes \cs{@@_set_split:Nw}
% to trim spaces, and leaves its result as
% \cs{@@_set_split:w} \meta{trimmed item}
% \cs{@@_set_split_end:}. This is then converted
% to the \pkg{l3seq} internal structure by another
-% \texttt{e}-expansion. In the first step, we insert
+% \texttt{x}-expansion. In the first step, we insert
% \cs{prg_do_nothing:} to avoid losing braces too early:
% that would cause space trimming to act within those
% lost braces. The second step is solely there to strip
@@ -1395,7 +1471,7 @@
% and skipping out of that would break horribly.
% The \cs{@@_wrap_item:n} function inserts the relevant
% \cs{@@_item:n} without expansion in the input stream,
-% hence in the \texttt{e}-expanding assignment.
+% hence in the \texttt{x}-expanding assignment.
% \begin{macrocode}
\cs_new_protected:Npn \seq_set_filter:NNn
{ \@@_set_filter:NNNn \__kernel_tl_set:Nx }
@@ -1411,6 +1487,84 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}
+% {
+% \seq_set_regex_extract_once:Nnn, \seq_set_regex_extract_once:cnn,
+% \seq_gset_regex_extract_once:Nnn, \seq_gset_regex_extract_once:cnn
+% }
+% \begin{macro}
+% {
+% \seq_set_regex_extract_all:Nnn, \seq_set_regex_extract_all:cnn,
+% \seq_gset_regex_extract_all:Nnn, \seq_gset_regex_extract_all:cnn
+% }
+% \begin{macro}
+% {
+% \seq_set_regex_extract_once:NNn, \seq_set_regex_extract_once:cNn,
+% \seq_gset_regex_extract_once:NNn, \seq_gset_regex_extract_once:cNn
+% }
+% \begin{macro}
+% {
+% \seq_set_regex_extract_all:NNn, \seq_set_regex_extract_all:cNn,
+% \seq_gset_regex_extract_all:NNn, \seq_gset_regex_extract_all:cNn
+% }
+% \begin{macro}
+% {
+% \seq_set_regex_split:Nnn, \seq_set_regex_split:cnn,
+% \seq_gset_regex_split:Nnn, \seq_gset_regex_split:cnn
+% }
+% \begin{macro}
+% {
+% \seq_set_regex_split:NNn, \seq_set_regex_split:cNn,
+% \seq_gset_regex_split:NNn, \seq_gset_regex_split:cNn
+% }
+% \begin{macrocode}
+\cs_new_protected:Npn \seq_set_regex_extract_once:Nnn #1#2#3
+ { \regex_extract_once:nnN {#2} {#3} #1 }
+\cs_generate_variant:Nn \seq_set_regex_extract_once:Nnn { c }
+\cs_new_protected:Npn \seq_set_regex_extract_once:NNn #1#2#3
+ { \regex_extract_once:NnN #2 {#3} #1 }
+\cs_generate_variant:Nn \seq_set_regex_extract_once:NNn { c }
+\cs_new_protected:Npn \seq_set_regex_extract_all:Nnn #1#2#3
+ { \regex_extract_all:nnN {#2} {#3} #1 }
+\cs_generate_variant:Nn \seq_set_regex_extract_all:Nnn { c }
+\cs_new_protected:Npn \seq_set_regex_extract_all:NNn #1#2#3
+ { \regex_extract_all:NnN #2 {#3} #1 }
+\cs_generate_variant:Nn \seq_set_regex_extract_all:NNn { c }
+\cs_new_protected:Npn \seq_set_regex_split:Nnn #1#2#3
+ { \regex_split:nnN {#2} {#3} #1 }
+\cs_generate_variant:Nn \seq_set_regex_split:Nnn { c }
+\cs_new_protected:Npn \seq_set_regex_split:NNn #1#2#3
+ { \regex_split:NnN #2 {#3} #1 }
+\cs_generate_variant:Nn \seq_set_regex_split:NNn { c }
+\group_begin:
+ \cs_set_protected:Npn \@@_tmp:w #1#2#3
+ {
+ \cs_new_protected:cpe { seq_gset_regex_ #1 :N #2 n } ##1##2##3
+ {
+ \group_begin:
+ \seq_set_eq:NN \exp_not:N \l_@@_tmp_seq ##1
+ \exp_not:c { regex_ #1 :Nn #2 }
+ #3 {##2} {##3} \exp_not:N \l_@@_tmp_seq
+ \seq_gset_eq:NN ##1 \exp_not:N \l_@@_tmp_seq
+ \group_end:
+ }
+ \cs_generate_variant:cn { seq_gset_regex_ #1 :N #2 n } { c }
+ }
+ \@@_tmp:w { extract_once } n { }
+ \@@_tmp:w { extract_once } N \use:n
+ \@@_tmp:w { extract_all } n { }
+ \@@_tmp:w { extract_all } N \use:n
+ \@@_tmp:w { split } n { }
+ \@@_tmp:w { split } N \use:n
+\group_end:
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
% \begin{macro}{\seq_concat:NNN, \seq_concat:ccc}
% \UnitTested
% \begin{macro}{\seq_gconcat:NNN, \seq_gconcat:ccc}
@@ -1519,16 +1673,16 @@
%
% \begin{macro}{\@@_wrap_item:n}
% This function converts its argument to a proper sequence item
-% in an \texttt{e}-expansion context.
+% in an \texttt{e}- or \texttt{x}-expansion context.
% \begin{macrocode}
\cs_new:Npn \@@_wrap_item:n #1 { \exp_not:n { \@@_item:n {#1} } }
% \end{macrocode}
% \end{macro}
%
-% \begin{variable}{\l_@@_remove_seq}
+% \begin{variable}{\l_@@_tmp_seq}
% An internal sequence for the removal routines.
% \begin{macrocode}
-\seq_new:N \l_@@_remove_seq
+\seq_new:N \l_@@_tmp_seq
% \end{macrocode}
% \end{variable}
%
@@ -1545,13 +1699,13 @@
{ \@@_remove_duplicates:NN \seq_gset_eq:NN }
\cs_new_protected:Npn \@@_remove_duplicates:NN #1#2
{
- \seq_clear:N \l_@@_remove_seq
+ \seq_clear:N \l_@@_tmp_seq
\seq_map_inline:Nn #2
{
- \seq_if_in:NnF \l_@@_remove_seq {##1}
- { \seq_put_right:Nn \l_@@_remove_seq {##1} }
+ \seq_if_in:NnF \l_@@_tmp_seq {##1}
+ { \seq_put_right:Nn \l_@@_tmp_seq {##1} }
}
- #1 #2 \l_@@_remove_seq
+ #1 #2 \l_@@_tmp_seq
}
\cs_generate_variant:Nn \seq_remove_duplicates:N { c }
\cs_generate_variant:Nn \seq_gremove_duplicates:N { c }
@@ -1581,15 +1735,15 @@
% items one at a time to an intermediate sequence.
% The approach taken is therefore similar to
% that in \cs{@@_pop_right:NNN}, using a \enquote{flexible}
-% \texttt{e}-type expansion to do most of the work. As \cs{tl_if_eq:nnT}
+% \texttt{x}-type expansion to do most of the work. As \cs{tl_if_eq:nnT}
% is not expandable, a two-part strategy is needed. First, the
-% \texttt{e}-type expansion uses \cs{str_if_eq:nnT} to find potential
+% \texttt{x}-type expansion uses \cs{str_if_eq:nnT} to find potential
% matches. If one is found, the expansion is halted and the necessary
-% set up takes place to use the \cs{tl_if_eq:NNT} test. The \texttt{e}-type
+% set up takes place to use the \cs{tl_if_eq:NNT} test. The \texttt{x}-type
% is started again, including all of the items copied already. This
% happens repeatedly until the entire sequence has been scanned. The code
% is set up to avoid needing an intermediate scratch list: the lead-off
-% \texttt{e}-type expansion (|#1 #2 {#2}|) ensures that nothing is lost.
+% \texttt{x}-type expansion (|#1 #2 {#2}|) ensures that nothing is lost.
% \begin{macrocode}
\cs_new_protected:Npn \seq_remove_all:Nn
{ \@@_remove_all_aux:NNn \__kernel_tl_set:Nx }
@@ -2032,7 +2186,7 @@
% use some of the same ideas as getting from the right. What is needed is a
% \enquote{flexible length} way to set a token list variable. This is
% supplied by the |{ \if_false: } \fi:| \ldots
-% |\if_false: { \fi: }| construct. Using an \texttt{e}-type
+% |\if_false: { \fi: }| construct. Using an \texttt{x}-type
% expansion and a \enquote{non-expanding} definition for \cs{@@_item:n},
% the left-most $n - 1$ entries in a sequence of $n$ items are stored
% back in the sequence. That needs a loop of unknown length, hence using the
@@ -2409,6 +2563,7 @@
\exp_after:wN \@@_map_pairwise_function:wNw #2 \s_@@_stop #3
#1 { ? \prg_break: } { }
\prg_break_point:
+ \prg_break_point:Nn \seq_map_break: { }
}
\cs_new:Npn \@@_map_pairwise_function:wNw \s_@@ #1 \s_@@_stop #2
{
diff --git a/macros/latex-dev/required/l3kernel/l3skip.dtx b/macros/latex-dev/required/l3kernel/l3skip.dtx
index 6e96b41326..2ae86598cb 100644
--- a/macros/latex-dev/required/l3kernel/l3skip.dtx
+++ b/macros/latex-dev/required/l3kernel/l3skip.dtx
@@ -3,7 +3,7 @@
%% File: l3skip.dtx
%
% Copyright (C) 2004-2011 Frank Mittelbach, The LaTeX Project
-% (C) 2012-2024 The LaTeX Project
+% (C) 2012-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -124,7 +124,10 @@
% \end{function}
%
% \begin{function}[updated = 2011-10-22]
-% {\dim_set:Nn, \dim_set:cn, \dim_gset:Nn, \dim_gset:cn}
+% {
+% \dim_set:Nn, \dim_set:cn, \dim_set:NV, \dim_set:cV,
+% \dim_gset:Nn, \dim_gset:cn, \dim_gset:NV, \dim_gset:cV
+% }
% \begin{syntax}
% \cs{dim_set:Nn} \meta{dimension} \Arg{dim expr}
% \end{syntax}
@@ -277,7 +280,8 @@
% \end{syntax}
% This function evaluates the \meta{test dim expr} and
% compares this in turn to each of the
-% \meta{dim expr cases}. If the two are equal then the
+% \meta{dim expr case}s until a match is found.
+% If the two are equal then the
% associated \meta{code} is left in the input stream
% and other cases are discarded. If any of the
% cases are matched, the \meta{true code} is also inserted into the
@@ -297,6 +301,10 @@
% { No idea! }
% \end{verbatim}
% leaves \enquote{\texttt{Medium}} in the input stream.
+% Since evaluation of the test expressions stops at the first
+% successful case, the order of possible matches should normally
+% be that the most likely are earlier: this will reduce the average
+% steps required to complete expansion.
% \end{function}
%
% \section{Dimension expression loops}
@@ -752,13 +760,16 @@
% \end{function}
%
% \begin{function}[updated = 2011-10-22]
-% {\skip_set:Nn, \skip_set:cn, \skip_gset:Nn, \skip_gset:cn}
+% {
+% \skip_set:Nn, \skip_set:cn, \skip_set:NV, \skip_set:cV,
+% \skip_gset:Nn, \skip_gset:cn, \skip_gset:NV, \skip_gset:cV
+% }
% \begin{syntax}
% \cs{skip_set:Nn} \meta{skip} \Arg{skip expr}
% \end{syntax}
% Sets \meta{skip} to the value of \meta{skip expr}, which
% must evaluate to a length with units and may include a rubber
-% component (for example |1 cm plus 0.5 cm|.
+% component (for example |1 cm plus 0.5 cm|).
% \end{function}
%
% \begin{function}
@@ -988,7 +999,10 @@
% \end{function}
%
% \begin{function}[updated = 2011-10-22]
-% {\muskip_set:Nn, \muskip_set:cn, \muskip_gset:Nn, \muskip_gset:cn}
+% {
+% \muskip_set:Nn, \muskip_set:cn, \muskip_set:NV, \muskip_set:cV,
+% \muskip_gset:Nn, \muskip_gset:cn, \muskip_gset:NV, \muskip_gset:cV
+% }
% \begin{syntax}
% \cs{muskip_set:Nn} \meta{muskip} \Arg{muskip expr}
% \end{syntax}
@@ -1245,8 +1259,8 @@
%
% \subsection{Setting \texttt{dim} variables}
%
-% \begin{macro}{\dim_set:Nn, \dim_set:cn}
-% \begin{macro}{\dim_gset:Nn, \dim_gset:cn}
+% \begin{macro}{\dim_set:Nn, \dim_set:cn, \dim_set:NV, \dim_set:cV}
+% \begin{macro}{\dim_gset:Nn, \dim_gset:cn, \dim_gset:NV, \dim_gset:cV}
% Setting dimensions is easy enough but when debugging we want both to
% check that the variable is correctly local/global and to wrap the
% expression in some code. The \cs{scan_stop:} deals with the case
@@ -1257,8 +1271,8 @@
{ #1 = \@@_eval:w #2 \@@_eval_end: \scan_stop: }
\cs_new_protected:Npn \dim_gset:Nn #1#2
{ \tex_global:D #1 = \@@_eval:w #2 \@@_eval_end: \scan_stop: }
-\cs_generate_variant:Nn \dim_set:Nn { c }
-\cs_generate_variant:Nn \dim_gset:Nn { c }
+\cs_generate_variant:Nn \dim_set:Nn { NV , c , cV }
+\cs_generate_variant:Nn \dim_gset:Nn { NV , c , cV }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -2208,16 +2222,16 @@
%
% \subsection{Setting \texttt{skip} variables}
%
-% \begin{macro}{\skip_set:Nn, \skip_set:cn}
-% \begin{macro}{\skip_gset:Nn, \skip_gset:cn}
+% \begin{macro}{\skip_set:Nn, \skip_set:cn, \skip_set:NV, \skip_set:cV}
+% \begin{macro}{\skip_gset:Nn, \skip_gset:cn, \skip_gset:NV, \skip_gset:cV}
% Much the same as for dimensions.
% \begin{macrocode}
\cs_new_protected:Npn \skip_set:Nn #1#2
{ #1 = \tex_glueexpr:D #2 \scan_stop: }
\cs_new_protected:Npn \skip_gset:Nn #1#2
{ \tex_global:D #1 = \tex_glueexpr:D #2 \scan_stop: }
-\cs_generate_variant:Nn \skip_set:Nn { c }
-\cs_generate_variant:Nn \skip_gset:Nn { c }
+\cs_generate_variant:Nn \skip_set:Nn { NV , c , cV }
+\cs_generate_variant:Nn \skip_gset:Nn { NV , c , cV }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -2459,16 +2473,16 @@
%
% \subsection{Setting \texttt{muskip} variables}
%
-% \begin{macro}{\muskip_set:Nn, \muskip_set:cn}
-% \begin{macro}{\muskip_gset:Nn, \muskip_gset:cn}
+% \begin{macro}{\muskip_set:Nn, \muskip_set:cn, \muskip_set:NV, \muskip_set:cV}
+% \begin{macro}{\muskip_gset:Nn, \muskip_gset:cn, \muskip_gset:NV, \muskip_gset:cV}
% This should be pretty familiar.
% \begin{macrocode}
\cs_new_protected:Npn \muskip_set:Nn #1#2
{ #1 = \tex_muexpr:D #2 \scan_stop: }
\cs_new_protected:Npn \muskip_gset:Nn #1#2
{ \tex_global:D #1 = \tex_muexpr:D #2 \scan_stop: }
-\cs_generate_variant:Nn \muskip_set:Nn { c }
-\cs_generate_variant:Nn \muskip_gset:Nn { c }
+\cs_generate_variant:Nn \muskip_set:Nn { NV , c , cV }
+\cs_generate_variant:Nn \muskip_gset:Nn { NV , c , cV }
% \end{macrocode}
% \end{macro}
% \end{macro}
diff --git a/macros/latex-dev/required/l3kernel/l3sort.dtx b/macros/latex-dev/required/l3kernel/l3sort.dtx
index 47cebcad25..5bbb0d3b34 100644
--- a/macros/latex-dev/required/l3kernel/l3sort.dtx
+++ b/macros/latex-dev/required/l3kernel/l3sort.dtx
@@ -2,7 +2,7 @@
%
%% File l3sort.dtx
%
-% Copyright (C) 2012-2024 The LaTeX Project
+% Copyright (C) 2012-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
diff --git a/macros/latex-dev/required/l3kernel/l3str-convert.dtx b/macros/latex-dev/required/l3kernel/l3str-convert.dtx
index baf705fe0c..dcb7872132 100644
--- a/macros/latex-dev/required/l3kernel/l3str-convert.dtx
+++ b/macros/latex-dev/required/l3kernel/l3str-convert.dtx
@@ -2,7 +2,7 @@
%
%% File: l3str-convert.dtx
%
-% Copyright (C) 2013-2024 The LaTeX Project
+% Copyright (C) 2013-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -139,10 +139,10 @@
%
% \begin{function}{\str_set_convert:Nnnn, \str_gset_convert:Nnnn}
% \begin{syntax}
-% \cs{str_set_convert:Nnnn} \meta{str~var} \Arg{string} \Arg{name~1} \Arg{name~2}
+% \cs{str_set_convert:Nnnn} \meta{str~var} \Arg{string} \Arg{name_1} \Arg{name_2}
% \end{syntax}
% This function converts the \meta{string} from the encoding given by
-% \meta{name~1} to the encoding given by \meta{name~2}, and stores the
+% \meta{name_1} to the encoding given by \meta{name_2}, and stores the
% result in the \meta{str~var}. Each \meta{name} can have the form
% \meta{encoding} or \meta{encoding}\texttt{/}\meta{escaping}, where
% the possible values of \meta{encoding} and \meta{escaping} are given
@@ -177,14 +177,14 @@
%
% \begin{function}[TF]{\str_set_convert:Nnnn, \str_gset_convert:Nnnn}
% \begin{syntax}
-% \cs{str_set_convert:NnnnTF} \meta{str~var} \Arg{string} \Arg{name~1} \Arg{name~2} \Arg{true code} \Arg{false code}
+% \cs{str_set_convert:NnnnTF} \meta{str~var} \Arg{string} \Arg{name_1} \Arg{name_2} \Arg{true code} \Arg{false code}
% \end{syntax}
% As \cs{str_set_convert:Nnnn}, converts the \meta{string} from the
-% encoding given by \meta{name~1} to the encoding given by
-% \meta{name~2}, and assigns the result to \meta{str~var}. Contrarily
+% encoding given by \meta{name_1} to the encoding given by
+% \meta{name_2}, and assigns the result to \meta{str~var}. Contrarily
% to \cs{str_set_convert:Nnnn}, the conditional variant does not raise
% errors in case the \meta{string} is not valid according to the
-% \meta{name~1} encoding, or cannot be expressed in the \meta{name~2}
+% \meta{name_1} encoding, or cannot be expressed in the \meta{name_2}
% encoding. Instead, the \meta{false code} is performed.
% \end{function}
%
@@ -195,7 +195,7 @@
%
% \begin{function}[EXP]{\str_convert_pdfname:n}
% \begin{syntax}
-% \cs{str_convert_pdfname:n} \meta{string}
+% \cs{str_convert_pdfname:n} \Arg{string}
% \end{syntax}
% As \cs{str_set_convert:Nnnn}, converts the \meta{string} on a byte-by-byte
% basis with non-ASCII codepoints escaped using hashes.
@@ -2068,7 +2068,7 @@
%
% \subsubsection{\textsc{utf-16} support}
%
-% The definitions are done in a category code regime where the bytes
+% The definitions are done in a category code régime where the bytes
% $254$ and $255$ used by the byte order mark have catcode~$12$.
% \begin{macrocode}
\group_begin:
@@ -2393,7 +2393,7 @@
%
% \subsubsection{\textsc{utf-32} support}
%
-% The definitions are done in a category code regime where the bytes
+% The definitions are done in a category code régime where the bytes
% $0$, $254$ and $255$ used by the byte order mark have catcode
% \enquote{other}.
% \begin{macrocode}
@@ -2624,9 +2624,7 @@
\exp_args:Ne \tl_to_str:n
{ \str_map_function:nN {#1} \@@_convert_pdfname:n }
}
-\bool_lazy_or:nnTF
- { \sys_if_engine_luatex_p: }
- { \sys_if_engine_xetex_p: }
+\sys_if_engine_opentype:TF
{
\cs_new:Npn \@@_convert_pdfname:n #1
{
diff --git a/macros/latex-dev/required/l3kernel/l3str.dtx b/macros/latex-dev/required/l3kernel/l3str.dtx
index f4f7b94b88..c6d8c74b80 100644
--- a/macros/latex-dev/required/l3kernel/l3str.dtx
+++ b/macros/latex-dev/required/l3kernel/l3str.dtx
@@ -2,7 +2,7 @@
%
%% File: l3str.dtx
%
-% Copyright (C) 2011-2024 The LaTeX Project
+% Copyright (C) 2011-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -212,7 +212,7 @@
% \begin{function}[added = 2015-09-18, updated = 2018-07-28]
% {
% \str_put_right:Nn, \str_put_right:NV, \str_put_right:Ne,
-% \str_put_right:cn, \str_put_right:cV, \str_put_right:Ne,
+% \str_put_right:cn, \str_put_right:cV, \str_put_right:ce,
% \str_gput_right:Nn, \str_gput_right:NV, \str_gput_right:Ne,
% \str_gput_right:cn, \str_gput_right:cV, \str_gput_right:ce
% }
@@ -303,7 +303,8 @@
% ~~\Arg{false code}
% \end{syntax}
% Compares the \meta{test string} in turn with each
-% of the \meta{string case}s (all token lists are converted to strings).
+% of the \meta{string case}s until a match is found
+% (all token lists are converted to strings).
% If the two are equal (as described for
% \cs{str_if_eq:nnTF}) then the associated \meta{code} is left in the
% input stream and other cases are discarded. If any of the
@@ -557,7 +558,7 @@
% \end{function}
%
% \begin{function}[EXP, added = 2015-09-18]
-% {\str_item:Nn, \str_item:nn, \str_item_ignore_spaces:nn}
+% {\str_item:Nn, \str_item:cn, \str_item:nn, \str_item_ignore_spaces:nn}
% \begin{syntax}
% \cs{str_item:nn} \Arg{token list} \Arg{integer expression}
% \end{syntax}
@@ -757,7 +758,7 @@
% \item Case changing text for typesetting: see the
% \cs[index=text_lowercase:n]{text_lowercase:n(n)},
% \cs[index=text_uppercase:n]{text_uppercase:n(n)} and
-% \cs[index=text_titlecase_all:n]{text_titlecase_(all|once):n(n)} functions which
+% \cs[index=text_titlecase_all:n]{text_titlecase_(all|first):n(n)} functions which
% correctly deal with context-dependence and other factors appropriate
% to text case changing.
% \end{itemize}
@@ -789,7 +790,7 @@
% \end{quote}
% The folding approach implemented by \cs{str_casefold:n} follows the
% \enquote{full} scheme defined by the Unicode Consortium
-% (\emph{e.g.}~\SS folds to \texttt{SS}). As case-folding is
+% (\emph{e.g.}~\SS{} folds to \texttt{SS}). As case-folding is
% a language-insensitive process, there is no special treatment of
% Turkic input (\emph{i.e.}~\texttt{I} always folds to \texttt{i} and
% not to \texttt{\i}).
@@ -797,9 +798,9 @@
%
% \begin{function}[added = 2023-05-19, EXP]{\str_mdfive_hash:n, \str_mdfive_hash:e}
% \begin{syntax}
-% \cs{str_mdfive_hash:n} \Arg{tl}
+% \cs{str_mdfive_hash:n} \Arg{tokens}
% \end{syntax}
-% Expands to the MD5 sum generated from the \meta{tl}, which is converted
+% Expands to the MD5 sum generated from the \meta{tokens}, which is converted
% to a \meta{string} as described for \cs{tl_to_str:n}.
% \end{function}
%
diff --git a/macros/latex-dev/required/l3kernel/l3styleguide.pdf b/macros/latex-dev/required/l3kernel/l3styleguide.pdf
index 2142c73e77..82147d44d2 100644
--- a/macros/latex-dev/required/l3kernel/l3styleguide.pdf
+++ b/macros/latex-dev/required/l3kernel/l3styleguide.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3styleguide.tex b/macros/latex-dev/required/l3kernel/l3styleguide.tex
index bcea3de06e..51b269459f 100644
--- a/macros/latex-dev/required/l3kernel/l3styleguide.tex
+++ b/macros/latex-dev/required/l3kernel/l3styleguide.tex
@@ -2,7 +2,7 @@
File: l3styleguide.tex
-Copyright (C) 2011,2012,2014-2024 The LaTeX Project
+Copyright (C) 2011,2012,2014-2025 The LaTeX Project
It may be distributed and/or modified under the conditions of the
LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -32,7 +32,7 @@ The released version of this bundle is available from CTAN.
{latex-team@latex-project.org}%
}%
}
-\date{Released 2024-05-27}
+\date{Released 2025-01-18}
\begin{document}
diff --git a/macros/latex-dev/required/l3kernel/l3syntax-changes.pdf b/macros/latex-dev/required/l3kernel/l3syntax-changes.pdf
index a44d06c052..26fae788ca 100644
--- a/macros/latex-dev/required/l3kernel/l3syntax-changes.pdf
+++ b/macros/latex-dev/required/l3kernel/l3syntax-changes.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3syntax-changes.tex b/macros/latex-dev/required/l3kernel/l3syntax-changes.tex
index 30d8d47747..0abcad3c8e 100644
--- a/macros/latex-dev/required/l3kernel/l3syntax-changes.tex
+++ b/macros/latex-dev/required/l3kernel/l3syntax-changes.tex
@@ -2,7 +2,7 @@
File: l3syntax-changes.tex
-Copyright (C) 2011,2012,2017-2024 The LaTeX Project
+Copyright (C) 2011,2012,2017-2025 The LaTeX Project
It may be distributed and/or modified under the conditions of the
LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -32,7 +32,7 @@ The released version of this bundle is available from CTAN.
{latex-team@latex-project.org}%
}%
}
-\date{Released 2024-05-27}
+\date{Released 2025-01-18}
\newcommand{\TF}{\textit{(TF)}}
diff --git a/macros/latex-dev/required/l3kernel/l3sys.dtx b/macros/latex-dev/required/l3kernel/l3sys.dtx
index b2228c7fd9..7c6d0e9dc5 100644
--- a/macros/latex-dev/required/l3kernel/l3sys.dtx
+++ b/macros/latex-dev/required/l3kernel/l3sys.dtx
@@ -2,7 +2,7 @@
%
%% File: l3sys.dtx
%
-% Copyright (C) 2015-2024 The LaTeX Project
+% Copyright (C) 2015-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -107,6 +107,26 @@
% |\sys_if_engine_ptex_p:| is true for \epTeX{} but false for \eupTeX{}.
% \end{function}
%
+% \begin{function}[added = 2024-11-05, pTF]{\sys_if_engine_opentype:}
+% \begin{syntax}
+% \cs{sys_if_engine_opentype_p:}
+% \cs{sys_if_engine_opentype:TF} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Conditional which allows functionality-specific code to be used.
+% The test is true for engines which can use OpenType fonts and
+% thus full Unicode typesetting. This tests for features not engine
+% name, but currently is equivalent to requiring either
+% \XeTeX{} or \LuaTeX{}.
+% \begin{texnote}
+% The underlying test here checks for \tn{Umathcode}, which
+% is used to implement OpenType math font typesetting. Any
+% engine which should give a \texttt{true} result here needs
+% to provide general Unicode support (accepting the full UTF-8
+% range for character codes), a mechanism to load system fonts
+% and a suitable interface for math mode typesetting.
+% \end{texnote}
+% \end{function}
+%
% \begin{variable}[added = 2015-09-19]{\c_sys_engine_str}
% The current engine given as a lower case string: one of
% |luatex|, |pdftex|, |ptex|, |uptex| or |xetex|.
@@ -336,9 +356,9 @@
% \begin{function}[added = 2024-03-08, updated = 2024-04-08]
% {\sys_get_query:nN, \sys_get_query:nnN, \sys_get_query:nnnN}
% \begin{syntax}
-% \cs{sys_get_query:nN} \Arg{cmd} \Arg{tl var}
-% \cs{sys_get_query:nnN} \Arg{cmd} \Arg{spec} \Arg{tl var}
-% \cs{sys_get_query:nnnN} \Arg{cmd} \Arg{options} \Arg{spec} \Arg{tl var}
+% \cs{sys_get_query:nN} \Arg{cmd} \meta{tl var}
+% \cs{sys_get_query:nnN} \Arg{cmd} \Arg{spec} \meta{tl var}
+% \cs{sys_get_query:nnnN} \Arg{cmd} \Arg{options} \Arg{spec} \meta{tl var}
% \end{syntax}
% Sets the \meta{tl var} to the information returned by the
% \texttt{l3sys-query} \meta{cmd}, potentially supplying the \meta{options}
@@ -374,11 +394,11 @@
% \begin{function}[added = 2024-03-08]
% {\sys_split_query:nN, \sys_split_query:nnN, \sys_split_query:nnnN}
% \begin{syntax}
-% \cs{sys_split_query:nN} \Arg{cmd} \Arg{seq}
-% \cs{sys_split_query:nnN} \Arg{cmd} \Arg{spec} \Arg{seq}
-% \cs{sys_split_query:nnnN} \Arg{cmd} \Arg{options} \Arg{spec} \Arg{seq}
+% \cs{sys_split_query:nN} \Arg{cmd} \meta{seq var}
+% \cs{sys_split_query:nnN} \Arg{cmd} \Arg{spec} \meta{seq var}
+% \cs{sys_split_query:nnnN} \Arg{cmd} \Arg{options} \Arg{spec} \meta{seq var}
% \end{syntax}
-% Works as described for \cs{sys_split_query:nnnN}, but sets the \meta{seq}
+% Works as described for \cs{sys_split_query:nnnN}, but sets the \meta{seq var}
% to contain one entry for each line returned by \texttt{l3sys-query}.
% This function should therefore be preferred where multi-line return is
% expected, e.g.~for the \texttt{ls} command.
@@ -514,6 +534,14 @@
% \end{variable}
% \end{macro}
%
+% \begin{function}[pTF]{\sys_if_engine_opentype:}
+% \begin{macrocode}
+\@@_const:nn
+ { sys_if_engine_opentype }
+ { \cs_if_exist_p:N \tex_Umathcode:D }
+% \end{macrocode}
+% \end{function}
+%
% \begin{variable}{\c_sys_engine_exec_str,\c_sys_engine_format_str}
% Take the functions defined above, and set up the engine and format
% names. \cs{c_sys_engine_exec_str} differs from \cs{c_sys_engine_str}
@@ -1030,7 +1058,7 @@ end
% \begin{variable}{\c_sys_timestamp_str}
% A simple expansion: Lua\TeX{} chokes if we use \tn{pdffeedback} here,
% hence the direct use of Lua. Notice that the function there is in the
-% \texttt{pdf} library but isn actually tied to PDF.
+% \texttt{pdf} library but isn't actually tied to PDF.
% \begin{macrocode}
\@@_everyjob:n
{
diff --git a/macros/latex-dev/required/l3kernel/l3term-glossary.pdf b/macros/latex-dev/required/l3kernel/l3term-glossary.pdf
index 6d014af4e7..14ae12a051 100644
--- a/macros/latex-dev/required/l3kernel/l3term-glossary.pdf
+++ b/macros/latex-dev/required/l3kernel/l3term-glossary.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/l3term-glossary.tex b/macros/latex-dev/required/l3kernel/l3term-glossary.tex
index 141749aa6b..c907fce097 100644
--- a/macros/latex-dev/required/l3kernel/l3term-glossary.tex
+++ b/macros/latex-dev/required/l3kernel/l3term-glossary.tex
@@ -2,7 +2,7 @@
File: l3term-glossary.tex
-Copyright (C) 2018-2024 The LaTeX Project
+Copyright (C) 2018-2025 The LaTeX Project
It may be distributed and/or modified under the conditions of the
LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -32,7 +32,7 @@ The released version of this bundle is available from CTAN.
{latex-team@latex-project.org}%
}%
}
-\date{Released 2024-05-27}
+\date{Released 2025-01-18}
\newcommand{\TF}{\textit{(TF)}}
diff --git a/macros/latex-dev/required/l3kernel/l3text-case.dtx b/macros/latex-dev/required/l3kernel/l3text-case.dtx
index 89cdb9e2b1..f8529b1090 100644
--- a/macros/latex-dev/required/l3kernel/l3text-case.dtx
+++ b/macros/latex-dev/required/l3kernel/l3text-case.dtx
@@ -2,7 +2,7 @@
%
%% File: l3text-case.dtx
%
-% Copyright (C) 2020-2024 The LaTeX Project
+% Copyright (C) 2020-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -801,9 +801,7 @@
% the standard catcode. If neither are true, we set as 13 on the grounds that
% this will be what is used anyway!
% \begin{macrocode}
-\bool_lazy_or:nnTF
- { \sys_if_engine_luatex_p: }
- { \sys_if_engine_xetex_p: }
+\sys_if_engine_opentype:TF
{
\cs_new:Npn \@@_change_case_catcode:nn #1#2
{ \@@_char_catcode:N #1 }
@@ -2319,9 +2317,7 @@
% A few adjustments to case mapping for combining chars: these are not needed
% for the Unicode engines
% \begin{macrocode}
-\bool_lazy_or:nnF
- { \sys_if_engine_luatex_p: }
- { \sys_if_engine_xetex_p: }
+\sys_if_engine_opentype:F
{
\text_declare_uppercase_mapping:nn { "01F0 } { \v { J } }
}
diff --git a/macros/latex-dev/required/l3kernel/l3text-map.dtx b/macros/latex-dev/required/l3kernel/l3text-map.dtx
index 3573002244..accfa0e06e 100644
--- a/macros/latex-dev/required/l3kernel/l3text-map.dtx
+++ b/macros/latex-dev/required/l3kernel/l3text-map.dtx
@@ -2,7 +2,7 @@
%
%% File: l3text-map.dtx
%
-% Copyright (C) 2022-2024 The LaTeX Project
+% Copyright (C) 2022-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
diff --git a/macros/latex-dev/required/l3kernel/l3text-purify.dtx b/macros/latex-dev/required/l3kernel/l3text-purify.dtx
index 35390811aa..6aa04bf399 100644
--- a/macros/latex-dev/required/l3kernel/l3text-purify.dtx
+++ b/macros/latex-dev/required/l3kernel/l3text-purify.dtx
@@ -2,7 +2,7 @@
%
%% File: l3text-purify.dtx
%
-% Copyright (C) 2020-2024 The LaTeX Project
+% Copyright (C) 2020-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
diff --git a/macros/latex-dev/required/l3kernel/l3text.dtx b/macros/latex-dev/required/l3kernel/l3text.dtx
index bcfd15cb62..f1f4ecee2f 100644
--- a/macros/latex-dev/required/l3kernel/l3text.dtx
+++ b/macros/latex-dev/required/l3kernel/l3text.dtx
@@ -2,7 +2,7 @@
%
%% File: l3text.dtx
%
-% Copyright (C) 2020-2024 The LaTeX Project
+% Copyright (C) 2020-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -65,11 +65,11 @@
% \end{syntax}
% Takes user input \meta{text} and expands the content.
% Protected commands (typically
-% formatting) are left in place, and no processing takes place of
+% formatting) are left in place, and no processing of
% math mode material (as delimited by pairs given in
% \cs{l_text_math_delims_tl} or as the argument to commands listed
-% in \cs{l_text_math_arg_tl}). Commands which are neither engine-
-% nor \LaTeX{} protected are expanded exhaustively.
+% in \cs{l_text_math_arg_tl}) takes place. Commands which are neither engine-
+% nor \LaTeX{}-protected are expanded exhaustively.
% Any commands listed in \cs{l_text_expand_exclude_tl} are excluded from
% expansion, as are those in \cs{l_text_case_exclude_arg_tl} and
% \cs{l_text_math_arg_tl}.
@@ -114,8 +114,8 @@
% \end{function}
%
% Upper- and lowercase have the obvious meanings. Titlecasing may be regarded
-% informally as converting the first character of the \meta{tokens} to
-% uppercase. However, the process is more complex
+% informally as converting the first \emph{non-space} character of the
+% \meta{tokens} to uppercase. However, the process is more complex
% than this as there are some situations where a single lowercase character
% maps to a special form, for example \texttt{ij} in Dutch which becomes
% \texttt{IJ}. There are two functions available for titlecasing: one which
@@ -214,8 +214,9 @@
% \text_declare_uppercase_mapping:nnn
% }
% \begin{syntax}
-% \cs{text_declare_lowercase_mapping:nn} \Arg{codeppoint} \Arg{replacement}
-% \cs{text_declare_lowercase_mapping:nnn} \Arg{BCP-47} \Arg{codeppoint} \Arg{replacement}
+% \cs{text_declare_lowercase_mapping:nn} \Arg{codepoint} \Arg{replacement}
+% \cs{text_declare_lowercase_mapping:nnn} \Arg{BCP-47} \Arg{codepoint} \\
+% ~~\Arg{replacement}
% \end{syntax}
% Declares that the \meta{replacement} tokens should be used when case mapping
% the \meta{codepoint}, rather than the standard mapping given in the
@@ -305,7 +306,7 @@
%
% \begin{function}[rEXP, added = 2022-08-04]{\text_map_function:nN}
% \begin{syntax}
-% \cs{text_map_function:nN} \meta{text} \Arg{function}
+% \cs{text_map_function:nN} \Arg{text} \meta{function}
% \end{syntax}
% Takes user input \meta{text} and expands as described for
% \cs{text_expand:n}, then maps over the \emph{graphemes} within the
@@ -323,7 +324,7 @@
%
% \begin{function}[added = 2022-08-04]{\text_map_inline:nn}
% \begin{syntax}
-% \cs{text_map_inline:nn} \meta{text} \Arg{inline function}
+% \cs{text_map_inline:nn} \Arg{text} \Arg{inline function}
% \end{syntax}
% Takes user input \meta{text} and expands as described for
% \cs{text_expand:n}, then maps over the \emph{graphemes} within the
@@ -653,9 +654,7 @@
% Grab a codepoint and apply some code to it: here |#1| should expect one
% following \emph{balanced text}.
% \begin{macrocode}
-\bool_lazy_or:nnTF
- { \sys_if_engine_luatex_p: }
- { \sys_if_engine_xetex_p: }
+\sys_if_engine_opentype:TF
{
\cs_new:Npn \@@_codepoint_process:nN #1#2 { #1 {#2} }
}
@@ -709,9 +708,7 @@
% Allows comparison for all engines using a first \enquote{character} followed
% by a codepoint.
% \begin{macrocode}
-\bool_lazy_or:nnTF
- { \sys_if_engine_luatex_p: }
- { \sys_if_engine_xetex_p: }
+\sys_if_engine_opentype:TF
{
\prg_new_conditional:Npnn
\@@_codepoint_compare:nNn #1#2#3 { TF , p }
diff --git a/macros/latex-dev/required/l3kernel/l3tl-analysis.dtx b/macros/latex-dev/required/l3kernel/l3tl-analysis.dtx
index 4df9ee68a3..fd162839a8 100644
--- a/macros/latex-dev/required/l3kernel/l3tl-analysis.dtx
+++ b/macros/latex-dev/required/l3kernel/l3tl-analysis.dtx
@@ -2,7 +2,7 @@
%
%% File: l3tl-analysis.dtx
%
-% Copyright (C) 2011-2024 The LaTeX Project
+% Copyright (C) 2011-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -1028,39 +1028,42 @@
%
% \subsection{Showing the results}
%
-% \begin{macro}{\tl_analysis_show:N, \tl_analysis_log:N, \@@_analysis_show:NNN}
+% \begin{macro}{\tl_analysis_show:N, \tl_analysis_log:N, \@@_analysis_show:NNnnN}
% Add to \cs{@@_analysis:n} a third pass to display tokens to the terminal.
% If the token list variable is not defined, throw the same error
% as \cs{tl_show:N} by simply calling that function.
% \begin{macrocode}
\cs_new_protected:Npn \tl_analysis_show:N
- { \@@_analysis_show:NNN \msg_show:nneeee \tl_show:N }
+ { \@@_analysis_show:NNnnN \msg_show:nneeee \tl_show:N {} {} }
\cs_new_protected:Npn \tl_analysis_log:N
- { \@@_analysis_show:NNN \msg_log:nneeee \tl_log:N }
-\cs_new_protected:Npn \@@_analysis_show:NNN #1#2#3
{
- \tl_if_exist:NTF #3
+ \@@_analysis_show:NNnnN \msg_log:nneeee \tl_log:N
+ { \iow_newline: >~ . } { . }
+ }
+\cs_new_protected:Npn \@@_analysis_show:NNnnN #1#2#3#4#5
+ {
+ \tl_if_exist:NTF #5
{
- \exp_args:No \@@_analysis:n {#3}
+ \exp_args:No \@@_analysis:n {#5}
#1 { tl } { show-analysis }
- { \token_to_str:N #3 } { \@@_analysis_show: } { } { }
+ { \token_to_str:N #5 } { \@@_analysis_show: } {#3} {#4}
}
{ #2 #3 }
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\tl_analysis_show:n, \tl_analysis_log:n, \@@_analysis_show:Nn}
+% \begin{macro}{\tl_analysis_show:n, \tl_analysis_log:n, \@@_analysis_show:Nnnn}
% No existence test needed here.
% \begin{macrocode}
\cs_new_protected:Npn \tl_analysis_show:n
- { \@@_analysis_show:Nn \msg_show:nneeee }
+ { \@@_analysis_show:Nnnn \msg_show:nneeee {} {} }
\cs_new_protected:Npn \tl_analysis_log:n
- { \@@_analysis_show:Nn \msg_log:nneeee }
-\cs_new_protected:Npn \@@_analysis_show:Nn #1#2
+ { \@@_analysis_show:Nnnn \msg_log:nneeee { \iow_newline: >~ . } { . } }
+\cs_new_protected:Npn \@@_analysis_show:Nnnn #1#2#3#4
{
- \@@_analysis:n {#2}
- #1 { tl } { show-analysis } { } { \@@_analysis_show: } { } { }
+ \@@_analysis:n {#4}
+ #1 { tl } { show-analysis } { } { \@@_analysis_show: } {#2} {#3}
}
% \end{macrocode}
% \end{macro}
@@ -1654,8 +1657,8 @@
{
The~token~list~ \tl_if_empty:nF {#1} { #1 ~ }
\tl_if_empty:nTF {#2}
- { is~empty }
- { contains~the~tokens: #2 }
+ { is~empty #3 }
+ { contains~the~tokens: #2 #4 }
}
% \end{macrocode}
%
diff --git a/macros/latex-dev/required/l3kernel/l3tl-build.dtx b/macros/latex-dev/required/l3kernel/l3tl-build.dtx
index 6cd9822ad2..ae38f34583 100644
--- a/macros/latex-dev/required/l3kernel/l3tl-build.dtx
+++ b/macros/latex-dev/required/l3kernel/l3tl-build.dtx
@@ -2,7 +2,7 @@
%
%% File: l3tl-build.dtx
%
-% Copyright (C) 2018-2024 The LaTeX Project
+% Copyright (C) 2018-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
diff --git a/macros/latex-dev/required/l3kernel/l3tl.dtx b/macros/latex-dev/required/l3kernel/l3tl.dtx
index 71d68d532c..85faa334a9 100644
--- a/macros/latex-dev/required/l3kernel/l3tl.dtx
+++ b/macros/latex-dev/required/l3kernel/l3tl.dtx
@@ -2,7 +2,7 @@
%
%% File: l3tl.dtx
%
-% Copyright (C) 1990-2024 The LaTeX Project
+% Copyright (C) 1990-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -55,7 +55,7 @@
% \begin{verbatim}
% \foo:n { a collection of \tokens }
% \end{verbatim}
-% or may be stored in a so-called \enquote{token list variable}, which
+% or may be stored in a so-called \enquote{tl~var} (\meta{tl~var}), which
% have the suffix \texttt{tl}: a token list variable can also be used as
% the argument to a function, for example
% \begin{verbatim}
@@ -99,8 +99,8 @@
%
% \begin{function}
% {
-% \tl_const:Nn, \tl_const:Ne,
-% \tl_const:cn, \tl_const:ce
+% \tl_const:Nn, \tl_const:NV, \tl_const:Ne,
+% \tl_const:cn, \tl_const:cV, \tl_const:ce
% }
% \begin{syntax}
% \cs{tl_const:Nn} \meta{tl~var} \Arg{tokens}
@@ -333,8 +333,8 @@
% Tests if the \meta{token list} and the special \cs{c_novalue_tl} marker
% contain the same list of tokens, both in respect of character codes and
% category codes. This means that
-% \cs{exp_args:No} \cs{tl_if_novalue:nTF} \{ \cs{c_novalue_tl} \} is
-% logically \texttt{true} but \cs{tl_if_novalue:nTF} \{ \cs{c_novalue_tl} \}
+% \cs{exp_args:No} \cs{tl_if_novalue:nTF} \texttt\{ \cs{c_novalue_tl} \texttt\} is
+% logically \texttt{true} but \cs{tl_if_novalue:nTF} \texttt\{ \cs{c_novalue_tl} \texttt\}
% is logically \texttt{false}.
% This function is intended to allow construction
% of flexible document interface structures in which missing optional
@@ -376,6 +376,28 @@
% Token groups (|{|\ldots|}|) are not single tokens.
% \end{function}
%
+% \begin{function}[TF, added = 2024-12-08]
+% {
+% \tl_if_regex_match:nn, \tl_if_regex_match:Vn,
+% \tl_if_regex_match:nN, \tl_if_regex_match:VN,
+% }
+% \begin{syntax}
+% \cs{tl_if_regex_match:nnTF} \Arg{token list} \Arg{regex} \Arg{true code} \Arg{false code}
+% \cs{tl_if_regex_match:nNTF} \Arg{token list} \meta{regex~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests whether the \meta{regular expression} matches any part
+% of the \meta{token list}. For instance,
+% \begin{verbatim}
+% \tl_if_regex_match:nnTF { abecdcx } { b [cde]* } { TRUE } { FALSE }
+% \tl_if_regex_match:nnTF { example } { [b-dq-w] } { TRUE } { FALSE }
+% \end{verbatim}
+% leaves \texttt{TRUE} then \texttt{FALSE} in the input stream.
+% Theses are alternative names for \cs{regex_match:nnTF} and friends,
+% with arguments re-ordered for \meta{token list} testing;
+% see \pkg{l3regex} chapter for more details of the \meta{regex}
+% format.
+% \end{function}
+%
% \subsection{Testing the first token}
%
% \begin{function}[updated = 2012-07-09, EXP, pTF]
@@ -1110,7 +1132,7 @@
%
% Within token lists, replacement takes place at the top level: there is
% no recursion into brace groups (more precisely, within a group defined by
-% a categroy code $1$/$2$ pair).
+% a category code $1$/$2$ pair).
%
% \begin{function}[updated = 2011-08-11]
% {
@@ -1158,6 +1180,51 @@
% for an example).
% \end{function}
%
+% \begin{function}[added = 2024-12-08]
+% {
+% \tl_regex_replace_once:Nnn, \tl_regex_replace_once:cnn,
+% \tl_regex_replace_once:NNn, \tl_regex_replace_once:cNn,
+% \tl_regex_greplace_once:Nnn, \tl_regex_greplace_once:cnn,
+% \tl_regex_greplace_once:NNn, \tl_regex_greplace_once:cNn
+% }
+% \begin{syntax}
+% \cs{tl_regex_replace_once:Nnn} \meta{tl~var} \Arg{regex} \Arg{replacement}
+% \cs{tl_regex_replace_once:NNn} \meta{tl~var} \meta{regex~var} \Arg{replacement}
+% \end{syntax}
+% Searches for the \meta{regular expression} in the contents of the
+% \meta{tl~var} and replaces the first match with the
+% \meta{replacement}. In the \meta{replacement},
+% |\0| represents the full match, |\1| represent the contents of the
+% first capturing group, |\2| of the second, \emph{etc.}
+% Theses are alternative names for \cs{regex_replace_once:nnN} and friends,
+% with arguments re-ordered for \meta{tl~var} setting;
+% See \pkg{l3regex} chapter for more details of the \meta{regex}
+% format.
+% \end{function}
+%
+% \begin{function}[added = 2024-12-08]
+% {
+% \tl_regex_replace_all:Nnn, \tl_regex_replace_all:cnn,
+% \tl_regex_replace_all:NNn, \tl_regex_replace_all:cNn,
+% \tl_regex_greplace_all:Nnn, \tl_regex_greplace_all:cnn,
+% \tl_regex_greplace_all:NNn, \tl_regex_greplace_all:cNn
+% }
+% \begin{syntax}
+% \cs{tl_regex_replace_all:Nnn} \meta{tl~var} \Arg{regex} \Arg{replacement}
+% \cs{tl_regex_replace_all:NNn} \meta{tl~var} \meta{regex~var} \Arg{replacement}
+% \end{syntax}
+% Replaces all occurrences of the \meta{regular expression} in the
+% contents of the \meta{tl~var}
+% by the \meta{replacement}, where |\0| represents
+% the full match, |\1| represent the contents of the first capturing
+% group, |\2| of the second, \emph{etc.} Every match is treated
+% independently, and matches cannot overlap.
+% Theses are alternative names for \cs{regex_replace_all:nnN} and friends,
+% with arguments re-ordered for \meta{tl~var} setting;
+% see \pkg{l3regex} chapter for more details of the \meta{regex}
+% format.
+% \end{function}
+%
% \begin{function}[updated = 2011-08-11]
% {
% \tl_remove_once:Nn, \tl_remove_once:NV, \tl_remove_once:Ne,
@@ -1277,7 +1344,7 @@
% read from a file.
%
% Contrarily to the \tn{scantokens} \eTeX{} primitive, \cs{tl_rescan:nn}
-% tokenizes the whole string in the same category code regime rather
+% tokenizes the whole string in the same category code régime rather
% than one token at a time, so that directives such as \tn{verb}
% that rely on changing category codes will not function properly.
% \end{texnote}
@@ -1369,8 +1436,8 @@
%
% \begin{macro}
% {
-% \tl_const:Nn, \tl_const:Ne, \tl_const:Nx,
-% \tl_const:cn, \tl_const:ce, \tl_const:cx
+% \tl_const:Nn, \tl_const:NV, \tl_const:Ne, \tl_const:Nx,
+% \tl_const:cn, \tl_const:cV, \tl_const:ce, \tl_const:cx
% }
% Constants are also easy to generate. They use \cs{cs_gset_nopar:Npe} instead
% of \cs{__kernel_tl_gset:Nx} so that the correct scope checking for |c|,
@@ -1384,7 +1451,7 @@
\__kernel_chk_if_free_cs:N #1
\cs_gset_nopar:Npe #1 { \__kernel_exp_not:w {#2} }
}
-\cs_generate_variant:Nn \tl_const:Nn { Ne , c , ce }
+\cs_generate_variant:Nn \tl_const:Nn { NV , Ne , c , cV , ce }
\cs_generate_variant:Nn \tl_const:Nn { Nx , cx }
% \end{macrocode}
% \end{macro}
@@ -2249,6 +2316,57 @@
%
% \begin{macro}
% {
+% \tl_regex_replace_once:Nnn, \tl_regex_replace_once:cnn,
+% \tl_regex_replace_once:NNn, \tl_regex_replace_once:cNn,
+% \tl_regex_greplace_once:Nnn, \tl_regex_greplace_once:cnn,
+% \tl_regex_greplace_once:NNn, \tl_regex_greplace_once:cNn
+% }
+% \begin{macro}
+% {
+% \tl_regex_replace_all:Nnn, \tl_regex_replace_all:cnn,
+% \tl_regex_replace_all:NNn, \tl_regex_replace_all:cNn,
+% \tl_regex_greplace_all:Nnn, \tl_regex_greplace_all:cnn,
+% \tl_regex_greplace_all:NNn, \tl_regex_greplace_all:cNn
+% }
+% Wrappers.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_regex_replace_once:Nnn #1#2#3
+ { \regex_replace_once:nnN {#2} {#3} #1 }
+\cs_generate_variant:Nn \tl_regex_replace_once:Nnn { c }
+\cs_new_protected:Npn \tl_regex_replace_once:NNn #1#2#3
+ { \regex_replace_once:NnN #2 {#3} #1 }
+\cs_generate_variant:Nn \tl_regex_replace_once:NNn { c }
+\cs_new_protected:Npn \tl_regex_replace_all:Nnn #1#2#3
+ { \regex_replace_all:nnN {#2} {#3} #1 }
+\cs_generate_variant:Nn \tl_regex_replace_all:Nnn { c }
+\cs_new_protected:Npn \tl_regex_replace_all:NNn #1#2#3
+ { \regex_replace_all:NnN #2 {#3} #1 }
+\cs_generate_variant:Nn \tl_regex_replace_all:NNn { c }
+\group_begin:
+ \cs_set_protected:Npn \@@_tmp:w #1#2#3
+ {
+ \cs_new_protected:cpe { tl_regex_greplace_ #1 :N #2 n } ##1##2##3
+ {
+ \group_begin:
+ \tl_set_eq:NN \exp_not:N \l_@@_internal_a_tl ##1
+ \exp_not:c { regex_replace_ #1 :Nn #2 }
+ #3 {##2} {##3} \exp_not:N \l_@@_internal_a_tl
+ \tl_gset_eq:NN ##1 \exp_not:N \l_@@_internal_a_tl
+ \group_end:
+ }
+ \cs_generate_variant:cn { tl_regex_greplace_ #1 :N #2 n } { c }
+ }
+ \@@_tmp:w { once } n { }
+ \@@_tmp:w { once } N \use:n
+ \@@_tmp:w { all } n { }
+ \@@_tmp:w { all } N \use:n
+\group_end:
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
% \tl_remove_once:Nn, \tl_remove_once:NV, \tl_remove_once:Ne,
% \tl_remove_once:cn, \tl_remove_once:cV, \tl_remove_once:ce
% }
@@ -2611,6 +2729,29 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}
+% {
+% \tl_if_regex_match:nn, \tl_if_regex_match:Vn,
+% \tl_if_regex_match:nN, \tl_if_regex_match:VN,
+% }
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \tl_if_regex_match:nn #1#2 { TF , T , F }
+ {
+ \regex_match:nnTF {#2} {#1}
+ \prg_return_true: \prg_return_false:
+ }
+\prg_generate_conditional_variant:Nnn \tl_if_regex_match:nn
+ { V } { TF , T , F }
+\prg_new_protected_conditional:Npnn \tl_if_regex_match:nN #1#2 { TF , T , F }
+ {
+ \regex_match:nNTF {#2} #1
+ \prg_return_true: \prg_return_false:
+ }
+\prg_generate_conditional_variant:Nnn \tl_if_regex_match:nN
+ { V } { TF , T , F }
+% \end{macrocode}
+% \end{macro}
+%
% \subsection{Mapping over token lists}
%
% \begin{macro}
@@ -2920,7 +3061,7 @@
% }
% \begin{macro}{\@@_trim_mark:}
% Trimming spaces from around the input is done using delimited
-% arguments and quarks, and to get spaces at odd places in the
+% arguments and \cs{@@_trim_mark:}, and to get spaces at odd places in the
% definitions, we nest those in \cs{@@_tmp:w}, which then receives
% a single space as its argument: |#1| is \verb*+ +.
% Removing leading spaces is done with \cs{@@_trim_spaces_auxi:w},
diff --git a/macros/latex-dev/required/l3kernel/l3token.dtx b/macros/latex-dev/required/l3kernel/l3token.dtx
index 03bf46b101..73d0ec2102 100644
--- a/macros/latex-dev/required/l3kernel/l3token.dtx
+++ b/macros/latex-dev/required/l3kernel/l3token.dtx
@@ -2,7 +2,7 @@
%
%% File: l3token.dtx
%
-% Copyright (C) 2005-2024 The LaTeX Project
+% Copyright (C) 2005-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -151,7 +151,7 @@
% $0$ is not allowed.
% Active characters cannot be generated in older versions of \XeTeX{}.
% Another way to build token lists with unusual category codes is
-% \cs{regex_replace:nnN} |{.*}| \Arg{replacement} \meta{tl~var}.
+% \cs{regex_replace_all:nnN} |{.*}| \Arg{replacement} \meta{tl~var}.
% \begin{texnote}
% Exactly two expansions are needed to produce the character.
% \end{texnote}
@@ -443,12 +443,6 @@
% not be used other than for category code tests.
% \end{variable}
%
-% \begin{variable}{\c_catcode_active_tl}
-% A token list containing an active token. This is used internally
-% for test purposes and should not be used other than in
-% appropriately-constructed category code tests.
-% \end{variable}
-%
% \section{Converting tokens}
%
% \begin{function}[EXP]{\token_to_meaning:N, \token_to_meaning:c}
@@ -660,7 +654,10 @@
% \cs{token_if_long_macro_p:N} \meta{token} \\
% \cs{token_if_long_macro:NTF} \meta{token} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if the \meta{token} is a long macro.
+% Tests if the \meta{token} is a long macro with no other prefix; to
+% test for a macro that is both long and protected, use
+% \cs[index = token_if_protected_long_macro:NTF]^^A
+% {token_if_protected_long_macro:N(TF)}.
% \end{function}
%
% \begin{function}[EXP,pTF, updated=2012-01-20]{\token_if_protected_macro:N}
@@ -668,8 +665,10 @@
% \cs{token_if_protected_macro_p:N} \meta{token} \\
% \cs{token_if_protected_macro:NTF} \meta{token} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if the \meta{token} is a protected macro: for a macro which
-% is both protected and long this returns \texttt{false}.
+% Tests if the \meta{token} is a protected macro with no other prefix; to
+% test for a macro that is both protected and long, use
+% \cs[index = token_if_protected_long_macro:NTF]^^A
+% {token_if_protected_long_macro:N(TF)}.
% \end{function}
%
% \begin{function}[EXP,pTF, updated=2012-01-20]{\token_if_protected_long_macro:N}
@@ -776,7 +775,7 @@
% ~~\Arg{false code}
% \end{syntax}
% This function compares the \meta{test token} in turn with each of
-% the \meta{token cases}. If the two are equal (as described for
+% the \meta{token case}s. If the two are equal (as described for
% \cs{token_if_eq_catcode:NNTF}, \cs{token_if_eq_charcode:NNTF} and
% \cs{token_if_eq_meaning:NNTF}, respectively) then the associated
% \meta{code} is left in the input stream and other cases are
@@ -794,7 +793,7 @@
% stream while leaving it in place. This is handled using the
% \enquote{peek} functions. The generic \cs{peek_after:Nw} is provided
% along with a family of predefined tests for common cases. Peeking
-% ahead does \emph{not} skip spaces: rather, \cs{peek_remove_spaces:n}.
+% ahead does \emph{not} skip spaces: rather, \cs{peek_remove_spaces:n}
% should be used. In addition, using \cs{peek_analysis_map_inline:n},
% one can map through the following tokens in the input stream and
% repeatedly perform some tests.
@@ -1013,7 +1012,7 @@
% In case the input stream has not yet been tokenized (converted
% from characters to tokens), characters are tokenized one by one as
% needed by \cs{peek_analysis_map_inline:n} using the current
-% category code regime.
+% category code régime.
% \end{texnote}
% \end{function}
%
@@ -1828,12 +1827,12 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{variable}{\c_catcode_active_tl}
+% \begin{variable}{\c_@@_active_tl}
% Not an implicit token!
% \begin{macrocode}
\group_begin:
\char_set_catcode_active:N \*
- \tl_const:Nn \c_catcode_active_tl { \exp_not:N * }
+ \tl_const:Nn \c_@@_active_tl { \exp_not:N * }
\group_end:
% \end{macrocode}
% \end{variable}
@@ -1970,13 +1969,13 @@
%
% \begin{macro}[pTF]{\token_if_active:N}
% Check if token is an active char token. We use the constant
-% \cs{c_catcode_active_tl} for this. A technical point is that
-% \cs{c_catcode_active_tl} is in fact a macro expanding to
+% \cs{c_@@_active_tl} for this. A technical point is that
+% \cs{c_@@_active_tl} is in fact a macro expanding to
% |\exp_not:N *|, where |*| is active.
% \begin{macrocode}
\prg_new_conditional:Npnn \token_if_active:N #1 { p , T , F , TF }
{
- \if_catcode:w \exp_not:N #1 \c_catcode_active_tl
+ \if_catcode:w \exp_not:N #1 \c_@@_active_tl
\prg_return_true: \else: \prg_return_false: \fi:
}
% \end{macrocode}
@@ -2828,7 +2827,7 @@ end
% \peek_meaning_remove:N,
% }
% The public functions themselves cannot be defined using
-% \cs{prg_new_conditional:Npnn}. Instead, the |TF|, |T|, |F| variants
+% \cs{prg_new_protected_conditional:Npnn}. Instead, the |TF|, |T|, |F| variants
% are defined in terms of corresponding variants of
% \cs{@@_token_generic:NNTF} or \cs{@@_token_remove_generic:NNTF},
% with first argument one of \cs{@@_execute_branches_catcode:},
diff --git a/macros/latex-dev/required/l3kernel/l3unicode.dtx b/macros/latex-dev/required/l3kernel/l3unicode.dtx
index 179817d490..535816e979 100644
--- a/macros/latex-dev/required/l3kernel/l3unicode.dtx
+++ b/macros/latex-dev/required/l3kernel/l3unicode.dtx
@@ -2,7 +2,7 @@
%
%% File: l3unicode.dtx
%
-% Copyright (C) 2018-2024 The LaTeX Project
+% Copyright (C) 2018-2025 The LaTeX Project
%
% It may be distributed and/or modified under the conditions of the
% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2024-05-27}
+% \date{Released 2025-01-18}
%
% \maketitle
%
@@ -162,9 +162,7 @@
% can generate character tokens for document use: those are defined below,
% in the data recovery setup.
% \begin{macrocode}
-\bool_lazy_or:nnTF
- { \sys_if_engine_luatex_p: }
- { \sys_if_engine_xetex_p: }
+\sys_if_engine_opentype:TF
{
\cs_new:Npn \codepoint_str_generate:n #1
{
@@ -390,9 +388,7 @@
{ \exp_args:Ne \@@_to_nfd:n { \int_eval:n {#1} } }
\cs_new:Npn \@@_to_nfd:n #1
{ \@@_to_nfd:nn {#1} { \char_value_catcode:n {#1} } }
-\bool_lazy_or:nnF
- { \sys_if_engine_luatex_p: }
- { \sys_if_engine_xetex_p: }
+\sys_if_engine_opentype:F
{
\cs_gset:Npn \@@_to_nfd:n #1
{
@@ -719,15 +715,22 @@
\tl_set:ce { l_@@_ #1 _block_tl }
{ \int_eval:n { \tl_use:c { l_@@_ #1 _block_tl } + 1 } }
}
- \prg_replicate:nn {#2}
+% \end{macrocode}
+% Here, we avoid \cs{prg_replicate:nn} as the number of tokens generated would be
+% high: that shows in the format dump (although \TeX{} recovers memory during
+% the subsequent runs).
+% \begin{macrocode}
+ \int_step_inline:nnn
+ { \tl_use:c { l_@@_ #1 _pos_tl } + 1 }
+ { \tl_use:c { l_@@_ #1 _pos_tl } + #2 }
{
- \tl_set:ce { l_@@_ #1 _pos_tl }
- { \int_eval:n { \tl_use:c { l_@@_ #1 _pos_tl } + 1 } }
\exp_args:Nc \__kernel_intarray_gset:Nnn
{ g_@@_ #1 _index_intarray }
- { \tl_use:c { l_@@_ #1 _pos_tl } }
+ {##1}
\l_@@_matched_block_tl
}
+ \tl_set:ce { l_@@_ #1 _pos_tl }
+ { \int_eval:n { \tl_use:c { l_@@_ #1 _pos_tl } + #2 } }
\clist_clear:c { l_@@_ #1 _block_clist }
}
% \end{macrocode}
diff --git a/macros/latex-dev/required/l3kernel/source3.pdf b/macros/latex-dev/required/l3kernel/source3.pdf
index b0795ec6c1..f64d5c7efe 100644
--- a/macros/latex-dev/required/l3kernel/source3.pdf
+++ b/macros/latex-dev/required/l3kernel/source3.pdf
Binary files differ
diff --git a/macros/latex-dev/required/l3kernel/source3.tex b/macros/latex-dev/required/l3kernel/source3.tex
index 00095ad319..9f664d1b77 100644
--- a/macros/latex-dev/required/l3kernel/source3.tex
+++ b/macros/latex-dev/required/l3kernel/source3.tex
@@ -2,7 +2,7 @@
File: source3.tex
-Copyright (C) 1990-2012,2017-2024 The LaTeX Project
+Copyright (C) 1990-2012,2017-2025 The LaTeX Project
It may be distributed and/or modified under the conditions of the
LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -57,7 +57,7 @@ for those people who are interested.
{latex-team@latex-project.org}%
}%
}
-\date{Released 2024-05-27}
+\date{Released 2025-01-18}
\pagenumbering{roman}
\maketitle
diff --git a/macros/latex-dev/required/l3kernel/source3body.tex b/macros/latex-dev/required/l3kernel/source3body.tex
index 8471296227..4b97218447 100644
--- a/macros/latex-dev/required/l3kernel/source3body.tex
+++ b/macros/latex-dev/required/l3kernel/source3body.tex
@@ -285,7 +285,7 @@ pass it to |\foo:N|.
Variables are named in a similar manner to functions, but begin with
a single letter to define the type of variable:
-\begin{description}
+\begin{description}[leftmargin=2\parindent, labelindent*=-\parindent]
\item[\texttt{c}] Constant: global parameters whose value should not
be changed.
\item[\texttt{g}] Parameters whose value should only be set globally.
@@ -302,7 +302,7 @@ function, typically starting with the module\footnote{The module names are
\texttt{\string\l_int_tmpa_int} would be very unreadable.} name
and then a descriptive part.
Variables end with a short identifier to show the variable type:
-\begin{description}%
+\begin{description}[leftmargin=2\parindent, labelindent*=-\parindent]
\item[\texttt{bitset}] a set of bits (a string made up of a series of \texttt{0}
and \texttt{1} tokens that are accessed by position).
\item[\texttt{clist}] Comma separated list.
@@ -318,7 +318,7 @@ Variables end with a short identifier to show the variable type:
Applying \texttt{V}-type or \texttt{v}-type expansion to variables of
one of the above types is supported, while it is not supported for the
following variable types:
-\begin{description}
+\begin{description}[leftmargin=2\parindent, labelindent*=-\parindent]
\item[\texttt{bool}] Either true or false.
\item[\texttt{box}] Box register.
\item[\texttt{coffin}] A \enquote{box with handles} --- a higher-level
@@ -335,6 +335,21 @@ following variable types:
lists (with access at both ends) and stacks.
\end{description}
+\subsection{Behavior of \texttt{c}-type arguments when the \texttt{N}-type token
+ resulting from expansion is undefined}
+
+When \texttt{c}-type expansion is applied, it will produce an \texttt{N}-type
+token to be consumed by the underlying function. If the result of this process
+is a token which is undefined, \TeX{}'s behavior is to make it equal to
+|\scan_stop:| (|\relax|).
+
+This will likely lead to low-level errors if it occurs in contexts where
+\pkg{expl3} expects a \enquote{variable}, e.g.~a \texttt{prop}, \texttt{seq},
+etc. Therefore, the programmer should ensure that \texttt{c}-type expansion is
+only applied when the resulting \texttt{N}-type token will definitely exist,
+i.e.~when it is either defined prior to the application of the \texttt{c}-type
+expansion or will be by the underlying \texttt{N}-type function.
+
\subsection{Scratch variables}
Modules focussed on variable usage typically provide four scratch variables,
@@ -344,6 +359,19 @@ are never used by the core code. The nature of \TeX{} grouping means that as
with any other scratch variable, these should only be set and used with no
intervening third-party code.
+There are two more special types of constants:
+\begin{description}[leftmargin=2\parindent, labelindent*=-\parindent]
+ \item[\texttt{q}] Quark constants.
+ \item[\texttt{s}] Scan mark constants.
+\end{description}
+Similarly, each quark or scan mark name starts with the module name,
+but doesn't end with a variable type, because the type is already
+marked by the prefix \texttt{q} or \texttt{s}.
+Some general quarks and scan marks provided by \LaTeX3 don't start
+with a module name, for example \cs{s_stop}.
+See documentation of quarks and scan marks in Chapter~\ref{sec:l3quarks}
+for more info.
+
\subsection{Terminological inexactitude}
A word of warning. In this document, and others referring to the \pkg{expl3}
@@ -402,12 +430,12 @@ show this more clearly. They will carry out the same function but will take
different types of argument:
\begin{function}[label = ]{\seq_new:N, \seq_new:c}
\begin{syntax}
- |\seq_new:N| \meta{sequence}
+ |\seq_new:N| \meta{seq var}
\end{syntax}
When a number of variants are described, the arguments are usually
- illustrated only for the base function. Here, \meta{sequence} indicates
- that |\seq_new:N| expects the name of a sequence. From the argument
- specifier, |\seq_new:c| also expects a sequence name, but as a
+ illustrated only for the base function. Here, \meta{seq var} indicates
+ that |\seq_new:N| expects a sequence variable. From the argument
+ specifier, |\seq_new:c| also expects a sequence variable, but as a
name rather than as a control sequence. Each argument given in the
illustration should be described in the following text.
\end{function}
@@ -435,7 +463,7 @@ an \texttt{f}-type argument. In this case a hollow star is used to indicate
this:
\begin{function}[rEXP, label = ]{\seq_map_function:NN}
\begin{syntax}
- |\seq_map_function:NN| \meta{seq} \meta{function}
+ |\seq_map_function:NN| \meta{seq var} \meta{function}
\end{syntax}
\end{function}
diff --git a/macros/latex-dev/required/latex-lab/README.md b/macros/latex-dev/required/latex-lab/README.md
index fb930aa965..779c04f2a9 100644
--- a/macros/latex-dev/required/latex-lab/README.md
+++ b/macros/latex-dev/required/latex-lab/README.md
@@ -1,6 +1,6 @@
# LaTeX laboratory
-Release 2024-11-01 pre-release 0
+Release 2025-06-01 pre-release 1
## Overview
diff --git a/macros/latex-dev/required/latex-lab/blocks-code.pdf b/macros/latex-dev/required/latex-lab/blocks-code.pdf
index a5d58887f2..4a6498c9af 100644
--- a/macros/latex-dev/required/latex-lab/blocks-code.pdf
+++ b/macros/latex-dev/required/latex-lab/blocks-code.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/blocks-doc.pdf b/macros/latex-dev/required/latex-lab/blocks-doc.pdf
index e62b76f5e3..7403f57f21 100644
--- a/macros/latex-dev/required/latex-lab/blocks-doc.pdf
+++ b/macros/latex-dev/required/latex-lab/blocks-doc.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/changes.txt b/macros/latex-dev/required/latex-lab/changes.txt
index cd53086b2b..300e2f0c86 100644
--- a/macros/latex-dev/required/latex-lab/changes.txt
+++ b/macros/latex-dev/required/latex-lab/changes.txt
@@ -1,12 +1,181 @@
+2024-11-26 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-math.dtx: changed handling of math/mathml/structelem to handle
+ fakemath better(tagging/764)
+ * latex-lab-math.dtx: made all main math sockets tagging sockets and
+ assign the plugs directly.
+ * disable para tagging also in $$-display (tagging/765)
+
+2024-11-23 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+
+ * latex-lab-block.dtx (subsubsection{Implementation of block templates \ldots}):
+ Use private storage bin for parindent and not \listparindent to decouple block
+ and list templates (tagging/767)
+
+ (subsubsection{Blockquote instances}):
+ Theorems use their own block-instance and not displayblock to allow for
+ customization (tagging/767)
+
+ * latex-lab-firstaid.dtx (subsection{ams classes and amsthm}):
+ Move the theorem link target later to not have to force hmode with \leavevmode.
+ Otherwise theorems get always an indentation.
+
+2024-11-21 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-float.dtx: Correct socket declaration.
+
+2024-11-18 Joseph Wright <Joseph.Wright@latex-project.org>
+ * latex-lab-math.dtx: Use "@@" for a couple of internals
+
+2024-10-25 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-math.dtx: reorganized luamml and mathml options
+ to support also structure elements and extended the documentation. Corrected
+ handling of alt-texts. Added examples for the various options.
+
+2024-10-16 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-firstaid.dtx: correct amsthm firstaid (tagging/733),
+ remove now unneeded code for cleveref.
+
+2024-10-12 Joseph Wright <Joseph.Wright@latex-project.org>
+ * latex-lab-math.dtx: Sync with protected-begin status
+
+2024-10-11 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-toc.dtx, latex-lab-sec.dtx, latex-lab-toc-kernel-changes: move target
+ handling (\MakeLinkTarget patches) into the kernel.
+
+2024-10-11 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+
+ * latex-lab-block.dtx (subsubsection{verse environment}):
+ Update \@itemlabel in \l_@@_legacy_env_params_tl and not at the start of
+ the environment (tagging/730)
+
+ Set the defaults for \@itemlabel, \@listctr and @nmbrlist early in the
+ block code before the setup code gets executed (tagging/730)
+
+ (subsubsection{Implementation of list templates ...):
+ Correct logic for setting up the list counter (tagging/730)
+
+2024-10-04 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-firstaid.dtx: add first support for fancyvrb environments.
+
+2024-10-04 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-sec.dtx (subsection{Sockets}):
+ add missing braces around optional arg (tagging/725)
+
+2024-10-03 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+ * latex-lab-block.dtx (subsubsection{Implementation of list templates ...}):
+ Pass user keys on list to \item for evaluation
+
+2024-10-02 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-math.dtx (subsection{Sockets}):
+ disable paratagging in inline math (tagging/711)
+
+2024-09-30 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-footnotes.dtx: remove unneeded NonStruct structure.
+
+2024-09-30 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+ * latex-lab-math.dtx (subsection{Content grabbing}):
+ Correct logic for inserting below skips after displays (tagging/721)
+
+2024-09-26 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-firstaid.dtx: add support for theorems declared with
+ amsthm, amsart, amsbook, amsproc.
+
+2024-09-24 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-sec.dtx,latex-lab-footnotes.dtx:
+ correct and improve footnotes in longtable
+
+2024-09-24 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-toc.dtx,latex-lab-footnotes.dtx: adapt Ref handling to tagpdf 0.99f
+
+2024-09-18 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-amsmath.dtx,latex-lab-graphic.dtc,
+ latex-lab-marginpar.dtx,latex-lab-math.dtx,latex-lab-mathtools.dtx,
+ latex-lab-minipage.dtx,latex-lab-sec.dtx,latex-lab-table.dtx,latex-lab-text.dtx:
+ switch to \tag_suspend:n and \tag_resume:n
+
+2024-09-17 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-float.dtx: switch to tagging sockets
+
+2024-09-13 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * documentmetadata-support.dtx: change warning to error if pdfstandard is unknown,
+ see https://github.com/latex3/pdfresources/issues/77#issuecomment-2329522654.
+
+2024-09-03 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * documentmetadata-support.dtx: switch to T1 encoding by default for non-Unicode
+ engines.
+
+2024-09-02 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+ * latex-lab-block.dtx (subsubsection{List tags}):
+ Do not close LI and LBody if they were never opened because of a
+ missing \item (issue tagging/641)
+
+ (subsubsection{Implementation of \cs{item} template(s)}):
+ Set @newlist to false after the first \item (issue tagging/36)
+
+ Call \@noitemerr in para/begin hook if hmode is started before
+ the first item
+
+ (subsubsection{Implementation of block templates \ldots}):
+ Drop \@noitemerr from \addvspace and \addpenalty
+
+2024-08-29 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-math.dtx: avoid loosing math if tagging is suspended,
+ tagging-project issue #661
+
+2024-08-22 Joseph Wright <Joseph.Wright@latex-project.org>
+ * latex-lab-math.dtx: correct handling of empty math processing
+
+2024-08-21 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-math.dtx: correct luamml patches for array,
+ allow to use luamml without unicode-math
+
+2024-08-14 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-math.dtx: add luamml support for automatic mathml generation
+
+2024-08-12 Joseph Wright <Joseph.Wright@latex-project.org>
+ * latex-lab-math.dtx: add support for math in tabulars
+
+2024-08-11 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-firstaid.dtx: amsproc support, discussion in PR #517
+
+2024-08-11 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-block.dtx: preset verbatim para-instance, issue #119
+
+2024-08-10 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-block.dtx, latex-lab-table.dtx: reset flattened level in para/restore, issue #544
+
+2024-08-08 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-minipage.dtx, latex-lab-table.dtx: improve support for minipage in tables.
+ handle issue #37
+
+2024-08-06 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-table.dtx: add support for header-columns
+ * latex-lab-table.dtx: add support for multirows
+ * latex-lab-table.dtx: handle issue #432
+ * latex-lab-marginpar.dtx: handle issue #444
+
+2024-07-11 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-footnote.dtx: restore paragraph defaults at the begin of the footnote
+ tagging-project#262
+
+2024-07-13 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+
+ * latex-lab-table.dtx (subsection{Tagging support sockets}):
+ add plugs for tbl/leaders/begin and /end
+ (subsection{Misc stuff}): drop unused socket
+
+2024-07-11 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * latex-lab-toc.dtx, latex-lab-toc-kernel-changes: switch from configuration points
+ to sockets.
+
2024-05-25 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
* latex-lab-table.dtx: disable table headers in presentation tables.
2024-05-25 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
- * latex-lab-firstaid.dtx: add firstaid for booktabs cmidrules,
+ * latex-lab-firstaid.dtx: add firstaid for booktabs cmidrules,
see tagging-issue 69.
2024-04-18 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
- * documentmetadata-support.dtx: change handling of default language.
+ * documentmetadata-support.dtx: change handling of default language.
The code now tries to detect languages set by babel/polyglossia.
2024-04-16 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
diff --git a/macros/latex-dev/required/latex-lab/documentmetadata-support-code.pdf b/macros/latex-dev/required/latex-lab/documentmetadata-support-code.pdf
index bc995e7cce..b715491e1a 100644
--- a/macros/latex-dev/required/latex-lab/documentmetadata-support-code.pdf
+++ b/macros/latex-dev/required/latex-lab/documentmetadata-support-code.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/documentmetadata-support-doc.pdf b/macros/latex-dev/required/latex-lab/documentmetadata-support-doc.pdf
index 9466a187ff..bc4391e583 100644
--- a/macros/latex-dev/required/latex-lab/documentmetadata-support-doc.pdf
+++ b/macros/latex-dev/required/latex-lab/documentmetadata-support-doc.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/documentmetadata-support.dtx b/macros/latex-dev/required/latex-lab/documentmetadata-support.dtx
index a629d9c551..6752e8098a 100644
--- a/macros/latex-dev/required/latex-lab/documentmetadata-support.dtx
+++ b/macros/latex-dev/required/latex-lab/documentmetadata-support.dtx
@@ -18,8 +18,8 @@
% for those people who are interested or want to report an issue.
%
% \begin{macrocode}
-\def\documentmetadatasupportversion{1.0h}
-\def\documentmetadatasupportdate{2024-03-26}
+\def\documentmetadatasupportversion{1.0j}
+\def\documentmetadatasupportdate{2024-09-13}
% \end{macrocode}
%
%
@@ -314,6 +314,19 @@
{ \tl_new:N \g_@@_testphase_tl }
% \end{macrocode}
% \end{variable}
+%
+% \subsection{Kernel changes with \cs{DocumentMetadata}}
+% \begin{macro}{\@kernel@before@DocumentMetadata}
+% \begin{macrocode}
+\cs_new_protected:Npn \@kernel@before@DocumentMetadata
+ {
+ \ifx\Umathcode\@undefined
+ \fontencoding{T1}
+ \renewcommand\encodingdefault{T1}
+ \fi
+ }
+% \end{macrocode}
+% \end{macro}
% \subsection{\cs{DocumentMetadata}}
%
@@ -330,6 +343,10 @@
{ \msg_error:nn { meta } { after-class } }
{
% \end{macrocode}
+% Load general format changes
+% \begin{macrocode}
+ \@kernel@before@DocumentMetadata
+% \end{macrocode}
%
% The wanted backend must be detected first, we read the init
% key and then force the loading of the backend.
@@ -481,7 +498,7 @@
}
,_pdfstandard / unknown .code:n =
{
- \msg_warning:nnn{pdf}{unknown-standard}{#1}
+ \msg_error:nnn{pdf}{unknown-standard}{#1}
}
,testphase .multichoice:
,testphase / tagpdf .code:n =
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-amsmath.dtx b/macros/latex-dev/required/latex-lab/latex-lab-amsmath.dtx
index 57e27067cb..8591b39b39 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-amsmath.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-amsmath.dtx
@@ -66,7 +66,7 @@
% \subsection{File declaration}
% \begin{macrocode}
\ProvidesFile{latex-lab-amsmath.ltx}
- [2024-02-12 v0.1b amsmath adaptions]
+ [2024-09-18 v0.1c amsmath adaptions]
% \end{macrocode}
% \subsection{Tagpdf support}
% To make the code independent from tagging being loaded and active
@@ -99,7 +99,7 @@
% \end{macrocode}
% Stop tagging when measuring:
% \begin{macrocode}
- \ifmeasuring@\tag_stop:\fi
+ \ifmeasuring@\tag_suspend:n{\measuring}\fi
\normalbaselines
\ifdim\linewidth=\columnwidth
\else \parshape\@ne \@totalleftmargin \linewidth
@@ -174,7 +174,7 @@
\def\text@#1
{{
\int_gincr:N\g__math_mathchoice_int
- \tag_stop:
+ \tag_suspend:n{\text@}
\mathchoice
{
\@@_tag_if_mathstyle:en{mathchoice-\int_use:N\g__math_mathchoice_int}{0}
@@ -200,8 +200,8 @@
% \end{macrocode}
%
% \subsection{\cs{pmb}}
-% \cs{pmb} prints is argument three times. For tagging we must mark
-% two of occurences as artifact.
+% \cs{pmb} prints its argument three times. For tagging we must mark
+% two of occurrences as artifact.
% For luatex the attributes in the box must be reset, for this
% we switch to expl3-boxes.
% \begin{macrocode}
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-amsmath.pdf b/macros/latex-dev/required/latex-lab/latex-lab-amsmath.pdf
index 794d259d4c..d3d83b9242 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-amsmath.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-amsmath.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-bib.dtx b/macros/latex-dev/required/latex-lab/latex-lab-bib.dtx
index e8ee192a7b..9d336aba20 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-bib.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-bib.dtx
@@ -16,7 +16,7 @@
%
% for those people who are interested or want to report an issue.
%
-\def\ltlabbibdate{2024-02-12}
+\def\ltlabbibdate{2024-07-05}
\def\ltlabbibversion{0.81b}
%<*driver>
\documentclass{l3doc}
@@ -128,7 +128,7 @@
%
% \begin{function}{\@extra@binfo,\@extra@b@citeb}
%
-% These are taken from hyperref, they are for chapterbib compability (and also
+% These are taken from hyperref, they are for chapterbib compatibility (and also
% signal to chapterbib not to change the citation commands)
% \end{function}
%
@@ -157,7 +157,7 @@
% \end{macrocode}
% \begin{macro}{\@extra@binfo,\@extra@b@citeb}
-% These are taken from hyperref, they are for chapterbib compability (and also
+% These are taken from hyperref, they are for chapterbib compatibility (and also
% signal to chapterbib not to change the citation commands)
% \begin{macrocode}
\providecommand*\@extra@binfo{}%
@@ -270,7 +270,7 @@
% \end{macrocode}
% Now we add the tagging structure.
% TODO: with the next tagpdf version it should no longer be
-% needed to exand the ref key.
+% needed to expand the ref key.
% \begin{macrocode}
\AddToHookWithArguments{bibcite/before}
{
@@ -305,7 +305,7 @@
% We need in part different code for both systems:
% with biblatex we have to take care that only the first
% structure sets a label, and if
-% hyperref is not loaded (or deactived) we will need additional code
+% hyperref is not loaded (or deactivated) we will need additional code
% but this currently doesn't exist.
% We assume that no document loads both package -- that will probably break.
% \begin{macrocode}
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-bib.pdf b/macros/latex-dev/required/latex-lab/latex-lab-bib.pdf
index 7eb16beaf9..ee7d80fc53 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-bib.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-bib.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-block.dtx b/macros/latex-dev/required/latex-lab/latex-lab-block.dtx
index 7d08b270d2..2399d15626 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-block.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-block.dtx
@@ -9,14 +9,17 @@
%
% https://www.latex-project.org/lppl.txt
%
-\def\ltlabblockdate{2024-03-23}
-\def\ltlabblockversion{0.8n}
+\def\ltlabblockdate{2024-11-25}
+\def\ltlabblockversion{0.8w}
%<*driver>
\documentclass[kernel]{l3doc}
\usepackage{amstext}
\EnableCrossrefs
\CodelineIndex
+\setcounter{secnumdepth}{4}
+\setcounter{tocdepth}{4}
+
\usepackage{todonotes}
\begin{document}
@@ -61,8 +64,9 @@
% printtype=\textit{inst.}] {Instance}{instance}
%
%
-% \newcommand\valuefrom[1]{\textrm{value from }\texttt{#1}}
% \newcommand\key[1]{\texttt{#1}}
+% \newcommand\keyvalue[1]{\texttt{#1}}
+% \newcommand\valuefrom[1]{\textrm{value from }\key{#1}}
%
%
% \NewDocumentCommand\fmi{sO{}m}
@@ -98,7 +102,7 @@
% \def\TemplateKey##1##2##3##4{^^A
% \item[\texttt{##1}~(\textit{\mdseries##2})]##3^^A
% \ifx\TemplateKey##4\TemplateKey\else
-% \hfill\penalty500\hbox{}\hfill Default:~\texttt{##4}^^A
+% \hfill\penalty500\hbox{}\hfill Default:~\keyvalue{##4}^^A
% \nobreak\hskip-\parfillskip\hskip0pt\relax
% \fi
% \par
@@ -239,14 +243,14 @@
% {An explicit tag class attribute}{}
% \TemplateKey{tagging-recipe}{tokenlist}
% {Defines the way tagging is done. Currently the values
-% \texttt{basic}, \texttt{standard}, and \texttt{list}
+% \keyvalue{basic}, \keyvalue{standard}, and \keyvalue{list}
% are supported}{standard}
% \TemplateKey{level-increase}{boolean}{Does this \xt{blockenv}
% increase the block level if it is nested in an outer block?}{true}
% \TemplateKey{setup-code}{tokenlist}
% {Initial setup code. This is
-% executed after legacy defaults (from \cs{@listi},
-% \cs{@listii}, etc.) are used but before the block instance is called}{}
+% executed after legacy defaults (from \tn{@listi},
+% \tn{@listii}, etc.) are used but before the block instance is called}{}
% \TemplateKey{block-instance}{tokenlist}{Part of the name of the
% \xt{block} instance that is called. The full name has
% a \texttt{-}\meta{level} appended}{displayblock}
@@ -263,22 +267,22 @@
% \TemplateKey{inner-instance}{tokenlist}{Name of the inner instance
% (if any).}{}
% \TemplateKey{para-flattened}{boolean}{\emph{describe}}{false}
-% \TemplateKey{final-code}{tokenlist}{Final setup code}{\cs{ignorespaces}}
+% \TemplateKey{final-code}{tokenlist}{Final setup code}{\tn{ignorespaces}}
%
% \TemplateSemantics
%
% This \xt{blockenv} template supports the legacy list setting that
-% are found in many document classes in the macros \cs{@listi},
-% \cs{@listii}, up to \cs{@listvi}. It also uses the counter
-% \cs{@listdepth} to track nesting of block, again mainly to
+% are found in many document classes in the macros \tn{@listi},
+% \tn{@listii}, up to \tn{@listvi}. It also uses the counter
+% \tn{@listdepth} to track nesting of block, again mainly to
% support legacy setups (internally it gives it a more appropriate
% name but it remains accessible through the \LaTeXe{} name).
%
%
% It first checks that nothing is too deeply nested.
% If the level should increase then the increments the
-% \cs{@listdepth} counter and
-% calls the corresponding \cs{@list...} macro to update the legacy
+% \tn{@listdepth} counter and
+% calls the corresponding \tn{@list...} macro to update the legacy
% defaults. If \key{level-increase} is set to false this is bypassed.
%
% It then sets up the
@@ -302,21 +306,21 @@
% called.
%
% Finally, the \key{final-code} is executed (by default
-% \cs{ignorespaces}).
+% \tn{ignorespaces}).
%
%
% \end{TemplateDescription}
%
% The maximum number of \xt{blockenv}s that can be nested into each
% other is restricted by the \LaTeX{} counter
-% \texttt{maxblocklevels} with a default value of \texttt{6}. If this
+% \texttt{maxblocklevels} with a default value of \keyvalue{6}. If this
% value is increased then it is necessary to provide additional
% instances, e.g., \texttt{displayblock-7}, etc. Decreasing is, of
% course, always possible, then some of the instances defined are not
% used and instead the user gets an error that there is too much
% nesting going on.
%
-% If the key \key{level-increase} is set to \texttt{false} then such
+% If the key \key{level-increase} is set to \keyvalue{false} then such
% an environment doesn't alter the nesting level and therefore you can
% nest those environments as often as you like (a typical example
% would be \env{flushleft} anywhere in the nesting hierarchy, that
@@ -326,22 +330,24 @@
% \begin{TemplateDescription}{block}{display}
%
% \TemplateKey{heading}{tokenlist}{\emph{not really used yet}}{}
-% \TemplateKey{beginsep}{skip}{}{\cs{topsep}}
-% \TemplateKey{begin-par-skip}{skip}{}{\cs{partopsep}}
-% \TemplateKey{par-skip}{skip}{}{\cs{parsep}}
+% \TemplateKey{beginsep}{skip}{}{\tn{topsep}}
+% \TemplateKey{begin-par-skip}{skip}{}{\tn{partopsep}}
+% \TemplateKey{par-skip}{skip}{}{\tn{parsep}}
% \TemplateKey{end-skip}{skip}{}{\valuefrom{beginsep}}
% \TemplateKey{end-par-skip}{skip}{}{\valuefrom{begin-par-skip}}
-% \TemplateKey{beginpenalty}{integer}{}{\cs{@beginparpenalty}}
-% \TemplateKey{endpenalty}{integer}{}{\cs{@endparpenalty}}
-% \TemplateKey{leftmargin}{length}{}{\cs{leftmargin}}
-% \TemplateKey{rightmargin}{length}{}{\cs{rightmargin}}
-% \TemplateKey{parindent}{length}{}{\cs{listparindent}}
+% \TemplateKey{item-skip}{skip}{The space in front of an item if the
+% block is a list; if not the setting has no effect}{\tn{itemsep}}
+% \TemplateKey{beginpenalty}{integer}{}{\tn{@beginparpenalty}}
+% \TemplateKey{endpenalty}{integer}{}{\tn{@endparpenalty}}
+% \TemplateKey{leftmargin}{length}{}{\tn{leftmargin}}
+% \TemplateKey{rightmargin}{length}{}{\tn{rightmargin}}
+% \TemplateKey{parindent}{length}{}{0pt}
%
% \TemplateSemantics
%
% The idea of a \key{heading} key needs some further
% thoughts. Maybe instead the object type should accept a second
-% argument and receive input for such a headding from the document
+% argument and receive input for such a heading from the document
% level instead.
%
% The names of the keys need further thoughts and some
@@ -356,14 +362,14 @@
%
% \begin{TemplateDescription}{para}{std}
%
-% \TemplateKey{indent-width}{length}{}{\cs{parindent}}
+% \TemplateKey{indent-width}{length}{}{\tn{parindent}}
% \TemplateKey{start-skip}{skip}{}{0pt}
% \TemplateKey{left-skip}{skip}{}{0pt}
% \TemplateKey{right-skip}{skip}{}{0pt}
-% \TemplateKey{end-skip}{skip}{}{\cs{@flushglue}}
+% \TemplateKey{end-skip}{skip}{}{\tn{@flushglue}}
% \TemplateKey{fixed-word-spaces}{boolean}{}{false}
% \TemplateKey{final-hyphen-demerits}{integer}{}{5000}
-% \TemplateKey{cr-cmd}{tokenlist}{}{\cs{@normalcr}}
+% \TemplateKey{cr-cmd}{tokenlist}{}{\tn{@normalcr}}
% \TemplateKey{para-class}{tokenlist}{}{justify}
%
% \TemplateSemantics
@@ -390,17 +396,17 @@
% {Instance of type \texttt{item} to be used to format
% the label string}{basic}
% \TemplateKey{item-skip}{skip}{The space in front of an item in the
-% list.\fmi{May need to be on a different template level}}{\cs{itemsep}}
+% list. If not specified the value specified in the block template instance is used}{}
% \TemplateKey{item-indent}{length}{Horizontal displacement of the item.}{0pt}
% \TemplateKey{item-penalty}{integer}
% {Penalty for breaking before an
-% item (except the first)}{\cs{@itempenalty}}
+% item (except the first)}{\tn{@itempenalty}}
% \TemplateKey{label-width}{length}
-% {Width reserved for the formatted item label}{\cs{labelwidth}}
+% {Width reserved for the formatted item label}{\tn{labelwidth}}
% \TemplateKey{label-sep}{length}
-% {Horizontal separation between label and following text}{\cs{labelsep}}
+% {Horizontal separation between label and following text}{\tn{labelsep}}
% \TemplateKey{legacy-support}{boolean}
-% {Is formatting the label via \cs{makelabel} supported?}{false}
+% {Is formatting the label via \tn{makelabel} supported?}{false}
%
% \TemplateSemantics
%
@@ -410,16 +416,16 @@
%
% \begin{TemplateDescription}{item}{std}
%
-% \TemplateKey{counter-label}{function{1}}{\emph{unused}}{\cs{arabic}\{\#1\}}
+% \TemplateKey{counter-label}{function{1}}{\emph{unused}}{\tn{arabic}\{\#1\}}
% \TemplateKey{counter-ref}{function{1}}{\emph{unused}}{\valuefrom{counter-label}}
% \TemplateKey{label-ref}{function{1}}{\emph{unused}}{\#1}
% \TemplateKey{label-autoref}{function{1}}{\emph{unused}}{item~\#1}
% \TemplateKey{label-format}{function{1}}
% {Formatting of the label, questionable the way it is used}{\#1}
-% \TemplateKey{label-strut}{boolean}{Add a \cs{strut} to the label?}{false}
+% \TemplateKey{label-strut}{boolean}{Add a \tn{strut} to the label?}{false}
% \TemplateKey{label-align}{choice}
-% {Supported values \texttt{left},\texttt{center},
-% \texttt{right}, and \texttt{parleft}. \emph{Only partly implemented}}{right}
+% {Supported values \keyvalue{left},\keyvalue{center},
+% \keyvalue{right}, and \keyvalue{parleft}. \emph{Only partly implemented}}{right}
% \TemplateKey{label-boxed}{boolean}
% {Should the label be boxed?}{true}
% \TemplateKey{next-line}{boolean}{}{false}
@@ -474,7 +480,7 @@
% \>\>\> The paragraph text before the display element \ldots\\
% \>\> \struct{/text}\\
% \>\> \struct{display element structure}\\
-% \>\>\> Content of the display structure possiblly involving inner \struct{text-unit} tags\\
+% \>\>\> Content of the display structure possibly involving inner \struct{text-unit} tags\\
% \>\> \struct{/display element structure}\\
% \>\> \struct{text}\\
% \>\>\> \ldots{} continuing the outer paragraph text\\
@@ -549,7 +555,8 @@
% \key{tagging-recipe} of the \xt{blockenv} template. Currently the
% following values are implemented:
% \begin{description}
-% \item[\texttt{standalone}]
+% \raggedright
+% \item[\keyvalue{standalone}]
% This recipe does the following:
% \begin{itemize}
% \item
@@ -560,7 +567,7 @@
% \item
% Text inside the body of the environment start with
% \struct{text-unit}\struct{text} unless the key
-% \key{para-flattened} is set to \texttt{true}
+% \key{para-flattened} is set to \keyvalue{true}
% (which is most likely the wrong thing to do because we then get just
% \struct{text} as the structure).
%
@@ -573,7 +580,7 @@
% \struct{text-unit} is started, if appropriate, e.g., if text is following.
% \end{itemize}
%
-% \item[\texttt{basic}]
+% \item[\keyvalue{basic}]
% This recipe does the following:
% \begin{itemize}
% \item
@@ -585,7 +592,7 @@
%
% \item
% Text inside the body of the environment start with
-% \struct{text-unit}\struct{text} if \key{para-flattened} is set to \texttt{false},
+% \struct{text-unit}\struct{text} if \key{para-flattened} is set to \keyvalue{false},
% otherwise just with \struct{text}.
%
% \item
@@ -594,14 +601,14 @@
%
% \item
% Then look if the environment is followed by an empty line
-% (\cs{par}). If so, close the outer \struct{/text-unit} and start any
+% (\tn{par}). If so, close the outer \struct{/text-unit} and start any
% following text with \struct{text-unit}\struct{text}. Otherwise,
% don't and following text restarts with a just a \struct{text} (and no
% paragraph indentation)
% \end{itemize}
%
-% \item[\texttt{standard}]
-% This recipe is like the \texttt{basic} one as far as handling
+% \item[\keyvalue{standard}]
+% This recipe is like the \keyvalue{basic} one as far as handling
% \struct{text-unit} and \struct{text} is concerned. In addition
% \begin{itemize}
% \item
@@ -620,8 +627,8 @@
%
%
%
-% \item[\texttt{list}]
-% This recipe is like the \texttt{standard} one except that
+% \item[\keyvalue{list}]
+% This recipe is like the \keyvalue{standard} one except that
% \begin{itemize}
% \item
% the inner structure is a list (\struct{L}).
@@ -665,7 +672,7 @@
% \end{function}
%
% \begin{function}{\@setupverbinvisiblespace}
-% A counterpart definition to the kernel command \cs{@setupverbinvisiblespace},
+% A counterpart definition to the kernel command \tn{@setupverbinvisiblespace},
% needed as we need to handle real space chars in verbatim.
% \end{function}
%
@@ -678,7 +685,7 @@
% \end{function}
%
% \begin{function}{\item,\@itemlabel}
-% The \cs{item} is redefined.
+% The \tn{item} is redefined.
% \end{function}
%
% \begin{function}{\c@maxblocklevels}
@@ -687,7 +694,7 @@
% \end{function}
%
% \begin{function}{\begin}
-% The \cs{begin} is slightly redefine to handle \cs{@doendpe} better.
+% The \tn{begin} is slightly redefine to handle \tn{@doendpe} better.
% TODO: move to kernel
% \end{function}
%
@@ -722,7 +729,7 @@
blockenv implementation]
% \end{macrocode}
%
-% Generell kernel changes, also loaded by the sec and toc code.
+% General kernel changes, also loaded by the sec and toc code.
% \begin{macrocode}
\RequirePackage{latex-lab-kernel-changes}
% \end{macrocode}
@@ -730,22 +737,17 @@
\ExplSyntaxOn
% \end{macrocode}
%
-% \ufi{this variable(s) must be declared:}
-% \begin{macrocode}
-\tl_new:N \l_@@_item_align_tl
-\tl_new:N\l_@@_legacy_env_params_tl
-% \end{macrocode}
%
-% \subsection{Handling \cs{par} after the end of the list}
+% \subsection{Handling \tn{par} after the end of the list}
%
-% An empty line (or a \cs{par}) after a list has semantic meaning as
+% An empty line (or a \tn{par}) after a list has semantic meaning as
% it defines whether then following text is logically within the same
% paragraph as the list (no empty line) or whether it starts a new
% paragraph and the paragraph containing the list ends at the end of
% the list (empty line after the list).
% This is handled by \LaTeX{} using a legacy flag called
% \texttt{@endpe} and set of commands inside the
-% generic \cs{end} (calling \cs{@doendpe}) and as part of the list
+% generic \tn{end} (calling \tn{@doendpe}) and as part of the list
% environments identifying themselves as \enquote{paragraph ending
% environments} (by setting this flag).
%
@@ -756,8 +758,9 @@
%
%
%
-% \begin{macro}{\@doendpe}
+% \begin{macro}{\@doendpe,\__kernel_displayblock_doendpe:}
% The original \LaTeXe{} command is augmented to allow for tagging.
+% TODO: use sockets for this and move to the kernel eventually.
% \begin{macrocode}
\def\@doendpe{\@endpetrue
\def\par
@@ -772,8 +775,8 @@
\__kernel_displayblock_doendpe:
% \end{macrocode}
%
-% The standard \cs{par} command (\cs{par_end:}) acts on
-% \texttt{@endpe} and attempts to close a still open \texttt{text-unit}
+% The standard \tn{par} command (\cs{par_end:}) acts on
+% \texttt{@endpe} and attempts to close a still open \struct{text-unit}s
% and this would be wrong if it was already closed above. So we
% have to reset the switch to false first.
% \begin{macrocode}
@@ -792,15 +795,10 @@
% \begin{macrocode}
\cs_new_eq:NN \__kernel_displayblock_doendpe: \prg_do_nothing:
% \end{macrocode}
-% The flag itself should be set globally not locally.\fmi{verify
-% that this claim is actually correct!}
-% \begin{macrocode}
-\def\@endpetrue {\global\let\if@endpe\iftrue}
-\def\@endpefalse{\global\let\if@endpe\iffalse}
-% \end{macrocode}
-% \end{macro}
%
%
+% \end{macro}
+%
%
% \subsection{Object and template interfaces}
%
@@ -847,21 +845,24 @@
%
% \begin{template}{block display}
%
+% \changes{v0.8s}{2024/10/03}{Offer item-skip key also on block templates}
% \begin{macrocode}
\DeclareTemplateInterface{block}{display}{1}
{
- heading : tokenlist = , %??
+ heading : tokenlist = , % ??
beginsep : skip = \topsep ,
begin-par-skip : skip = \partopsep ,
par-skip : skip = \parsep ,
- end-skip : skip = \KeyValue{beginsep} , % conflict with name below
+ end-skip : skip = \KeyValue{beginsep} , % conflict with name below
end-par-skip : skip = \KeyValue{begin-par-skip} ,
+ item-skip : skip = \itemsep ,
beginpenalty : integer = \UseName{@beginparpenalty} ,
endpenalty : integer = \UseName{@endparpenalty} ,
leftmargin : length = \leftmargin ,
rightmargin : length = \rightmargin ,
- parindent : length = \listparindent ,
-% font : tokenlist % maybe add? (or more general for fonts and color)
+ parindent : length = 0pt ,
+% maybe add? (or more general for fonts and color)
+% font : tokenlist
}
% \end{macrocode}
% \end{template}
@@ -872,6 +873,7 @@
% \begin{macrocode}
\DeclareTemplateInterface{para}{std}{1}
{
+ para-class : tokenlist = justify ,
indent-width : length = \parindent ,
start-skip : skip = 0pt ,
left-skip : skip = 0pt ,
@@ -880,7 +882,6 @@
fixed-word-spaces : boolean = false ,
final-hyphen-demerits : integer = 5000 ,
cr-cmd : tokenlist = \@normalcr ,
- para-class : tokenlist = justify ,
}
% \end{macrocode}
% \end{template}
@@ -1019,504 +1020,6 @@
%
%
%
-% \subsection{Implementation of the document-level block environments}
-%
-% Most such environments are pretty simple: they take an option
-% argument and call a \texttt{blockenv} instance to do the work. At
-% the end of environment we call \cs{endblockenv} to finish.
-%
-%
-% \subsubsection{Displayblock environments}
-%
-%
-% There are two basic block environment which are similar to
-% \LaTeXe{}'s \env{trivlist} except that there aren't degenerated
-% lists and thus have no hidden \cs{item} inside.
-%
-%
-% \begin{environment}{displayblock}
-%
-% \begin{macrocode}
-\NewDocumentEnvironment{displayblock}{ !O{} }
- { \UseInstance{blockenv}{displayblock} {#1} }
- { \endblockenv }
-% \end{macrocode}
-% \end{environment}
-%
-%
-%
-%
-% \begin{environment}{displayblockflattened}
-%
-% \begin{macrocode}
-\NewDocumentEnvironment{displayblockflattened}{ !O{} }
- { \UseInstance{blockenv}{displayblockflattened} {#1} }
- { \endblockenv }
-% \end{macrocode}
-% \end{environment}
-%
-%
-%
-%
-%
-%
-%
-%
-% \begin{environment}{center,flushleft,flushright}
-%
-% \begin{macrocode}
-\AddToHook{begindocument/before}{
- \RenewDocumentEnvironment{center} { !O{} }
- { \UseInstance{blockenv}{center}{#1} }
- { \endblockenv }
-% \end{macrocode}
-%
-% \begin{macrocode}
- \RenewDocumentEnvironment{flushright} { !O{} }
- { \UseInstance{blockenv}{flushright}{#1} }
- { \endblockenv }
-% \end{macrocode}
-%
-% \begin{macrocode}
- \RenewDocumentEnvironment{flushleft} { !O{} }
- { \UseInstance{blockenv}{flushleft}{#1} }
- { \endblockenv }
-}
-% \end{macrocode}
-%
-%
-% \end{environment}
-%
-%
-%
-%
-% \subsubsection{Display quote environments}
-%
-%
-% \begin{environment}{quote,quotation}
-%
-% \begin{macrocode}
-\AddToHook{begindocument/before}{
- \RenewDocumentEnvironment{quote}{ !O{} }
- { \UseInstance{blockenv}{quote} {#1} }
- { \endblockenv }
-% \end{macrocode}
-%
-% \begin{macrocode}
- \RenewDocumentEnvironment{quotation}{ !O{} }
- { \UseInstance{blockenv}{quotation} {#1} }
- { \endblockenv }
-}
-% \end{macrocode}
-% \end{environment}
-%
-%
-%
-%
-%
-%
-% \subsubsection{Verbatim environments}
-%
-%
-% \begin{environment}{verbatim,verbatim*}
-%
-% \begin{macrocode}
-\AddToHook{begindocument/before}{
- \RenewDocumentEnvironment{verbatim}{ !O{} }
- { \UseInstance{blockenv}{verbatim} {#1}
-% \end{macrocode}
-% This is the part of the code where \env{verbatim}
-% and\env{verbatim*} differ.
-% \begin{macrocode}
- \@setupverbinvisiblespace\frenchspacing\@vobeyspaces
- \@xverbatim
- }
- { \endblockenv }
-% \end{macrocode}
-%
-% \begin{macrocode}
- \RenewDocumentEnvironment{verbatim*}{ !O{} }
- { \UseInstance{blockenv}{verbatim} {#1}
- \@setupverbvisiblespace\frenchspacing\@vobeyspaces
- \@sxverbatim
- }
- { \endblockenv }
-}
-% \end{macrocode}
-% \end{environment}
-%
-%
-%
-% \paragraph{Helper commands for verbatim}
-%
-%
-% \begin{macro}{\legacyverbatimsetup}
-%
-% This code resembles the \LaTeXe{} verbatim implementation with a
-% slight twist: in \LaTeXe{} each code line was a paragraph using
-% \cs{leftskip}=\cs{@totalleftmargin}. This was possible because
-% the whole environment was implemented as a trivlist. As this is
-% no longer the case setting \cs{leftskip} would alter the layout
-% of a surrounding list. So instead we need to make sure that the
-% paragraph end is executed in a group so that any parshape setup
-% is preserved.
-% \begin{macrocode}
-%<@@=>
-\def\legacyverbatimsetup{%
- \language\l@nohyphenation
- \@tempswafalse
- \def\par{%
- \if@tempswa
- \leavevmode \null {\@@par}\penalty\interlinepenalty
- \else
- \@tempswatrue
- \ifhmode{\@@par}\penalty\interlinepenalty\fi
- \fi}%
- \let\do\@makeother \dospecials
- \obeylines \verbatim@font \@noligs
- \everypar \expandafter{\the\everypar \unpenalty}%
-% \end{macrocode}
-%
-% \begin{macrocode}
- \tl_set:Nn \l__tag_para_main_tag_tl {codeline}
- \tagtool{paratag=Code}% oder faster: \tl_set:Nn\l__tag_para_tag_tl{Code}
-}
-%<@@=block>
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{\@setupverbinvisiblespace}
-% In the \pdfTeX{} engine we need to use \cs{pdffakespace} chars
-% for the invisible spaces.
-% \begin{macrocode}
-\newcommand\@setupverbinvisiblespace{}
-\tag_if_active:T {
- \bool_if:NF\g__tag_mode_lua_bool
- {
- \renewcommand\@setupverbinvisiblespace{\def\@xobeysp{\nobreakspace\pdffakespace}}
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \subsubsection{Standard list environments}
-%
-%
-% \begin{environment}{itemize,enumerate,description}
-%
-% For the standard lists everything is managed by the blockenv instance.
-% \begin{macrocode}
-\AddToHook{begindocument/before}{
- \RenewDocumentEnvironment{itemize}{!O{}}
- { \UseInstance{blockenv}{itemize} {#1} }
- { \endblockenv }
-% \end{macrocode}
-%
-% \begin{macrocode}
- \RenewDocumentEnvironment{enumerate}{!O{}}
- { \UseInstance{blockenv}{enumerate} {#1} }
- { \endblockenv }
-% \end{macrocode}
-%
-% \begin{macrocode}
- \RenewDocumentEnvironment{description}{!O{}}
- { \UseInstance{blockenv}{description} {#1} }
- { \endblockenv }
-}
-% \end{macrocode}
-% \end{environment}
-%
-%
-% \subsubsection{verse environment}
-%
-% \begin{environment}{verse}
-% The verse environment has not special tagging currently. It is
-% defined as a simple standard list and takes the tagging from there.
-% But it must be redefined so that \cs{itemindent} is correctly set.
-% \begin{macrocode}
-\AddToHook{begindocument/before}{
- \RenewDocumentEnvironment{verse}{ !O{} }
- {
- \let\\\@centercr
- \UseInstance{blockenv}{list}
- {
- item-indent=-1.5em,
- parindent=-1.5em,
- item-skip=0pt,
- rightmargin=\leftmargin,
- leftmargin=\leftmargin+1.5em,
- #1
- }
- \item\relax
- }
- { \endblockenv }
- }
-% \end{macrocode}
-% \end{environment}
-%
-%
-% \begin{environment}{list}
-%
-% The legacy 2e list environment is more complicated as we have to get the
-% extra arguments accounted for.
-% \begin{macrocode}
-\AddToHook{begindocument/before}{
- \RenewDocumentEnvironment{list}{O{} m m }
- {
-% \end{macrocode}
-% We do this by storing them away and then call the list
-% instance. Inside this instance the \texttt{setup-code} key
-% contains \cs{legacylistsetupcode}, which makes use of the stored values.
-% \begin{macrocode}
- \tl_set:Nn \@itemlabel {#2}
- \tl_set:Nn \l_@@_legacy_env_params_tl {#3}
-% \end{macrocode}
-%
-% \begin{macrocode}
- \UseInstance{blockenv}{list} {#1}
- }
- { \endblockenv }
-}
-% \end{macrocode}
-%
-% \end{environment}
-%
-%
-%
-% \begin{variable}{\l_@@_env_params_tl}
-% Declare the variable for the parameter argument; \cs{@itemlabel}
-% is already declared in \LaTeXe{}.
-% \begin{macrocode}
-\tl_new:N \l_@@_env_params_tl
-% \end{macrocode}
-% \end{variable}
-%
-%
-% \begin{macro}{\legacylistsetupcode}
-%
-% And here is the extra code for use in the list instance setup
-% inside the key \texttt{setup-code}.
-% \begin{macrocode}
-\cs_new:Npn \legacylistsetupcode {
-% \end{macrocode}
-% Reset values to defaults:
-% \begin{macrocode}
- \dim_zero:N \listparindent
- \dim_zero:N \rightmargin
- \dim_zero:N \itemindent
-% \end{macrocode}
-%
-% By default a \env{list} environment is not numbered:
-% \begin{macrocode}
- \tl_set:Nn \@listctr {}
- \legacy_if_set_false:n { @nmbrlist } % needed if lists are nested
-% \end{macrocode}
-% By default there is a simple definition for \cs{makelabel}. It can be
-% overwritten in the second mandatory argument to the list
-% environment (stored in \cs{l_@@_legacy_env_params_tl}) and
-% is used if the instance sets the compatibility key to true.
-% \begin{macrocode}
- \let\makelabel\@mklab % TODO: customize
-% \end{macrocode}
-% Now we use the argument with parameter settings to update some or
-% all of the above defaults:
-% \begin{macrocode}
- \l_@@_legacy_env_params_tl
-% \end{macrocode}
-% As we don't know much about this list we can only make a guess about
-% the nature of the list and the setting of the tag name (default
-% \texttt{list} rolemapped to \texttt{L}) and any tag attributes
-% may have to be overwritten in the optional key/value argument. But we do have some hints to play with.
-% \begin{macrocode}
- \legacy_if:nTF { @nmbrlist }
- { \tl_set:Nn \l__tag_L_attr_class_tl {enumerate} } % numbered list
- { \tl_if_empty:NTF \@itemlabel
- { \tl_set:Nn \l__tag_L_attr_class_tl {list} } % no label
- { \tl_set:Nn \l__tag_L_attr_class_tl {itemize} } % unnumbered, unordered
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-%
-%
-%
-% \begin{environment}{trivlist}
-%
-% \begin{macrocode}
-\AddToHook{begindocument/before}{
- \RenewDocumentEnvironment{trivlist}{ !O{} }
- { \list[#1]{}
- {
- \dim_zero:N \leftmargin
- \dim_zero:N \labelwidth
- \cs_set_eq:NN \makelabel \use:n
- }
- }
- { \endblockenv }
-}
-% \end{macrocode}
-% \end{environment}
-%
-%
-% \subsubsection{Theorem-like environments}
-%
-% Theorem-like environments are defined in \LaTeX{} with the help of
-% \cs{newtheorem} declarations. Internally they used a list with a
-% single item. Using lists was convenient back then, but in a tagged
-% document you end up with a strange structure. We therefore alter the
-% mechanism.
-%
-%
-% \begin{macro}{\newtheorem}
-% This is a slightly streamlined version of \cs{newtheorem}, but it
-% still uses a lot of the 2e code for now. Eventually this will change.
-% \begin{macrocode}
-\RenewDocumentCommand \newtheorem { m O{#1} m o }
-{
- \expandafter\@ifdefinable\csname #1\endcsname
- {
- \str_if_eq:nnTF{#1}{#2}
- {
- \@definecounter {#2}
- \IfNoValueTF {#4}
- { % @ynthm
- \tl_gset:ce { the #2 }
- {
- \@thmcounter{#2}
- }
- }
- { % @xnthm
- \@newctr{#1}[#4]
- \tl_gset:ce { the #2 }
- {
- \expandafter\noexpand\csname the#4\endcsname
- \@thmcountersep
- \@thmcounter{#2}
- }
- }
- }
- { % @othm
- \@ifundefined{c@#2}
- { \@nocounterr{#2} }
- {
- \tl_gset:cn { the #1 }
- { \UseName { the #2 } }
- }
- }
- \global\@namedef{#1} { \@thm{#2}{#3} }
- \global\@namedef{end#1}{ \@endtheorem }
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@thm}
-% \cs{@thm} executes \cs{refstepcounter} too early for hyperref
-% and structure destinations: the generated target is outside the structure
-% and can be separated from the theorem by a page break. We therefore move
-% the anchor setting into \cs{@begintheorem}. \cs{@begintheorem} doesn't
-% currently get the name of the counter as argument, so we store it in variable
-% for now, to be able to pass it along.
-% \begin{macrocode}
-\tl_new:N \l_@@_thm_current_counter_tl
-\def\@thm#1#2{%
- \@kernel@refstepcounter{#1}
- \tl_set:Nn \l_@@_thm_current_counter_tl{#1}
- \@ifnextchar[{\@ythm{#1}{#2}}{\@xthm{#1}{#2}}}
-% \end{macrocode}
-% To avoid that hyperref overwrites the definition again we must its patch:
-% \begin{macrocode}
-\def\hyper@nopatch@thm{}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@begintheorem,\@opargbegintheorem}
-%
-% The \cs{@thm} command expands to either \cs{@beginthorem} or
-% \cs{@opargbegintheorem}. For the moment we stick with this as it
-% will help with the transition. But instead of using a
-% \env{trivlist} we use a blockenv and some tagging for the title
-% (as a Caption).
-% We do not want potential tagging from \cs{textbf} here,
-% so we use \cs{bfseries} to set the font. The commands set also the link targets
-% which should be inside the main structure.
-% \begin{macrocode}
-\def\@begintheorem#1#2{
- \UseInstance{blockenv}{theorem}{}
- \tagpdfparaOff
- \mode_leave_vertical:
- \MakeLinkTarget{\l_@@_thm_current_counter_tl}
- \tag_struct_begin:n{tag=Caption}
- \group_begin:
- \bfseries
- \tag_mc_begin:n {}
- #1\
- \tag_mc_end:
- \tag_struct_begin:n{tag=Lbl}
- \tag_mc_begin:n {}
- #2
- \tag_mc_end:
- \tag_struct_end:
- \group_end:
- \tag_struct_end:
- \tagpdfparaOn
-% \end{macrocode}
-%
-% \begin{macrocode}
- \@@_start_para_structure_unconditionally:n { \PARALABEL }
-% \end{macrocode}
-%
-% \begin{macrocode}
- \itshape
- \hskip\labelsep
- \ignorespaces
-}
-\def\@opargbegintheorem#1#2#3{
- \UseInstance{blockenv}{theorem}{}
- \tagpdfparaOff
- \mode_leave_vertical:
- \MakeLinkTarget{\l_@@_thm_current_counter_tl}
- \tag_struct_begin:n{tag=Caption}
- \group_begin:
- \bfseries
- \tag_mc_begin:n {}
- #1\
- \tag_mc_end:
- \tag_struct_begin:n{tag=Lbl}
- \tag_mc_begin:n {}
- #2
- \tag_mc_end:
- \tag_struct_end:
- \tag_mc_begin:n {}
- \ (#3)
- \tag_mc_end:
- \group_end:
- \tag_struct_end:
- \tagpdfparaOn
-% \end{macrocode}
-%
-% \begin{macrocode}
- \@@_start_para_structure_unconditionally:n { \PARALABEL }
-% \end{macrocode}
-%
-% \begin{macrocode}
- \itshape
- \hskip\labelsep
- \ignorespaces
-}
-% \end{macrocode}
-%
-% \begin{macrocode}
-\def\@endtheorem{\endblockenv}
-% \end{macrocode}
-% \end{macro}
-%
-%
-%
-%
%
%
% \subsection{Implementation of templates}
@@ -1529,11 +1032,11 @@
% \begin{macro}{\g_block_nesting_depth_int}
% \LaTeXe{} already has a counter to record the nesting depth of
% blocks, but we want our own name because it isn't really tied to
-% \enquote{lists} any more. However, \cs{@listdepth} is really part
+% \enquote{lists} any more. However, \tn{@listdepth} is really part
% of the legacy interface (for example \env{minipage} alters it to
% point to a different counter) so that we are stuck with using at
% least indirectly for now and the following line makes this look
-% like an L3 integer variable but internally expands to \cs{@listdepth}:
+% like an L3 integer variable but internally expands to \tn{@listdepth}:
% \begin{macrocode}
\cs_new:Npn \g_block_nesting_depth_int { \@listdepth } % a fake int
% for now
@@ -1554,11 +1057,11 @@
setup-code = \l_@@_setup_code_tl ,
block-instance = \l_@@_block_instance_tl ,
para-instance = \l_@@_para_instance_tl ,
+ para-flattened = \l__tag_para_flattened_bool ,
inner-level-counter = \l_@@_inner_level_counter_tl ,
max-inner-levels = \l_@@_max_inner_levels_tl ,
inner-instance-type = \l_@@_inner_instance_type_tl ,
inner-instance = \l_@@_inner_instance_tl ,
- para-flattened = \l__tag_para_flattened_bool ,
final-code = \l_@@_final_code_tl ,
}
{
@@ -1569,23 +1072,23 @@
% \end{macrocode}
% We need to know later if we have nested blockenvs inside
% a flattened environment. Whenever we start a new blockenv we
-% increment \cs{\l_@@_flattened_level_int} if it is already
+% increment \cs{l__tag_block_flattened_level_int} if it is already
% different from zero. If it is zero we increment it if flattening
% is requested.
% Thus a value of \texttt{0} means no flattening requested so far
% and \texttt{1} means this is the first blockenv requesting
% flattening. In either case we have to make sure that the blockenv
-% is surrounded by a \texttt{text-unit} tag, while for any value above
-% \texttt{1} we have to omit the \texttt{text-unit}.
+% is surrounded by a \struct{text-unit} tag, while for any value above
+% \texttt{1} we have to omit the \struct{text-unit}.
% \begin{macrocode}
- \int_compare:nNnTF \l_@@_flattened_level_int > 0
+ \int_compare:nNnTF \l__tag_block_flattened_level_int > 0
{
- \int_incr:N \l_@@_flattened_level_int
+ \int_incr:N \l__tag_block_flattened_level_int
}
{
\bool_if:NT \l__tag_para_flattened_bool
{
- \int_incr:N \l_@@_flattened_level_int
+ \int_incr:N \l__tag_block_flattened_level_int
}
}
%
@@ -1613,7 +1116,8 @@
% does nothing, i.e., the current values (from the last level
% become the defaults for the next.
% \begin{macrocode}
- \use:c { @list \int_to_roman:n { \g_block_nesting_depth_int } }
+ \use:c { @list \int_to_roman:n
+ { \g_block_nesting_depth_int } }
}
}
% \end{macrocode}
@@ -1621,7 +1125,25 @@
% tagging, which alters various kernel hooks to add appropriate
% tagging structures.
% \begin{macrocode}
- \tag_if_active:T { \use:c { @@_recipe_ \l_@@_tagging_recipe_tl : } }
+ \tag_if_active:T
+ { \use:c { @@_recipe_ \l_@@_tagging_recipe_tl : } }
+% \end{macrocode}
+% The default for \env{list} environments is that they have an
+% empty label and are not numbered (something that is then
+% overwritting by the setup of a specific list). We ensure
+% this here even for non-lists, because we need a defined state
+% that then can be overwritting by the legacy setup code for
+% the \env{list} environment in \cs{l_@@_setup_code_tl}.
+% This is needed in case lists are nested as they otherwise would
+% inherit outer values (and suddenly an \env{itemize} would start
+% incrementing an outer \env{enumerate} counter, etc.
+% \changes{v0.8v}{2024/10/11}{Set the defaults for \tn{@itemlabel},
+% \tn{@listctr} and \texttt{@nmbrlist} early in the block code
+% before the setup code gets executed (tagging/730)}
+% \begin{macrocode}
+ \tl_clear:N \@itemlabel
+ \tl_clear:N \@listctr
+ \legacy_if_set_false:n { @nmbrlist }
% \end{macrocode}
% Then run the setup code if any is given in the instance.
% \begin{macrocode}
@@ -1645,7 +1167,8 @@
% \begin{macrocode}
\tl_if_empty:NF \l_@@_para_instance_tl
{
- \@@_debug_typeout:n{use~ para~ instance:~ \l_@@_para_instance_tl }
+ \@@_debug_typeout:n{ use~ para~ instance:~
+ \l_@@_para_instance_tl }
% \end{macrocode}
% For now we don't offer to alter instance parameters here so we
% pass an empty argument.
@@ -1665,14 +1188,14 @@
\UseInstance{ \l_@@_inner_instance_type_tl }
{ \l_@@_inner_instance_tl
\tl_if_empty:NF \l_@@_inner_level_counter_tl
- { - \int_use:N \l_@@_inner_level_counter_tl } % not clean
- % use "o"?
+ % not clean use "o"?
+ { - \int_use:N \l_@@_inner_level_counter_tl }
}
{#1}
}
% \end{macrocode}
% We finish off with \cs{l_@@_final_code_tl} which defaults to
-% \cs{ignorespaces} so that spaces between \verb=\begin{...}= and
+% \tn{ignorespaces} so that spaces between \verb=\begin{...}= and
% the start of the text are ignored.
% \begin{macrocode}
\l_@@_final_code_tl
@@ -1681,11 +1204,15 @@
% \end{template}
%
%
-% \begin{macro}{\l_@@_flattened_level_int}
+% \begin{macro}{\l__tag_block_flattened_level_int}
% Count the levels of nested blockenvs starting with the first that
-% is \enquote{flattened}.
+% is \enquote{flattened}. The counter is defined in lttagging.dtx,
+% but until the next release 11/24 we set it up here too
% \begin{macrocode}
-\int_new:N \l_@@_flattened_level_int
+\int_if_exist:NF \l__tag_block_flattened_level_int
+ {
+ \int_new:N \l__tag_block_flattened_level_int
+ }
% \end{macrocode}
% \end{macro}
%
@@ -1716,7 +1243,7 @@
\bool_if:NT \l_@@_level_incr_bool
{ \int_gdecr:N \g_block_nesting_depth_int }
% \end{macrocode}
-% If this block was a list and there are still \cs{item} labels to
+% If this block was a list and there are still \tn{item} labels to
% be placed we move to horizontal mode to get them typeset.
% \begin{macrocode}
\legacy_if:nT { @inlabel }
@@ -1725,15 +1252,19 @@
\legacy_if_gset_false:n { @inlabel }
}
% \end{macrocode}
-% In a pure ``displayblock'' scenario \texttt{@newlist} will be
-% always false and the code bypassed, but we may have an outer list
-% followed immediately by a displayblock (with the \cs{item} missing)
+% If we are ending a list environment and we have not seen any
+% \tn{item}, i.e., \texttt{@newlist} is still true, we raise an
+% error. In basic a ``displayblock'' scenario \texttt{@newlist} will
+% always be false, but if such an environment appears inside an outer
+% list then \tn{noitemerr} could still be triggered and that is undesirable
+% (as the missing item will be detected at the wrong point and again later,
+% during the outer list processing). We
+% therefore run it only if the current environment is a list.
+% \changes{v0.8q}{2024/09/03}{Raise a \tn{@noitemerr} if appropriate}
+% \begin{macrocode}
+ \@@_if_list:T { \legacy_if:nT { @newlist } { \@noitemerr } }
+% \end{macrocode}
% \begin{macrocode}
- \legacy_if:nT { @newlist }
- {
- \@noitemerr
- \legacy_if_gset_false:n { @newlist }
- }
\mode_if_horizontal:TF
{ \@@_skip_remove_last: \@@_skip_remove_last: \par }
{ \@inmatherr{\end{\@currenvir}} }
@@ -1743,6 +1274,13 @@
% \begin{macrocode}
\__kernel_displayblock_end:
% \end{macrocode}
+% Resetting the \texttt{@newlist} switch is also only done if the
+% current enviornment is a list and not unconditionally.
+% \changes{v0.8q}{2024/09/03}{Setting \texttt{@newlist} to false
+% moved after tagging code if in a list}
+% \begin{macrocode}
+ \@@_if_list:T { \legacy_if_gset_false:n { @newlist } }
+% \end{macrocode}
% What to do in terms of vertical spacing in different situations
% is still somewhat open to debate, right now this is more or less
% implementing what \LaTeXe{} list environment have been
@@ -1777,9 +1315,9 @@
% should be added only if the paragraph ends here and not if it
% continues, so this need some further cleanup.\fmi{decide}
%
-% Finally, we have a socket that handles the \cs{par} handling
+% Finally, we have a socket that handles the \tn{par} handling
% after the block. Normally, we use it with the \plug{on} plug (check for a
-% following \cs{par}) but in the case of standalone environments we
+% following \tn{par}) but in the case of standalone environments we
% assign it the \plug{off} plug.
% \begin{macrocode}
\socket_use:n {tagsupport/block-endpe}
@@ -1789,6 +1327,19 @@
% \end{macro}
%
%
+% \begin{macro}{\@@_if_list:T}
+% The following code may need some redesigning, as there is no good test for \enquote{is
+% this environment a \enquote{list} that has \tn{item}s}. For now
+% this here does the trick well enough.\fmi{revisit}
+% \changes{v0.8q}{2024/09/03}{Provide a test for: Am I in a list?}
+% \begin{macrocode}
+\cs_new:Npn \@@_if_list:T
+ { \tl_if_eq:NnT \l_@@_block_instance_tl {list} }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
% \begin{macro}{\__kernel_displayblock_end:}
% The kernel hook for tagging at the end of the block.
% \begin{macrocode}
@@ -1801,7 +1352,7 @@
%
%
% \begin{socketdecl}{tagsupport/block-endpe}
-% This socket is responsible for the end environment \cs{par}
+% This socket is responsible for the end environment \tn{par}
% handling. We define two plugs for it (\plug{on} and \plug{off}).
% \begin{macrocode}
\socket_new:nn {tagsupport/block-endpe}{0}
@@ -1814,9 +1365,13 @@
% and should not inherit the setting from the outer environment.
% \begin{macrocode}
\socket_new_plug:nnn{tagsupport/block-endpe}{on}
- { \legacy_if_gset_true:n { @endpe } }
+% \end{macrocode}
+% We can't use \cs{legacy_if_gset_true:n} because this is now doing
+% more than setting the legacy switch
+% \begin{macrocode}
+ { \@endpetrue }
\socket_new_plug:nnn{tagsupport/block-endpe}{off}
- { \legacy_if_gset_false:n { @endpe } }
+ { \@endpefalse }
% \end{macrocode}
%
% \begin{macrocode}
@@ -1864,6 +1419,13 @@
%
% \begin{template}{block display}
%
+% In contrast to the \LaTeXe{} implementation we do not directly
+% use \tn{listparindent} here but a private register of the
+% template. The reason is that block template instances are also
+% used outside of lists.
+% \changes{v0.8s}{2024/10/03}{Offer item-skip key also on block templates}
+% \changes{v0.8w}{2024/11/23}{Use private storage bin for parindent
+% and not \tn{listparindent} to decouple block and list templates (tagging/767)}
% \begin{macrocode}
\DeclareTemplateCode{block}{display}{1}
{
@@ -1873,11 +1435,12 @@
par-skip = \parsep ,
end-skip = \l_@@_botsep_skip ,
end-par-skip = \l_@@_parbotsep_skip ,
+ item-skip = \itemsep ,
beginpenalty = \@beginparpenalty ,
endpenalty = \@endparpenalty ,
rightmargin = \rightmargin ,
leftmargin = \leftmargin ,
- parindent = \listparindent ,
+ parindent = \l_@@_parindent_dim ,
}
{
\tl_if_empty:nF {#1} { \SetTemplateKeys{block}{display}{#1} }
@@ -1885,7 +1448,8 @@
% \fmi{generalize heading usage (or drop?)}
% \begin{macrocode}
\tl_if_blank:oF \l_@@_heading_tl
- { \mode_leave_vertical: \textbf{\l_@@_heading_tl} } % TODO customize
+ { \mode_leave_vertical:
+ \textbf{\l_@@_heading_tl} } % TODO customize
% \end{macrocode}
% The code largely follows the logic of \LaTeXe{}'s \env{trivlist}
% implementation as far as it applicable for the \enquote{display
@@ -1911,11 +1475,11 @@
% \end{macrocode}
% If we are in horizontal mode then the displayblock has to return
% to vertical mode now (after removing any immediately preceding
-% skip or kern. But before we actually issue the\cs{par} we execute
+% skip or kern. But before we actually issue the\tn{par} we execute
% a kernel hook in which we can add tagging code. This hook is
% \enquote{weird} because by default it does nothing, but if
% tagging is wanted it takes an argument and grabs the following
-% \cs{par} in order to put tagging code before and after the \cs{par}.
+% \tn{par} in order to put tagging code before and after the \tn{par}.
% \begin{macrocode}
\@@_skip_remove_last: \@@_skip_remove_last:
\__kernel_displayblock_beginpar_hmode:w \par
@@ -1935,8 +1499,9 @@
}
\skip_add:Nn \l_@@_effective_top_skip { \parskip }
% \end{macrocode}
-% Next lines set some paragraph defaults, this may get overwritten
-% if there is a \key{para-instance} specified on the \xt{blockenv}.
+% Next lines set some paragraph defaults, any of them may get overwritten
+% if there is a \key{para-instance} specified on the \xt{blockenv}
+% instance.
% \begin{macrocode}
\skip_zero:N \leftskip
\skip_set_eq:NN \rightskip \@rightskip
@@ -1945,8 +1510,8 @@
% The next lines establish a parshape which is retained across
% paragraphs be executing \cs{para_end:} within a group and thus
% reestablishing the parshape for the next paragraph again. In case
-% a list got started \cs{par} is ignored until we have seen an
-% \cs{item} (or we have executed \cs{par} one thousand times.
+% a list got started \tn{par} is ignored until we have seen an
+% \tn{item} (or we have executed \tn{par} one thousand times.
% \begin{macrocode}
\int_zero:N \par@deathcycles
\@setpar
@@ -1965,7 +1530,11 @@
}
\skip_set_eq:NN \@outerparskip \parskip
\skip_set_eq:NN \parskip \parsep
- \dim_set_eq:NN \parindent \listparindent
+% \end{macrocode}
+% \changes{v0.8w}{2024/11/23}{Use private storage bin for parindent
+% and not \tn{listparindent} to decouple block and list templates (tagging/767)}
+% \begin{macrocode}
+ \dim_set_eq:NN \parindent \l_@@_parindent_dim
\dim_add:Nn \linewidth { - \rightmargin - \leftmargin }
\dim_add:Nn \@totalleftmargin { \leftmargin }
\tex_parshape:D 1 ~ \@totalleftmargin \linewidth
@@ -1978,10 +1547,10 @@
% \end{macrocode}
% Finally, we have to output the vertical separation and penalty at
% the start of the block and make corrections for a change in
-% \cs{parskip} and some other housekeeping, unless this block is inside a list and the list
-% \cs{item} has not yet placed. In that case the vertical
+% \tn{parskip} and some other housekeeping, unless this block is inside a list and the list
+% \tn{item} has not yet placed. In that case the vertical
% space and penalty us suppressed. This
-% is controled through the legacy switches \texttt{@noparitem},
+% is controlled through the legacy switches \texttt{@noparitem},
% \texttt{minipage}, and \texttt{@nobreak}.
% \begin{macrocode}
\legacy_if:nTF { @noparitem }
@@ -2000,7 +1569,8 @@
{
\@@_skip_set_to_last:N \l_@@_tmpa_skip
\skip_vertical:n { - \l_@@_tmpa_skip }
- \skip_vertical:n { \l_@@_tmpa_skip + \@outerparskip - \parskip }
+ \skip_vertical:n { \l_@@_tmpa_skip +
+ \@outerparskip - \parskip }
}
}
{
@@ -2028,26 +1598,28 @@
% \end{template}
%
%
-%
% \begin{macro}{\__kernel_displayblock_begin:,
% \__kernel_displayblock_beginpar_hmode:w,
% \__kernel_displayblock_beginpar_vmode:}
% The internal kernel hooks for tagging.
% \begin{macrocode}
\cs_new:Npn \__kernel_displayblock_begin: {
- \@@_debug_typeout:n{\detokenize{__kernel_displayblock_begin:}}
+ \@@_debug_typeout:n
+ {\detokenize{__kernel_displayblock_begin:}}
}
% \end{macrocode}
%
% \begin{macrocode}
\cs_new:Npn \__kernel_displayblock_beginpar_hmode:w {
- \@@_debug_typeout:n{\detokenize{__kernel_displayblock_beginpar_hmode:w}}
+ \@@_debug_typeout:n
+ {\detokenize{__kernel_displayblock_beginpar_hmode:w}}
}
% \end{macrocode}
%
% \begin{macrocode}
\cs_new:Npn \__kernel_displayblock_beginpar_vmode: {
- \@@_debug_typeout:n{\detokenize{__kernel_displayblock_beginpar_vmode:}}
+ \@@_debug_typeout:n
+ {\detokenize{__kernel_displayblock_beginpar_vmode:}}
}
% \end{macrocode}
% \end{macro}
@@ -2060,7 +1632,7 @@
%
%
% \begin{macro}{\@itemlabel,\@listctr}
-% Both \cs{@itemlabel} and \cs{@listctr} from the \LaTeXe{} list
+% Both \tn{@itemlabel} and \tn{@listctr} from the \LaTeXe{} list
% implementation are used (or set) by various packages. We
% therefore use them too, so that these packages have a fighting
% chance to work with the new tagging-aware implementation for
@@ -2073,6 +1645,40 @@
%
%
%
+% \begin{macro}{\@@_evaluate_saved_user_keys:nn}
+% Keys set on individual list environments may be intended to alter
+% the behavior of the template instance that defines the \tn{item}
+% command. If meant to alter only a single \tn{item} command one
+% would specify them in the optional argument of the \tn{item}, but
+% if they should alter all items the right place would be the list
+% environment. For this reason we need to store the values and then
+% set them inside the \tn{item} template code using
+% \tn{SetTemplateKeys} in the appropriate context (template type
+% and template name). This is done in
+% \cs{@@_evaluate_saved_user_keys:nn}. The context is provided in
+% the two arguments (because different list environments may use
+% different \tn{item} instances based on different templates. By
+% default the command does
+% nothing because most environments do not have user key settings.
+% \changes{v0.8s}{2024/10/03}{Pass user keys on list to \tn{item} for
+% evaluation}
+% \begin{macrocode}
+\cs_new_eq:NN \@@_evaluate_saved_user_keys:nn \use_none:nn
+% \end{macrocode}
+% Maybe something like this should become a public function, but
+% for now this is a one-off for the \tn{item} command and therefore
+% coded inline and internal to the block code.
+% \begin{macrocode}
+%\cs_new:Npn \@@_save_user_keys:n #1 {
+% \tl_if_empty:nTF {#1}
+% { \cs_set_eq:NN \@@_evaluate_saved_user_keys:nn \use_none:nn }
+% {
+% \cs_set:Npe \@@_evaluate_saved_user_keys:nn ##1##2
+% { \SetTemplateKeys{##1}{##2}{ \exp_not:n{#1} } }
+% }
+%}
+% \end{macrocode}
+% \end{macro}
%
%
% \begin{template}{list std}
@@ -2098,36 +1704,48 @@
{
\@@_debug_typeout:n{template:list:std}
%
- \tl_if_empty:nF {#1} { \SetTemplateKeys{list}{std}{#1} }
+% \end{macrocode}
+% We start by looking at the user supplied keys in \texttt{\#1}. If
+% there aren't any we reset \cs{@@_evaluate_saved_user_keys:nn} to
+% do nothing. Otherwise we evaluate and set the keys in the contect
+% of the current list template. In addition we prepare
+% \cs{@@_evaluate_saved_user_keys:nn} for execution in the
+% template for \tn{item}.
+% \changes{v0.8s}{2024/10/03}{Prepare \cs{@@_evaluate_saved_user_keys:nn}
+% for use in \tn{item}}
+% \begin{macrocode}
+ \tl_if_empty:nTF {#1}
+ { \cs_set_eq:NN \@@_evaluate_saved_user_keys:nn \use_none:nn }
+ {
+ \SetTemplateKeys{list}{std}{#1}
+ \cs_set:Npe \@@_evaluate_saved_user_keys:nn ##1##2
+ { \SetTemplateKeys{##1}{##2}{ \exp_not:n{#1} } }
+ }
% \end{macrocode}
% Has this list a counter name defined in the instance?
% \begin{macrocode}
\tl_if_empty:NTF \l_@@_counter_tl
{
% \end{macrocode}
-% If not we check if \cs{@listctr} has a non-empty value to be used
-% for the list counter.
-%
-% We better test for blank not empty in case somebody had defined
-% \cs{@listctr} using \cs{renewcommand} or \cs{cs_set:Npn}.
+% If not we check if \tn{@nmbrlist} is true which may be the case
+% in legacy environments that used \tn{usecounter} in the argument
+% to the \env{list} environment.
+% \changes{v0.8v}{2024/10/11}{Correct logic for setting up the list
+% counter (tagging/730)}
% \begin{macrocode}
- \tl_if_blank:oF \@listctr
- {
+ \legacy_if:nT { @nmbrlist }
+ {
% \end{macrocode}
-% In that case \texttt{@nmbrlist} should have been set too, for
-% example, through \cs{usecounter}, so we do not set it
-% explicitly. However, we check if we should resume a previous list.
+% In that case we only check if we should resume a previous list
+% (\tn{@listctr} should be set in that case through the legacy
+% method as well so we should be able to use it).
% \begin{macrocode}
\bool_if:NF \l_@@_resume_bool
{
\int_gset:cn{ c@ \@listctr }
{ \l_@@_counter_start_int - 1 }
}
- }
-% \end{macrocode}
-% If \cs{@listctr} is not set then we have definitely an unnumbered list.
-% \begin{macrocode}
- { \@nmbrlistfalse }
+ }
}
% \end{macrocode}
% If a counter is set in the list instance we use that
@@ -2148,8 +1766,8 @@
% \end{macrocode}
% Does the current instance has an item label representation? This
% would be possible whether or not we have a numbered list. If yes,
-% then we use this for \cs{@itemlabel}, otherwise we expect that
-% \cs{@itemlabel} is provided from the outside, e.g., as part of
+% then we use this for \tn{@itemlabel}, otherwise we expect that
+% \tn{@itemlabel} is provided from the outside, e.g., as part of
% the \env{list} environment argument.
% \begin{macrocode}
\tl_if_empty:NF \l_@@_item_label_tl
@@ -2157,12 +1775,28 @@
\tl_set_eq:NN \@itemlabel \l_@@_item_label_tl
}
% \end{macrocode}
-% finally, we signal that we are at the start of a new list (which
-% effects how the first \cs{item} is handled and how \cs{par}
+% Finally, we signal that we are at the start of a new list (which
+% affects how the first \tn{item} is handled and how \tn{par}
% commands are interpreted.
% \begin{macrocode}
\legacy_if_gset_true:n { @newlist }
% \end{macrocode}
+% If we encounter horizontal material before the first \tn{item} we
+% do want a \tn{@noitemerr} straight away, because afterwards we
+% end up with tagging structure faults whose cause is the
+% missing \tn{item}. So we setup up \cs{@@_item_everypar:} to test
+% for this; when the first \tn{item} is encountered this will get
+% reset. This is only relevant for vertical lists, when dealing with
+% inline lists one would need to test for something else to
+% identify that there is horizontal material between the start of the list and
+% the first \tn{item} (maybe some \tn{spacefactor} trick could be
+% used then, or the material is boxed first and the width is
+% inspected as suggested by Joseph).\fmi{Think about a better
+% implementation at some point.}
+% \changes{v0.8q}{2024/09/02}{}
+% \begin{macrocode}
+ \cs_set_eq:NN \@@_item_everypar: \@@_item_everypar_first:
+% \end{macrocode}
%
% \begin{macrocode}
\@@_debug_typeout:n{template:list:std~end}
@@ -2187,17 +1821,17 @@
% \end{template}
%
%
-% \subsubsection{Implementation of \cs{item} template(s)}
+% \subsubsection{Implementation of \tn{item} template(s)}
%
%
%
% \begin{template}{item std}
-% The item template has one hidden key \texttt{label} which is not available on the
+% The item template has one hidden key \key{label} which is not available on the
% template for setting because it is only used to receive any
-% optional data passed to the \cs{item} command. We therefore
+% optional data passed to the \tn{item} command. We therefore
% declare it with \cs{keys_define:nn} and ensure that the optional
-% argument data to \cs{item} (if it is not a key/value list
-% already) is passed to this \texttt{label} key.
+% argument data to \tn{item} (if it is not a key/value list
+% already) is passed to this \key{label} key.
% \begin{macrocode}
\keys_define:nn { template/item/std }
{ label .tl_set:N = \l_@@_label_given_tl }
@@ -2237,7 +1871,7 @@
% from the counter. If it is boxed and reasonably short, add padding to
% make it at least of size \tn{labelwidth}, then add another layer of
% box. This way, when we unpack it in \cs{g_@@_labels_box} it correctly
-% remains boxed in those cases. Afterwards, in the \texttt{nextline}
+% remains boxed in those cases. Afterwards, in the \keyvalue{nextline}
% case add \tn{newline} if the label did not fit in the allotted space.
% \begin{macrocode}
{
@@ -2246,13 +1880,24 @@
%
% First deal with the key--value input, which in particular may
% provide a value for the label (the usual optional argument of
-% \cs{item}). For this we set \cs{l_@@_label_given_tl} to
+% \tn{item}). For this we set \cs{l_@@_label_given_tl} to
% \cs{c_novalue_tl} so that we can identify if an optional argument
% was given.
% \begin{macrocode}
\tl_set_eq:NN \l_@@_label_given_tl \c_novalue_tl
+% \end{macrocode}
+% First we evaluate and set any keys specified on the list
+% environment by calling
+% \cs{@@_evaluate_saved_user_keys:nn}. Then we do the same
+% with all keys specified on this \tn{item} command (which may
+% overwrite one or the other setting just made).
+% \changes{v0.8s}{2024/10/03}{Use \cs{@@_evaluate_saved_user_keys:nn}
+% to make use of user keys on the list level}
+% \begin{macrocode}
+ \@@_evaluate_saved_user_keys:nn {item}{std}
\tl_if_empty:nF{#1}{ \SetTemplateKeys{item}{std}{#1} }
% \end{macrocode}
+%
% If no optional argument was given then \cs{l_@@_label_given_tl}
% is still equal to \cs{c_novalue_tl} and so we can distinuish
% that from \verb=\item[]=.
@@ -2265,10 +1910,13 @@
% incomplete and partly wrong.\fmi{fix}
% \begin{macrocode}
\tl_if_blank:oF \@listctr { \@kernel@refstepcounter \@listctr }
- \bool_if:NTF \l_@@_item_compatibility_bool % not sure that conditional
- % makes sense
- { \@@_make_label_box:n { \MakeLinkTarget[\@listctr]{}\@itemlabel } } % TODO ?
- { \@@_make_label_box:n { \MakeLinkTarget[\@listctr]{}\@@_counter_label:n { \@listctr } } }
+ \bool_if:NTF \l_@@_item_compatibility_bool % not sure that
+ % conditional
+ % makes sense
+ { \@@_make_label_box:n { \MakeLinkTarget[\@listctr]{}%
+ \@itemlabel } } % TODO ?
+ { \@@_make_label_box:n { \MakeLinkTarget[\@listctr]{}%
+ \@@_counter_label:n { \@listctr } } }
}
{
\@@_debug_typeout:n{item~ with~ optional}
@@ -2276,7 +1924,9 @@
\bool_if:nT
{
\l_@@_label_boxed_bool
- && \dim_compare_p:n { \box_wd:N \l_@@_one_label_box <= \linewidth } % TODO: is \linewidth correct?
+% TODO: is \linewidth correct?
+ && \dim_compare_p:n
+ { \box_wd:N \l_@@_one_label_box <= \linewidth }
}
{
\dim_compare:nNnT
@@ -2293,7 +1943,8 @@
% enumitem offers that in some cases too) but it should probably
% not the default.
% \begin{macrocode}
-% \hbox_unpack_drop:N \l_@@_one_label_box %TODO: customize?
+% TODO: customize?
+% \hbox_unpack_drop:N \l_@@_one_label_box
\box_use_drop:N \l_@@_one_label_box
% \end{macrocode}
%
@@ -2320,12 +1971,33 @@
{ \bool_if:NT \l_@@_long_label_bool { \nobreak \hfil \break } }
% version of \newline inside an hbox that will be unpacked
}
- % \skip_set_eq:NN \parsep \l_@@_item_parsep_skip TODO??? FMi
- % what's that?
- \dim_set_eq:NN \parindent \listparindent
+ % TODO??? FMi what's that?
+ % \skip_set_eq:NN \parsep \l_@@_item_parsep_skip
+% \end{macrocode}
+% The next setting is for compatibility: The list template sets
+% \tn{listparindent} to zero and otherwise doesn't use it any
+% more. However, in the second argument of a legacy \env{list}
+% envrironment the user may have set it explicitly to some other
+% value and whatever value it had was then used for \tn{parindent}
+% within the list. Now we use its value only if it differs from
+% zero but otherwise use whatever the template instances
+% specify. This gives 99.9\% compatibility for legacy
+% documents. 100\% for definitions using the \env{list} environment
+% and a setting inside, but if the user used \tn{listparindent}
+% within the document, e.g., inside a \env{verse} environment there
+% there is one case in which the setting is ignored, i.e., when it
+% was set back to zero. That's a rather unlikely scenario, but it
+% is not impossible. However, I couldn't think of an approach that
+% circumvents such boundary cases.
+%
+% \changes{v0.8w}{2024/11/24}{Only use \tn{listparindent} if it was changed
+% from its default (tagging/767)}
+% \begin{macrocode}
+ \dim_compare:nNnF \listparindent = {0pt}
+ { \dim_set_eq:NN \parindent \listparindent }
% \end{macrocode}
% Placing the list label(s) is done when the paragraph for the
-% \cs{item} is started, which executes \cs{@@_item_everypar:}
+% \tn{item} is started, which executes \cs{@@_item_everypar:}
% inside \hook{para/begin}. By default this command does nothing, now we
% change it to attach the pending label or labels.
% \begin{macrocode}
@@ -2336,6 +2008,12 @@
%
%
%
+% \begin{macro}{\l_@@_item_align_tl}
+%
+% \begin{macrocode}
+\tl_new:N \l_@@_item_align_tl
+% \end{macrocode}
+% \end{macro}
%
% \begin{variable}{\l_@@_one_label_box, \g_@@_labels_box}
% Each label is typeset in \cs{l_@@_one_label_box} to be measured.
@@ -2404,26 +2082,26 @@
%
%
%
-% \begin{macro}{\@@_item_everypar:, \@@_item_everypar_std:}
+% \begin{macro}{\@@_item_everypar:, \@@_item_everypar_std:, \@@_item_everypar_first:}
% The \cs{@@_item_everypar:} command is executed as part of \hook{para/begin}
% but most of the time does nothing, i.e., it has the following
-% default definition.
+% default definition outside of lists (and most of the time within lists).
% \begin{macrocode}
\cs_new_eq:NN \@@_item_everypar: \prg_do_nothing:
% \end{macrocode}
-%
+%
% \begin{macrocode}
-\AddToHook{para/begin}[lists]{\@@_item_everypar:}
+\AddToHook{para/begin}[items]{\@@_item_everypar:}
% \end{macrocode}
%
% Note that we have to make sure that the above code is executed
-% after the hook chunk from \texttt{tagpdf} because the latter uses
+% after the hook chunk from \pkg{tagpdf} because the latter uses
% \texttt{@inlabel} to make a decision.
%
% By the end of the day both should probably move into the kernel
-% hook instead!
+% hook instead or, better, into sockets.
% \begin{macrocode}
-\DeclareHookRule{para/begin}{lists}{after}{tagpdf}
+\DeclareHookRule{para/begin}{items}{after}{tagpdf}
% \end{macrocode}
%
%
@@ -2475,6 +2153,16 @@
}
% \end{macrocode}
%
+% This is the definition of \cs{@@_item_everypar:} before the first
+% \tn{item} is encountered.
+% \changes{v0.8q}{2024/09/02}{Call \tn{@noitemerr} if hmode is
+% started before the first item}
+% \begin{macrocode}
+\cs_new:Npn \@@_item_everypar_first: {
+ \legacy_if:nT { @newlist } { \@noitemerr }
+}
+% \end{macrocode}
+%
% \end{macro}
%
%
@@ -2520,10 +2208,10 @@
%
% \begin{macro}{\item}
% Here we already have all the building blocks. Complain in math
-% mode. Distingusih between first item (do necessary tagging) and
+% mode. Distinguish between first item (do necessary tagging) and
% later items \cs{@@_inter_item:} to
% cleanly close what's before, then call \cs{@@_item_instance:n} (which
-% calls \cs{UseInstance}\{item\}\marg{instance}) to prepare the
+% calls \tn{UseInstance}\{item\}\marg{instance}) to prepare the
% upcoming item: it will be actually inserted only once some later
% material triggers \tn{everypar}.
% \begin{macrocode}
@@ -2541,8 +2229,16 @@
}
{
\legacy_if:nTF { @newlist }
- { \__kernel_list_item_begin: }
- { \@@_inter_item: }
+ {
+ \__kernel_list_item_begin:
+% \end{macrocode}
+% The first item of a list also has to change the \texttt{@newlist} switch.
+% \changes{v0.8q}{2024/09/02}{Set \texttt{@newlist} to false after
+% the first \tn{item}}
+% \begin{macrocode}
+ \legacy_if_gset_false:n { @newlist }
+ }
+ { \@@_inter_item: }
% \end{macrocode}
% To avoid unnecessary key/val processing we make a quick check if
% there was an optional argument.
@@ -2572,7 +2268,7 @@
\legacy_if:nT { @inlabel }
{ \indent \par } % case of \item\item
% \end{macrocode}
-% \cs{par} may have a strange definition and may not get us back to
+% \tn{par} may have a strange definition and may not get us back to
% vertical mode in one go, so we better do not treat the next line
% as an else case to the above conditional (for now).
% \begin{macrocode}
@@ -2607,21 +2303,564 @@
%
%
%
+% \subsection{Tagging support commands}
+%
+% In this section we provide code to the various kernel hooks to support
+% the tagging of different displayblock environments.
+%
+% All of the following definitions should only be made if tagging
+% is active!
+% \begin{macrocode}
+\tag_if_active:TF {
+% \end{macrocode}
+%
+% \begin{macro}{\@@_beginpar_vmode:}
+% When a block starts out in vertical mode, i.e., is not yet part of
+% a paragraph, we have to start a paragraph
+% structure. However, this is not the case if we are already
+% flattening paragraphs, thus in this case we do nothing.
+% We also do nothing if \texttt{@endpe} is currently true, because
+% that means we are right now just after the end of a
+% \texttt{blockenv} and in the process of looking if we have to end
+% the current \struct{text-unit}, i.e., it is already open.
+% \begin{macrocode}
+ \cs_set:Npn \@@_beginpar_vmode: {
+ \@@_debug_typeout:n
+ { @endpe = \legacy_if:nTF { @endpe }{true}{false}
+ \on@line }
+ \legacy_if:nTF { @endpe }
+ {
+ \legacy_if_gset_false:n { @endpe }
+ }
+% \end{macrocode}
+% We test for \texttt{<2} because the first flattened environment
+% has to surround itself with a \struct{text-unit}. Only any inner ones
+% then have to avoid adding another \struct{text-unit}.
+% \begin{macrocode}
+ {
+ \int_compare:nNnT \l__tag_block_flattened_level_int < 2
+ {
+ \__tag_gincr_para_main_begin_int:
+ \tag_struct_begin:n
+ {
+ tag=\l__tag_para_main_tag_tl,
+ attribute-class=\l__tag_para_main_attr_class_tl,
+ }
+ \__tag_para_main_store_struct:
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_beginpar_hmode:N}
+% If the block is already part of a part of a paragraph, i.e., when it has
+% some text directly in front, then the first thing to
+% do is to return to vertical mode. However, that should be done
+% without inserting a paragraph end tag, so before calling \tn{par}
+% to do its normal work, we disable paragraph tagging and
+% restarting afterwards again. The argument to this config point
+% simply gobbles the \tn{par} following it in the code above (which
+% is used when there is no tagging going on.
+% \begin{macrocode}
+ \cs_set:Npn \@@_beginpar_hmode:N #1
+ {
+ \tag_mc_end:
+ \__tag_gincr_para_end_int:
+ \@@_debug_typeout:n{increment~ /P \on@line }
+ \bool_if:NT \l__tag_para_show_bool
+ { \tag_mc_begin:n{artifact}
+ \rlap{\color_select:n{red}\tiny\ \int_use:N\g__tag_para_end_int}
+ \tag_mc_end:
+ }
+ \tag_struct_end:
+ \tagpdfparaOff \par \tagpdfparaOn
+ }
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\__kernel_displayblock_doendpe:}
+% If a display block ends and is followed by a blank line we have to end the
+% enclosing paragraph tagging structure.
+% \begin{macrocode}
+\cs_set:Npn \__kernel_displayblock_doendpe: {
+ \bool_if:NT \l__tag_para_bool
+ {
+% \end{macrocode}
+% Given that restoring \tn{par} through the legacy \LaTeXe{} method
+% can take a few iterations (for example, in case of nested lists,
+% e.g., \verb=...\end{itemize} \item ...\par= it can happen that
+% \cs{__kernel_displayblock_doendpe:} is called while
+% \texttt{@endpe} is already handled and then we should not attempt
+% to close a \struct{text-unit} structure). So we need to check for this.
+% \begin{macrocode}
+ \legacy_if:nT { @endpe }
+ {
+% \end{macrocode}
+% If the display block currently ending was \enquote{flattened}
+% (i.e., uses simplified paragraphs that are not tagged by a
+% combination of \struct{text-unit} followed by \struct{text}, but simply
+% with a \struct{text}),
+% then we don't have to do anything, because the \struct{text} is already closed.
+% \begin{macrocode}
+ \@@_debug_typeout:n
+ { flattened= \bool_if:NTF
+ \l__tag_para_flattened_bool
+ {true}{false}
+ \on@line }
+ \bool_if:NF \l__tag_para_flattened_bool
+ {
+ \@@_debug_typeout:n{Structure-end~
+ \l__tag_para_main_tag_tl\space
+ after~ displayblock \on@line }
+ \__tag_gincr_para_main_end_int:
+ \tag_struct_end: %text-unit
+ }
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{para/begin}
+%
+% Paragraph tagging is mainly done using the paragraph hooks (will
+% get moved eventually). The default hook setting is not good
+% enough when lists get supported: we need to delay starting the
+% paragraph tagging if we still have to place the list label.
+% We therefore remove the existing hook data and replace it with an
+% augmented version (this will get combined eventually).
+% \begin{macrocode}
+\RemoveFromHook{para/begin}[tagpdf]
+% \end{macrocode}
+%
+% \begin{macrocode}
+\AddToHook{para/begin}[tagpdf]{
+ \bool_if:NT \l__tag_para_bool {
+% \end{macrocode}
+% if we are still waiting to typeset the list label we do nothing
+% (the paragraph tagging then happens when the list is finally
+% typeset).
+% \begin{macrocode}
+ \legacy_if:nF { @inlabel }
+ {
+% \end{macrocode}
+% Otherwise, we start a \struct{text} tag structure but only if we are not
+% starting a paragraph immediately \emph{after} a list, in which
+% case we only start a new MC (because the \struct{text} tag is still open from
+% before the list --- one of the reasons why lists are always put
+% \enquote{inside} paragraphs.
+%
+% We do this in a separate command, because it is needed elsewhere too.
+% \begin{macrocode}
+ \@@_start_para_structure:n { \PARALABEL }
+ }
+ }
+}
+% \end{macrocode}
+%
+%
+% \begin{macro}{\@@_start_para_structure:n}
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_start_para_structure:n #1 {
+ \@@_debug_typeout:n
+ { @endpe = \legacy_if:nTF { @endpe }{true}{false}
+ \on@line }
+ \legacy_if:nF { @endpe }
+ {
+ \bool_if:NF \l__tag_para_flattened_bool
+ {
+ \__tag_gincr_para_main_begin_int:
+ \tag_struct_begin:n
+ {
+ tag=\l__tag_para_main_tag_tl,
+ attribute-class=\l__tag_para_main_attr_class_tl,
+ }
+ \__tag_para_main_store_struct:
+ }
+ }
+ \__tag_gincr_para_begin_int:
+ \@@_debug_typeout:n{increment~ P \on@line }
+ \tag_struct_begin:n
+ {
+ tag=\l__tag_para_tag_tl
+ ,attribute-class=\l__tag_para_attr_class_tl
+ }
+ \__tag_check_para_begin_show:nn {green}{#1}
+ \tag_mc_begin:n {}
+}
+% \end{macrocode}
+% The same code, but without testing \texttt{@endpe}. This is not
+% needed in the standalone case and wrong inside lists.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_start_para_structure_unconditionally:n #1 {
+ \bool_if:NF \l__tag_para_flattened_bool
+ {
+ \__tag_gincr_para_main_begin_int:
+ \tag_struct_begin:n
+ {
+ tag=\l__tag_para_main_tag_tl,
+ attribute-class=\l__tag_para_main_attr_class_tl,
+ }
+ \__tag_para_main_store_struct:
+ }
+ \__tag_gincr_para_begin_int:
+ \@@_debug_typeout:n{increment~ P \on@line }
+ \tag_struct_begin:n
+ {
+ tag=\l__tag_para_tag_tl
+ ,attribute-class=\l__tag_para_attr_class_tl
+ }
+ \__tag_check_para_begin_show:nn {green}{#1}
+ \tag_mc_begin:n {}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+\RemoveFromHook{para/end}[tagpdf]
+\AddToHook{para/end}
+ {
+ \bool_if:NT \l__tag_para_bool
+ {
+ \__tag_gincr_para_end_int:
+ \@@_debug_typeout:n{increment~ /P \on@line }
+ \tag_mc_end:
+ \__tag_check_para_end_show:nn {red}{}
+ \tag_struct_end:
+ \bool_if:NF \l__tag_para_flattened_bool
+ {
+ \__tag_gincr_para_main_end_int:
+ \tag_struct_end:
+ }
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\PARALABEL{NP-}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\para_end:}
+% If we see a \tn{par} in vmode and a \struct{text-unit} is still open
+% we need to close that. For this we check if a request for
+% \text{@endpe} was made (but the \tn{par} redefinition got lost
+% due to (bad?) coding).
+% \begin{macrocode}
+\cs_set_protected:Npn \para_end: {
+ \scan_stop:
+ \mode_if_horizontal:TF {
+ \mode_if_inner:F {
+ \tex_unskip:D
+ \hook_use:n{para/end}
+ \@kernel@after@para@end
+ \mode_if_horizontal:TF {
+ \if_int_compare:w 11 = \tex_lastnodetype:D
+ \tex_hskip:D \c_zero_dim
+ \fi:
+ \tex_par:D
+ \hook_use:n{para/after}
+ \@kernel@after@para@after
+ }
+ { \msg_error:nnnn { hooks }{ para-mode }{end}{horizontal} }
+ }
+ }
+ {
+ \__kernel_endpe_vmode: % should do nothing if no tagging
+ \tex_par:D
+ }
+}
+\cs_set_eq:NN \par \para_end:
+\cs_set_eq:NN \@@par \para_end:
+\cs_set_eq:NN \endgraf \para_end:
+% \end{macrocode}
+%
+% \end{macro}
+%
+%
+% \begin{macro}{\begin}
+% We need to do a little more than canceling \texttt{@endpe} now.
+% \begin{macrocode}
+\DeclareRobustCommand*\begin[1]{%
+ \UseHook{env/#1/before}%
+ \@ifundefined{#1}%
+ {\def\reserved@a{\@latex@error{Environment~#1~undefined}\@eha}}%
+ {\def\reserved@a{\def\@currenvir{#1}%
+ \edef\@currenvline{\on@line}%
+ \@execute@begin@hook{#1}%
+ \csname #1\endcsname}}%
+ \@ignorefalse
+ \begingroup
+ \__kernel_endpe_vmode:
+ \reserved@a}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\__kernel_endpe_vmode:}
+% Close an open \struct{text-unit} if \texttt{@endpe} is true and we
+% are in vmode. Used in \cs{para_end:} and \tn{begin}.
+% \begin{macrocode}
+\cs_new:Npn \__kernel_endpe_vmode: {
+ \if@endpe \ifvmode
+ \bool_if:NT \l__tag_para_bool
+ {
+ \bool_if:NF \l__tag_para_flattened_bool
+ {
+ \__tag_gincr_para_main_end_int:
+ \tag_struct_end:
+ }
+ \@endpefalse
+ }
+ \fi \fi
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\__kernel_list_label_after:}
+% If starting the text-unit/text tags got delayed because of a pending label we
+% have to do it after the label got typeset
+% \begin{macrocode}
+\cs_set:Npn \__kernel_list_label_after: {
+ \bool_if:NT \l__tag_para_bool
+ {
+ \@@_start_para_structure_unconditionally:n { LI- }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_inner_begin:}
+% Start a block that has an inner structure if it isn't also a list.
+% \begin{macrocode}
+\cs_new:Npn \@@_inner_begin: {
+ \tagstructbegin{tag=\l_@@_tag_inner_tag_tl}
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@@_inner_end:}
+% End a block (which isn't also a list).
+% \begin{macrocode}
+\cs_new:Npn \@@_inner_end: {
+ \@@_debug_typeout:n{block-end \on@line}
+ \legacy_if:nT { @endpe }
+ {
+ \__tag_gincr_para_main_end_int:
+ \@@_debug_typeout:n{close~ /text-unit \on@line}
+ \tagstructend
+ }
+ \tagstructend % end inner structure
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+% \subsubsection{List tags}
+%
+%
+% \begin{macrocode}
+\tl_new:N \l__tag_L_tag_tl
+\tl_set:Nn \l__tag_L_tag_tl {L}
+
+\tl_new:N\l__tag_L_attr_class_tl
+\tl_set:Nn \l__tag_L_attr_class_tl {list}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\tag_if_active:T
+{
+ \tagpdfsetup
+ {
+ role/new-attribute = {itemize}
+ {/O /List /ListNumbering/Unordered},
+ role/new-attribute = {enumerate}
+ {/O /List /ListNumbering/Ordered},
+ role/new-attribute = {description}
+ {/O /List /ListNumbering/Description},
+% \end{macrocode}
+% Initially, we had \texttt{/None} for the basic \env{list}
+% environment, but that is not allowed in PDF/UA-2 if the list
+% contains any Lbl tags. So now we default to
+% \texttt{Unordered}.
+% \begin{macrocode}
+ % default if unknown
+ role/new-attribute = {list}{/O /List /ListNumbering/Unordered},
+ }
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\LItag{LI}
+% \end{macrocode}
+%
+% \begin{macro}{\@@_list_begin:}
+% Start a list \ldots
+% \begin{macrocode}
+\cs_set:Npn \@@_list_begin: {
+ \tagstructbegin
+ {
+ tag=\l__tag_L_tag_tl
+ ,attribute-class=\l__tag_L_attr_class_tl
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_list_item_begin:}
+% Start tagging a list item.
+% \begin{macrocode}
+\cs_set:Npn \@@_list_item_begin: { \tagstructbegin{tag=\LItag} }
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\__kernel_list_label_begin:}
+% A list label needs a \struct{Lbl} structure tag and an MC.
+% \begin{macrocode}
+\cs_set:Npn \__kernel_list_label_begin: {
+%
+% FMi: this needs a different logic to decide when to make the label
+% an artifact (after cleaning up the \item code ), therefore
+% disabled for now
+% \tl_if_empty:oTF \@itemlabel
+% {
+% \tag_mc_begin:n {artifact}
+% }
+% {
+ \tagstructbegin{tag=Lbl}
+ \tagmcbegin{tag=Lbl}
+% }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\__kernel_list_label_end:}
+% And when we are done with the label we have to close the MC and
+% the \struct{Lbl} structure. We then start the \struct{LBody}. The
+% material inside will be \enquote{paragraph} text and the tagging
+% for that is handled by the normal para tagging.
+% \begin{macrocode}
+\cs_set:Npn \__kernel_list_label_end: {
+ \tagmcend % end mc-Lbl or artifact
+% FMi: unconditionally for now
+% \tl_if_empty:oF \@itemlabel
+ \tagstructend % end Lbl
+ \tagstructbegin{tag=\LBody}
+}
+\def\LBody{LBody}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\@@_list_item_end:}
+% When a list item ends we have to close \struct{LBody} and
+% \struct{LI} but also a \struct{text} in the special case that the
+% item material ends in a list (identifiable via \texttt{@endpe}).
+% \begin{macrocode}
+\cs_set:Npn \@@_list_item_end: {
+ \legacy_if:nT { @endpe }
+ {
+ \__tag_gincr_para_main_end_int:
+ \tagstructend % text-unit
+% \@@_debug_typeout:n{Structure-end~ P~ at~ item-end \on@line }
+ }
+ \tagstructend \tagstructend % end LBody, LI
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\@@_list_end:}
+% Finally, at the list end we have to close the open
+% \struct{LBody}, \struct{LI}, \struct{L}, and possibly a
+% \struct{text} if the last item ends with a list.
+% However, if the user forgot to add an \tn{item} then there will be no
+% \struct{LI} and \struct{LBody} open, so we check for the status
+% of \texttt{@newlist}. The corresponding no-item error was
+% generated earlier outside the tagging code.
+%
+% One could argue that it doesn't matter if the tagging is wrong
+% after a \tn{@noitemerr} was issued. However, there is one case
+% where it isn't an error: In the \env{thebibliography}
+% environment (which is internally a list) it is often the case
+% that documents start out with an empty environment, not
+% containing any \tn{bibitem}s. For that reason \tn{@noitemerr} is
+% redefined inside that environment to only produce a warning;
+% hence we have to produce correct tag structures in that case.
+% \changes{v0.8q}{2024/09/02}{Do not close LI and LBody if they
+% never were opened.}
+% \begin{macrocode}
+\cs_set:Npn \@@_list_end: {
+% \end{macrocode}
+% If \texttt{@newlist} is true (i.e., when we have an error or warning
+% situation) there is not much to close.
+% \begin{macrocode}
+ \legacy_if:nF { @newlist }
+ {
+ \legacy_if:nT { @endpe }
+ {
+ \__tag_gincr_para_main_end_int:
+ \tagstructend % text-unit
+ \@@_debug_typeout:n{Structure-end~ P~ at~ list-end \on@line }
+ }
+ \tagstructend\tagstructend % end LBody, LI
+ }
+ \tagstructend % end L
+}
+% \end{macrocode}
+% \end{macro}
+% End of tagging related declarations.
+% \begin{macrocode}
+}
+% \end{macrocode}
+% These command should have a dummy declaration if tagging is not active
+% \begin{macrocode}
+{
+ \cs_new:Npn \@@_start_para_structure_unconditionally:n #1 {}
+}
+% \end{macrocode}
+%
+%
+%
+%
+%
+%
+%
+%
+%
%
%
% \subsection{Tagging recipes}
%
% \begin{macro}{\@@_recipe_basic:}
-% The \texttt{basic} recipe simply ensures that the block is inside
-% a \texttt{text-unit} structure and if necessary starts one. When the
-% block ends and is followed by a blank line the \texttt{text-unit}
+% The \keyvalue{basic} recipe simply ensures that the block is inside
+% a \struct{text-unit} structure and if necessary starts one. When the
+% block ends and is followed by a blank line the \struct{text-unit}
% structure is closed too, otherwise it remains open and further
% text starts with just a \struct{text} structure.
%
% There is otherwise no inner structure so
% \cs{__kernel_displayblock_begin:} and
% \cs{__kernel_displayblock_end:} do nothing---blockenvs with inner
-% structure use the \texttt{standard} or \texttt{list} recipe instead.
+% structure use the \keyvalue{standard} or \keyvalue{list} recipe instead.
% \begin{macrocode}
\cs_new:Npn \@@_recipe_basic: {
\cs_set_eq:NN \__kernel_displayblock_beginpar_hmode:w
@@ -2631,7 +2870,7 @@
\let \__kernel_displayblock_begin: \prg_do_nothing:
\let \__kernel_displayblock_end: \prg_do_nothing:
% \end{macrocode}
-% End environment \cs{par} handling:
+% End environment \tn{par} handling:
% \begin{macrocode}
\socket_assign_plug:nn{tagsupport/block-endpe}{on}
}
@@ -2640,9 +2879,9 @@
%
% \begin{macro}{\@@_recipe_standalone:}
%
-% The \texttt{standalone} recipe produces a block that ensures that
-% a previous \texttt{text-unit} ends and that after the block a new
-% \texttt{text-unit} starts.
+% The \keyvalue{standalone} recipe produces a block that ensures that
+% a previous \struct{text-unit} ends and that after the block a new
+% \struct{text-unit} starts.
% \begin{macrocode}
\cs_new:Npn \@@_recipe_standalone: {
\cs_set_eq:NN \__kernel_displayblock_beginpar_hmode:w
@@ -2652,7 +2891,7 @@
\cs_set_eq:NN \__kernel_displayblock_begin: \@@_inner_begin:
\cs_set_eq:NN \__kernel_displayblock_end: \@@_inner_end:
% \end{macrocode}
-% End environment \cs{par} handling:
+% End environment \tn{par} handling:
% \begin{macrocode}
\socket_assign_plug:nn{tagsupport/block-endpe}{off}
% \end{macrocode}
@@ -2666,21 +2905,21 @@
% \end{macro}
%
% \begin{macro}{\@@_recipe_standard:}
-% The \texttt{standard} recipe does the following:
+% The \keyvalue{standard} recipe does the following:
% \begin{itemize}
-% \item surround the block with a \texttt{text-unit}-structure if not already in a
-% a \texttt{text-unit}. In the latter case end the
-% MC and the \struct{text} but leave the \texttt{text-unit} open.
+% \item surround the block with a \struct{text-unit} structure if not already in a
+% a \struct{text-unit}. In the latter case end the
+% MC and the \struct{text} but leave the \struct{text-unit} open.
%
% If we are producing flattened paragraphs, just close any
-% \struct{text} but do not open a \texttt{text-unit}.
+% \struct{text} but do not open a \struct{text-unit}.
%
% \item Then open an new (inner) structure (by default
-% \texttt{Figure} but typically the one specified on the instance).
+% \struct{Figure} but typically the one specified on the instance).
% \item At the end of the block close the inner structure
-% (\texttt{Figure} or explicit one)
-% but leave the \texttt{text-unit} open to be either continued or closed due to a
-% following \cs{par}.
+% (\struct{Figure} or explicit one)
+% but leave the \struct{text-unit} open to be either continued or closed due to a
+% following \tn{par}.
% \end{itemize}
% \begin{macrocode}
\cs_new:Npn \@@_recipe_standard:
@@ -2692,7 +2931,7 @@
\cs_set_eq:NN \__kernel_displayblock_begin: \@@_inner_begin:
\cs_set_eq:NN \__kernel_displayblock_end: \@@_inner_end:
% \end{macrocode}
-% End environment \cs{par} handling:
+% End environment \tn{par} handling:
% \begin{macrocode}
\socket_assign_plug:nn{tagsupport/block-endpe}{on}
% \end{macrocode}
@@ -2716,7 +2955,7 @@
%
%
% \begin{macro}{\@@_recipe_list:}
-% The \texttt{list} recipe does the following.
+% The \keyvalue{list} recipe does the following.
% \begin{itemize}
% \item It opens a \struct{text-unit}-structure or keeps the current one open (only
% closing the MC).
@@ -2738,7 +2977,7 @@
\cs_set_eq:NN \__kernel_displayblock_end: \@@_list_end:
% \end{macrocode}
% The next two lines could be done globally, because they are only
-% called if we do have \cs{item}s, i.e., if we are in a list. It is
+% called if we do have \tn{item}s, i.e., if we are in a list. It is
% therefore also not necessary to reset them in other recipes
% (right now---this may change if we get more templates (like
% inline lists)).
@@ -2746,12 +2985,12 @@
\cs_set_eq:NN \__kernel_list_item_begin: \@@_list_item_begin:
\cs_set_eq:NN \__kernel_list_item_end: \@@_list_item_end:
% \end{macrocode}
-% End environment \cs{par} handling:
+% End environment \tn{par} handling:
% \begin{macrocode}
\socket_assign_plug:nn{tagsupport/block-endpe}{on}
% \end{macrocode}
%
-% Handle the tag name and attribute classess using the key values
+% Handle the tag name and attribute classes using the key values
% from the current list instance.
% \begin{macrocode}
\tl_if_empty:NTF \l_@@_tag_name_tl
@@ -2763,36 +3002,590 @@
}
% \end{macrocode}
% \end{macro}
-
-
-
+%
+%
+%
+%
+% \section[Implementation of document-level block environments]
+% {Implementation of document-level block\\ environments}
+%
+% Most such environments are pretty simple: they take an optional
+% argument and call a \texttt{blockenv} instance to do the work. At
+% the end of environment we call \tn{endblockenv} to finish.
+%
+%
+% \subsection{Displayblock environments}
+%
+%
+% There are two basic block environment which are similar to
+% \LaTeXe{}'s \env{trivlist} except that there aren't degenerated
+% lists and thus have no hidden \tn{item} inside.
+%
+%
+% \begin{environment}{displayblock}
+%
+% \begin{macrocode}
+\NewDocumentEnvironment{displayblock}{ !O{} }
+ { \UseInstance{blockenv}{displayblock} {#1} }
+ { \endblockenv }
+% \end{macrocode}
+% \end{environment}
+%
+%
+% \begin{environment}{displayblockflattened}
+%
+% \begin{macrocode}
+\NewDocumentEnvironment{displayblockflattened}{ !O{} }
+ { \UseInstance{blockenv}{displayblockflattened} {#1} }
+ { \endblockenv }
+% \end{macrocode}
+% \end{environment}
+%
+%
+%
+%
+% \subsection{The \env{center}, \env{flushleft}, and \env{flushright} environments}
+%
+%
+%
+% \begin{environment}{center,flushleft,flushright}
+%
+% \begin{macrocode}
+\AddToHook{begindocument/before}{
+ \RenewDocumentEnvironment{center} { !O{} }
+ { \UseInstance{blockenv}{center}{#1} }
+ { \endblockenv }
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \RenewDocumentEnvironment{flushright} { !O{} }
+ { \UseInstance{blockenv}{flushright}{#1} }
+ { \endblockenv }
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \RenewDocumentEnvironment{flushleft} { !O{} }
+ { \UseInstance{blockenv}{flushleft}{#1} }
+ { \endblockenv }
+}
+% \end{macrocode}
+% \end{environment}
+%
+%
+%
+% \subsection{Display quote environments}
+%
+%
+% \begin{environment}{quote,quotation}
+%
+% \begin{macrocode}
+\AddToHook{begindocument/before}{
+ \RenewDocumentEnvironment{quote}{ !O{} }
+ { \UseInstance{blockenv}{quote} {#1} }
+ { \endblockenv }
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \RenewDocumentEnvironment{quotation}{ !O{} }
+ { \UseInstance{blockenv}{quotation} {#1} }
+ { \endblockenv }
+}
+% \end{macrocode}
+% \end{environment}
+%
+%
+%
+%
+%
+%
+% \subsection{Verbatim environments}
+%
+%
+% \begin{environment}{verbatim,verbatim*}
+%
+% \begin{macrocode}
+\AddToHook{begindocument/before}{
+ \RenewDocumentEnvironment{verbatim}{ !O{} }
+ { \UseInstance{blockenv}{verbatim} {#1}
+% \end{macrocode}
+% This is the part of the code where \env{verbatim}
+% and\env{verbatim*} differ.
+% \begin{macrocode}
+ \@setupverbinvisiblespace\frenchspacing\@vobeyspaces
+ \@xverbatim
+ }
+ { \endblockenv }
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \RenewDocumentEnvironment{verbatim*}{ !O{} }
+ { \UseInstance{blockenv}{verbatim} {#1}
+ \@setupverbvisiblespace\frenchspacing\@vobeyspaces
+ \@sxverbatim
+ }
+ { \endblockenv }
+}
+% \end{macrocode}
+% \end{environment}
+%
+%
+%
+% \subsubsection{Helper commands for verbatim}
+%
+%
+% \begin{macro}{\legacyverbatimsetup}
+%
+% This code resembles the \LaTeXe{} verbatim implementation with a
+% slight twist: in \LaTeXe{} each code line was a paragraph using
+% \tn{leftskip}=\tn{@totalleftmargin}. This was possible because
+% the whole environment was implemented as a trivlist. As this is
+% no longer the case setting \tn{leftskip} would alter the layout
+% of a surrounding list. So instead we need to make sure that the
+% paragraph end is executed in a group so that any parshape setup
+% is preserved.
+% \begin{macrocode}
+%<@@=>
+\def\legacyverbatimsetup{%
+ \language\l@nohyphenation
+ \@tempswafalse
+ \def\par{%
+ \if@tempswa
+ \leavevmode \null {\@@par}\penalty\interlinepenalty
+ \else
+ \@tempswatrue
+ \ifhmode{\@@par}\penalty\interlinepenalty\fi
+ \fi}%
+ \let\do\@makeother \dospecials
+ \obeylines \verbatim@font \@noligs
+ \everypar \expandafter{\the\everypar \unpenalty}%
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \tl_set:Nn \l__tag_para_main_tag_tl {codeline}
+ \tagtool{paratag=Code}% oder faster: \tl_set:Nn\l__tag_para_tag_tl{Code}
+}
+%<@@=block>
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\@setupverbinvisiblespace}
+% In the \pdfTeX{} engine we need to use \tn{pdffakespace} chars
+% for the invisible spaces.
+% \begin{macrocode}
+\newcommand\@setupverbinvisiblespace{}
+\tag_if_active:T {
+ \bool_if:NF\g__tag_mode_lua_bool
+ {
+ \renewcommand\@setupverbinvisiblespace
+ {\def\@xobeysp{\nobreakspace\pdffakespace}}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsection{Standard list environments}
+%
+%
+% \begin{environment}{itemize,enumerate,description}
+%
+% For the standard lists everything is managed by the blockenv instance.
+% \begin{macrocode}
+\AddToHook{begindocument/before}{
+ \RenewDocumentEnvironment{itemize}{!O{}}
+ { \UseInstance{blockenv}{itemize} {#1} }
+ { \endblockenv }
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \RenewDocumentEnvironment{enumerate}{!O{}}
+ { \UseInstance{blockenv}{enumerate} {#1} }
+ { \endblockenv }
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \RenewDocumentEnvironment{description}{!O{}}
+ { \UseInstance{blockenv}{description} {#1} }
+ { \endblockenv }
+}
+% \end{macrocode}
+% \end{environment}
+%
+%
+% \subsection{verse environment}
+%
+% \begin{environment}{verse}
+% The verse environment has not special tagging currently. It is
+% defined as a simple standard list and takes the tagging from there.
+% But it must be redefined so that \tn{itemindent} is correctly set.
+% \begin{macrocode}
+\AddToHook{begindocument/before}{
+ \RenewDocumentEnvironment{verse}{ !O{} }
+ {
+ \let\\\@centercr
+ \UseInstance{blockenv}{list}
+ {
+ item-indent=-1.5em,
+ parindent=-1.5em,
+ item-skip=0pt,
+ rightmargin=\leftmargin,
+ leftmargin=\leftmargin+1.5em,
+ #1
+ }
+ \item\relax
+ }
+ { \endblockenv }
+ }
+% \end{macrocode}
+% \end{environment}
+%
+%
+% \begin{environment}{list}
+%
+% The legacy 2e list environment is more complicated as we have to get the
+% extra arguments accounted for.
+% \begin{macrocode}
+\AddToHook{begindocument/before}{
+ \RenewDocumentEnvironment{list}{O{} m m }
+ {
+% \end{macrocode}
+% We do this by storing them away and then call the list
+% instance. Inside this instance the \key{setup-code} key
+% contains \tn{legacylistsetupcode}, which makes use of the stored values.
+% \changes{v0.8v}{2024/10/11}{Update \tn{@itemlabel} in
+% \cs{l_@@_legacy_env_params_tl} and not at the start of the
+% environment (tagging/730)}
+% \begin{macrocode}
+ \tl_set:Nn \l_@@_legacy_env_params_tl
+ {
+ \tl_set:Nn \@itemlabel {#2}
+ #3
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \UseInstance{blockenv}{list} {#1}
+ }
+ { \endblockenv }
+}
+% \end{macrocode}
+%
+% \end{environment}
+%
+%
+%
+% \begin{macro}{\legacylistsetupcode}
+%
+% And here is the extra code for use in the list instance setup
+% inside the key \key{setup-code}.
+% \begin{macrocode}
+\cs_new:Npn \legacylistsetupcode {
+% \end{macrocode}
+% Reset values to defaults:
+% \begin{macrocode}
+ \dim_zero:N \listparindent
+ \dim_zero:N \rightmargin
+ \dim_zero:N \itemindent
+% \end{macrocode}
+%
+% By default a \env{list} environment is not numbered, but this
+% happens already in the block template.
+% \changes{v0.8v}{2024/10/11}{Set the defaults for \tn{@itemlabel},
+% \tn{@listctr} and \texttt{@nmbrlist} early in the block code
+% before the setup code gets executed (tagging/730)}
+% \begin{macrocode}
+% \tl_set:Nn \@listctr {}
+% \legacy_if_set_false:n { @nmbrlist } % needed if lists are nested
+% \end{macrocode}
+% By default there is a simple definition for \tn{makelabel}. It can be
+% overwritten in the second mandatory argument to the list
+% environment (stored in \cs{l_@@_legacy_env_params_tl}) and
+% is used if the instance sets the compatibility key to true.
+% \begin{macrocode}
+ \let\makelabel\@mklab % TODO: customize
+% \end{macrocode}
+% Now we use the argument with parameter settings to update some or
+% all of the above defaults:
+% \begin{macrocode}
+ \l_@@_legacy_env_params_tl
+% \end{macrocode}
+% As we don't know much about this list we can only make a guess about
+% the nature of the list and the setting of the tag name (default
+% \keyvalue{list} rolemapped to \struct{L}) and any tag attributes
+% may have to be overwritten in the optional key/value argument.
+% But we do have some hints to play with.
+% \begin{macrocode}
+ \legacy_if:nTF { @nmbrlist }
+ { \tl_set:Nn \l__tag_L_attr_class_tl {enumerate} } % numbered list
+ { \tl_if_empty:NTF \@itemlabel
+ { \tl_set:Nn \l__tag_L_attr_class_tl {list} } % no label
+ { \tl_set:Nn \l__tag_L_attr_class_tl {itemize} } % unnumbered,
+ % unordered
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\l_@@_legacy_env_params_tl}
+%
+% \begin{macrocode}
+\tl_new:N\l_@@_legacy_env_params_tl
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{environment}{trivlist}
+% \fmi{Replace with code not using \tn{list}}
+% \begin{macrocode}
+\AddToHook{begindocument/before}{
+ \RenewDocumentEnvironment{trivlist}{ !O{} }
+ { \list[#1]{}
+ {
+ \dim_zero:N \leftmargin
+ \dim_zero:N \labelwidth
+ \cs_set_eq:NN \makelabel \use:n
+ }
+ }
+ { \endblockenv }
+}
+% \end{macrocode}
+% \end{environment}
+%
+%
+% \subsection{Theorem-like environments}
+%
+% Theorem-like environments are defined in \LaTeX{} with the help of
+% \tn{newtheorem} declarations. Internally they used a list with a
+% single item. Using lists was convenient back then, but in a tagged
+% document you end up with a strange structure. We therefore alter the
+% mechanism.
+%
+%
+% \begin{macro}{\newtheorem}
+% This is a slightly streamlined version of \tn{newtheorem}, but it
+% still uses a lot of the 2e code for now. Eventually this will change.
+% \begin{macrocode}
+\RenewDocumentCommand \newtheorem { m O{#1} m o }
+{
+ \expandafter\@ifdefinable\csname #1\endcsname
+ {
+ \str_if_eq:nnTF{#1}{#2}
+ {
+ \@definecounter {#2}
+ \IfNoValueTF {#4}
+ { % @ynthm
+ \tl_gset:ce { the #2 }
+ {
+ \@thmcounter{#2}
+ }
+ }
+ { % @xnthm
+ \@newctr{#1}[#4]
+ \tl_gset:ce { the #2 }
+ {
+ \expandafter\noexpand\csname the#4\endcsname
+ \@thmcountersep
+ \@thmcounter{#2}
+ }
+ }
+ }
+ { % @othm
+ \@ifundefined{c@#2}
+ { \@nocounterr{#2} }
+ {
+ \tl_gset:cn { the #1 }
+ { \UseName { the #2 } }
+ }
+ }
+ \global\@namedef{#1} { \@thm{#2}{#3} }
+ \global\@namedef{end#1}{ \@endtheorem }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@thm}
+% \tn{@thm} executes \tn{refstepcounter} too early for hyperref
+% and structure destinations: the generated target is outside the structure
+% and can be separated from the theorem by a page break. We therefore move
+% the anchor setting into \tn{@begintheorem}. \tn{@begintheorem} doesn't
+% currently get the name of the counter as argument, so we store it in variable
+% for now, to be able to pass it along.
+% \begin{macrocode}
+\tl_new:N \l_@@_thm_current_counter_tl
+\def\@thm#1#2{%
+ \@kernel@refstepcounter{#1}
+ \tl_set:Nn \l_@@_thm_current_counter_tl{#1}
+ \@ifnextchar[{\@ythm{#1}{#2}}{\@xthm{#1}{#2}}}
+% \end{macrocode}
+% To avoid that hyperref overwrites the definition again we must its patch:
+% \begin{macrocode}
+\def\hyper@nopatch@thm{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@begintheorem,\@opargbegintheorem}
+%
+% The \tn{@thm} command expands to either \tn{@beginthorem} or
+% \tn{@opargbegintheorem}. For the moment we stick with this as it
+% will help with the transition. But instead of using a
+% \env{trivlist} we use a blockenv and some tagging for the title
+% (as a Caption).
+% We do not want potential tagging from \tn{textbf} here,
+% so we use \tn{bfseries} to set the font. The commands set also the link targets
+% which should be inside the main structure.
+% \begin{macrocode}
+\def\@begintheorem#1#2{
+ \UseInstance{blockenv}{theorem}{}
+ \tagpdfparaOff
+% \end{macrocode}
+%
+% \changes{v0.8w}{2024/11/23}{\LaTeXe{} theorems always start out
+% without indentation (tagging/767)}
+% \begin{macrocode}
+ \noindent
+ \MakeLinkTarget{\l_@@_thm_current_counter_tl}
+ \tag_struct_begin:n{tag=Caption}
+ \group_begin:
+ \bfseries
+ \tag_mc_begin:n {}
+ #1\
+ \tag_mc_end:
+ \tag_struct_begin:n{tag=Lbl}
+ \tag_mc_begin:n {}
+ #2
+ \tag_mc_end:
+ \tag_struct_end:
+ \group_end:
+ \tag_struct_end:
+ \tagpdfparaOn
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \@@_start_para_structure_unconditionally:n { \PARALABEL }
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \itshape
+ \hskip\labelsep
+ \ignorespaces
+}
+\def\@opargbegintheorem#1#2#3{
+ \UseInstance{blockenv}{theorem}{}
+ \tagpdfparaOff
+% \end{macrocode}
+%
+% \changes{v0.8w}{2024/11/23}{\LaTeXe{} theorems always start out
+% without indentation (tagging/767)}
+% \begin{macrocode}
+ \noindent
+ \MakeLinkTarget{\l_@@_thm_current_counter_tl}
+ \tag_struct_begin:n{tag=Caption}
+ \group_begin:
+ \bfseries
+ \tag_mc_begin:n {}
+ #1\
+ \tag_mc_end:
+ \tag_struct_begin:n{tag=Lbl}
+ \tag_mc_begin:n {}
+ #2
+ \tag_mc_end:
+ \tag_struct_end:
+ \tag_mc_begin:n {}
+ \ (#3)
+ \tag_mc_end:
+ \group_end:
+ \tag_struct_end:
+ \tagpdfparaOn
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \@@_start_para_structure_unconditionally:n { \PARALABEL }
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \itshape
+ \hskip\labelsep
+ \ignorespaces
+}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\def\@endtheorem{\endblockenv}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \section{Instance declarations for environments}
+%
% \subsection{Blockenv instances}
%
+% The blockenv instances handle overall setup for the document-level
+% environments, i.e.,
+% \begin{itemize}
+% \raggedright
+% \item name of the environment for debugging purposes (\key{env-name})
+% \item how tagging should be performed (\key{tagging-recipe},
+% \key{tag-name}, \key{tag-class})
+% \item does this environment changes the block level if nested
+% (\key{level-increase})
+% \item any special setup code; normally not used (\key{setup-code})
+% \item what kind of block instance should be used (\key{block-instance})
+% \item what kind of para instance should be used; empty means
+% inherit from the outside (\key{para-instance})
+% \item are inner paragraphs real paragraphs (default) or are they
+% just \struct{text} structures and part of an outer
+% paragraph (\key{para-flattened})
+% \item what kind of inner instance should be used, if any
+% (\key{inner-instance}, \key{inner-instance-type})
+% \item the counter name of the inner level, if any (\key{inner-level-counter})
+% \item supported nesting depth of the inner level, if relevant
+% (\key{max-inner-levels})
+% \item extra code executed at the end, by default \tn{ignorespaces}
+% (\key{final-code})
+% \end{itemize}
+% The blockenv displayblock instance below shows the full set with
+% those using default values being commented out.
%
% \subsubsection{Basic instances}
%
+%
% \begin{instance}{blockenv displayblock}
-%
+% This is like \LaTeXe{}'s \env{trivlist}, i.e., it produces a
+% vertical block with default setting, but doesn't put a list
+% inside but uses a \struct{Figure} structure.
+% \fmi{should this really generate a /Figure structure?}
% \begin{macrocode}
\DeclareInstance{blockenv}{displayblock}{display}
{
env-name = displayblock,
- tag-name = ,
- tag-class = ,
- tagging-recipe = standard,
- inner-level-counter = ,
+% tagging-recipe = standard,
+% tag-name = ,
+% tag-class = ,
level-increase = false,
- setup-code = ,
- block-instance = displayblock ,
- inner-instance = ,
+% setup-code = ,
+% block-instance = displayblock ,
+% para-instance = ,
+% para-flattened = false ,
+% inner-instance = ,
+% inner-instance-type = list , % not relevant as there is no inner instance
+% inner-level-counter = , % not relevant as there is no inner instance
+% max-inner-levels = 4, % not relevant as there is no inner instance
+% final-code = \ignorespaces ,
}
% \end{macrocode}
% \end{instance}
%
%
%
+%
% \begin{instance}{blockenv displayblockflattened}
-%
+% This flattens inner paragraphs without any surrounding tag
+% structure by using the \keyvalue{basic} tagging recipe.
% \begin{macrocode}
\DeclareInstance{blockenv}{displayblockflattened}{display}
{
@@ -2812,8 +3605,15 @@
%
%
%
+%
+%
+% \subsubsection{Center, flushleft, and flushright instances}
+%
+% All three environments use the \texttt{displayblock} instance as
+% block instance. They only differ in the choice of para instance.
+%
% \begin{instance}{blockenv center}
-%
+% The \env{center} environment without using a list internally.
% \begin{macrocode}
\DeclareInstance{blockenv}{center}{display}
{
@@ -2834,7 +3634,7 @@
%
%
% \begin{instance}{blockenv flushleft}
-%
+% The \env{flushleft} environment without using a list internally.
% \begin{macrocode}
\DeclareInstance{blockenv}{flushleft}{display}
{
@@ -2857,6 +3657,7 @@
%
% \begin{instance}{blockenv flushright}
%
+% The \env{flushright} environment without using a list internally.
% \begin{macrocode}
\DeclareInstance{blockenv}{flushright}{display}
{
@@ -2877,10 +3678,18 @@
%
%
%
+%
% \subsubsection{Blockquote instances}
%
+
+% \LaTeXe{} has two environments for quoting: \env{quote} and
+% \env{quoation}. By default they differ only in indentation of inner
+% paragraphs. This is handled by using separate block instances.
+%
+% The tag names are both roll-mapped to \struct{BlockQuote}.
+%
% \begin{instance}{blockenv quotation}
- %
+% For the \env{quotation} environment:
% \begin{macrocode}
\DeclareInstance{blockenv}{quotation}{display}
{
@@ -2900,7 +3709,7 @@
%
%
% \begin{instance}{blockenv quote}
-%
+% For the \env{quote} environment:
% \begin{macrocode}
\DeclareInstance{blockenv}{quote}{display}
{
@@ -2917,44 +3726,18 @@
% \end{macrocode}
% \end{instance}
%
-% An alternative setup for quotations, using the displayblock instance and
-% just overwrite a bit in the setup code.\fmi{I guess the setup
-% code is still executed too early, have to check.}
-% This would be less flexible but would ensure visual consistency,
-% because the displayblock settings are used throughout.
-% \begin{macrocode}
-% \DeclareInstance{blockenv}{quotation}{display}
-% {
-% env-name = quotation,
-% tag-name = ,
-% tag-class = ,
-% tagging-recipe = blockquote,
-% inner-level-counter = ,
-% level-increase = true,
-% setup-code = \setlength\rightmargin{\leftmargin}
-% \setlength\parsep{1.5em} ,
-% block-instance = displayblock ,
-% inner-instance = ,
-% }
-% \end{macrocode}
+%
+%
+% \subsubsection{The theorem instance}
+%
+% \begin{instance}{blockenv theorem}
%
-% \begin{macrocode}
-% \DeclareInstance{blockenv}{quote}{display}
-% {
-% env-name = quote,
-% tag-name = ,
-% tag-class = ,
-% tagging-recipe = blockquote,
-% inner-level-counter = ,
-% level-increase = true,
-% setup-code = \setlength\rightmargin{\leftmargin} ,
-% block-instance = displayblock ,
-% inner-instance = ,
-% }
-% \end{macrocode}
+% We use \struct{theorem-like} as the structure name and rolemap it
+% to a \struct{Sect} because that can hold a \struct{Caption}.
%
-
%
+% \changes{v0.8w}{2024/11/23}{Theorems use their own block-instance
+% and not displayblock to allow for customization (tagging/767)}
% \begin{macrocode}
\DeclareInstance{blockenv}{theorem}{display}
{
@@ -2965,21 +3748,20 @@
inner-level-counter = ,
level-increase = false,
setup-code = ,
- block-instance = displayblock ,
-% inner-instance-type = innerblock ,
-% inner-instance = theorem,
+ block-instance = theoremblock ,
}
% \end{macrocode}
+% \end{instance}
%
-% We use \struct{theorem-like} as the structure name and rolemap it
-% to a \struct{Sect} because that can hold a \struct{Caption}.
%
-% \subsubsection{Verbatim instances}
+%
+% \subsubsection{The verbatim instance}
%
% \begin{instance}{blockenv verbatim}
%
-% The rolemapping is current verbatim to P and codeline to Sub (which is role mapped
-% to Span in pdf 1.7. Alternatives for PDF 1.7: Div and P.
+% The rolemapping is currently \struct{verbatim} to \struct{P} and
+% \struct{codeline} to \struct{Sub} (which is role mapped
+% to \struct{Span} in pdf 1.7. Alternatives for PDF 1.7: \struct{Div} and \struct{P}.
%
% \begin{macrocode}
\DeclareInstance{blockenv}{verbatim}{display}
@@ -2994,6 +3776,7 @@
block-instance = verbatimblock ,
inner-instance = ,
final-code = \legacyverbatimsetup ,
+ para-instance = justify
}
% \end{macrocode}
% \end{instance}
@@ -3002,7 +3785,7 @@
% \subsubsection{Standard list instances}
%
% \begin{instance}{blockenv itemize}
-%
+% For the \env{itemize} environment:
% \begin{macrocode}
\DeclareInstance{blockenv}{itemize}{display}
{
@@ -3023,6 +3806,7 @@
%
% \begin{instance}{blockenv enumerate}
%
+% For the \env{enumerate} environment:
% \begin{macrocode}
\DeclareInstance{blockenv}{enumerate}{display}
{
@@ -3043,6 +3827,7 @@
%
% \begin{instance}{blockenv description}
%
+% For the \env{description} environment:
% \begin{macrocode}
\DeclareInstance{blockenv}{description}{display}
@@ -3063,7 +3848,7 @@
%
% \begin{instance}{blockenv list}
% The general (legacy) \env{list} environment does some of its
-% setup in the \texttt{setup-code} key.
+% setup in the \key{setup-code} key.
% \begin{macrocode}
\DeclareInstance{blockenv}{list}{display}
{
@@ -3085,12 +3870,18 @@
%
% \subsection{Block instances}
%
+% Below, we declare the different block instances for the
+% document-level environments. Some, such as the displayblock ones
+% are shared between different environments (as long as one doesn't
+% need to adjust individual values), other environments have their
+% own instances (for precisely that reason).
+%
% \subsubsection{Displayblock instances}
%
% We provide 6 nesting levels (as in \LaTeXe{}). If you want to
% provide more you need to change the \texttt{maxblocklevels}
% counter, offer further \texttt{displayblock-xx} instances but
-% also define further (legacy) \cs{list\meta{romannumeral}} commands
+% also define further (legacy) \tn{list\meta{romannumeral}} commands
% for the defaults. If not, then the settings from the previous
% level are reused automatically---which may or may not be good enough).
% \begin{macrocode}
@@ -3107,11 +3898,24 @@
%
% Here we need level zero as well in case a flattened displayblock
% (like the center env) it is used on top-level.
+%
+% We show all keys here for reference, with those using their
+% default values commented out:
% \begin{macrocode}
\DeclareInstance{block}{displayblock-0}{display}
{
+% heading = , %??
+% beginsep = \topsep ,
+% begin-par-skip = \partopsep ,
+% par-skip = \parsep ,
+% end-skip = \KeyValue{beginsep} ,
+% end-par-skip = \KeyValue{begin-par-skip} ,
+% item-skip = \itemsep ,
+% beginpenalty = \UseName{@beginparpenalty} ,
+% endpenalty = \UseName{@endparpenalty} ,
leftmargin = 0pt ,
- parindent = 0pt ,
+% rightmargin = \rightmargin ,
+% parindent = 0pt ,
}
% \end{macrocode}
%
@@ -3144,7 +3948,6 @@
\DeclareInstance{block}{verbatimblock-0}{display}
{
leftmargin = 0pt ,
- parindent = 0pt ,
par-skip = 0pt ,
}
% \end{macrocode}
@@ -3173,7 +3976,7 @@
% block quoteblock-4,
% block quoteblock-5,
% block quoteblock-6 }
-% Default layout is to indent equaly from both side.
+% Default layout is to indent equally from both sides.
% \begin{macrocode}
\DeclareInstance{block}{quoteblock-1}{display}
{ rightmargin = \KeyValue{leftmargin} }
@@ -3212,6 +4015,26 @@
% \end{instance}
%
%
+% \subsubsection{Block instances for the theorems}
+%
+%
+% \begin{instance}{block theoremblock-0}
+% Theorems do not support nesting, so we have only one to set up.
+% The \LaTeX{} default reused the general value of \tn{parindent}
+% and \tn{parskip} and, of course, they start at the outer margin.
+% \changes{v0.8w}{2024/11/23}{Add block instance for theorems}
+% \begin{macrocode}
+\DeclareInstance{block}{theoremblock-0}{display}
+ {
+ leftmargin = 0pt ,
+ parindent = \parindent ,
+ par-skip = \parskip ,
+ }
+% \end{macrocode}
+% \end{instance}
+%
+%
+%
% \subsubsection{Block instances for the standard lists}
%
% \begin{instance}{block list-1,
@@ -3221,13 +4044,13 @@
% block list-5,
% block list-6 }
% The block instances for the various list environments use the
-% same underlying instance (well by default) and nothing
+% same underlying instance (well, by default) and nothing
% needs to be set up specifically (because that is already done in
-% the legacy \cs{list\meta{romannumeral}} unless a
+% the legacy \tn{list\meta{romannumeral}} unless a
% different layout is wanted.
% \begin{macrocode}
\DeclareInstance{block}{list-1}{display}{
-% heading = ,
+% heading = , % unused, might vanish
% beginsep = \topsep ,
% begin-par-skip = \partopsep ,
% par-skip = \parsep ,
@@ -3237,7 +4060,7 @@
% endpenalty = \UseName{@endparpenalty} ,
% leftmargin = \leftmargin ,
% rightmargin = \rightmargin ,
-% parindent = \listparindent ,
+% parindent = 0pt ,
}
\DeclareInstance{block}{list-2}{display}{}
\DeclareInstance{block}{list-3}{display}{}
@@ -3252,7 +4075,7 @@
% \subsection{List instances for the standard lists}
%
% For all list instances we have to say what kind of label we want
-% (\texttt{label-instance}) and how it should be formatted.
+% (\key{item-label}) and how it should be formatted.
%
% \begin{instance}{list itemize-1,
% list itemize-2,
@@ -3260,7 +4083,7 @@
% list itemize-4}
% For \env{itemize} environments this is all we need to do and we
% refer back to the external definitions rather than defining the
-% \texttt{item-label} code in the instance to ensure that old
+% \key{item-label} code in the instance to ensure that old
% documents still work.
%
% \begin{macrocode}
@@ -3278,7 +4101,7 @@
% list enumerate-3,
% list enumerate-4}
% \env{enumerate} environments are similar, except that we also
-% have to say which counter to use on every level.
+% have to say which counter to use on each level.
% \begin{macrocode}
\DeclareInstance{list}{enum-1}{std}
{ item-label = \labelenumi , counter = enumi }
@@ -3298,8 +4121,8 @@
% which is reused on all levels. This is done this way one because
% the legacy \env{list} environment sets all its
% parameters through its arguments. So this instances shouldn't
-% really be touched. It sets the \texttt{legacy-support} key to
-% true, which means that the list code uses \cs{makelabel} for
+% really be touched. It sets the \key{legacy-support} key to
+% true, which means that the list code uses \tn{makelabel} for
% formatting the label
% \begin{macrocode}
\DeclareInstance{list}{legacy}{std} {
@@ -3323,14 +4146,12 @@
%
%
% \begin{instance}{item basic, item description}
-% There two item instances set up: \texttt{description} for use
-% with the \env{description} environment and \texttt{basic} for use
+% There two item instances set up: \keyvalue{description} for use
+% with the \env{description} environment and \keyvalue{basic} for use
% with all other lists (up to now).
% \begin{macrocode}
\DeclareInstance{item}{basic}{std}
- {
- label-align = right ,
- }
+ { label-align = right }
% \end{macrocode}
%
% \begin{macrocode}
@@ -3363,56 +4184,64 @@
% \begin{macrocode}
\DeclareInstance{para}{center}{std}
{
+ para-class = center ,
indent-width = 0pt ,
- start-skip = 0pt ,
+% start-skip = 0pt ,
left-skip = \@flushglue ,
right-skip = \@flushglue ,
end-skip = \z@skip ,
final-hyphen-demerits = 0 ,
cr-cmd = \@centercr ,
- para-class = center ,
}
% \end{macrocode}
+% \end{instance}
%
+% \begin{instance}{para raggedright}
% \begin{macrocode}
\DeclareInstance{para}{raggedright}{std}
{
+ para-class = raggedright ,
indent-width = 0pt ,
- start-skip = 0pt ,
+% start-skip = 0pt ,
left-skip = \z@skip ,
right-skip = \@flushglue ,
end-skip = \z@skip ,
final-hyphen-demerits = 0 ,
cr-cmd = \@centercr ,
- para-class = raggedright ,
}
% \end{macrocode}
+% \end{instance}
%
+% \begin{instance}{para raggedleft}
% \begin{macrocode}
\DeclareInstance{para}{raggedleft}{std}
{
+ para-class = raggedleft ,
indent-width = 0pt ,
- start-skip = 0pt ,
+% start-skip = 0pt ,
left-skip = \@flushglue ,
right-skip = \z@skip ,
end-skip = \z@skip ,
final-hyphen-demerits = 0 ,
cr-cmd = \@centercr ,
- para-class = raggedleft ,
}
% \end{macrocode}
+% \end{instance}
%
+% \begin{instance}{para justify}
+% Justifying is exactly what the default values do, so the instance
+% hasn't any special setup.
% \begin{macrocode}
\DeclareInstance{para}{justify}{std}
{
-% indent-width = 0pt ,
- start-skip = 0pt ,
- left-skip = \z@skip ,
- right-skip = \z@skip ,
- end-skip = \@flushglue ,
- final-hyphen-demerits = 5000 ,
- cr-cmd = \@normalcr ,
- para-class = justify ,
+% para-class = justify ,
+% indent-width = \parindent ,
+% start-skip = 0pt ,
+% left-skip = \z@skip ,
+% right-skip = \z@skip ,
+% end-skip = \@flushglue ,
+% final-hyphen-demerits = 5000 ,
+% cr-cmd = \@normalcr ,
}
% \end{macrocode}
% \end{instance}
@@ -3420,532 +4249,21 @@
%
%
%
+% \begin{macro}[no-user-doc]{\centering,\raggedleft,\raggedright,\justifying}
+%
% \begin{macrocode}
\DeclareRobustCommand\centering {\UseInstance{para}{center}{}}
\DeclareRobustCommand\raggedleft {\UseInstance{para}{raggedleft}{}}
\DeclareRobustCommand\raggedright{\UseInstance{para}{raggedright}{}}
\DeclareRobustCommand\justifying {\UseInstance{para}{justify}{}}
-
-\justifying
-% \end{macrocode}
-%
-%
-%
-%
-%
-% \subsection{Tagging support}
-%
-% In this section we provide code to the various kernel hooks to support
-% the tagging of the different displayblock environments.
-%
-% All of the following definitions should only be made if tagging
-% is active!
-% \begin{macrocode}
-\tag_if_active:TF {
-% \end{macrocode}
-%
-% \begin{macro}{\@@_beginpar_vmode:}
-% When a block starts out in vertical mode, i.e., is not yet part of
-% a paragraph, we have to start a paragraph
-% structure. However, this is not the case if we are already
-% flattening paragraphs, thus in this case we do nothing.
-% We also do nothing if \texttt{@endpe} is currently true, because
-% that means we are right now just after the end of a
-% \texttt{blockenv} and in the process of looking if we have to end
-% the current \texttt{text-unit}, i.e., it is already open.
-% \begin{macrocode}
- \cs_set:Npn \@@_beginpar_vmode: {
- \@@_debug_typeout:n
- { @endpe = \legacy_if:nTF { @endpe }{true}{false}
- \on@line }
- \legacy_if:nTF { @endpe }
- {
- \legacy_if_gset_false:n { @endpe }
- }
-% \end{macrocode}
-% We test for \texttt{<2} because the first flattened environment
-% has to surround itself with a \texttt{text-unit}. Only any inner ones
-% then have to avoid adding another \texttt{text-unit}.
-% \begin{macrocode}
- {
- \int_compare:nNnT \l_@@_flattened_level_int < 2
- {
- \__tag_gincr_para_main_begin_int:
- \tag_struct_begin:n
- {
- tag=\l__tag_para_main_tag_tl,
- attribute-class=\l__tag_para_main_attr_class_tl,
- }
- \__tag_para_main_store_struct:
- }
- }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_beginpar_hmode:N}
-% If the block is already part of a part of a paragraph, i.e., when it has
-% some text directly in front, then the first thing to
-% do is to return to vertical mode. However, that should be done
-% without inserting a paragraph end tag, so before calling \cs{par}
-% to do its normal work, we disable paragraph tagging and
-% restarting afterwards again. The argument to this config point
-% simply gobbles the \cs{par} following it in the code above (which
-% is used when there is no tagging going on.
-% \begin{macrocode}
- \cs_set:Npn \@@_beginpar_hmode:N #1
- {
- \tag_mc_end:
- \__tag_gincr_para_end_int:
- \@@_debug_typeout:n{increment~ /P \on@line }
- \bool_if:NT \l__tag_para_show_bool
- { \tag_mc_begin:n{artifact}
- \rlap{\color_select:n{red}\tiny\ \int_use:N\g__tag_para_end_int}
- \tag_mc_end:
- }
- \tag_struct_end:
- \tagpdfparaOff \par \tagpdfparaOn
- }
-% \end{macrocode}
-% \end{macro}
-%
-%
-%
-% \begin{macro}{\__kernel_displayblock_doendpe:}
-% If a display block ends and is followed by a blank line we have to end the
-% enclosing paragraph tagging structure.
-% \begin{macrocode}
-\cs_set:Npn \__kernel_displayblock_doendpe: {
- \bool_if:NT \l__tag_para_bool
- {
-% \end{macrocode}
-% Given that restoring \cs{par} through the legacy \LaTeXe{} method
-% can take a few iterations (for example, in case of nested lists,
-% e.g., \verb=...\end{itemize} \item ...\par= it can happen that
-% \cs{__kernel_displayblock_doendpe:} is called while
-% \texttt{@endpe} is already handled and then we should not attempt
-% to close a \texttt{text-unit} structure). So we need to check for this.
-% \begin{macrocode}
- \legacy_if:nT { @endpe }
- {
-% \end{macrocode}
-% If the display block currently ending was \enquote{flattened}
-% (i.e., uses simplified paragraphs that are not tagged by a
-% combination of \texttt{text-unit} followed by \struct{text}, but simply
-% with a \struct{text}),
-% then we don't have to do anything, because the \struct{text} is already closed.
-% \begin{macrocode}
- \@@_debug_typeout:n
- { flattened= \bool_if:NTF
- \l__tag_para_flattened_bool {true}{false}
- \on@line }
- \bool_if:NF \l__tag_para_flattened_bool
- {
- \@@_debug_typeout:n{Structure-end~
- \l__tag_para_main_tag_tl\space after~ displayblock \on@line }
- \__tag_gincr_para_main_end_int:
- \tag_struct_end: %text-unit
- }
- }
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{para/begin}
-%
-% Paragraph tagging is mainly done using the paragraph hooks (will
-% get moved eventually). The default hook setting is not good
-% enough when lists get supported: we need to delay starting the
-% paragraph tagging if we still have to place the list label.
-% We therefore remove the existing hook data and replace it with an
-% augmented version (this will get combined eventually).
-% \begin{macrocode}
-\RemoveFromHook{para/begin}[tagpdf]
-% \end{macrocode}
-%
-% \begin{macrocode}
-\AddToHook{para/begin}[tagpdf]{
- \bool_if:NT \l__tag_para_bool {
-% \end{macrocode}
-% if we are still waiting to typeset the list label we do nothing
-% (the paragraph tagging then happens when the list is finally
-% typeset).
-% \begin{macrocode}
- \legacy_if:nF { @inlabel }
- {
-% \end{macrocode}
-% Otherwise, we start a \struct{text} tag structure but only if we are not
-% starting a paragraph immediately \emph{after} a list, in which
-% case we only start a new MC (because the \struct{text} tag is still open from
-% before the list --- one of the reasons why lists are always put
-% \enquote{inside} paragraphs.
-%
-% We do this in a separate command, because it is needed elsewhere too.
-% \begin{macrocode}
- \@@_start_para_structure:n { \PARALABEL }
- }
- }
-}
% \end{macrocode}
%
-%
-% \begin{macro}{\@@_start_para_structure:n}
-%
% \begin{macrocode}
-\cs_new_protected:Npn \@@_start_para_structure:n #1 {
- \@@_debug_typeout:n
- { @endpe = \legacy_if:nTF { @endpe }{true}{false}
- \on@line }
- \legacy_if:nF { @endpe }
- {
- \bool_if:NF \l__tag_para_flattened_bool
- {
- \__tag_gincr_para_main_begin_int:
- \tag_struct_begin:n
- {
- tag=\l__tag_para_main_tag_tl,
- attribute-class=\l__tag_para_main_attr_class_tl,
- }
- \__tag_para_main_store_struct:
- }
- }
- \__tag_gincr_para_begin_int:
- \@@_debug_typeout:n{increment~ P \on@line }
- \tag_struct_begin:n
- {
- tag=\l__tag_para_tag_tl
- ,attribute-class=\l__tag_para_attr_class_tl
- }
- \__tag_check_para_begin_show:nn {green}{#1}
- \tag_mc_begin:n {}
-}
-% \end{macrocode}
-% The same code, but without testing \texttt{@endpe}. This is not
-% needed in the standalone case and wrong inside lists.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_start_para_structure_unconditionally:n #1 {
- \bool_if:NF \l__tag_para_flattened_bool
- {
- \__tag_gincr_para_main_begin_int:
- \tag_struct_begin:n
- {
- tag=\l__tag_para_main_tag_tl,
- attribute-class=\l__tag_para_main_attr_class_tl,
- }
- \__tag_para_main_store_struct:
- }
- \__tag_gincr_para_begin_int:
- \@@_debug_typeout:n{increment~ P \on@line }
- \tag_struct_begin:n
- {
- tag=\l__tag_para_tag_tl
- ,attribute-class=\l__tag_para_attr_class_tl
- }
- \__tag_check_para_begin_show:nn {green}{#1}
- \tag_mc_begin:n {}
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macrocode}
-\RemoveFromHook{para/end}[tagpdf]
-\AddToHook{para/end}
- {
- \bool_if:NT \l__tag_para_bool
- {
- \__tag_gincr_para_end_int:
- \@@_debug_typeout:n{increment~ /P \on@line }
- \tag_mc_end:
- \__tag_check_para_end_show:nn {red}{}
- \tag_struct_end:
- \bool_if:NF \l__tag_para_flattened_bool
- {
- \__tag_gincr_para_main_end_int:
- \tag_struct_end:
- }
- }
- }
-% \end{macrocode}
-%
-% \begin{macrocode}
-\def\PARALABEL{NP-}
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{\para_end:}
-% If we see a \cs{par} in vmode and a \texttt{text-unit} is still open
-% we need to close that. For this we check if a request for
-% \text{@endpe} was made (but the \cs{par} redefinition got lost
-% due to (bad?) coding).
-% \begin{macrocode}
-\cs_set_protected:Npn \para_end: {
- \scan_stop:
- \mode_if_horizontal:TF {
- \mode_if_inner:F {
- \tex_unskip:D
- \hook_use:n{para/end}
- \@kernel@after@para@end
- \mode_if_horizontal:TF {
- \if_int_compare:w 11 = \tex_lastnodetype:D
- \tex_hskip:D \c_zero_dim
- \fi:
- \tex_par:D
- \hook_use:n{para/after}
- \@kernel@after@para@after
- }
- { \msg_error:nnnn { hooks }{ para-mode }{end}{horizontal} }
- }
- }
- {
- \__kernel_endpe_vmode: % should do nothing if no tagging
- \tex_par:D
- }
-}
-\cs_set_eq:NN \par \para_end:
-\cs_set_eq:NN \@@par \para_end:
-\cs_set_eq:NN \endgraf \para_end:
-% \end{macrocode}
-%
-% \end{macro}
-%
-%
-% \begin{macro}{\begin}
-% We need to do a little more than canceling \texttt{@endpe} now.
-% \begin{macrocode}
-\DeclareRobustCommand*\begin[1]{%
- \UseHook{env/#1/before}%
- \@ifundefined{#1}%
- {\def\reserved@a{\@latex@error{Environment~#1~undefined}\@eha}}%
- {\def\reserved@a{\def\@currenvir{#1}%
- \edef\@currenvline{\on@line}%
- \@execute@begin@hook{#1}%
- \csname #1\endcsname}}%
- \@ignorefalse
- \begingroup
- \__kernel_endpe_vmode:
- \reserved@a}
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{\__kernel_endpe_vmode:}
-% Close an open \texttt{text-unit} if \texttt{@endpe} is true and we
-% are in vmode. Used in \cs{para_end:} and \cs{begin}.
-% \begin{macrocode}
-\cs_new:Npn \__kernel_endpe_vmode: {
- \if@endpe \ifvmode
- \bool_if:NT \l__tag_para_bool
- {
- \bool_if:NF \l__tag_para_flattened_bool
- {
- \__tag_gincr_para_main_end_int:
- \tag_struct_end:
- }
- \@endpefalse
- }
- \fi \fi
-}
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{\__kernel_list_label_after:}
-% If starting the text-unit/text tags got delayed because of a pending label we
-% have to do it after the label got typeset
-% \begin{macrocode}
-\cs_set:Npn \__kernel_list_label_after: {
- \bool_if:NT \l__tag_para_bool
- {
- \@@_start_para_structure_unconditionally:n { LI- }
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{\@@_inner_begin:}
-% Start a block that has an inner structure if it isn't also a list.
-% \begin{macrocode}
-\cs_new:Npn \@@_inner_begin: {
- \tagstructbegin{tag=\l_@@_tag_inner_tag_tl}
-}
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{\@@_inner_end:}
-% End a block (which isn't also a list).
-% \begin{macrocode}
-\cs_new:Npn \@@_inner_end: {
- \@@_debug_typeout:n{block-end \on@line}
- \legacy_if:nT { @endpe }
- {
- \__tag_gincr_para_main_end_int:
- \@@_debug_typeout:n{close~ /text-unit \on@line}
- \tagstructend
- }
- \tagstructend % end inner structure
-}
-% \end{macrocode}
-% \end{macro}
-%
-%
-%
-%
-%
-%
-% \subsubsection{List tags}
-%
-%
-% \begin{macrocode}
-\tl_new:N \l__tag_L_tag_tl
-\tl_set:Nn \l__tag_L_tag_tl {L}
-
-\tl_new:N\l__tag_L_attr_class_tl
-\tl_set:Nn \l__tag_L_attr_class_tl {list}
-% \end{macrocode}
-%
-% \begin{macrocode}
-\tag_if_active:T
-{
- \tagpdfsetup
- {
- role/new-attribute = {itemize}{/O /List /ListNumbering/Unordered},
- role/new-attribute = {enumerate}{/O /List /ListNumbering/Ordered},
- role/new-attribute = {description}{/O /List /ListNumbering/Description},
-% \end{macrocode}
-% Initially, we had \texttt{/None} for the basic \env{list}
-% environment, but that is not allowed in PDF/UA-2 if the list
-% contains any Lbl tags. So now we default to
-% \texttt{Unordered}.
-% \begin{macrocode}
- % default if unknown
- role/new-attribute = {list}{/O /List /ListNumbering/Unordered},
- }
-}
-% \end{macrocode}
-%
-% \begin{macrocode}
-\def\LItag{LI}
-% \end{macrocode}
-%
-% \begin{macro}{\@@_list_begin:}
-% Start a list \ldots
-% \begin{macrocode}
-\cs_set:Npn \@@_list_begin: {
- \tagstructbegin
- {
- tag=\l__tag_L_tag_tl
- ,attribute-class=\l__tag_L_attr_class_tl
- }
-}
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_list_item_begin:}
-% Start tagging a list item.
-% \begin{macrocode}
-\cs_set:Npn \@@_list_item_begin: { \tagstructbegin{tag=\LItag} }
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{\__kernel_list_label_begin:}
-% A list label needs a \texttt{Lbl} structure tag and an MC.
-% \begin{macrocode}
-\cs_set:Npn \__kernel_list_label_begin: {
-%
-% FMi: this needs a different logic to decide when to make the label
-% an artifact (after cleaning up the \item code ), therefore
-% disabled for now
-% \tl_if_empty:oTF \@itemlabel
-% {
-% \tag_mc_begin:n {artifact}
-% }
-% {
- \tagstructbegin{tag=Lbl}
- \tagmcbegin{tag=Lbl}
-% }
-}
-% \end{macrocode}
-% \end{macro}
-%
-%
-%
-% \begin{macro}{\__kernel_list_label_end:}
-% And when we are done with the label we have to close the MC and
-% the \texttt{Lbl} structure. We then start the \texttt{LBody}. The
-% material inside will be \enquote{paragraph} text and the tagging
-% for that is handled by the normal para tagging.
-% \begin{macrocode}
-\cs_set:Npn \__kernel_list_label_end: {
- \tagmcend % end mc-Lbl or artifact
-% FMi: unconditionally for now
-% \tl_if_empty:oF \@itemlabel
- \tagstructend % end Lbl
- \tagstructbegin{tag=\LBody}
-}
-\def\LBody{LBody}
-% \end{macrocode}
-% \end{macro}
-%
-%
-%
-% \begin{macro}{\@@_list_item_end:}
-% When a list item ends we have to close \texttt{LBody} and
-% \texttt{LI} but also a \struct{text} in the special case that the
-% item material ends in a list (identifiable via \texttt{@endpe}).
-% \begin{macrocode}
-\cs_set:Npn \@@_list_item_end: {
- \legacy_if:nT { @endpe }
- {
- \__tag_gincr_para_main_end_int:
- \tagstructend % text-unit
-% \@@_debug_typeout:n{Structure-end~ P~ at~ item-end \on@line }
- }
- \tagstructend \tagstructend % end LBody, LI
-}
-% \end{macrocode}
-% \end{macro}
-%
-%
-%
-% \begin{macro}{\@@_list_end:}
-% Finally, at the list end we have to close the open
-% \texttt{LBody}, \texttt{LI}, \texttt{L}, and possibly a
-% \struct{text} if the last item ends with a list.
-% \begin{macrocode}
-\cs_set:Npn \@@_list_end: {
- \legacy_if:nT { @endpe }
- {
- \__tag_gincr_para_main_end_int:
- \tagstructend % text-unit
- \@@_debug_typeout:n{Structure-end~ P~ at~ list-end \on@line }
- }
- \tagstructend\tagstructend % end LBody, LI
- \tagstructend % end L
-}
+\justifying
% \end{macrocode}
% \end{macro}
-% End of tagging related declarations.
-% \begin{macrocode}
-}
-% \end{macrocode}
-% These command should have a dummy declaration if tagging is not active
-% \begin{macrocode}
-{
- \cs_new:Npn \@@_start_para_structure_unconditionally:n #1 {}
-}
-% \end{macrocode}
-%
%
%
-%
-%
-%
%
%
%
@@ -3966,6 +4284,7 @@
%
% \end{implementation}
%
+% \appendix
%
% \section{Documentation from first prototype implementations}
%
@@ -3977,10 +4296,11 @@
%
% \subsection{Code cleanup}
% \begin{itemize}
+% \raggedright
% \item Actually implement what's announced.
%
% \item Encapsulate most uses of \cs[no-index]{legacy_if\dots} into
-% commands with \texttt{expl3} syntax: we cannot rename these booleans
+% commands with \pkg{expl3} syntax: we cannot rename these booleans
% for compatibility reasons but we can make the code cleaner
% nevertheless. --- made issue ---
%
@@ -4015,8 +4335,8 @@
%
% \item Add key--value settings mimicking \pkg{enumitem}'s ability to
% set any four of five horizontal parameters and deduce the fifth by
-% $\cs{leftmargin} + \cs{itemindent} = \cs{labelindent} +
-% \cs{labelwidth} + \cs{labelsep}$.
+% $\tn{leftmargin} + \tn{itemindent} = \tn{labelindent} +
+% \tn{labelwidth} + \tn{labelsep}$.
%
% \item Provide good ways to customize how overlong labels are dealt with.
%
@@ -4066,8 +4386,8 @@
% horizontal spacing around it. This type of layout is shared with
% environments such as \texttt{quote}, \texttt{flushright}, or
% \texttt{tabbing}. This common layout is implemented in \LaTeXe{}
-% through \cs{trivlist} (or \cs{list}).
-% \item It defines how each \cs{item} should be typeset: how to
+% through \tn{trivlist} (or \tn{list}).
+% \item It defines how each \tn{item} should be typeset: how to
% construct the label, in particular the \texttt{counter} name, and
% how to format the content of the item.
% \end{itemize}
@@ -4093,6 +4413,7 @@
% run-in lists.} that omits the \texttt{heading} parameter and whose
% default for \texttt{item-instance} is non-empty.
% \begin{itemize}
+% \raggedright
% \item Structural parameters: the \texttt{heading} to place before,
% \texttt{counter} name, \texttt{start} value, whether to
% \texttt{resume} a previous list, and the \texttt{item-instance} (an
@@ -4145,7 +4466,7 @@
% \texttt{label-strut} boolean.
% \item Label alignment (\texttt{label-align}, \texttt{label-boxed},
% \texttt{next-line}).
-% \item Content parameters: \texttt{text-font}.
+% \item Content parameters: \key{text-font}.
% \item A \texttt{compatibility} boolean that controls for instance
% whether \tn{makelabel} is used.
% \end{itemize}
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-block.pdf b/macros/latex-dev/required/latex-lab/latex-lab-block.pdf
index d13acb45d3..59aa1c08a0 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-block.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-block.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-firstaid.dtx b/macros/latex-dev/required/latex-lab/latex-lab-firstaid.dtx
index ce0d46f815..a5c44b8241 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-firstaid.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-firstaid.dtx
@@ -16,8 +16,8 @@
%
% for those people who are interested or want to report an issue.
%
-\def\ltlabfirstaiddate{2024-05-25}
-\def\ltlabfirstaidversion{0.85d}
+\def\ltlabfirstaiddate{2024-11-23}
+\def\ltlabfirstaidversion{0.85i}
%<*driver>
\documentclass{l3doc}
\EnableCrossrefs
@@ -53,7 +53,9 @@
%
% Similar to the main firstaid package the goal is to remove the
% patches once the packages have been updated.
-
+%
+% \changes{v0.85g}{2024/10/04}{Removed firstaid for blindtext. No longer needed with new doenpe-code.}
+% \changes{v0.85g}{2024/10/04}{Added firstaid for fancyvrb.}
% \section{Implementation}
%
% \begin{macrocode}
@@ -87,12 +89,11 @@
} }
\exp_args:Ncx\str_if_eq:onT{ver@#1.#2}{#3}
}
-\ExplSyntaxOff
% \end{macrocode}
% \end{macro}
% \subsection{ams classes}
-% The amsart and amsbook classes do not use \cs{@author} to store the author list
+% The amsart, amsbook and amsproc classes do not use \cs{@author} to store the author list
% but a command \cs{authors}. To be able to nevertheless use the authors in the
% xmp-metadata we map \cs{@author} to this new command.
%
@@ -101,9 +102,182 @@
{\def\@author{\authors}}
\AddToHook{class/amsbook/after}
{\def\@author{\authors}}
+\AddToHook{class/amsproc/after}
+ {\def\@author{\authors}}
% \end{macrocode}
%
+% \subsection{ams classes and amsthm}
+% The amsart, amsbook and amsproc classes redefine the theorem code
+% and this breaks the tagging added by the block code. The following
+% reenables tagging. It does \emph{not} give a completly identical output
+% (similar to the new theorem code,
+% see \url{https://github.com/latex3/tagging-project/issues/715}).
+% The code also does not try to use sockets yet, as the theorem definitions
+% in the block code don't do that yet either.
%
+% \begin{macrocode}
+\AddToHook{class/amsart/after}[latex-lab-testphase-firstaid/amsthm]
+ {\tag_if_active:T{\@@_firstaid_amsthm:}}
+\AddToHook{class/amsbook/after}[latex-lab-testphase-firstaid/amsthm]
+ {\tag_if_active:T{\@@_firstaid_amsthm:}}
+\AddToHook{class/amsproc/after}[latex-lab-testphase-firstaid/amsthm]
+ {\tag_if_active:T{\@@_firstaid_amsthm:}}
+\AddToHook{package/amsthm/after}[latex-lab-testphase-firstaid/amsthm]
+ {\tag_if_active:T{\@@_firstaid_amsthm:}}
+% \end{macrocode}
+% \changes{v0.85h}{2024/10/16}{moved Caption tag into \@begintheorem, tagging issue\#733}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_firstaid_amsthm:
+ {
+% \end{macrocode}
+% \cs{@endtheorem} must use the endblock code
+% \begin{macrocode}
+ \def\@endtheorem{\endblockenv}
+% \end{macrocode}
+% In \cs{@thm} we have to remove the \cs{trivlist}
+% \begin{macrocode}
+ \RenewDocumentCommand\@thm{mmmO{}}{%
+ \ifhmode\unskip\unskip\par\fi
+ \normalfont
+ \let\thmheadnl\relax
+ \let\thm@swap\@gobble
+ \thm@notefont{\fontseries\mddefault\upshape}%
+ \thm@headpunct{.}% add period after heading
+ \thm@headsep 5\p@ plus\p@ minus\p@\relax
+ \thm@space@setup
+ ##1% style overrides
+ \@topsep \thm@preskip % used by thm head
+ \@topsepadd \thm@postskip % used by \@endparenv
+% \end{macrocode}
+% We store the counter name so that the anchor can make use of it.
+% \begin{macrocode}
+ \tl_set:Nn \l__block_thm_current_counter_tl{##2}
+ \tl_if_empty:nTF{##2}
+ {
+ \@begintheorem{##3}{}[##4]
+ }
+ {
+ \@kernel@refstepcounter{##2}
+ \@begintheorem{##3}{\csname the##2\endcsname}[##4]
+ }
+ }
+% \end{macrocode}
+% \cs{@begintheorem} has a larger number of changes
+% \begin{macrocode}
+ \def\@begintheorem##1##2[##3]{%
+% \end{macrocode}
+% We use the theorem instance.
+% \changes{v0.85h}{2024/10/16}{Added pre and post skips tagging/733}
+% \begin{macrocode}
+ \UseInstance{blockenv}{theorem}{beginsep=\thm@preskip}
+% \end{macrocode}
+% There is no working key to set the endskip, so we set the skip directly
+% similar to what amsthm is doing after the \cs{trivlist}.
+% \begin{macrocode}
+ \skip_set:Nn\l__block_topsepadd_skip { \thm@postskip }
+% \end{macrocode}
+% While create the caption/label we disable para-tagging.
+% \begin{macrocode}
+ \tagpdfparaOff
+ \group_begin:
+ \normalfont
+ \the\thm@headfont \thm@indent
+% \end{macrocode}
+% The anchor for links. It must be inserted when we have started hmode
+% (which happens with \cs{thm@indent}). \pkg{amsthm} allows for unnumbered
+% theorems so we have to test for an empty counter.
+% \changes{v0.85h}{2024/10/16}{add test if counter is empty
+% tagging/736}
+% \changes{v0.85i}{2024/11/23}{Do not use \cs{leavevmode} but wait
+% for hmode to add the link target}
+% \begin{macrocode}
+ \tl_if_empty:NTF \l__block_thm_current_counter_tl
+ {\MakeLinkTarget[theorem]{}}
+ {\MakeLinkTarget{\l__block_thm_current_counter_tl}}
+ \@ifempty{##1}
+ {\let\thmname\@gobble}
+% \end{macrocode}
+% we insert the MC and the Lbl structure into \cs{thmname},
+% \cs{thmnumber} and \cs{thmnote}. This will also work
+% with new theorem style as long as they use these command.
+% \begin{macrocode}
+ {\def\thmname####1{\tag_mc_begin:n {}####1\tag_mc_end:}}%
+ \@ifempty{##2}
+ {\let\thmnumber\@gobble}
+ {\def\thmnumber####1
+ {\tag_struct_begin:n{tag=Lbl}\tag_mc_begin:n {}
+ ####1
+ \tag_mc_end:\tag_struct_end:}}%
+ \@ifempty{##3}
+ {\let\thmnote\@gobble}
+ {\def\thmnote####1{\tag_mc_begin:n{}####1\tag_mc_end:}}%
+ \tag_struct_begin:n{tag=Caption}
+ \thm@swap\swappedhead\thmhead{##1}{##2}{##3}%
+ \tag_mc_begin:n{}\the\thm@headpunct\tag_mc_end:
+ \tag_struct_end:
+ \thmheadnl % possibly a newline.
+ \hskip\thm@headsep
+ \group_end:
+% \end{macrocode}
+% Now we restart para tagging and start a paragraph. The socket
+% is currently defined in tagpdf, so the code should only
+% be used if tagging is active!
+% \begin{macrocode}
+ \tagpdfparaOn
+ \UseTaggingSocket{para/begin}
+ \ignorespaces}
+% \end{macrocode}
+% This redefines the standard styles for the theorem heads.
+% \cs{thm@headpunct} has been moved into the head code
+% to make tagging more easier.
+% \begin{macrocode}
+ \def\thmhead@plain##1##2##3{%
+ \thmname{##1}
+ \thmnumber{
+ \@ifnotempty{##1}{~}\@upn{##2}
+ }%
+ \thmnote{\pdffakespace\space{\the\thm@notefont(##3)}}
+ }
+ \let\thmhead\thmhead@plain
+ \def\swappedhead##1##2##3{%
+ \thmnumber{##2}
+ \thmname{\@ifnotempty{##2}{\nobreakspace}##1}
+ \thmnote{\pdffakespace\space{\the\thm@notefont(##3)}}
+ }
+ \let\swappedhead@plain=\swappedhead
+% \end{macrocode}
+% At last some adjustments for the proof environment.
+% The qed symbols use a drawn box by default. We add an actualtext.
+% \begin{macrocode}
+ \renewcommand{\openbox}{\leavevmode
+ \hbox to.77778em{\pdf_bdc:nn{Span}{/ActualText<FEFF220E>}%
+ \pdffakespace\hfil\vrule
+ \vbox to.675em{\hrule width.6em\vfil\hrule}%
+ \vrule\hfil\pdf_emc:}}
+% \end{macrocode}
+% And redefine proof to no longer use a trivlist.
+% \begin{macrocode}
+ \renewenvironment{proof}[1][\proofname]{\par
+ \pushQED{\qed}%
+ \UseInstance{blockenv}{theorem}{beginsep=6\p@\@plus6\p@}
+ \normalfont
+ \tagpdfparaOff
+ \AddToHookNext{para/begin}
+ {\tag_struct_begin:n{tag=Caption}
+ \tag_mc_begin:n{}%
+ \textit{##1\@addpunct{.}}%
+ \tag_mc_end:
+ \tag_struct_end:
+ \tagpdfparaOn
+ \UseTaggingSocket{para/begin}
+ \pdffakespace\hspace{\labelsep}}
+ \ignorespaces
+ }{%
+ \popQED\endblockenv\par
+ }
+ }
+\ExplSyntaxOff
+% \end{macrocode}
%
% \subsection{verse}
%
@@ -210,54 +384,12 @@
%\end{verbatim}
%
%
-% \subsection{blindtext}
-%
-% The blindtext package generates lists with nested \cs{loop} command.
-% The inner loop introduces a group around the list which error when lists are tagged
-% as \cs{@doendpe} is lost.
-% \begin{macrocode}
-\AddToHook{file/blindtext.sty/after}[latex-lab-firstaid]{%
- \FirstAidNeededT{blindtext}{sty}{\blindfiledate\space\blindfileversion\space%
- blindtext-Package}%
- {%
- \renewcommand{\blind@items}{%
- \setcounter{blind@listcount}{1}%
- \loop
- \ifblind@optional
- \ifblind@long
- \item[\blindtext@countitem] \blindtext@text
- \else
- \item[\blindtext@count] \blindtext@item
- \fi
- \else % \blind@optionalfalse
- \ifblind@long
- \item \blindtext@text
- \else
- \item \blindtext@countitem
- \fi
- \fi % \ifblind@optional
- {%
- \loop
- \ifnum\value{blindlistlevel}>\value{blindlist@level}%
- \stepcounter{blind@levelcount}%
- \blind@list[\value{blindlist}]\relax
- \addtocounter{blind@levelcount}{-1}%
- \setcounter{blind@listcount}{1}%
- \repeat
- \expandafter}\if@endpe\@doendpe\fi % <----------changed
- \ifnum\value{blind@listcount}<\value{blindlist}%
- \stepcounter{blind@listcount}%
- \repeat
- }
- }%
- }
-% \end{macrocode}
-%
-%
% \subsection{cleveref}
%
% The cleveref package redefines \cs{@makefntext} and this means that the patches in
-% the new footnote code fails. We use a hook instead
+% the new footnote code fails. We use a hook instead.
+% \changes{v0.85h}{2024/10/16}{Remove redefinition of refstepcounter. It no longer uses
+% the hook.}
% \begin{macrocode}
\AddToHook{package/cleveref/after}
{
@@ -267,16 +399,6 @@
\protected@edef\cref@currentlabel{%
[footnote][\arabic{footnote}][\cref@result]%
\p@footnote\@thefnmark}}
-% \end{macrocode}
-% The second problem is that it redefines \cs{refstepcounter} to use an argument.
-% In itself this isn't a problem but as the new definition doesn't grab the arguments
-% directly it fails over the generic hook inserted at the end of the definition
-% \begin{macrocode}
- \RenewDocumentCommand\refstepcounter{om}{%
- \IfNoValueTF{#1}%
- {\refstepcounter@noarg{#2}}%
- {\refstepcounter@optarg[#1]{#2}}%
- }%
}
% \end{macrocode}
%
@@ -290,6 +412,7 @@
% See also issue \url{https://github.com/latex3/tagging-project/issues/69}
%
%
+% \begin{macrocode}
\ExplSyntaxOn
\AddToHook{package/booktabs/after}
{
@@ -314,8 +437,145 @@
\tag_mc_end: \int_gdecr:N \g__tbl_row_int
\cr}
}
-\ExplSyntaxOff
+\ExplSyntaxOff
+% \end{macrocode}
+
%
+% \subsection{fancyvrb}
+% The firstaid adds first partial tagging support to the environments
+% of fancyvrb (inline verbatim is untested).
+% This supports then also packages like minted which internally uses fancyvrb
+% and classes like l3doc (where currently the verbatim environment based on fancyvrb
+% is overwritten by the block code).
+% The environments are surrounded by a \texttt{verbatim} structure,
+% every line by a \texttt{codeline}
+% structure (this requires the block code, but firstaid should be used only with
+% phase-III anyway). Line numbers are tagged as Lbl, currently outside of the
+% \texttt{codeline} structure. The frame lines are marked as artifact.
+%
+% \begin{macro}{\FV@LeaveVMode}
+% If we are in vmode we have to open a text-unit structure, if we are
+% in hmode we have to set para mode to flattened before the fancyhdr code
+% issues the\cs{par}. The closing of the text-unit structure is handled by the
+% doendpe code in the block code.
+% \begin{macrocode}
+\ExplSyntaxOn
+\AddToHook{package/fancyvrb/after}
+{
+ \def\FV@LeaveVMode{%
+ \if@noskipsec
+ \leavevmode
+ \else
+ \if@FV@ResetMargins\if@inlabel\leavevmode\fi\fi
+ \fi
+ \ifvmode
+ \@noparlisttrue
+ \__tag_gincr_para_main_begin_int:
+ \tag_struct_begin:n{tag=\l__tag_para_main_tag_tl}
+ \else
+ \bool_set_true:N\l__tag_para_flattened_bool
+ \@noparlistfalse
+ \unskip\par
+ \fi
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\FV@List}
+% At the begin of the list code we have to tag the frame as artifact
+% and start the \texttt{verbatim} structure
+% \begin{macrocode}
+ \def\FV@List#1{%
+ \begingroup
+ \FV@UseKeyValues
+ \FV@LeaveVMode
+ \if@inlabel\else\setbox\@labels=\box\voidb@x\fi
+ \FV@ListNesting{#1}%
+ \FV@ListParameterHook
+ \FV@ListVSpace
+ \FV@SetLineWidth
+ \FV@InterLinePenalty
+ \let\FV@ProcessLine\FV@ListProcessLine@i
+ \FV@CatCodes
+ \FV@FormattingPrep
+ \FV@ObeyTabsInit
+ \cs_if_exist:NT \FV@BeginListFrame
+ {
+ \tag_mc_begin:n{artifact}
+ \FV@BeginListFrame
+ \tag_mc_end:
+ }
+ \tag_struct_begin:n{tag=verbatim}
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}{\FV@EndList}
+% At the end of the list code we close the \texttt{verbatim} structure and
+% tag the frame as artifact.
+% \begin{macrocode}
+ \def\FV@EndList{%
+ \FV@ListProcessLastLine
+ \tag_struct_end:
+ \cs_if_exist:NT \FV@EndListFrame
+ {
+ \tag_mc_begin:n{artifact}
+ \FV@EndListFrame
+ \tag_mc_end:
+ }
+ \@endparenv
+ \endgroup
+ \@endpetrue
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\FV@ListProcessLine}
+% At last the tagging of the code lines. Here we have to tag also
+% numbers and frame parts if they exist.
+% \begin{macrocode}
+ \def\FV@ListProcessLine#1{%
+ \hbox to \hsize{%
+ \kern\leftmargin
+ \hbox to \linewidth{%
+ \cs_if_exist:NT \FV@LeftListNumber
+ {
+ \tag_struct_begin:n{tag=Lbl}
+ \tag_mc_begin:n{}
+ \FV@LeftListNumber
+ \tag_mc_end:
+ \tag_struct_end:
+ }
+ \cs_if_exist:NT \FV@LeftListFrame
+ {
+ \tag_mc_begin:n{artifact}
+ \FV@LeftListFrame
+ \tag_mc_end:
+ }
+ \tag_struct_begin:n{tag=codeline}
+ \tag_mc_begin:n{}%
+ \FancyVerbFormatLine{#1}%
+ \tag_mc_end:
+ \tag_struct_end:\hss
+ \cs_if_exist:NT \FV@RightListFrame
+ {
+ \tag_mc_begin:n{artifact}
+ \FV@RightListFrame
+ \tag_mc_end:
+ }
+ \cs_if_exist:NT \FV@RightListNumber
+ {
+ \tag_struct_begin:n{tag=Lbl}
+ \tag_mc_begin:n{}
+ \FV@RightListNumber
+ \tag_mc_begin:n{}
+ \tag_struct_end:
+ }
+ }
+ \hss}}
+ }
+\ExplSyntaxOff
+% \end{macrocode}
+% \end{macro}
% \begin{macrocode}
%</package>
% \end{macrocode}
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-firstaid.pdf b/macros/latex-dev/required/latex-lab/latex-lab-firstaid.pdf
index c035081f6b..11345681be 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-firstaid.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-firstaid.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-float.dtx b/macros/latex-dev/required/latex-lab/latex-lab-float.dtx
index a817133713..0bbf7b7eb6 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-float.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-float.dtx
@@ -16,8 +16,8 @@
%
% for those people who are interested or want to report an issue.
%
-\def\ltlabfloatdate{2024-03-23}
-\def\ltlabfloatversion{0.81e}
+\def\ltlabfloatdate{2024-11-21}
+\def\ltlabfloatversion{0.81g}
%<*driver>
\documentclass{l3doc}
\EnableCrossrefs
@@ -43,6 +43,9 @@
% customizations}}
%
% \providecommand\hook[1]{\texttt{#1}}
+% \ProvideDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl}
+% \ProvideDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl}
+%
% \begin{documentation}
% \begin{abstract}
% The following code implements a first draft for the tagging of float
@@ -64,7 +67,7 @@
%
% A special type, called a H-float, (provided by the float package)
% is always placed in the main text stream and does not
-% necessarly preserve the order with normal floats of the same type: It is basically
+% necessarily preserve the order with normal floats of the same type: It is basically
% a minipage with a caption.
%
% Floats typically contain a figure (or a table, etc.) and a caption,
@@ -125,7 +128,10 @@
%
% \section{Kernel commands}
% \begin{function}{\@current@float@struct}
-% This variable holds the structure number of current float structure.
+% This variable holds the number of the current float structure. With tagging
+% this is the structure number, without tagging a unique counter. A float
+% can contain more than one float structure (e.g. if there is more than one
+% caption).
% \end{function}
%
% \begin{function}{\@makecaption}
@@ -146,22 +152,28 @@
{Code related to the tagging of floats}
% \end{macrocode}
% \subsection{Variables}
-% We rolemap to float to Aside, and float sections to Sect.
+% We rolemap floats to Aside, and float sections to Sect.
%
% \begin{variable}{
% \g_@@_float_sect_prop,
% \g_@@_float_types_seq,
-% \@current@float@struct
+% \@current@float@struct,
+% \g_@@_float_int
% }
% These variables will hold the structure number for the float container
% and the list of float types. Currently only figure and table are supported
% TODO: interface to declare new float types.
+% To set the target for links we need also a unique counter.
+% With tagging we could use the structure number, but
+% the structure commands now are hidden inside tagging sockets
+% so we use a dedicated counter.
% \begin{macrocode}
\prop_new:N \g_@@_float_sect_prop
\seq_new:N \g_@@_float_types_seq
\seq_gput_right:Nn \g_@@_float_types_seq {figure}
\seq_gput_right:Nn \g_@@_float_types_seq {table}
\tl_new:N\@current@float@struct
+\int_new:N\g_@@_float_int
% \end{macrocode}
% \end{variable}
%
@@ -176,6 +188,19 @@
% \end{macrocode}
% \end{variable}
%
+% \begin{macro}{\@@_float_init:}
+% To be able to set unique targets for links, we
+% need a counter outside the tagging sockets.
+% TODO: check if this command should be public or
+% a socket or a hook.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_float_init:
+ {
+ \int_gincr:N \g_@@_float_int
+ \tl_set:Ne \@current@float@struct { \int_use:N \g_@@_float_int}
+ }
+% \end{macrocode}
+% \end{macro}
%
%\subsection{Moving float structures}
%
@@ -260,15 +285,71 @@
{
split-float .code:n =
{
- \@@_float_end:
- \@@_float_begin:
- \MakeLinkTarget*{floatstructure.\int_use:N\c@g__tag_struct_abs_int}
+ \UseTaggingSocket{float/end}
+ \@@_float_init:
+ \UseTaggingSocket{float/begin}
+ \MakeLinkTarget*{floatstructure.\@current@float@struct}
}
}
% \end{macrocode}
% \end{macro}
-
-% \subsection{Patching}
+%
+% \subsection{Tagging sockets}
+% For now we test if the sockets are already defined
+% \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/float/begin_plug_str }
+ {
+ \NewSocket{tagsupport/float/hmode/begin}{0}
+ \NewSocket{tagsupport/float/hmode/end}{0}
+ \NewSocket{tagsupport/float/begin}{0}
+ \NewSocket{tagsupport/float/end}{0}
+ }
+% \end{macrocode}
+%
+% \begin{plugdecl}{default (tagsupport/float/hmode/begin)}
+% This plug should be used if a float is called in hmode.
+% In then closes the MC-chunks and starts the structure.
+% \begin{macrocode}
+\NewSocketPlug {tagsupport/float/hmode/begin}{default}
+ {
+ \@@_float_stop_par:
+ }
+\AssignSocketPlug{tagsupport/float/hmode/begin}{default}
+% \end{macrocode}
+% \end{plugdecl}
+%
+% \begin{plugdecl}{default (tagsupport/float/hmode/end)}
+% This plug should be used if a float is called in hmode
+% and the end of the float it then restarts the MC.
+% \begin{macrocode}
+\NewSocketPlug{tagsupport/float/hmode/end}{default}
+ {
+ \@@_float_start_par:
+ }
+\AssignSocketPlug{tagsupport/float/hmode/end}{default}
+% \end{macrocode}
+% \end{plugdecl}
+%
+% \begin{plugdecl}{default (tagsupport/float/begin)}
+% \begin{macrocode}
+\NewSocketPlug{tagsupport/float/begin}{default}
+ {
+ \@@_float_begin:
+ }
+\AssignSocketPlug{tagsupport/float/begin}{default}
+% \end{macrocode}
+% \end{plugdecl}
+%
+% \begin{plugdecl}{default (tagsupport/float/end)}
+% \begin{macrocode}
+\NewSocketPlug{tagsupport/float/end}{default}
+ {
+ \@@_float_end:
+ }
+\AssignSocketPlug{tagsupport/float/end}{default}
+% \end{macrocode}
+% \end{plugdecl}
+%
% \begin{macro}{\@@_float_stop_par:,\@@_float_start_par:}
% if a float is in a par, we need commands to stop and restart the P-mc
% \begin{macrocode}
@@ -287,8 +368,7 @@
\tag_struct_begin:n{tag=text}%
}
\tag_mc_begin:n{tag=P}
- }
-
+ }
% \end{macrocode}
% \end{macro}
% These commands are the main commands to start and end the float tagging.
@@ -315,6 +395,7 @@
\cs_new_protected:Npn\@@_float_end:{\tag_struct_end:} %end Aside
% \end{macrocode}
+% \subsection{Patching}
% This patches the main command \cs{@xfloat}.
% There is a : in the code, so we disable expl3 syntax
% \begin{macrocode}
@@ -337,7 +418,7 @@
% \end{macrocode}
% If the float is in hmode we have to interrupt the P
% \begin{macrocode}
- \@nameuse{@@_float_stop_par:}% <---end P
+ \UseTaggingSocket{float/hmode/begin}%
\@floatpenalty -\@Mii
\else
\@floatpenalty-\@Miii
@@ -383,7 +464,8 @@
% \end{macrocode}
% This starts the structure for the float.
% \begin{macrocode}
- \@nameuse{@@_float_begin:}%
+ \csname @@_float_init:\endcsname
+ \UseTaggingSocket{float/begin}%
\global \setbox\@currbox
\color@vbox
\normalcolor
@@ -394,14 +476,14 @@
% \end{macrocode}
% We add a target for links. TODO: check that it doesn't affect spacing!!
% \begin{macrocode}
- \MakeLinkTarget*{floatstructure.\number\value{g__tag_struct_abs_int}}%
+ \MakeLinkTarget*{\@captype.struct.\@current@float@struct}%
}%
% \end{macrocode}
% The end code of the float ...
% \begin{macrocode}
\def\end@float{%
\@endfloatbox
- \@nameuse{@@_float_end:}%
+ \UseTaggingSocket{float/end}%
\ifnum\@floatpenalty <\z@
\@largefloatcheck
\@cons\@currlist\@currbox
@@ -413,7 +495,7 @@
\penalty\@floatpenalty
\else
\vadjust{\penalty -\@Miv \vbox{}\penalty\@floatpenalty}\@Esphack
- \@nameuse{@@_float_start_par:}% restart P safe here??
+ \UseTaggingSocket{float/hmode/end}%
\fi
\fi
}
@@ -423,7 +505,7 @@
\def\end@dblfloat{%
\if@twocolumn
\@endfloatbox
- \@nameuse{@@_float_end:}%
+ \UseTaggingSocket{float/end}%
\ifnum\@floatpenalty <\z@
\@largefloatcheck
\global\dp\@currbox1sp %
@@ -436,7 +518,7 @@
\penalty\@floatpenalty
\else
\vadjust{\penalty -\@Miv \vbox{}\penalty\@floatpenalty}\@Esphack
- \@nameuse{@@_float_start_par:}% restart P safe here??
+ \UseTaggingSocket{float/hmode/end}%
\fi
\fi
\else
@@ -453,10 +535,114 @@
\def\hyper@nopatch@caption{}
% \end{macrocode}
%
+% \subsubsection{(Tagging) sockets}
+%
+% First some temporary sockets.
+% These sockets are in lttagging.
+% \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/caption/begin_plug_str }
+ {
+ \NewSocket{tagsupport/caption/begin}{1}
+ \NewSocket{tagsupport/caption/end}{0}
+ \NewSocket{tagsupport/caption/label/begin}{0}
+ \NewSocket{tagsupport/caption/label/end}{0}
+ }
+% \end{macrocode}
+% These socket are currently defined in tagpdf.
+% \changes{v0.81g}{2024-11-21}{add missing argument to socket}
+% \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/para/begin_plug_str }
+ {
+ \NewSocket{tagsupport/para/begin}{0}
+ \NewSocket{tagsupport/para/end}{0}
+ }
+% \end{macrocode}
+%
+% \begin{socketdecl}{caption/label}
+% This socket is a lightweight start for
+% some interface to format the label or add a font command.
+% The argument is the label text.
+% The default plug \texttt{kernel} adds a colon
+% and a space.
+% TODO: revisit after checking float and caption packages
+% to identify which sockets and hooks are needed.
+% \begin{macrocode}
+\NewSocket{caption/label}{1}
+% \end{macrocode}
+% \end{socketdecl}
+%
+% \begin{plugdecl}{kernel (caption/label)}
+% The standard label formatting from the kernel.
+% \begin{macrocode}
+\NewSocketPlug{caption/label}{kernel}
+ {
+ #1:~
+ }
+\AssignSocketPlug{caption/label}{kernel}
+% \end{macrocode}
+% \end{plugdecl}
+% \begin{plugdecl}{default}
+% The caption begin socket takes an argument: the structure number of
+% the parent float. If the argument is empty, the current structure is used.
+% TODO: a tagpdf key that moves a structure to the begin of the parent.
+% The caption is moved to the first position with the firstkid option.
+% \begin{macrocode}
+\NewSocketPlug {tagsupport/caption/begin}{default}
+ {
+ \tl_if_empty:eTF {#1}
+ {
+ \tag_struct_begin:n{tag=Caption,firstkid}
+ }
+ {
+ \tag_struct_begin:n{tag=Caption,parent=#1,firstkid}
+ }
+ \bool_set_true:N \l__tag_para_flattened_bool
+ }
+\AssignSocketPlug{tagsupport/caption/begin}{default}
+% \end{macrocode}
+% \end{plugdecl}
+% \begin{plugdecl}{default}
+% \begin{macrocode}
+\NewSocketPlug {tagsupport/caption/end}{default}
+ {
+ \tag_struct_end:
+ }
+\AssignSocketPlug{tagsupport/caption/end}{default}
+% \end{macrocode}
+% \end{plugdecl}
+%
+% \begin{plugdecl}{default (tagsupport/caption/label/begin)}
+% \begin{macrocode}
+\NewSocketPlug {tagsupport/caption/label/begin}{default}
+ {
+% \end{macrocode}
+% suppress para tagging at the begin.
+% \begin{macrocode}
+ \tagpdfparaOff
+ \tag_struct_begin:n{tag=Lbl}
+ \tag_mc_begin:n{}
+ }
+\AssignSocketPlug{tagsupport/caption/label/begin}{default}
+% \end{macrocode}
+% \end{plugdecl}
+%
+% \begin{plugdecl}{default (tagsupport/caption/label/end)}
+% \begin{macrocode}
+\NewSocketPlug {tagsupport/caption/label/end}{default}
+ {
+ \tag_mc_end:
+ \tag_struct_end:
+ \tagpdfparaOn
+ }
+\AssignSocketPlug{tagsupport/caption/label/end}{default}
+% \end{macrocode}
+% \end{plugdecl}
+%
+% \subsubsection{Redefinitions}
+%
% With hyperref that means that the \cs{refstepcounter} now can affect spacing so we
% change that to the kernel refstepcounter:
% \begin{macrocode}
-\let\@kernel@refstepcounter\refstepcounter %as long it is not in the kernel
\def\caption{%
\ifx\@captype\@undefined
\@latex@error{\noexpand\caption\c_space_tl outside~float}\@ehd
@@ -474,22 +660,16 @@
\@kernel@refstepcounter\@captype
% \end{macrocode}
% we need to reset the target for \cs{addcontentsline}.
+% We use \cs{@captype} to support autoref.
% \begin{macrocode}
- \xdef\@currentHref{floatstructure.\@current@float@struct}%
+ \xdef\@currentHref{\@captype.struct.\@current@float@struct}%
}
\expandafter\@firstofone
\fi
{\@dblarg{\@caption\@captype}}%
}
% \end{macrocode}
-% As we will use the structure number in the target, we need to provide a
-% theH-representation. (Once the kernel will create
-% theH-representation generally this will be provided automatically, as tagpdf uses
-% \cs{newcounter})
-% \begin{macrocode}
-\providecommand\theHg__tag_struct_abs_int{\int_use:N\c@g__tag_struct_abs_int}
-% \end{macrocode}
-
+%
% \begin{macro}{\@makecaption}
% \cs{@makecaption} is defined by the classes so we overwrite it for now
% at begin document.
@@ -501,53 +681,36 @@
% \end{macrocode}
% we don't want tagging when storing the caption for the singleline check
% \begin{macrocode}
- \tag_stop:n{caption}
+ \SuspendTagging{\@makecaption}
\sbox\@tempboxa{#1:~#2}%
- \tag_start:n{caption}
+ \ResumeTagging{\@makecaption}
% \end{macrocode}
-% we stop paratagging. TODO: check
+% We pass \cs{@current@float@struct} as parent structure
+% number. If that is empty the socket will use the parent structure and hope ...
% \begin{macrocode}
- \tagtool{para=false}
-% \end{macrocode}
-% if caption is used outside a float there is perhaps no number, then we use
-% the parent structure and hope ...
-% \begin{macrocode}
- \tl_if_empty:NT \@current@float@struct
- { \tl_set:Ne \@current@float@struct {\tag_get:n{struct_num}} }
- \tag_struct_begin:n{tag=Caption,parent=\@current@float@struct}
-% \end{macrocode}
-% move the caption to the begin of the float structure:
-% \begin{macrocode}
- \tag_if_active:T
- {
- \seq_gpop_right:cN {g__tag_struct_kids_\@current@float@struct _seq}\l_@@_tmpa_tl
- \seq_gput_left:cV {g__tag_struct_kids_\@current@float@struct _seq}\l_@@_tmpa_tl
- }
+ \UseTaggingSocket{caption/begin}{\@current@float@struct}
\ifdim \wd\@tempboxa >\hsize
- \tag_struct_begin:n{tag=Lbl}
- \tag_mc_begin:n{}
- #1:~
- \tag_mc_end:
- \tag_struct_end:
- \tag_mc_begin:n{}
- #2\par
- \tag_mc_end:
+ \UseTaggingSocket{caption/label/begin}
+ \UseSocket{caption/label}{#1}
+ \UseTaggingSocket{caption/label/end}
+ \UseTaggingSocket{para/begin}
+ #2
+ \par
\else
% \end{macrocode}
% we don't reuse the box as it doesn't contain tagging, but set the text explicitly.
% \begin{macrocode}
\global \@minipagefalse
\hb@xt@\hsize{\hfil
- \tag_struct_begin:n{tag=Lbl}
- \tag_mc_begin:n{}
- #1:~
- \tag_mc_end:
- \tag_struct_end:
- \tag_mc_begin:n{}
+ \UseTaggingSocket{caption/label/begin}
+ \UseSocket{caption/label}{#1}
+ \UseTaggingSocket{caption/label/end}
+ \UseTaggingSocket{para/begin}
#2
- \tag_mc_end:\hfil}%
+ \UseTaggingSocket{para/end}
+ \hfil}%
\fi
- \tag_struct_end: %caption
+ \UseTaggingSocket{caption/end}
\vskip\belowcaptionskip}
}
% \end{macrocode}
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-float.pdf b/macros/latex-dev/required/latex-lab/latex-lab-float.pdf
index edc88f0b2a..425f521ac9 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-float.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-float.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-footnotes.dtx b/macros/latex-dev/required/latex-lab/latex-lab-footnotes.dtx
index a3d044ab87..f4ad7edd9d 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-footnotes.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-footnotes.dtx
@@ -17,8 +17,8 @@
%
% for those people who are interested or want to report an issue.
%
-\def\ltlabfootnotedate{2024-03-12}
-\def\ltlabfootnoteversion{0.8d}
+\def\ltlabfootnotedate{2024-09-30}
+\def\ltlabfootnoteversion{0.8g}
%<*driver>
\documentclass{l3doc}
@@ -228,7 +228,8 @@
%
% To cater for different layout configurations there are four
% sockets that can be set by a package or
-% class but there should be only one per document setting them, i.e., if two packages/classes set them they are mutually
+% class but there should be only one per document setting them,
+% i.e., if two packages/classes set them they are mutually
% incompatible (or rather the last one wins most likely).
% These are:
% \begin{description}
@@ -491,11 +492,21 @@
% \subsection{Technical details for the tagging}
%
% The following sockets are set up for kernel use, when doing tagging:
+% There name and/or function will probably change as they currently
+% mix tagging with the link support.
+%
+% TODO: review this sockets
% \begin{description}
% \item[\socket{tagsupport/fnmark} (1 argument)]
%
% \DescribeSocket[noprint]{tagsupport/fnmark}
-%
+%
+% The socket is used in \cs{@footnotemark}/\cs{fnote_footnotemark:}
+% and takes \cs{@makefnmark} as argument. It prints the mark in the text
+% and surrounds it with a tagging structure and a link. As such it is
+% not solely for tagging and so should not be used with \cs{UseTaggingSocket}
+% as this would swallow the argument and loose the link support.
+%
% \fmi{describe and decide on names}
%
%
@@ -503,31 +514,45 @@
%
% \DescribeSocket[noprint]{tagsupport/fntext/begin}
%
+% This socket is used before the main processing socket
+% (so before the \cs{insert} command). It opens the FEnote structure.
+% As it sets also the tl-var for the current structure and this is used
+% in destinations it should not use as tagging socket.
+%
%
% \item[\socket{tagsupport/fntext/end} (no argument)]
%
% \DescribeSocket[noprint]{tagsupport/fntext/end}
%
+% This socket is used after the main processing socket
+% (so after the \cs{insert} command). It closes the FEnote structure.
%
% \item[\socket{tagsupport/fntext/mark} (1 argument)]
%
% \DescribeSocket[noprint]{tagsupport/fntext/mark}
-%
+%
+% This socket is used around the mark in the footnote text.
+% It adds tagging support but also link support, so like the other
+% tagsupport sockets it should be always active.
%
% \item[\socket{tagsupport/fntext/text} (1 argument)]
%
% \DescribeSocket[noprint]{tagsupport/fntext/text}
%
+% This socket handles mc-chunks around the text of the footnote. As it
+% takes an argument (the text) is should not be use as tagging socket either.
%
% \end{description}
%
%
% The \emph{footnotemark} should create a \texttt{/Lbl} structure\footnote{to make it easier
-% to identify the role we use \texttt{/footnotemark} which we rolemap to \texttt{/Lbl}} that should contain a \texttt{/Ref} entry pointing
+% to identify the role we use \texttt{/footnotemark} which we rolemap to \texttt{/Lbl}}
+% that should contain a \texttt{/Ref} entry pointing
% to the structure of the \emph{footnotetext}.
%
-% The \emph{footnotetext} should create a \texttt{/FENote}\footnote{We tag it as \texttt{/footnote} and role map it.}
-% structure with a \texttt{/Ref}
+% The \emph{footnotetext} should create a \texttt{/FENote}%
+% \footnote{We tag it as \texttt{/footnote} and role map it.}
+% structure with a \texttt{/Ref}
% entry pointing to the structures of \emph{all} marks related to the note.
% The mark at the begin of the
% note is in a \texttt{/Lbl}\footnote{We tag it as \texttt{/footnotelabel}.}
@@ -582,8 +607,8 @@
% with their own structure number as a key in a property.
%
% A following \cs{footnotetext} compares its own \cs{@thefnmark} with the values in
-% the prop. If there is a match it stores the structure numbers and removes the entries
-% from the properties (so in a normal document the property will never contain more than
+% the prop. If there is one or more match it stores the structure numbers and removes the entries
+% from the property (so in a normal document the property will never contain more than
% a few entries).
%
% This works well as long as the \cs{footnotemark} commands are issued before the \cs{footnotetext} and
@@ -626,9 +651,9 @@
%
% \subsubsection{\cs{footref}}
%
-% \cs{footref} use internally the same command to set the mark as \cs{footnotemark}, it only
+% \cs{footref} uses internally the same command to set the mark as \cs{footnotemark}, it only
% defines \cs{@thefnmark} differently. This \cs{@thefnmark} is not suitable for the method described
-% above, as it contains a reference command it can't be used to match a note, also \cs{footref} can
+% above: as it contains a reference command it can't be used to match a note, also \cs{footref} can
% be used after the note has already been set. \cs{footref} disables therefore the automatic detection.
%
% Instead the \cs{label} command is
@@ -636,7 +661,7 @@
% number to setup the reference and the link.
%
% The structure related to the \cs{footref} is added to the end of the \texttt{/Ref} array of the note and so the
-% \texttt{/Ref} array doesn't necessarly reflect the order of the marks in the document. It would probably
+% \texttt{/Ref} array doesn't necessarily reflect the order of the marks in the document. It would probably
% be possible to change this, but it is not clear if it actually matters and so it worth the additional coding
% and processing.
%
@@ -672,7 +697,7 @@
%
% A \cs{footnotetext} creates a bunch of destinations (in most cases this sums up to
% two destinations): one for every structure number in the \texttt{/Ref} (used as target
-% by the mark commands) and one for the structure number of the footnotetest itself
+% by the mark commands) and one for the structure number of the footnotetext itself
% (used as target by \cs{footref}s commands).
%
% \subsection{Implementation details regarding tagging}
@@ -899,8 +924,8 @@
% This is used to pass the structure number of the note around, e.g.
% to a label inside the note.
% \begin{macrocode}
-\tl_new:N \l_@@_currentstruct_tl
-\tl_set:Nn \l_@@_currentstruct_tl {1}
+\tl_new:N \l_@@_currentstruct_tl
+\tl_set:Nn \l_@@_currentstruct_tl {2}
% \end{macrocode}
%
%
@@ -1150,6 +1175,21 @@
%
%
% \begin{macro}{\fnote_footnotetext:n}
+% We temporarily test for the tagging socket until it is in the next release:
+% \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/para/restore_plug_str }
+ {
+ \NewSocket{tagsupport/para/restore}{0}
+ \NewSocketPlug{tagsupport/para/restore}{default}
+ {
+ \tl_set:Nn \l__tag_para_main_tag_tl {text-unit}
+ \tl_set_eq:NN \l__tag_para_tag_tl\l__tag_para_tag_default_tl
+ \bool_set_false:N\l__tag_para_flattened_bool
+ }
+ \AssignSocketPlug{tagsupport/para/restore}{default}
+ }
+% \end{macrocode}
+%
% \begin{macrocode}
\cs_new_protected:Npn \fnote_footnotetext:n #1 {
\@@_debug_footnotetext:
@@ -1191,6 +1231,7 @@
\floatingpenalty \@MM
\hsize\columnwidth
\@parboxrestore
+ \UseTaggingSocket{para/restore}
\parindent 1em % typical default used in \@makefntext moved up here
\def\@currentcounter{footnote}
\protected@edef \@currentlabel { \p@footnote \@thefnmark }
@@ -1673,7 +1714,7 @@
%
% \subsubsection{\pkg{memoir}}
% The \pkg{memoir} class redefines various internal commands to inject its
-% hooks and addtional code. The following reinstates the kernel command and
+% hooks and additional code. The following reinstates the kernel command and
% so probably breaks various options of \pkg{memoir}, but without the
% changes it errors anyway. The \pkg{footmisc} package should be used to change
% for example to para footnotes.
@@ -1937,10 +1978,7 @@
% \begin{macrocode}
\cs_new_protected:Npn \@@_gput_ref:nn #1 #2 %#1 the structure number receiving the ref #2
{
- \tag_if_active:T
- {
- \tag_struct_gput:nne {#1}{ref}{\tag_struct_object_ref:e { #2 }}
- }
+ \tag_struct_gput:nnn {#1}{ref_num}{#2}
}
\cs_new_protected:Npn \fnote_gput_refs:nn #1 #2 % pair of numbers
{
@@ -1951,11 +1989,7 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macrocode}
-\tl_new:N \l_@@_dflt_struct_tl
-\tl_set:Nn \l_@@_dflt_struct_tl {1}
-% \end{macrocode}
-% kernel hooks for taggin
+% kernel hooks for tagging
% this sets the structure around the whole text
%
%
@@ -1965,25 +1999,30 @@
{
\tag_mc_end_push:
% \end{macrocode}
-% test if a footnote is allowed, if not move up to the document structure.
+% test if a footnote is allowed, if not move up to the next sect or
+% the document structure.
% \begin{macrocode}
\tag_check_child:nnTF {FENote}{pdf2}
{
\tag_struct_begin:n { tag=footnote }
}
{
- \tag_struct_begin:n { tag=footnote,parent=\l_@@_dflt_struct_tl }
+ \tag_struct_begin:n
+ {
+ tag=footnote,
+% \end{macrocode}
+% We add 0 for now to ensure to get a number even if the sec code is not loaded
+% or if the seq is empty (which it shouldn't unless there is an coding error)
+% \begin{macrocode}
+ parent=\int_max:nn{2}{\tag_get:n{current_Sect}+0}
+ }
}
% \end{macrocode}
% Store the current structure number for labels.
% \begin{macrocode}
\tl_set:Ne \l_@@_currentstruct_tl { \tag_get:n{struct_num} }
% \end{macrocode}
-% We want to move the label structure here. So we provide a container
-% It number is |\l__fnote_currentstruct_tl| plus 1.
-% \begin{macrocode}
- \tag_struct_begin:n { tag=footnotelabel }\tag_struct_end:
-% \end{macrocode}
+%
% after we have opened the structure we can use the structure number to
% try to detect the connected marks. As with the marks we assume that sometimes
% no auto detection is done.
@@ -2066,12 +2105,9 @@
\MakeLinkTarget*{footnote*.\l_@@_currentstruct_tl}
% \end{macrocode}
% Now we add the tagging commands. We move the structure of the label to
-% to the container at the begin of the note.
-% \begin{NOTE}{UF}
-% Check if the NonStruct is really needed. Perhaps we can simply move the mc.
-% \end{NOTE}
+% the begin of the footnote structure.
% \begin{macrocode}
- \tag_struct_begin:n { tag=NonStruct,parent=\l_@@_currentstruct_tl +1 }
+ \tag_struct_begin:n { tag=footnotelabel,parent=\l_@@_currentstruct_tl,firstkid }
\tag_mc_begin:n { tag=Lbl }
#1
\tag_mc_end:
@@ -2446,7 +2482,7 @@
% This can use the default interface, except that a negative value for
% \footnotemargin makes little sense, so we test for this and warn if
-% necessary. But -\maxdimen is ok again, so would need to be a litte bit more elaborate.
+% necessary. But -\maxdimen is ok again, so would need to be a little bit more elaborate.
%
%\AddToHook{fntext/para}{
@@ -2483,7 +2519,7 @@
\leavevmode
% \end{macrocode}
% Typesetting the mark twice means that one can't have any material
-% inside that gets unhappy in that case. Tha shouldn't be a
+% inside that gets unhappy in that case. That shouldn't be a
% problem, but perhaps we have to come up with a more elaborate
% solution in the end.
% \begin{macrocode}
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-footnotes.pdf b/macros/latex-dev/required/latex-lab/latex-lab-footnotes.pdf
index 6fa73ecf8b..f3125ae942 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-footnotes.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-footnotes.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-graphic.dtx b/macros/latex-dev/required/latex-lab/latex-lab-graphic.dtx
index 5ea4a2db9c..b3ee3eb6c6 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-graphic.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-graphic.dtx
@@ -15,8 +15,8 @@
% https://github.com/latex3/latex2e/required/latex-lab
%
% for those people who are interested or want to report an issue.
-\def\ltlabgraphicdate{2024-03-13}
-\def\ltlabgraphicversion{0.80d}
+\def\ltlabgraphicdate{2024-09-18}
+\def\ltlabgraphicversion{0.80e}
%
%<*driver>
\documentclass{l3doc}
@@ -78,7 +78,7 @@
% The value of a \texttt{BBox} is an array of four numbers that gives the
% coordinates of the left, bottom, right, and top edges
% of the structure element’s bounding box. That is the rectangle that completely encloses
-% its \emph{visible} content so not necessarly the TeX bounding box:
+% its \emph{visible} content so not necessarily the TeX bounding box:
% if \texttt{viewport} or \texttt{trim} is used and the
% graphic is not clipped, the visible content can be larger.
%
@@ -146,8 +146,8 @@
% \item[\texttt{artifact}] When used the graphic will be tagged as artifact. This doesn't
% require a \texttt{BBox} and so works also in some of the not yet supported cases described
% above.
-% \item[\texttt{false}] When used tagging will be stopped completly. It is then the
-% responsability of the surrounding code to add appropriate tagging commands.
+% \item[\texttt{false}] When used tagging will be stopped completely. It is then the
+% responsibility of the surrounding code to add appropriate tagging commands.
% \item[\meta{name}] Other values will be used as tag names in the structure. If the tag is not
% known as a structure tag you will get an warning from tagpdf. The default name is currently
% \texttt{Figure}
@@ -291,7 +291,7 @@
% ,\l_@@_graphic_trim_uy_fp
% }
% A bunch of fp-variables (we don't use tl-vars,
-% to avoid to have to take care about minus signs everwhere)
+% to avoid to have to take care about minus signs everywhere)
% \begin{macrocode}
\fp_new:N\l_@@_graphic_sin_fp
\fp_new:N\l_@@_graphic_cos_fp
@@ -489,7 +489,7 @@
\bool_set_true:N \l_@@_graphic_artifact_bool
\bool_set_false:N \l_@@_graphic_BBox_bool
}
- {false}{\tag_stop:}
+ {false}{\tag_suspend:n{Gin}}
}
{\tl_set:Nn\l_@@_graphic_struct_tl{#1}}
}
@@ -528,7 +528,7 @@
\bool_set_true:N \l_@@_graphic_artifact_bool
\bool_set_false:N \l_@@_graphic_BBox_bool
}
- {false}{\tag_stop:}
+ {false}{\tag_suspend:n{picture}}
}
{\tl_set:Nn\l_@@_graphic_struct_tl{#1}}
}
@@ -1012,7 +1012,7 @@
\@defaultunitsset\@tempdimc{#1}\unitlength
\Gin@tag@struct@begin
\setbox\@picbox\hb@xt@\@tempdimc\bgroup
- \tag_stop: %do not tag inside the picture box
+ \tag_suspend:n{\@picture} %do not tag inside the picture box
\@defaultunitsset\@tempdimc{#3}\unitlength
\hskip -\@tempdimc
\@defaultunitsset\@tempdimc{#4}\unitlength
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-graphic.pdf b/macros/latex-dev/required/latex-lab/latex-lab-graphic.pdf
index 04e6d424d0..f1eb149e5b 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-graphic.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-graphic.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-marginpar.dtx b/macros/latex-dev/required/latex-lab/latex-lab-marginpar.dtx
index ca79d8a67f..2f293ee492 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-marginpar.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-marginpar.dtx
@@ -18,8 +18,8 @@
%
% for those people who are interested or want to report an issue.
%
-\def\ltlabmarginpardate{2024-02-12}
-\def\ltlabmarginparversion{0.85b}
+\def\ltlabmarginpardate{2024-09-18}
+\def\ltlabmarginparversion{0.85d}
%<*driver>
\documentclass[kernel]{l3doc}
@@ -72,7 +72,7 @@
% They can be tagged either as artifacts (if they are merely distracting decoration),
% as small headings before the paragraph, or as |Aside|. Unlike the PDF 1.7 fallback |Note|
% the structure |Aside| is not allowed inside |P|,
-% so if |Aside| is used, it must be placed before or after the current |P| in the surounding |text-unit|,
+% so if |Aside| is used, it must be placed before or after the current |P| in the surrounding |text-unit|,
% or it must split the |P|. Splitting is probably not so good as
% |\marginpar| is often used somewhere in the middle of sentence.
% The best default is probably to use |Aside|, find the parent |text-unit| and add it there.
@@ -153,13 +153,38 @@
\socket_new:nn {tagsupport/marginpar/end}{0}
% \end{macrocode}
% \end{socketdecl}
+%
+% \begin{macro}{\@@_get_marginpar_parent:N,\@@_get_marginpar_parent_aux:nn}
+% In a paragraph we must retrieve
+% the structure number of the surrounding Part structure
+% TODO: if this is needed in more places this should
+% go into tagpdf.
+% \begin{macrocode}
+\cs_new_protected:Npn\@@_get_marginpar_parent_aux:nn #1 #2
+ {
+ \str_if_eq:eeT{\use_ii:nn #1}{Part}{\seq_put_right:Nn\l_@@_tmpa_seq {#2}}
+ }
+\cs_new_protected:Npn \@@_get_marginpar_parent:N #1
+ {
+ \seq_clear:N\l_@@_tmpa_seq
+ \seq_map_pairwise_function:NNN
+ \g_@@_struct_tag_stack_seq
+ \g_@@_struct_stack_seq
+ \@@_get_marginpar_parent_aux:nn
+ \seq_put_right:Nn\l_@@_tmpa_seq {2}
+ \seq_get_left:NN \l_@@_tmpa_seq #1
+ }
+\cs_generate_variant:Nn \tag_struct_begin:n {e}
+% \end{macrocode}
+% \end{macro}
% \begin{plugdecl}{tagsupport/marginpar/begin,tagsupport/marginpar/end}
% \begin{macrocode}
\socket_new_plug:nnn {tagsupport/marginpar/begin}{default}
{
\if_mode_horizontal:
- \tag_mc_end:
- \tag_struct_begin:n{tag=Aside,parent=\g__tag_para_main_struct_tl}%
+ \tag_mc_end:
+ \@@_get_marginpar_parent:N \l_@@_tmpa_tl
+ \tag_struct_begin:e{tag=Aside,parent=\l_@@_tmpa_tl}%
\else:
\tag_struct_begin:n{tag=Aside}%
\fi:
@@ -202,9 +227,9 @@
\long\def\@ympar#1{%
\@savemarbox\@marbox{#1}%
\global\setbox\@currbox\copy\@marbox
- \tag_stop:
+ \tag_suspend:n{\@ympar}
\@xympar
- \tag_start:}
+ \tag_resume:n{\@ympar}}
% \end{macrocode}
% \end{macro}
%
@@ -223,9 +248,9 @@
\property_record:ee
{ tag_marginpar-opt-\int_use:N\g__kernel_marginpar_int }{page}
}%
- \tag_stop:
+ \tag_suspend:n{\@xmpar}
\@savemarbox\@currbox{#2}%
- \tag_start:
+ \tag_resume:n{\@xmpar}
}
% \end{macrocode}
% order matters! the tagged box should be first so that it can pick up
@@ -233,15 +258,15 @@
% \begin{macrocode}
{
\@savemarbox\@currbox{#2}%
- \tag_stop:
+ \tag_suspend:n{\@xmpar}
\@savemarbox\@marbox{#1
\property_record:ee
{ tag_marginpar-opt-\int_use:N\g__kernel_marginpar_int }{page}}
- \tag_start:
+ \tag_resume:n{\@xmpar}
}
- \tag_stop:
+ \tag_suspend:n{\@xmpar}
\@xympar
- \tag_start:
+ \tag_resume:n{\@xmpar}
}
%</package>
% \end{macrocode}
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-marginpar.pdf b/macros/latex-dev/required/latex-lab/latex-lab-marginpar.pdf
index 1e9317d8f4..747fca9fb5 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-marginpar.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-marginpar.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-math.dtx b/macros/latex-dev/required/latex-lab/latex-lab-math.dtx
index 0dbc591185..7ff1e74273 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-math.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-math.dtx
@@ -19,13 +19,13 @@
% for those people who are interested or want to report an issue.
%
%
-\def\ltlabmathdate{2024-04-16}
-\def\ltlabmathversion{0.5j}
+\def\ltlabmathdate{2024-11-26}
+\def\ltlabmathversion{0.6j}
%
%<*driver>
\documentclass{l3doc}
\EnableCrossrefs
-\CodelineIndex
+\CodelineIndex
\usepackage{todonotes}
@@ -40,7 +40,7 @@
% \title{The \texttt{latex-lab-math} code\thanks{}}
% \author{Frank Mittelbach, Joseph Wright, \LaTeX{} Project}
% \date{v\ltlabmathversion\ \ltlabmathdate}
-%
+%
% \maketitle
%
% \newcommand\NEW[1]{\marginpar{\mbox{}\hfill\fbox{New: #1}}}
@@ -77,21 +77,21 @@
% \tableofcontents
%
% \section{Introduction}
-% \car*{Todo: update all the documentation! Both here and
+% \car*{Todo: update all the documentation! Both here and
% (what little there is!) in the implementation section.}
%
% Tagging math involves a variety of tasks that require that math is captured before the
% typesetting
-% \begin{itemize}
-% \item When typesetting the math MC-tags and structure commands must
-% be inserted at the begin and the end, and perhaps also around lines
-% or other subparts of the equation.
+% \begin{itemize}
+% \item When typesetting the math MC-tags and structure commands must
+% be inserted at the begin and the end, and perhaps also around lines
+% or other subparts of the equation.
% \item The source and/or a mathml-representation of the source must be available
% so that it can be (perhaps after some preprocessing) be used in an associated file
% or in an alternate text
-% \item It must be possible to measure the math for e.g. a bbox setting.
+% \item It must be possible to measure the math for, e.g., a bbox setting.
% \end{itemize}
-%
+%
% This file implements capture of all math mode material at the outer
% level, i.e., a formula is captured in its entirety with inner text
% blocks (possibly containing further math) absorbed as part of the
@@ -101,24 +101,24 @@
%\end{verbatim}
% would only result in a single capture of the tokens
% ``\verb*/a \in A \text{ for all $a<5$}/''.
-%
+%
%
% \section{Math capture} \label{sec:mathcapture}
-% In the current setup
+% In the current setup
% \begin{itemize}
% \item |$|, |\(...\)| and |$$| grab (through a command in \cs{everymath}/cs{everydisplay})
% if the boolean \cs{l_@@_collected_bool} is false.
% If the boolean is true they behave normally and can for example contain verbatim.
-%
-% \item All (registered) environments grab their body
+%
+% \item All (registered) environments grab their body
% regardless of the state of the boolean. For
-% |equation|, |equation*| and |math| this is a change as they no longer can
+% |equation|, |equation*| and |math| this is a change as they no longer can
% contain verbatim.
-%
+%
% \item BUG: |\[...\]| grabs if \cs{l_@@_collected_bool} is false. If it is
-% true it falls back to |equation*| and then errors because this can't find the end.
-% \end{itemize}
-%
+% true it falls back to |equation*| and then errors because this can't find the end.
+% \end{itemize}
+%
% \subsection{Code level interfaces}
%
% \begin{function}{\math_register_env:n, \math_register_env:nn}
@@ -163,50 +163,50 @@
% material.
% \end{itemize}
% \end{function}
-%
+%
% \section{Math tagging}
-%
-% The tagging code has to handle
+%
+% \subsection{Code requirements}
+% The tagging code has to handle
% \begin{itemize}
-% \item the embedding into the surrounding. This means
-% \begin{itemize}
-% \item closing and reopening MC-chunks
+% \item the embedding into the surrounding. This means
+% \begin{itemize}
+% \item closing and reopening MC-chunks
% \item closing and reopening text/P-structures
% \item handling interferences of the tagging code with penalties and spacing.
% \end{itemize}
% \item the actual tagging which means to do some or all of the following tasks:
% \begin{itemize}
% \item setup content for an associated source file
-% \item setup content for an associated mathml file
+% \item setup content for an associated mathml file
% \item setup content for the /Alt key
% \item setup content for the /ActualText key
% \item setup attributes
-% \item add associated files
+% \item add associated files
% \item add a Formula structure
-% \item surround subparts (e.g. lines) with Formula sub structures
+% \item surround subparts (e.g., lines) with Formula sub structures
% (perhaps with their own set of additional content)
-% \item surround elements of the equation with mathml structure elements
+% \item surround elements of the equation with mathml structure elements
% (currently only luatex with luamml)
% \end{itemize}
% \end{itemize}
-%
+%
% \subsection{Inline math}
-%
+%
% The embedding code is added through
-% the sockets
+% the sockets
% \begin{itemize}
-% \item |tagsupport/math/inline/begin|
+% \item |tagsupport/math/inline/begin|
% \item |tagsupport/math/inline/end|
-% \end{itemize}
+% \end{itemize}
% The sockets simply push and pop the MC currently. Without
-% tagging they use the noop-plug.
-%
+% tagging they use the noop-plug.
+%
% The actual tagging is in done through the sockets
% \begin{itemize}
% \item |tagsupport/math/inline/formula/begin|
-% This socket takes the math as argument and its code
-% should output it for typesetting. Without tagging the
-% socket uses the identity plug.
+% This socket takes the math as second argument and its code
+% should output it for typesetting.
% The |default| plug of the socket calls these three internal sockets
% for the tagging support:
% \begin{itemize}
@@ -216,55 +216,62 @@
% \item |tagsupport/math/struct/begin| This calls \cs{tag_struct_begin:n}.
% It should also write the associated files if needed.
% \item |tagsupport/math/substruct/begin| this handles subparts.
-% TODO: does it really make sense in inline math to have that??
+% TODO: does it really make sense in inline math to have that??
% \end{itemize}
% \item |tagsupport/math/inline/formula/end|
% This socket ends the formula structure(s). The |default|
% plug calls these internal sockets:
% \begin{itemize}
% \item |tagsupport/math/substruct/end|
-% \item |tagsupport/math/struct/end|
+% \item |tagsupport/math/struct/end|
% \end{itemize}
-% \end{itemize}
-%
+% \end{itemize}
+%
% \subsection{Display math}
-%
+%
% \textit{to be written}
-%
+%
% \subsection{Associated Files}
-%
+%
% The current code allows the attachment of two types of associated file to the
% Formula structure:
-% the \LaTeX\ source and a MathML representation.
+% the \LaTeX\ source and a MathML representation.
% Technically both can be attached---AF is an array
-% of file references---practically there can be problems with PDF consumers:
-% e.g. ngpdf used both and so showed the equation twice
-% (this has been corrected in the newest version) and
+% of file references-----in practice there can be problems with PDF consumers:
+% e.g., ngpdf used both and so showed the equation twice
+% (this has been corrected in the newest version) and
% Foxit seems to see only the first AF in the array (so we attach the
% mathml as first file).
-%
-% The \LaTeX\ source can be (and is) attached automatically.
+%
+% The \LaTeX\ source can be (and is) attached automatically.
% It can be suppressed by an option with
-% \texttt{math/tex/AF=false}, see below.
-%
-% The MathML is attached if a file |\jobname-mathml.html| is found and
-% if it contains a suitable MathML snippet for the current formula.
+% \texttt{math/tex/AF=false}, see below.
+%
+% The MathML is attached if the files |\jobname-mathml.html| and/or
+% |\jobname-luamml-mathml.html| are found
+% and if they contains a suitable MathML snippet for the current formula.
+% If the files contain more than one suitable snippet (as identified by the hash)
+% the first one is used.
+% |\jobname-luamml-mathml.html| is automatically generated (see below section~\ref{sec:luamml})
+% and read after |\jobname-mathml.html|. This means that |\jobname-mathml.html| can contain
+% improved versions of a formula.
+%
% The MathML processing can be suppressed globally by emptying the list of
% mathml files with |math/mathml/sources=|. Locally for a formula |math/mathml/AF=false|
-% can be used.
-%
-% For a MathML representation a file with such representations must be provided.
-% If the equation is numbered the numbering should be part of the MathML as
+% can be used.
+%
+% For a MathML representation a file with such representations must be provided.
+% If the equation is numbered the numbering should be part of the MathML as
% the |Lbl| substructure is ignored if an MathML is used (see https://github.com/foxitsoftware/PDF_UA-2).
-%
-% The MathML representation is given in a special format.
+%
+% The MathML representation is given in a special format.
% It is meant to be a valid html file
% that can be viewed in a browser.
% For this it can start with |<!DOCTYPE html><html>| and end with |</html>|
-% It should have the extension \texttt{.html}. The \meta{mathml} content
+% It should have the extension \texttt{.html}. The \meta{mathml} content
% is read with special catcodes, so can contain ambersands, hashes, comment chars
% and unmatched braces such as |<mo>{</mo>|
-%
+%
% The file should contain a number of representations in this format:
% \begin{quote}
% |<div>| \\
@@ -278,176 +285,338 @@
% \end{quote}
% The keywords |<div>|, |<h2>\mml|, |<p>|, |<math|, |</math>| |</div>| are required as
% they are used to delimit the arguments by the \LaTeX{} code.
-%
+%
% \meta{key} and \meta{source} are only used for debugging, they help to identify
% the equation referred by this representation. The source should be used correctly escaped
% |&| and |<| so that if gives valid html!
-%
-% \meta{attributes} is not required either, but can e.g. contain attributes
+%
+% \meta{attributes} is not required either, but can, e.g., contain attributes
% to improve the display in a browser:
% \begin{verbatim}
% <math alttext="\mathbf{G}" class="ltx_Math" display="inline">
% \end{verbatim}
% It can also contain the name space declaration: |xmlns="http://www.w3.org/1998/Math/MathML"|%
% \footnote{But it is probably not needed and only blows up the PDF.}
-%
-%
-% By default the code tries at the begin of the document
-% to read a file |\jobname-mathml.html| in the |html|-format.
-% The file name can be changed with |mathml/setfiles={filename1,filename2}|
-% (without extension, |html| is added automatically).
-% If there is a list, all files are loaded.
+%
+%
+% By default the code tries at the begin of the document
+% to read a file |\jobname-mathml.html| in the |html|-format.
+% The file name can be changed with |mathml/setfiles={filename1,filename2}|
+% (without extension, |html| is added automatically).
+% If there is a list, all files are loaded.
% If a file doesn't exist it is ignored, only an info is written to the log.
-%
-% Currently every MathML-snippet from a file is embedded into the PDF,
-% it is not checked first if it is actually used (simply writing everything to the PDF
-% is a bit easier than keeping everything in memory and also means that
-% the snippets are one after the other in the PDF).
-%
-% As mentioned above the MathML-AF can be suppressed for the equations in a group with
+%
+% Currently every MathML-snippet from a file is embedded into the PDF,
+% it is not checked first if it is actually used (simply writing everything to the PDF
+% is a bit easier than keeping everything in memory and also means that
+% the snippets are one after the other in the PDF).
+%
+% As mentioned above the MathML-AF can be suppressed for the equations in a group with
% |math/mathml/AF=false|, or
-% completly by setting |math/mathml/sources=| in the preamble.
-%
+% completely by setting |math/mathml/sources=| in the preamble.
+%
% Files embedded in a PDF can be listed in the attachments panel of a PDF viewer.
% This is probably not so useful for lots of small files (but one could create
-% collections), but as long as PDF editors or viewers don't offer
+% collections), but as long as PDF editors or viewers don't offer
% proper support to access the AF it can help so have them there. The MathML are
% added by default, but the \LaTeX{} source not. This can be changed with
% |viewer/pane/mathsource=true| (anywhere in the document) and |viewer/pane/mathml=false| (in the
-% preamble, before the external file is read).
+% preamble, before the external file is read).
+%
+%
+% \subsection{Automatic mathml creation with luamml}\label{sec:luamml}
+%
+% If lualatex and the package \pkg{unicode-math} is used
+% the package \texttt{luamml} is loaded and
+% will automatically generate the file |\jobname-luamml-mathml.html|
+% with mathml representations of all math formulas.
+% This file is then used in subsequent compilations and works also with
+% pdflatex.
%
-% \subsection{Options}
-%
-%
+% The generation of the file can be suppressed (in the preamble)
+% with |math/mathml/luamml/write=false|.
+%
+% If the package \pkg{unicode-math} is not used,
+% the loading of \pkg{luamml} and with it the generation of the file can be forced
+% with |math/mathml/luamml/load=true| or |math/mathml/luamml/write=true|
+% but be aware that it is then possible that various symbols
+% are mapped to the wrong Unicode code points.
+%
+% The package \pkg{luamml} is still quite experimental and the output should be checked.
+% The |\jobname-luamml-mathml.html| file may be previewed in a browser although
+% you may need to add additional css or javascript declarations
+% to enable browser support for all mathml constructs.
+%
+%
+% \subsection{Summary of math options}
+% The following options exist to make math more accessible:
+% \begin{description}
+% \item[ActualText] An \texttt{ActualText} can be placed on structure elements,
+% but can also be added in the stream on a \texttt{BDC} marker with a \texttt{Span}
+% tag (normally an independant marker without an MCID number, it is not clear yet
+% if it can be used on a MC-chunk).
+% The content is a text string, typically one or a few Unicode characters.
+% \texttt{ActualText} is meant to replaces the content
+% and should only be used on small entities,
+% e.g., to define the semantic or the Unicode code point of a symbol.
+% \texttt{ActualText} is not supported by all PDF reader.
+% It is also unknown where it should be used at best (in a structure element,
+% or on an independent Span-BDC) and what happens if it is used in more than
+% one place.
+% \begin{description}
+% \item[enabled by default?] False
+% \item[how to enable/disable] No interface yet.
+% \texttt{ActualText} can only be added on the Formula structure element by
+% changing the \texttt{tagsupport/math/content} or some other socket.
+% For a BDC marker one can, e.g., use
+% \begin{verbatim}
+% \pdf_string_from_unicode:nnN{utf16/hex}{€}\l_tmpa_tl
+% \pdf_bdc:ee{Span}{/ActualText\l_tmpa_tl}content\pdf_emc:
+% \end{verbatim}
+% There should be no pagebreak in the \meta{content} and the BDC should be correctly
+% nested into tagging, so, e.g., a \cs{leavevmode} should be issued before the bdc command.
+% \item[Consumer support] in part and in part buggy, needs tests \ldots
+% \end{description}
+%
+% \item[Alt] Like \texttt{ActualText} the \texttt{Alt} key can be used on
+% structure elements and on \texttt{Span} in the stream. It should contain a description
+% of the content and is mainly meant for images. PDF/UA-1,
+% which views math formulas as illustrations, mandates the key
+% also for \texttt{Formula} structure elements.
+% \begin{description}
+% \item[enabled by default?] false unless PDF/UA-1 is detected,
+% then it is enabled in the begindocument/end hook
+% (this will reconsidered when it is clear, that
+% the use of \texttt{Alt} does not shadow mathml). It can be enabled for
+% all engines and PDF versions.
+% \item[enable/disable] \verb+\tagpdfsetup{math/alt/use}+ (local boolean,
+% so can be used on individual equations)
+% \item[default value] A template text (stored in \cs{l_@@_content_template_tl})
+% starting with \texttt{LaTeX formula starts}.
+% \item[user value] No interface currently provided. This needs optional arguments
+% or an external setup command.
+% See \url{https://github.com/latex3/tagging-project/discussions/717}.
+%
+% \end{description}
+%
+% \item[source-AF] The \LaTeX{}-source of the equation can
+% be attached as an associated file with mime-type
+% application/Fx-tex. The \texttt{AFRelationship} is \texttt{Source}.
+% The source is embedded without expansion. This means that targets of
+% references and macros are not resolved.
+% The files are by default not shown in the EmbeddedFiles pane,
+% this can be enabled with |viewer/pane/mathsource=true|.
+% If an A-standard is used, it must be one that allows embedded files, e.g., A-4f.
+%
+% \begin{description}
+% \item[enabled by default?] true for all engines and PDF versions
+% \item[enable/disable] \verb+\tagpdfsetup{math/tex/AF}+ (local boolean, so can
+% be used on individual equations)
+% \item[default value] source code including dollars or environment name.
+% \item[consumer support] Currently only ngpdf makes
+% use of it: if there is no mathml it passes the source to mathjax.
+% \end{description}
+%
+% \item[luamml] The following options make (with lualatex) use
+% of the \pkg{luamml} package. \pkg{luamml} is currently automatically
+% loaded (at the end of the preamble) if \pkg{unicode-math} has been detected.
+% The loading can be forced or suppressed
+% with \verb+\tagpdfsetup{math/mathml/luamml/load=true/false}+.
+%
+% \pkg{luamml} affects all math, locally it can be stopped with |math/mathml/ignore|,
+% or by using the commands described in the package.
+%
+% \item[mathml-AF] A mathml representation of the equation can be attached
+% to the structure. The configuration possibilities are rather complex as the
+% keys have to control three different tasks:
+% The \emph{generation} of the file with the mathml fragments,
+% the \emph{reading} and \emph{embedding} of the mathml fragments,
+% and the \emph{association} of a mathml fragment to a specific equation.
+%
+% \begin{description}
+% \item[generation]
+% With pdf\LaTeX{} mathml fragments can not be generated automatically,
+% but a file with dummy fragments for every equation will be written if
+% \verb+\tagpdfsetup{math/mathml/write-dummy}+ is issued in the preamble.
+%
+% With lua\LaTeX{} a file with mathml fragments will be created automatically
+% if the package \pkg{luamml} has been loaded (see above).
+%
+% \item[reading and embedding]
+% By default the code will read and embed
+% mathml from |\jobname-mathml.html| and |\jobname-luamml-mathml.html| in this order and
+% the first fragment with a new hash value will be inserted.%
+% The list of sources and their order can be changed with the key
+% |math/mathml/sources|, setting that to an empty value suppresses
+% the loading mathml associated files completely. For efficiency reasons
+% it embeds math fragments directly, there is no check yet if the fragment is
+% actually used.
+%
+% The files are by default shown in the EmbeddedFiles pane,
+% this can be disabled with |viewer/pane/mathml=false|.
+%
+% \item[attaching] A mathml fragment is currently
+% attached as an associated file to an Formula if the hash of
+% the source matches the hash of the fragment. This is not a perfect test:
+% equations with the same source and so the same hash
+% can have different mathml representation, e.g.,
+% if there are references or commands or counters in the equation. This
+% will change in a feature version.
+% The attachment can be suppressed locally with |math/mathml/AF=false|.
+% The mathml fragment will still be embedded in the PDF!
+%
+% % TODO: adapt test
+% \end{description}
+%
+% \item[mathml structure elements]
+% Mathml structure elements can be used in PDF~2.0 directly.
+% In PDF~1.7. one could theoretically
+% use them if one declares a role mapping first,
+% (this can be done with \verb+\tagpdfsetup{role/mathml-tags}+)
+% which maps all to \texttt{Span}. But such a role mapping currently breaks reading,
+% e.g. in Adobe, and so it is not recommended.
+%
+% Automatic generation of structure elements is only possible with
+% lualatex. It requires that the packages \pkg{luamml} and \pkg{tagpdf}
+% have been loaded.
+% \begin{description}
+% \item[enabled by default?] false
+% \item[enable/disable] \verb+\tagpdfsetup{math/mathml/structelem}+
+% (local setting, so can be used with grouping on individual equations).
+% \item[consumer support] Needs more tests.
+% \end{description}
+%
+% \end{description}
+%
+%
+%
% \section{Known current bugs, etc.}
-% \car*{New Section, now with subsections.\\
-% As indicated, these lists are probably incomplete.\\
-% Some of these have been addressed in a more recent branch.}
%
% \subsection{Capture/grabbing problems}
-%
+%
% \begin{enumerate}
-% \item Incorrect grabbing of |$|-math when there is also
-% explicit |$|-math within a \textit{text environment}
+% \item Incorrect grabbing of |$|-math when there is also
+% explicit |$|-math within a \textit{text environment}
% that is itself within the math that should all be grabbed.
% For example,
% \begin{verbatim}
% $a\begin{minipage}{1cm}$b$\end{minipage}$
% \end{verbatim}
% would only result in the capture of the tokens
-% ``\verb*/a\begin {minipage}{1cm}/''.
+% ``\verb*/a\begin {minipage}{1cm}/''.
% This can be avoided by an additional brace group:
% \begin{verbatim}
% $a{\begin{minipage}{1cm}$b$\end{minipage}}$
-% \end{verbatim}
-%
+% \end{verbatim}
+%
% \item Similar incorrect grabbing with |$$| also.
-%
+%
% \item The grabbing, for all the display environments (and |\) \]|), needs
-% to deal with nesting: \pkg{amsmath} contains code for this.
-%
-% \item The math can't contain verbatim and verbatim-like commands. This is
+% to deal with nesting: \pkg{amsmath} contains code for this.
+%
+% \item The math can't contain verbatim and verbatim-like commands. This is
% nothing new for the \pkg{amsmath} environments but changes |$| and |\[\]|
-% and |equation*| (see e.g. tagging-project issue \#30).
-%
+% and |equation*| (see, e.g., tagging-project issue \#30).
+%
% \item Begin and end of the math or math environment can not be hidden in commands.
-% For example \verb+>{$}l<{$}+ in a tabular would lead to errors.
-% Defining |\[| to fall back to |equation*| doesn't work if |equation*| is
+% For example \verb+>{$}l<{$}+ in a tabular would lead to errors.
+% Defining |\[| to fall back to |equation*| doesn't work if |equation*| is
% a grabbing environment.
-%
+%
% \item The behaviour of |\[...\]| is faulty. See above.
-% \end{enumerate}
+% \end{enumerate}
%
% \subsection{Fake math}
-% In a number of places in \LaTeX{} math commands (mainly |$|) is used
-% only for technical reason, e.g. to access a math font, to setup a symbol
-% or to use \cs{vcenter}.
-%
+% In a number of places in \LaTeX{} math commands (mainly |$|) is used
+% only for technical reason, e.g., to access a math font, to setup a symbol
+% or to use \cs{vcenter}.
+%
% The code identifies such fake math mostly by making use of the \cs{m@th} command
% where two methods are used for the automatic detection:
-%
+%
% \begin{itemize}
-% \item After grabbing math content the code checks if the content contains the token
+% \item After grabbing math content the code checks if the content contains the token
% \cs{m@th} and if yes it doesn't call the processor before reinserting
% the content and perhaps adding tagging code.
% This method requires that the math can be grabbed (e.g. that the end dollar is visible)
% and that the \cs{m@th} is visible. It applies for example in \cs{@iiiparbox} where the
% code from |$\vcenter| to |\m@th$| is grabbed an put back. It does not work for
% example for |tabular| where the dollars and the \cs{m@th} token are spread around
-% over three commands. |tabular| needs therefore manual intervention.
-%
+% over three commands. |tabular| needs therefore manual intervention.
+%
% A look in the list of usages (in \texttt{usage-of-m@th.md}) justifies this approach.
% All usages are either not math at all, or related to small elements that probably
-% shouldn't be grabbed and processed on their own.
+% shouldn't be grabbed and processed on their own.
%
% \item \cs{m@th} is redefined so that it sets the boolean \cs{l_@@_collected_bool}
% to true. If \cs{m@th} is used inside math that has been grabbed
% this doesn't change much as the boolean is set by the grabbing anyway. For usages
% outside math the benefit is not so clear: The setting avoids that in \cs{LaTeXe}
% the epsilon is processed as math, but it also prevents that the content of the amsmath
-% command \cs{boxed} is processed as math.
+% command \cs{boxed} is processed as math.
% It means that if one wants to reenable math processing inside some (fake) math
% one has to do it after \cs{m@th} calls.
% \end{itemize}
-%
-% Open problems
+%
+% \subsubsection{Open problems}
+%
% \begin{enumerate}
% \item The grabbing code doesn't pass the info that it detected a \cs{m@th} token.
% This means that the tagging code has to do the same check (and doesn't do this
% in all cases yet).
-%
-% \item Commands are missing to locally disable the grabbing and processing, e.g.
+%
+% \item Commands are missing to locally disable the grabbing and processing, e.g.,
% to handle |tabular|.
-%
+%
% \item It must be checked if setting the boolean in \cs{m@th} really makes sense
-% or if commands like \cs{LaTeXe} should be handled manually.
-%
+% or if commands like \cs{LaTeXe} should be handled manually.
+%
% \end{enumerate}
-%
+%
% \subsection{Processor}
-%
+%
% The grabbed math is at first passed to the processor. The processor is not called
-% in a measuring phase (from the amsmath \cs{ifmeasuring@}) and if the \cs{m@th}
-% token is detected.
+% in a measuring phase (from the amsmath \cs{ifmeasuring@}) and if the \cs{m@th}
+% token is detected.
% It is not quite clear what purpose the processor has. As it is a public interface
% it can't be used for internal code. And typesetting happens later and the processor
% can't really change this. Currently it is mostly used for debugging and messages.
% If the \cs{m@th} is found the \cs{l_@@_fakemath_bool} is set, so if the code
% is changed this must be preserved.
-%
+%
% \subsection{Other problems}
-%
-% \begin{enumerate}
-% \item
+%
+% \begin{enumerate}
+% \item
% The presence of \cs{m@th} in association with \cs{ensuremath}
-% does not necessarily indicate fakemath. This is because
-% wanting mathsurround to be zero is very reasonable and common,
+% does not necessarily indicate fakemath. This is because
+% wanting mathsurround to be zero is very reasonable and common,
% \emph{even when the math is genuine} (and hence needs to be collected).
-%
-% TODO: this claim needs some examples.
-%
-% \item User-defined environments can create problems; but this area, of
-% new, copied and changed environments, has not yet been developed.
-%
+%
+% TODO: this claim needs some examples.
+%
+% \item User-defined environments can create problems; but this area, of
+% new, copied and changed environments, has not yet been developed.
+%
% \car*{Joseph wrote, inter alia:\\
% My thinking [regarding] \cs{RegisterMathEnvironment}\\
% - (New) Math environments should not be created-then-patched, but only
-% generated by a [(future)] dedicated command (\cs{DeclareMathEnvironment},
+% generated by a [(future)] dedicated command (\cs{DeclareMathEnvironment},
% presumably)\\
% - Math environments created with \pkg{ltcmd} [commands] should not be copied, . . .\\
% - Package authors should be able to manually set up math environments with a public boolean.}
-% \end{enumerate}
+% \end{enumerate}
%
%
% \subsection{Other ToDos}
%
% \begin{enumerate}
-% \item Add (some of) the math display commands that were \enquote{lifted from
+% \item Add (some of) the math display commands that were \enquote{lifted from
% plain}, e.g., \cs{displaylines} \cs{eqalign}(??).
% \item The breqn packages changes catcodes and that isn't yet covered
% by our mechanism.
% \item \cs{intertext} is not correctly taken into account by the
-% code splitting multiline math into subformulas.
+% code splitting multiline math into subformulas.
% \end{enumerate}
%
%
@@ -494,7 +663,7 @@
% neatly.
% \begin{macrocode}
\AddToHook{begindocument/before}{ \RequirePackage { amsmath } }
-% \end{macrocode}
+% \end{macrocode}
%
%
% \subsection{Data structures}
@@ -502,7 +671,7 @@
% \begin{variable}{\l_@@_collected_bool}
% Tracks whether math mode material has been collected, which happens inside
% \pkg{amsmath} environments as well as those handled directly here.
-% If true following math will not grab and/or process.
+% If true following math will not grab and/or process.
% See \ref{sec:mathcapture} for details.
% \begin{macrocode}
\bool_new:N \l_@@_collected_bool
@@ -511,7 +680,7 @@
%
% \begin{variable}{\l_@@_fakemath_bool}
% Tracks whether math mode material has been identified as fake math during
-% the grabbing phase, which happens currently if the
+% the grabbing phase, which happens currently if the
% grabbed contents contains the \cs{m@th} token.
%
% \begin{macrocode}
@@ -532,20 +701,21 @@
\tl_new:N \g_@@_grabbed_math_tl
% \end{macrocode}
% \end{variable}
-%
+%
% \begin{variable}{\l_@@_tmpa_tl,\l_@@_tmpa_skip,\l_@@_tmpa_str}
% Temporary variables
% \begin{macrocode}
\tl_new:N \l_@@_tmpa_tl
\skip_new:N \l_@@_tmpa_skip
+\str_new:N \l_@@_tmpa_str
% \end{macrocode}
% \end{variable}
%
% \begin{variable}{\l_@@_content_alt_tl,
% \l_@@_content_actual_tl,
% \l_@@_content_AF_tl}
-% Temporary variables to hold math content that should
-% be used in actual or alt text and stored as AF.
+% Temporary variables to hold math content that should
+% be used in actual or alt text and stored as AF.
% \begin{macrocode}
\tl_new:N \l_@@_content_alt_tl
\tl_new:N \l_@@_content_actual_tl
@@ -554,15 +724,15 @@
\tl_new:N \l_@@_content_AF_mathml_tl
% \end{macrocode}
% \end{variable}
-%
+%
% \subsection{Tagging tools}
-% The following commands implement small tagging code chunks.
+% The following commands implement small tagging code chunks.
% This should probably be collected and moved into tagpdf later.
% \begin{macro}{\__tag_tool_close_P:}
% This closes a P/text-chunk, both the MC and the structure and
% increases the counter manually.
% \begin{macrocode}
-\cs_new_protected:Npn \__tag_tool_close_P:
+\cs_new_protected:Npn \__tag_tool_close_P:
{
\tag_if_active:T
{
@@ -574,14 +744,14 @@
}
% \end{macrocode}
% \end{macro}
-%
-% We add also an attribute.
-% \begin{macrocode}
+%
+% We add also an attribute.
+% \begin{macrocode}
\tl_new:N\l_@@_attribute_class_tl
\tagpdfsetup
{role/new-attribute = {inline} {/O /Layout /Placement/Inline},
role/new-attribute = {display} {/O /Layout /Placement/Block},
- }
+ }
% \end{macrocode}
%
% \subsection{Code related to AF}
@@ -592,8 +762,12 @@
% \l__tag_math_mathml_AF_bool,
% \g__tag_math_mathml_AF_bool,
% \l__tag_math_mathml_pane_bool,
-% \l__tag_math_alt_bool
+% \l__tag_math_alt_bool,
+% \g__tag_math_luamml_tl,
% }
+% The variable \cs{g__tag_math_luamml_tl} is initially 0 and
+% the user key can set it to -1 or 1. This allows to distinguish
+% the unset case from a value set by the user.
% \begin{macrocode}
\bool_new:N\l__tag_math_texsource_AF_bool
\bool_new:N\l__tag_math_texsource_pane_bool
@@ -601,9 +775,11 @@
\bool_new:N\g__tag_math_mathml_AF_bool
\bool_new:N\l__tag_math_mathml_pane_bool
\bool_new:N\l__tag_math_alt_bool
+\tl_new:N\g__tag_math_luamml_tl
+\tl_gset:Nn\g__tag_math_luamml_tl {0}
% \end{macrocode}
% \end{variable}
-%
+%
% \begin{variable}{
% \g_@@_mathml_total_int,
% \g_@@_mathml_int,
@@ -613,13 +789,13 @@
% }
% \cs{g_@@_mml_total_int} records the mathml fragments read in.
% \cs{g_@@_mml_int} records the mathml fragments read in with a different hash.
-% \cs{g_@@_AF_total_int} records the number of math structures that try to
-% attach a mathml AF.
+% \cs{g_@@_AF_total_int} records the number of math structures that try to
+% attach a mathml AF.
% \cs{g_@@_AF_found_int} records the number of math structures for which a fitting
-% mathml is found.
+% mathml is found.
% \cs{g_@@_AF_attached_int} records the number of math structures which got a mathml fragment
% (if mathml-AF are not disabled locally this should be the equal to the previous number.
-%
+%
% \begin{macrocode}
\int_new:N\g_@@_mathml_total_int
\int_new:N\g_@@_mathml_int
@@ -631,13 +807,15 @@
%
% \begin{variable}{\l__tag_math_mathml_files_clist}
% A sequence to store the file list for the mathml.
+% We also check the luamml file.
% \begin{macrocode}
\clist_new:N\l__tag_math_mathml_files_clist
-\clist_put_right:Ne\l__tag_math_mathml_files_clist {\c_sys_jobname_str-mathml}
+\clist_put_right:Ne\l__tag_math_mathml_files_clist
+ {\c_sys_jobname_str-mathml,\c_sys_jobname_str-luamml-mathml}
% \end{macrocode}
% \end{variable}
-
-% This is the internal variant of the \cs{mml} command.
+%
+% This is the internal variant of the \cs{mml} command.
% \begin{macro}{\@@_AF_mml:nnnn}
% \begin{macrocode}
\cs_new_protected:Npn \@@_AF_mml:nnnn #1 #2 #3 #4
@@ -653,22 +831,22 @@
% \end{macrocode}
% a simple Desc key, take care that it is a valid string!
% \begin{macrocode}
- \pdfdict_put:nne {l_pdffile/Filespec} {Desc}{(mathml-#1)}
+ \pdfdict_put:nne {l_pdffile/Filespec} {Desc}{(mathml-#1)}
\pdffile_embed_stream:nnN {#4}{mathml-#1.xml}\l_@@_tmpa_tl
% \end{macrocode}
-% not strictly necessary but makes the files visible in the file attachment
-% page
+% not strictly necessary but makes the files visible in the file attachment
+% page
% \begin{macrocode}
\bool_if:NT \l__tag_math_mathml_pane_bool
{\pdfmanagement_add:nne {Catalog/Names}{EmbeddedFiles}{\l_@@_tmpa_tl}}
\tl_new:c{g_@@_mathml_#3_tl}
- \tl_gset_eq:cN{g_@@_mathml_#3_tl}\l_@@_tmpa_tl
+ \tl_gset_eq:cN{g_@@_mathml_#3_tl}\l_@@_tmpa_tl
}
- }
+ }
% \end{macrocode}
% \end{macro}
%
-% The html reader.
+% The html reader.
% \begin{macrocode}
\cs_new_protected:Npn \@@_AF_html_reader:w#1</h2>#2<p>#3</p>#4<p>#5</p>#6<math{
\begingroup
@@ -685,39 +863,397 @@
\@@_AF_mml:nnnn{#1}{#2}{#3}{#4}
}
% \end{macrocode}
+%
+% As with luatex we write two files we define a few constants for
+% the shared texts.
+%
+% \begin{macro}
+% {\c_@@_mathml_write_init_tl,\l_@@_mathml_write_before_tl,
+% \c_@@_mathml_write_after_tl,\c_@@_mathml_write_final_tl}
+% \begin{macrocode}
+\tl_const:Nn \c_@@_mathml_write_init_tl
+ {
+ <!DOCTYPE~html>
+ \iow_newline:
+ <html>
+ \iow_newline:
+ }
+\tl_new:N \l_@@_mathml_write_before_tl
+\tl_const:Nn \c_@@_mathml_write_after_tl
+ {
+ \iow_newline:
+ </div>
+ \iow_newline:
+ }
+\tl_const:Nn \c_@@_mathml_write_final_tl
+ {
+ </html>
+ }
+% \end{macrocode}
+% \end{macro}
+
+% \begin{socketdecl}{tagsupport/math/mathml/write/prepare}
+% To prepare the hash and the starting command we use a socket, so
+% that both the dummy and luamml can make use of it.
+% \begin{macrocode}
+\socket_new:nn {tagsupport/math/mathml/write/prepare}{0}
+% \end{macrocode}
+% \end{socketdecl}
+%
+% \begin{plugdecl}{On}
+% \begin{macrocode}
+\socket_new_plug:nnn{tagsupport/math/mathml/write/prepare}{On}
+ {
+ \str_set:NV\l_@@_tmpa_str\l_@@_content_AF_source_tl
+ \str_replace_all:Nnn\l_@@_tmpa_str{&}{&amp;}
+ \str_replace_all:Nnn\l_@@_tmpa_str{<}{&lt;}
+ \tl_set:Nn \l_@@_mathml_write_before_tl
+ {
+ <div>
+ \iow_newline:
+ <h2>\c_backslash_str mml\c_space_tl \int_use:N \g_@@_math_total_int </h2>
+ \iow_newline:
+ <p>\l_@@_tmpa_str</p>
+ \iow_newline:
+ <p>\l_@@_content_hash_tl </p>
+ \iow_newline:
+ }
+ }
+% \end{macrocode}
+% \end{plugdecl}
+%
+% With luatex we automatically generate mathml with \pkg{luamml} if the package
+% can be loaded and \pkg{unicode-math} is detected.
+% We start the process in the begindocument/end hook
+% so that the reading from a previous compilation can happen before!
+%
+% For other engines, for future name changes
+% and in case luamml is not loaded we provide
+% some commands
+% \begin{macrocode}
+\cs_new_protected:Npn\@@_provide_luamml_commands:
+ {
+ \providecommand\luamml_flag_structelem:{}
+ \cs_if_free:NT \luamml_structelem:
+ {
+ \cs_set_eq:NN\luamml_structelem:\luamml_flag_structelem:
+ }
+ \providecommand\luamml_flag_process:{}
+ \cs_if_free:NT \luamml_process:
+ {
+ \cs_set_eq:NN\luamml_process:\luamml_flag_process:
+ }
+ \providecommand\luamml_flag_ignore:{}
+ \cs_if_free:NT \luamml_ignore:
+ {
+ \cs_set_eq:NN\luamml_ignore:\luamml_flag_ignore:
+ }
+ }
+% \end{macrocode}
+% \begin{macrocode}
+\sys_if_engine_luatex:TF
+ {
+% \end{macrocode}
+% Temporary (!) fixes for endarray
+% \begin{macrocode}
+ \cs_new_protected:Npn \@@_correct_luamml_array_patches:
+ {
+ \AddToHook{package/array/after}
+ {
+ \cs_set:Npn \endarray
+ {
+ \tbl_crcr:n{endarray}
+ \__luamml_array_save_array:
+ \egroup
+ \UseTaggingSocket{tbl/finalize}
+ \tbl_restore_outer_cell_data:
+ \egroup
+ \mode_if_math:T { \__luamml_array_finalize_array: }
+ \@arrayright
+ \gdef \@preamble {}
+ }
+ \cs_set:Npn \@classz
+ {
+ \@classx
+ \@tempcnta \count@
+ \prepnext@tok
+ \@addtopreamble {
+ \ifcase \@chnum
+ \hfil
+ \hskip 1sp
+ \d@llarbegin
+ \cs_if_eq:NNTF \d@llarbegin \begingroup {
+ \insert@column
+ \d@llarend
+ } {
+ \__luamml_array_init_col:
+ \insert@column
+ \luamml_flag_save:nn {} {mtd}
+ \d@llarend
+ \__luamml_array_finalize_col:w 0~
+ }
+ \do@row@strut
+ \hfil
+ \or
+ \hskip 1sp
+ \d@llarbegin
+ \cs_if_eq:NNTF \d@llarbegin \begingroup {
+ \insert@column
+ \d@llarend
+ } {
+ \__luamml_array_init_col:
+ \insert@column
+ \luamml_flag_save:nn {} {mtd}
+ \d@llarend
+ \__luamml_array_finalize_col:w 1~
+ }
+ \do@row@strut
+ \hfil
+ \or
+ \hfil
+ \hskip 1sp
+ \d@llarbegin
+ \cs_if_eq:NNTF \d@llarbegin \begingroup {
+ \insert@column
+ \d@llarend
+ } {
+ \__luamml_array_init_col:
+ \insert@column
+ \luamml_flag_save:nn {} {mtd}
+ \d@llarend
+ \__luamml_array_finalize_col:w 2~
+ }
+ \do@row@strut
+ \or
+ \setbox \ar@mcellbox \vbox \@startpbox { \@nextchar }
+ \insert@pcolumn
+ \@endpbox
+ \ar@align@mcell
+ \do@row@strut
+ \or
+ \vtop \@startpbox { \@nextchar }
+ \insert@pcolumn
+ \@endpbox
+ \do@row@strut
+ \or
+ \vbox \@startpbox { \@nextchar }
+ \insert@pcolumn
+ \@endpbox
+ \do@row@strut
+ \fi
+ }
+ \prepnext@tok
+ }
+ }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+ \AddToHook{begindocument/before}
+ {
+ \str_case:on \g_@@_luamml_load_tl
+ {
+ { 1 } {
+ \RequirePackage { luamml }
+ \@@_correct_luamml_array_patches:
+ \AddToHook{begindocument/end}
+ {
+ \@@_luamml_activate_write:
+ }
+ }
+ {-1 } {
+ \AddToHook{begindocument/end}
+ {
+ \msg_note:nnnn { tag }
+ { luamml-status }{ disabled }{ not~create }
+ }
+ }
+ { 0 }
+ {
+ \@ifpackageloaded { unicode-math }
+ {
+ \RequirePackage { luamml }
+ \@@_correct_luamml_array_patches:
+ \AddToHook{begindocument/end}
+ {
+ \@@_luamml_activate_write:
+ }
+ }
+ { \msg_warning:nn { tag }{ unicode-math-missing } }
+ }
+ }
+ \@@_provide_luamml_commands:
+ }
+ }
+ {
+ \@@_provide_luamml_commands:
+ }
+\msg_new:nnn { tag }{ luamml-status }
+ {
+ luamml~has~been~#1~and~will~#2~an~MathML~file.
+ }
+\msg_new:nnn { tag }{ unicode-math-missing }
+ {
+ The~package~unicode-math~is~missing\\
+ luamml~will~not~create~an~MathML~file.\\
+ To~avoid~this~warning~load~unicode-math~\\
+ or~disable~luamml~with~\\
+ \tl_to_str:n{\tagpdfsetup{math/mathml/luamml/load=false}}\\
+ or~force~luamml~with~\\
+ \tl_to_str:n{\tagpdfsetup{math/mathml/luamml/load=true}}
+ }
+\cs_new_protected:Npn \@@_luamml_activate_write:
+ {
+ \bool_if:NT \g_@@_luamml_write_bool
+ {
+% \end{macrocode}
+% to avoid that nothing is written in the first run, we must activate the sockets:
+% \begin{macrocode}
+ \bool_gset_true:N\g__tag_math_mathml_AF_bool
+ \AssignSocketPlug{tagsupport/math/struct/begin}{mathml-AF}
+ \AssignSocketPlug{tagsupport/math/struct/end}{mathml-AF}
+ \AssignSocketPlug{tagsupport/math/substruct/begin}{single}
+ \AssignSocketPlug{tagsupport/math/substruct/end}{single}
+ \int_set:Nn \l__luamml_pretty_int { 7 }
+ \RegisterFamilyMapping\symsymbols{oms}
+ \RegisterFamilyMapping\symletters{oml}
+ \AssignSocketPlug{tagsupport/math/mathml/write/prepare}{On}
+ \iow_new:N \g_@@_luamml_iow
+ \iow_open:Nn \g_@@_luamml_iow {\c_sys_jobname_str-luamml-mathml.html}
+ \iow_now:Ne \g_@@_luamml_iow { \c_@@_mathml_write_init_tl }
+ \cs_new:Npn \@@_luamml_output_hook:n ##1
+ {
+ \tl_if_empty:NF \l_@@_mathml_write_before_tl
+ {
+ \iow_now:Ne \g_@@_luamml_iow
+ {
+ \l_@@_mathml_write_before_tl
+ ##1
+ \c_@@_mathml_write_after_tl
+ }
+ }
+ }
+ \__luamml_register_output_hook:N \@@_luamml_output_hook:n
+% \end{macrocode}
+% At the end of the document we must finish and close the file:
+% \begin{macrocode}
+ \AddToHook{enddocument/afterlastpage}
+ {
+ \iow_now:Ne \g_@@_luamml_iow
+ { \c_@@_mathml_write_final_tl }
+ \iow_close:N \g_@@_luamml_iow
+ }
+ \msg_note:nnnn { tag }
+ { luamml-status }{ enabled }{ create }
+ }
+ }
+% \end{macrocode}
+% And now keys to activate/deactivate luamml feature
+% \begin{variable}{\g_@@_luamml_load_tl}
+% This variable will be used to suppress the loading of luamml
+% altogether.
+% \begin{macrocode}
+\tl_new:N \g_@@_luamml_load_tl
+\tl_gset:Nn \g_@@_luamml_load_tl {0}
+% \end{macrocode}
+% \end{variable}
+% \begin{variable}{\g_@@_luamml_write_bool}
+% This variable decides if luamml writes a mathml
+% altogether.
+% \begin{macrocode}
+\bool_new:N \g_@@_luamml_write_bool
+\bool_gset_true:N \g_@@_luamml_write_bool
+% \end{macrocode}
+% \end{variable}
+% \begin{macro}{\@@_luamml_ignore:,\@@_luamml_structelem:}
+% Internal variants of the luamml commands, that can be remapped if needed.
+% \begin{macrocode}
+\cs_new:Npn\@@_luamml_structelem:{}
+\cs_new:Npn\@@_luamml_ignore:{}
+% \end{macrocode}
+% \end{macro}
%
+% \begin{macrocode}
+\msg_new:nnn { tag }{ PDF-2.0-recommended }
+ {
+ The~key~#1~will~not~work~properly~with~PDF~#2.\\
+ Switching~to~PDF~2.0~is~recommended.
+ }
+\keys_define:nn { __tag / setup }
+ {
+% \end{macrocode}
+% At first a key to suppress the loading altogether
+% \begin{macrocode}
+ math/mathml/luamml/load .choice: ,
+ math/mathml/luamml/load/true .code:n = {\tl_gset:Nn \g_@@_luamml_load_tl{1}},
+ math/mathml/luamml/load/false .code:n = {\tl_gset:Nn \g_@@_luamml_load_tl{-1}},
+ math/mathml/luamml/load .default:n = true,
+ math/mathml/luamml/load .usage:n=preamble,
+% \end{macrocode}
+% A key to activate math structure elements.
+% \changes{v0.6j}{2024-11-19}{no longer enable globally for better fake math handling, issue \#764}
+% \begin{macrocode}
+ math/mathml/structelem .choice:,
+ math/mathml/structelem/true .code:n =
+ {
+ \pdf_version_compare:NnT < {2.0}
+ {
+ \msg_warning:nnne { tag }{ PDF-2.0-recommended }
+ { math/mathml/structelem }{ \pdf_version: }
+ }
+ \cs_set:Npn\@@_luamml_structelem:{\luamml_structelem:}
+ \cs_set:Npn\@@_luamml_ignore:{\luamml_ignore:}
+ },
+ math/mathml/structelem/false .code:n =
+ {
+ \cs_set_eq:NN\@@_luamml_structelem:\prg_do_nothing:
+ \cs_set_eq:NN\@@_luamml_ignore:\prg_do_nothing:
+ },
+ math/mathml/structelem .default:n = true,
+% \end{macrocode}
+% and a key to call the ignore flag. This should only be used locally.
+% \begin{macrocode}
+ math/mathml/ignore .code:n = {\luamml_ignore:},
+% \end{macrocode}
+% \begin{macrocode}
+ math/mathml/luamml/write .choice:,
+ math/mathml/luamml/write/true .code:n =
+ {
+ \tl_gset:Nn \g_@@_luamml_load_tl{1}
+ \bool_gset_true:N \g_@@_luamml_write_bool
+ },
+ math/mathml/luamml/write/false .code:n =
+ {
+ \bool_gset_false:N \g_@@_luamml_write_bool
+ },
+ math/mathml/luamml/write .default:n = true,
+ math/mathml/luamml/write .usage:n=preamble,
+% \end{macrocode}
+% alias keys for compatibility
+% \begin{macrocode}
+ math/mathml/luamml .bool_gset:N = \g_@@_luamml_write_bool,
+ math/mathml/luamml .usage:n=preamble
+ }
+% \end{macrocode}
% \begin{socketdecl}{tagsupport/math/mathml/write}
% This writes a html-dummy with the hash and the math content.
% This should be optional, so it uses a socket that can be disabled
-%
+%
% \begin{macrocode}
\socket_new:nn {tagsupport/math/mathml/write}{0}
% \end{macrocode}
% \end{socketdecl}
-%
+%
% \begin{plugdecl}{On}
% \begin{macrocode}
\socket_new_plug:nnn{tagsupport/math/mathml/write}{On}
{
- \str_set:NV\l_@@_tmpa_str\l_@@_content_AF_source_tl
- \str_replace_all:Nnn\l_@@_tmpa_str{&}{&amp;}
- \str_replace_all:Nnn\l_@@_tmpa_str{<}{&lt;}
- \iow_now:Ne \g_@@_writedummy_iow
+ \iow_now:Ne \g_@@_writedummy_iow
{
- \iow_newline:
- <div>
- \iow_newline:
- <h2>\c_backslash_str mml\c_space_tl \int_use:N \g_@@_math_total_int </h2>
- \iow_newline:
- <p>\l_@@_tmpa_str</p>
- \iow_newline:
- <p>\l_@@_content_hash_tl </p>
- \iow_newline:
+ \l_@@_mathml_write_before_tl
<math></math>
- \iow_newline:
- </div>
- \iow_newline:
+ \c_@@_mathml_write_after_tl
}
}
% \end{macrocode}
@@ -727,32 +1263,32 @@
\keys_define:nn { __tag / setup }
{
- math/mathml/write-dummy .code:n =
+ math/mathml/write-dummy .code:n =
{
\bool_gset_true:N \g__tag_math_mathml_AF_bool
- \tl_if_exist:NF\g_@@_writedummy_iow
+ \tl_if_exist:NF\g_@@_writedummy_iow
{
\iow_new:N \g_@@_writedummy_iow
- \iow_open:Nn \g_@@_writedummy_iow
- {
+ \iow_open:Nn \g_@@_writedummy_iow
+ {
\c_sys_jobname_str-mathml-dummy.html
}
\iow_now:Ne \g_@@_writedummy_iow
{
- <!DOCTYPE~html>
- \iow_newline:
- <html>
+ \c_@@_mathml_write_init_tl
}
+ \AssignSocketPlug {tagsupport/math/mathml/write/prepare}{On}
\AssignSocketPlug {tagsupport/math/mathml/write}{On}
\AddToHook{enddocument/afterlastpage}
{
- \iow_now:Nn \g_@@_writedummy_iow {</html>}
+ \iow_now:Ne \g_@@_writedummy_iow
+ { \c_@@_mathml_write_final_tl }
\iow_close:N \g_@@_writedummy_iow
}
- }
+ }
},
- math/mathml/write-dummy .usage:n=preamble
- }
+ math/mathml/write-dummy .usage:n=preamble
+ }
% \end{macrocode}
%
% \begin{macro}{\@@_AF_process_mathml_files:}
@@ -763,9 +1299,9 @@
\hbox_set:Nn \l_@@_tmpa_box
{
\pdfdict_put:nnn { l_pdffile/Filespec }{AFRelationship} { /Supplement }
- \pdfdict_put:nne
- { l_pdffile }{Subtype}
- { \pdf_name_from_unicode_e:n{application/mathml+xml} }
+ \pdfdict_put:nne
+ { l_pdffile }{Subtype}
+ { \pdf_name_from_unicode_e:n{application/mathml+xml} }
\char_set_catcode_other:N \#
\cs_set_eq:NN\mml \@@_AF_html_reader:w
\clist_map_inline:Nn \l__tag_math_mathml_files_clist
@@ -779,13 +1315,13 @@
{
\typeout{Info:~mathml~file~##1~does~not~exist}%info message
}
- }
+ }
}
\bool_if:NT\g__tag_math_mathml_AF_bool
{
\typeout{Info:~Activating~mathml~support}
- \AssignSocketPlug{tagsupport/math/struct/begin}{test-mathml}
- \AssignSocketPlug{tagsupport/math/struct/end}{test-mathml}
+ \AssignSocketPlug{tagsupport/math/struct/begin}{mathml-AF}
+ \AssignSocketPlug{tagsupport/math/struct/end}{mathml-AF}
% \end{macrocode}
% mathml handling doesn't like subparts, so we disable them for now:
% \begin{macrocode}
@@ -795,29 +1331,29 @@
{
\iow_term:n{MathML~statistic}
\iow_term:n{================}
- \iow_term:e{==>~\int_use:N\g_@@_mathml_total_int\c_space_tl
+ \iow_term:e{==>~\int_use:N\g_@@_mathml_total_int\c_space_tl
MathML~fragments~read}
- \iow_term:e{==>~\int_use:N\g_@@_mathml_int\c_space_tl
+ \iow_term:e{==>~\int_use:N\g_@@_mathml_int\c_space_tl
different~MathML~fragments}
- \iow_term:e{==>~\int_use:N\g_@@_math_total_int\c_space_tl
+ \iow_term:e{==>~\int_use:N\g_@@_math_total_int\c_space_tl
math~fragments~found}
- \iow_term:e{==>~\int_use:N\g_@@_mathml_AF_found_int\c_space_tl
+ \iow_term:e{==>~\int_use:N\g_@@_mathml_AF_found_int\c_space_tl
fitting~MathML~AF~found}
- \iow_term:e{==>~\int_use:N\g_@@_mathml_AF_attached_int\c_space_tl
+ \iow_term:e{==>~\int_use:N\g_@@_mathml_AF_attached_int\c_space_tl
MathML~AF~attached}
}
- }
+ }
}
-\AddToHook{begindocument}{\@@_AF_process_mathml_files:}
+\AddToHook{begindocument}{\@@_AF_process_mathml_files:}
% \end{macrocode}
% \end{macro}
-%
+%
% \subsection{Mathstyle detection}
% In some cases we need to detect the mathstyle used in a \cs{mathchoice}
-% command and to disable/enable tagging in the unused branches.
+% command and to disable/enable tagging in the unused branches.
% This is currently only used in the amstext command \cs{text}
% but is perhaps also needed in other cases, so we create a general command.
-%
+%
%\begin{macro}{\l_@@_mathstyle_int,\g_@@_mathchoice_int,mathstyle}
% \begin{macrocode}
\int_new:N \l_@@_mathstyle_int
@@ -828,43 +1364,64 @@
% For now internal, but perhaps will need a public version.
% The command should be used in every branch of a \cs{mathchoice}
% (with the correct mathstyle number) and with an unique label (which should
-% be the same in every branch).
-% \cs{g_@@_mathchoice_int} can be e.g. increased before the mathchoice and
+% be the same in every branch).
+% \cs{g_@@_mathchoice_int} can be, e.g., increased before the mathchoice and
% then used.
% \begin{macro}{\@@_tag_if_mathstyle:nn}
% \begin{macrocode}
-\cs_new_protected:Npn \@@_tag_if_mathstyle:nn #1 #2
+\cs_new_protected:Npn \@@_tag_if_mathstyle:nn #1 #2
%#1 refers to label
%#2 is a number for the mathstyle (typically 0,2,4,6)
{
\int_set:Nn \l_@@_mathstyle_int {#2}
\property_record:nn {#1} { mathstyle }
\int_compare:nNnTF { \property_ref:nn {#1}{ mathstyle} } = { #2 }
- { \tag_start: }{ \tag_stop: }
+ { \tag_resume:n{\mathchoice} }{ \tag_suspend:n{\mathchoice} }
}
-\cs_generate_variant:Nn \@@_tag_if_mathstyle:nn {en}
+\cs_generate_variant:Nn \@@_tag_if_mathstyle:nn {en}
% \end{macrocode}
% \end{macro}
-%
+%
% \subsection{Tagging options}
% \begin{macrocode}
\keys_define:nn { __tag / setup }
{
math/mathml/sources .clist_set:N = \l__tag_math_mathml_files_clist,
- math/alt/use .bool_set:N = \l__tag_math_alt_bool,
+ math/alt/use .bool_set:N = \l__tag_math_alt_bool,
viewer/pane/mathml .bool_set:N = \l__tag_math_mathml_pane_bool,
viewer/pane/mathml .initial:n = true,
- viewer/pane/mathsource .bool_set:N = \l__tag_math_texsource_pane_bool,
+ viewer/pane/mathsource .bool_set:N = \l__tag_math_texsource_pane_bool,
math/mathml/AF .bool_set:N = \l__tag_math_mathml_AF_bool,
math/mathml/AF .initial:n = true,
math/tex/AF .bool_set:N = \l__tag_math_texsource_AF_bool,
math/tex/AF .initial:n = true
- }
+ }
+% \end{macrocode}
+% alt is required for pdf/UA-1.
+% TODO: l3pdfmeta should support this test.
+% \begin{macrocode}
+\AddToHook{begindocument/end}
+ {
+ \str_if_eq:eeT
+ {1}
+ {
+ \exp_last_unbraced:Ne\use_i:nn
+ {\GetDocumentProperties{document/pdfstandard-UA}}
+ \c_empty_tl\c_empty_tl
+ }
+ {
+ \bool_if:NF \l__tag_math_alt_bool
+ {
+ \typeout{PDF/UA-1~detected.~Enabling~alt~text~on~Formula}
+ }
+ \bool_set_true:N\l__tag_math_alt_bool
+ }
+ }
% \end{macrocode}
%
% \subsection{Sockets}
% \subsubsection{Main inline math sockets}
-%
+%
% \begin{socketdecl}
% {
% tagsupport/math/inline/begin,
@@ -873,20 +1430,22 @@
% tagsupport/math/inline/formula/end,
% }
% The first two sockets are meant to embed inline
-% math into the surrounding (so to close/reopen e.g. MC-chunks).
-% The other two implement the actual formula structure.
+% math into the surrounding (so to close/reopen, e.g., MC-chunks).
+% The other two implement the actual formula structure.
% The formula sockets are despite their naming not symmetric:
-% the begin socket is issued after the math has started, while
-% the end socket is after the math!
+% the begin socket is issued after the math has started, while
+% the end socket is after the math!
+% \changes{v0.6j}{2024-11-19}{change the socket to two arguments so that it can
+% be used as tagging socket}
% \begin{macrocode}
\socket_new:nn {tagsupport/math/inline/begin}{0}
\socket_new:nn {tagsupport/math/inline/end}{0}
-\socket_new:nn {tagsupport/math/inline/formula/begin}{1} %
+\socket_new:nn {tagsupport/math/inline/formula/begin}{2} %
\socket_new:nn {tagsupport/math/inline/formula/end}{0}
% \end{macrocode}
%\end{socketdecl}
-%
-%
+%
+%
% \begin{plugdecl}{MC}
% \begin{macrocode}
\socket_new_plug:nnn
@@ -896,39 +1455,45 @@
\socket_new_plug:nnn
{tagsupport/math/inline/end}
{MC}
- {\tag_mc_begin_pop:n{}}
+ {\tag_mc_begin_pop:n{}}
% \end{macrocode}
% \end{plugdecl}
-%
-% We probably will want to test different tagging receipes.
+%
+% We probably will want to test different tagging recipes.
% \begin{plugdecl}{default}
% \begin{macrocode}
\socket_new_plug:nnn
{tagsupport/math/inline/formula/begin}
{default}
- {
- \socket_use:n{tagsupport/math/content}
- \socket_use:n{tagsupport/math/struct/begin}
+% \end{macrocode}
+% \changes{v0.6g}{2024-10-02}{disable paratagging, issue \#711}
+% \changes{v0.6j}{2024-11-19}{activate structelem locally issue \#764}
+% \changes{v0.6j}{2024-11-19}{change to two arguments}
+% \begin{macrocode}
+ { \tagpdfparaOff
+ \@@_luamml_structelem:
+ \tag_socket_use:n{math/content}
+ \tag_socket_use:n{math/struct/begin}
% \end{macrocode}
% TODO: does inline math need subformula handling?
% \begin{macrocode}
% inner formula if multiple parts (not really implemented yet)
- \socket_use:n{tagsupport/math/substruct/begin}
- #1
- \socket_use:n{tagsupport/math/end}
+ \tag_socket_use:n{math/substruct/begin}
+ #2
+ \tag_socket_use:n{math/end}
}
\socket_new_plug:nnn
{tagsupport/math/inline/formula/end}
{default}
- {
+ {
\socket_use:n{tagsupport/math/substruct/end}
\socket_use:n{tagsupport/math/struct/end}
- }
+ }
% \end{macrocode}
% \end{plugdecl}
-%
+%
% \subsubsection{Main display math sockets}
-%
+%
% \begin{socketdecl}
% {
% tagsupport/math/display/begin,
@@ -937,16 +1502,17 @@
% tagsupport/math/display/formula/end,
% }
% The first two sockets are meant to embed display
-% math into the surrounding (so to close/reopen e.g. MC-chunks and
+% math into the surrounding (so to close/reopen, e.g., MC-chunks and
% P-structure).
-% The other two implement the actual formula structure.
+% The other two implement the actual formula structure.
% The formula sockets are despite their naming not symmetric:
-% the begin socket is issued after the math has started, while
-% the end socket is after the math!
+% the begin socket is issued after the math has started, while
+% the end socket is after the math!
+% \changes{v0.6j}{2024-11-19}{change number of arguments of formula/begin socket}
% \begin{macrocode}
\socket_new:nn {tagsupport/math/display/begin}{0}
\socket_new:nn {tagsupport/math/display/end}{0}
-\socket_new:nn {tagsupport/math/display/formula/begin}{1} %
+\socket_new:nn {tagsupport/math/display/formula/begin}{2} %
\socket_new:nn {tagsupport/math/display/formula/end}{0}
% \end{macrocode}
%\end{socketdecl}
@@ -961,35 +1527,38 @@
{tagsupport/math/display/end}
{default}
{
- }
+ }
% \end{macrocode}
% \end{plugdecl}
% \begin{plugdecl}{default}
+% \changes{v0.6j}{2024-11-19}{moved \cs{tagpdfparaOff} into the socket, tagging/765}
% \begin{macrocode}
\socket_new_plug:nnn
{tagsupport/math/display/formula/begin}
{default}
- {
- \socket_use:n{tagsupport/math/content}
- \socket_use:n{tagsupport/math/struct/begin}
- \socket_use:n{tagsupport/math/substruct/begin}
- #1
- \socket_use:n{tagsupport/math/end}
+ {
+ \tagpdfparaOff
+ \@@_luamml_structelem:
+ \tag_socket_use:n{math/content}
+ \tag_socket_use:n{math/struct/begin}
+ \tag_socket_use:n{math/substruct/begin}
+ #2
+ \tag_socket_use:n{math/end}
}
\socket_new_plug:nnn
{tagsupport/math/display/formula/end}
{default}
- {
+ {
\socket_use:n{tagsupport/math/substruct/end}
\socket_use:n{tagsupport/math/struct/end}
- }
+ }
% \end{macrocode}
% \end{plugdecl}
%
% \subsubsection{Internal sockets}
-%
+%
% \begin{variable}{\l_@@_content_template_tl}
% The default text used as alt or actual text.
% \begin{macrocode}
@@ -1003,7 +1572,7 @@
\c_space_tl
\exp_not:N\end{\g_@@_grabbed_env_tl}
\c_space_tl LaTeX~ formula~ ends~
- }
+ }
% \end{macrocode}
% \end{variable}
@@ -1013,7 +1582,7 @@
\tl_new:N\l_@@_texsource_template_tl
\tl_const:Nn\c_@@_inline_env_tl {math}
\tl_set:Nn \l_@@_texsource_template_tl
- {
+ {
\tl_if_eq:NNTF\g_@@_grabbed_env_tl\c_@@_inline_env_tl
{
$
@@ -1024,29 +1593,29 @@
\exp_not:N\begin{\g_@@_grabbed_env_tl}
\exp_not:V\g_@@_grabbed_math_tl
\exp_not:N\end{\g_@@_grabbed_env_tl}
- }
- }
+ }
+ }
% \end{macrocode}
% \end{variable}
-%
+%
% \begin{socketdecl}{tagsupport/math/content}
-% The math content is stored in associated files and used for
+% The math content is stored in associated files and used for
% actual and alternative text. As the exact text is still
% unclear we use a socket to be able to test variants.
% The socket should set all four tl vars above, if needed
-% to identical values. It can use the two variables
+% to identical values. It can use the two variables
% \cs{g_@@_grabbed_env_tl} and \cs{g_@@_grabbed_math_tl}
% \begin{macrocode}
\socket_new:nn {tagsupport/math/content}{0}
% \end{macrocode}
% \end{socketdecl}
-%
+%
% Some default sockets to set the contents.
-% TODO: think about naming convention.
+% TODO: think about naming convention.
% TODO: think how this should organized so that one
% has options to change from the outside and so that
-% there are less repetitions.
+% there are less repetitions.
% \begin{plugdecl}{actual+source}
% \begin{macrocode}
\socket_new_plug:nnn
@@ -1056,17 +1625,17 @@
\tl_set:Ne\l_@@_content_actual_tl
{
\l_@@_content_template_tl
- }
- \tl_set:Ne \l_@@_content_AF_source_tl
+ }
+ \tl_set:Ne \l_@@_content_AF_source_tl
{
\l_@@_texsource_template_tl
- }
+ }
\tl_set:Nn \l_@@_content_AF_mathml_tl {}
\tl_set:Nn \l_@@_content_alt_tl {}
}
% \end{macrocode}
-% \end{plugdecl}
-%
+% \end{plugdecl}
+%
% \begin{plugdecl}{alt+source}
% \begin{macrocode}
\socket_new_plug:nnn
@@ -1076,26 +1645,26 @@
\tl_set:Ne\l_@@_content_alt_tl
{
\l_@@_content_template_tl
- }
- \tl_set:Ne \l_@@_content_AF_source_tl
+ }
+ \tl_set:Ne \l_@@_content_AF_source_tl
{
\l_@@_texsource_template_tl
- }
+ }
\tl_set:Nn \l_@@_content_AF_mathml_tl {}
\tl_set:Nn \l_@@_content_actual_tl {}
}
% \end{macrocode}
% \end{plugdecl}
% \begin{macrocode}
-\socket_assign_plug:nn {tagsupport/math/content}{alt+source}
+\socket_assign_plug:nn {tagsupport/math/content}{alt+source}
% \end{macrocode}
%
% \begin{socketdecl}{tagsupport/math/struct/begin,
% tagsupport/math/struct/end}
-% For the main structure we use a socket too.
-% This allow e.g. to create a special one for luamml
-% which setups additional objects.
-% The begin socket can use the two variables
+% For the main structure we use a socket too.
+% This allows, e.g., to create a special one for luamml
+% which setups additional objects.
+% The begin socket can use the two variables
% \cs{g_@@_grabbed_env_tl} and \cs{g_@@_grabbed_math_tl}
% \begin{macrocode}
\socket_new:nn {tagsupport/math/struct/begin}{0}
@@ -1110,12 +1679,22 @@
{tagsupport/math/struct/begin}
{default}
{
- \bool_if:NTF\l__tag_math_texsource_AF_bool
+ \bool_if:NTF\l__tag_math_texsource_AF_bool
{ \tl_set_eq:NN \l_@@_content_AF_source_tmpa_tl \l_@@_content_AF_source_tl }
{ \tl_clear:N \l_@@_content_AF_source_tmpa_tl }
+ \tl_if_eq:NnTF\g_@@_grabbed_env_tl {math}
+ {
+ \tl_set:Nn\l_@@_attribute_class_tl{inline}
+ }
+ {
+ \tl_set:Nn\l_@@_attribute_class_tl{display}
+ }
+ \bool_if:NF\l__tag_math_alt_bool
+ { \tl_set:Nn \l_@@_content_alt_tl{} }
\tag_struct_begin:n
{
tag=Formula,
+ attribute-class=\l_@@_attribute_class_tl,
texsource = \l_@@_content_AF_source_tmpa_tl,
title-o = \g_@@_grabbed_env_tl,
actualtext = \l_@@_content_actual_tl,
@@ -1126,19 +1705,18 @@
{tagsupport/math/struct/end}
{default}
{ \tag_struct_end: }
-
-\socket_assign_plug:nn {tagsupport/math/struct/begin}{default}
-\socket_assign_plug:nn {tagsupport/math/struct/end}{default}
-% \end{macrocode}
-% \end{plugdecl}
-%
-% \begin{plugdecl}{test-mathml}
-% This (test-)socket tries to add a mathml-AF to formula.
-% It is activated if a mathml.html has been found and loaded.
-% Additionally it also sets an attribute
-% (this can perhaps be done by default anyway.)
-% As it disturbs the reading of the AF it currently deactivates the /Alt key,
-% unless it has been reenabled with |math/alt/use=true|
+
+\socket_assign_plug:nn {tagsupport/math/struct/begin}{default}
+\socket_assign_plug:nn {tagsupport/math/struct/end}{default}
+% \end{macrocode}
+% \end{plugdecl}
+%
+% \begin{plugdecl}{mathml-AF}
+% This socket tries to add a mathml-AF to formula.
+% It is activated if a mathml.html has been found and loaded.
+% As it disturbs the reading of the AF
+% it currently deactivates the /Alt key,
+% unless it has been reenabled with |math/alt/use=true|
% \begin{macrocode}
\cs_generate_variant:Nn \str_mdfive_hash:n {o}
\tl_new:N\l_@@_content_hash_tl
@@ -1151,48 +1729,52 @@
% \begin{macrocode}
\socket_new_plug:nnn
{tagsupport/math/struct/begin}
- {test-mathml}
- {
- \int_gincr:N\g_@@_math_total_int
- \tl_set:Ne\l_@@_content_hash_tl
- {\str_mdfive_hash:o { \l_@@_content_AF_source_tl }}
- \tl_set_eq:NN\l_@@_grabbed_math_tl\g_@@_grabbed_math_tl
+ {mathml-AF}
+ {
+ \int_gincr:N\g_@@_math_total_int
+ \tl_set:Ne\l_@@_content_hash_tl
+ {\str_mdfive_hash:o { \l_@@_content_AF_source_tl }}
+ \tl_set_eq:NN\l_@@_grabbed_math_tl\g_@@_grabbed_math_tl
\tl_if_eq:NnTF\g_@@_grabbed_env_tl {math}
{
- \tl_set:Nn\l_@@_attribute_class_tl{inline}
+ \tl_set:Nn\l_@@_attribute_class_tl{inline}
}
{
\tl_set:Nn\l_@@_attribute_class_tl{display}
}
\bool_if:NF\l__tag_math_alt_bool
- { \tl_set:Nn \l_@@_content_alt_tl{} }
+ { \tl_set:Nn \l_@@_content_alt_tl{} }
% \end{macrocode}
% debugging option. TODO: hide in debug key.
% \begin{macrocode}
\tl_if_exist:cTF { g_@@_mathml_ \l_@@_content_hash_tl _tl }
- {
- \int_gincr:N\g_@@_mathml_AF_found_int
- \bool_if:NTF \l__tag_math_mathml_AF_bool
- {
- \int_gincr:N\g_@@_mathml_AF_attached_int
- \typeout {Inserting~mathml~with~Hash~\l_@@_content_hash_tl}
- }
- {
- \typeout {Ignoring~mathml~with~Hash~\l_@@_content_hash_tl}
- }
- }
- {
- \typeout{WARNING:~mathml~missing~for~hash~\l_@@_content_hash_tl}
- }
- \socket_use:n {tagsupport/math/mathml/write} % write hash if request
- \bool_if:NTF\l__tag_math_texsource_AF_bool
+ {
+ \int_gincr:N\g_@@_mathml_AF_found_int
+ \bool_if:NTF \l__tag_math_mathml_AF_bool
+ {
+ \int_gincr:N\g_@@_mathml_AF_attached_int
+ \typeout {Inserting~mathml~with~Hash~\l_@@_content_hash_tl}
+ }
+ {
+ \typeout {Ignoring~mathml~with~Hash~\l_@@_content_hash_tl}
+ }
+ }
+ {
+ \bool_if:NT \l__tag_math_mathml_AF_bool
+ {
+ \typeout {WARNING:~mathml~missing~for~hash~\l_@@_content_hash_tl}
+ }
+ }
+ \socket_use:n {tagsupport/math/mathml/write/prepare}
+ \socket_use:n {tagsupport/math/mathml/write} % write hash if request
+ \bool_if:NTF\l__tag_math_texsource_AF_bool
{ \tl_set_eq:NN \l_@@_content_AF_source_tmpa_tl \l_@@_content_AF_source_tl }
- { \tl_clear:N \l_@@_content_AF_source_tmpa_tl }
+ { \tl_clear:N \l_@@_content_AF_source_tmpa_tl }
\tag_struct_begin:n
{
tag=Formula,
attribute-class=\l_@@_attribute_class_tl, %
- AFref =
+ AFref =
\bool_if:NT\l__tag_math_mathml_AF_bool
{
\cs_if_exist_use:c {g_@@_mathml_ \l_@@_content_hash_tl _tl}
@@ -1207,13 +1789,13 @@
% \begin{macrocode}
\socket_new_plug:nnn
{tagsupport/math/struct/end}
- {test-mathml}
+ {mathml-AF}
{
\tag_struct_end:
- }
+ }
% \end{macrocode}
% \end{plugdecl}
-%
+%
% \begin{socketdecl}{tagsupport/math/substruct/begin,
% tagsupport/math/substruct/end}
% This holds the code to handle subparts of the formula.
@@ -1222,7 +1804,7 @@
\socket_new:nn {tagsupport/math/substruct/end}{0}
% \end{macrocode}
% \end{socketdecl}
-%
+%
% \begin{plugdecl}{default}
% \begin{macrocode}
\socket_new_plug:nnn
@@ -1232,16 +1814,16 @@
\socket_new_plug:nnn
{tagsupport/math/substruct/end}
{default}
- {
+ {
\tagmcend
\if@subformulas
\tagstructend
\fi
- }
-\socket_assign_plug:nn {tagsupport/math/substruct/begin}{default}
-\socket_assign_plug:nn {tagsupport/math/substruct/end}{default}
-% \end{macrocode}
-% \end{plugdecl}
+ }
+\socket_assign_plug:nn {tagsupport/math/substruct/begin}{default}
+\socket_assign_plug:nn {tagsupport/math/substruct/end}{default}
+% \end{macrocode}
+% \end{plugdecl}
% \begin{plugdecl}{single}
% We need an option to disable subparts as it is unclear
@@ -1253,7 +1835,7 @@
{
\typeout{====>subpart~splitting~deactivated}
\typeout{====>grabbed~math=\meaning\g_@@_grabbed_math_tl}
- \tag_mc_begin:n{}
+ \tag_mc_begin:n{}
}
\socket_new_plug:nnn
{tagsupport/math/substruct/end}
@@ -1261,56 +1843,29 @@
{ \tag_mc_end:}
% \end{macrocode}
% \end{plugdecl}
-%
+%
% \begin{socketdecl}{tagsupport/math/end}
% A socket used at the end of the math (before the closing dollar(s))
-% which can e.g. set a flag for luamml.
+% which can, e.g., set a flag for luamml.
% \begin{macrocode}
\socket_new:nn {tagsupport/math/end}{0}
% \end{macrocode}
% \end{socketdecl}
-
-%
-% \begin{macro}{\__tag_math_disable:}
-% Similar to the table code we collect the plugs that should be
-% assigned to do nothing if we don't want tagging
-% \begin{macrocode}
-\cs_new_protected:Npn \__tag_math_disable:
- {
- \socket_assign_plug:nn {tagsupport/math/inline/begin}{noop}
- \socket_assign_plug:nn {tagsupport/math/inline/end}{noop}
- \socket_assign_plug:nn {tagsupport/math/inline/formula/begin}{identity}
- \socket_assign_plug:nn {tagsupport/math/inline/formula/end}{noop}
- \socket_assign_plug:nn {tagsupport/math/display/begin}{noop}
- \socket_assign_plug:nn {tagsupport/math/display/end}{noop}
- \socket_assign_plug:nn {tagsupport/math/display/formula/begin}{identity}
- \socket_assign_plug:nn {tagsupport/math/display/formula/end}{noop}
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\__tag_math_enable:}
-% Similar to the table code we collect the default plugs that should be
-% assigned if we want tagging
-% \begin{macrocode}
-\cs_new_protected:Npn \__tag_math_enable:
- {
- \socket_assign_plug:nn {tagsupport/math/inline/begin}{MC}
- \socket_assign_plug:nn {tagsupport/math/inline/end}{MC}
- \socket_assign_plug:nn {tagsupport/math/inline/formula/begin}{default}
- \socket_assign_plug:nn {tagsupport/math/inline/formula/end}{default}
- \socket_assign_plug:nn {tagsupport/math/display/begin}{default}
- \socket_assign_plug:nn {tagsupport/math/display/end}{default}
- \socket_assign_plug:nn {tagsupport/math/display/formula/begin}{default}
- \socket_assign_plug:nn {tagsupport/math/display/formula/end}{default}
- }
-% \end{macrocode}
-% \end{macro}
-% At begin document we can activate:
+%
+%
+% \changes{v0.6j}{2024-11-19}{removed enable/disable command and assign tagging sockets directly}
% \begin{macrocode}
-\AtBeginDocument{\tag_if_active:T{\__tag_math_enable: }}
+\socket_assign_plug:nn {tagsupport/math/inline/begin}{MC}
+\socket_assign_plug:nn {tagsupport/math/inline/end}{MC}
+\socket_assign_plug:nn {tagsupport/math/inline/formula/begin}{default}
+\socket_assign_plug:nn {tagsupport/math/inline/formula/end}{default}
+\socket_assign_plug:nn {tagsupport/math/display/begin}{default}
+\socket_assign_plug:nn {tagsupport/math/display/end}{default}
+\socket_assign_plug:nn {tagsupport/math/display/formula/begin}{default}
+\socket_assign_plug:nn {tagsupport/math/display/formula/end}{default}
% \end{macrocode}
%
+%
% \subsection{Interface commands}
%
% \begin{macro}
@@ -1349,49 +1904,67 @@
% \subsection{Content grabbing}
%
% \begin{macro}{\@@_grab_dollar:w}
-% Grab up to a single |$|, for inline math mode, suppressing
-% any processing if the token is \tn{m@th} found in the content.
-%
-% \fmi{what's that test doing?}
-%
-% \car{It is some kind of fix, to avoid the remote
-% possibility that the math is empty, making the code
-% produce an unwanted \texttt{\$\$}.}
-%
-%\car{cf.~the code for this in \cs{@ensuredmath}}
-%
-%\car{It is harmless but unnecessary in the dollardollar grabbing below.}
-%
+% \begin{macro}{\@@_grab_dollar:n}
+% \changes{v0.6c}{2024-08-22}{Correct handling of empty math segments}
+% Top-level function to handle grabbing of inline math mode delimited by
+% |$| tokens. We provide two different ways to do that: a token-by-token
+% one that can be used everywhere, and a fast delimited one that does not
+% work anywhere that the end |$| token may be hidden, most obviously in
+% tabulars. The function here is therefore set up as a variable starting
+% point.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_dollar:w { \@@_grab_dollar_delim:w }
+% \end{macrocode}
+% After grabbing inline math material, there is again common processing
+% independent of mechanism of collection.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_grab_dollar:w % $
- #1 $
+\cs_new_protected:Npn \@@_grab_dollar:n #1
{
% \end{macrocode}
-% \fmi{what's that test doing?}
+% We need to do processing first as this picks up \enquote{fake} math mode:
+% that information is needed below.
% \begin{macrocode}
- \tl_if_blank:nF {#1}
- {
- \@@_process:nn { math } {#1} % $
+ \@@_process:nn { math } {#1}
% \end{macrocode}
% We do not want math tagging in fakemath or when measuring,
% We also do not want math tagging if tagging has been suspended.
% \begin{macrocode}
- \bool_lazy_or:nnTF
- {\legacy_if_p:n { measuring@ }}
- { \l_@@_fakemath_bool }
- { #1 $ }
+ \bool_lazy_any:nTF
+ {
+ {\legacy_if_p:n { measuring@ }}
+ { \l_@@_fakemath_bool }
+ { \tl_if_blank_p:n {#1} }
+ }
+ {
+ \@@_luamml_ignore:
+ #1 $ % $
+ }
{
- \tag_socket_use:n {math/inline/begin} %end P-MC
- \tag_socket_use:nn {math/inline/formula/begin}{#1}
- $
+ \tag_socket_use:n {math/inline/begin} %end P-MC
+% \end{macrocode}
+% We do no use a tagging socket here, so that the argument (the
+% math) is not lost, tagging-project issue 661.
+% \changes{v0.6j}{2024-11-19}{change socket to tagging socket}
+% \begin{macrocode}
+ \tag_socket_use:nnn {math/inline/formula/begin}{}{#1}
+ $ % $
\tag_socket_use:n {math/inline/formula/end}
\tag_socket_use:n {math/inline/end} % restart P-MC
- }
- }
+ }
}
% \end{macrocode}
% \end{macro}
-%
+% \end{macro}
+%
+% \begin{macro}{\@@_grab_dollar_delim:w}
+% Grab up to a single |$|, for inline math mode, suppressing
+% any processing if the token is \tn{m@th} found in the content.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_dollar_delim:w #1 $ % $
+ { \@@_grab_dollar:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\@@_grab_dollardollar:w}
% And for the classical \TeX{} display structure.
% \begin{macrocode}
@@ -1401,34 +1974,46 @@
\tl_if_blank:nF {#1}
{
\@@_process:nn { equation* } {#1}
- \socket_use:n {tagsupport/math/display/begin}
- \socket_use:nn{tagsupport/math/display/formula/begin}{#1}
- $$
+ \tag_socket_use:n {math/display/begin}
+ \tag_socket_use:nn{math/display/formula/begin}{}{#1}
}
+ $$
}
% \end{macrocode}
-%
+%
% The end code is added through a \cs{aftergroup} so we
% store it inside a command.
+% \changes{v0.6j}{2024-11-19}{removed unneeded \cs{tagpdfparaOn}}
% \begin{macrocode}
-\cs_new_protected:Npn \@@_tag_dollardollar_display_end:
+\cs_new_protected:Npn \@@_tag_dollardollar_display_end:
{
% \typeout{== tag dollarldollar display end}
% \ShowTagging{struct-stack}
\para_raw_end:
% \end{macrocode}
-% TODO why is that needed? where is para-tagging disabled?
+% The \cs{postdisplaypenalty} was temporarily set to 10000 inside
+% the display and the \cs{belowdisplayskip} and the
+% \cs{belowdisplayshortskip} was negated, so whatever was inserted
+% it should have been a negative skip. Whatever skip was added we
+% pick it ups value up here, so that we can correct the spacing
+% after the tagging code was inserted.
% \begin{macrocode}
- \tagpdfparaOn
\l_@@_tmpa_skip \lastskip
- \socket_use:n{tagsupport/math/display/formula/end}
- \penalty \postdisplaypenalty
+ \tag_socket_use:n{math/display/formula/end}
% \end{macrocode}
-% This reinserts the below display skips. It must be doubled to
-% get the right amount:
+% Now we add a skip without indroducing a page break possibility,
+% that should bring the current vertical position back to the point
+% where \TeX{} would add the penalty and the \enquote{below skip}.
+% \changes{v0.6f}{2024-09-30}{Correct logic for inserting below skips
+% after displays (tagging/721)}
% \begin{macrocode}
- \skip_vertical:n { -\l_@@_tmpa_skip * 2 }
-%
+ \nobreak
+ \skip_vertical:n { -\l_@@_tmpa_skip } % remove the negative belowdisplayskip
+% \end{macrocode}
+% Then we finally add the real stuff:
+% \begin{macrocode}
+ \penalty \postdisplaypenalty
+ \skip_vertical:n { -\l_@@_tmpa_skip } % insert the correct skip
\@doendpe % this has no \end{...} to take care of it
}
@@ -1463,6 +2048,164 @@
% \end{macrocode}
% \end{macro}
%
+% \subsection{Token-by-token inline grabbing}
+%
+% Grabbing inline math token-by-token is more involved. The mechanism here
+% is essentially a simplified version of that originally seen in
+% \pkg{collcell} and refined in \pkg{siunitx}. We make use of the fact that
+% in math mode spaces are ignored, so we have to deal with only \texttt{N}-type
+% tokens and groups. Furthermore, there is no need to look inside groups, so
+% the only special cases are a small selection of \texttt{N}-type tokens.
+%
+% \begin{variable}{\l_@@_grabbed_tl}
+% For collection of the material piecewise.
+% \begin{macrocode}
+\tl_new:N \l_@@_grabbed_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_grab_env_int}
+% Needed to count up the number of nested environments encountered.
+% \begin{macrocode}
+\int_new:N \l_@@_grab_env_int
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}{\@@_grab_dollar_loop:}
+% \begin{macro}{\@@_grab_loop:}
+% The lead-off here establishes a group: we need that as we will have to
+% be careful in the way \tn{cr} is handled and ensure this is only
+% manipulated whilst grabbing. The main loop is then started.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_dollar_loop:
+ {
+ \group_begin:
+ \tl_clear:N \l_@@_grabbed_tl
+ \@@_grab_loop:
+ }
+\cs_new_protected:Npn \@@_grab_loop:
+ {
+ \peek_remove_spaces:n
+ {
+ \peek_meaning:NTF \c_group_begin_token
+ { \@@_grab_loop_group:n }
+ { \@@_grab_loop_token:N }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_grab_loop_group:n}
+% \begin{macro}{\@@_grab_loop_store:n}
+% Handling of grabbed groups is pretty easy.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_loop_group:n #1
+ { \@@_grab_loop_store:n { {#1} } }
+\cs_new_protected:Npn \@@_grab_loop_store:n #1
+ {
+ \tl_put_right:Nn \l_@@_grabbed_tl {#1}
+ \@@_grab_loop:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_grab_loop_token:N}
+% \begin{macro}
+% {
+% \@@_grab_loop_$: ,
+% \@@_grab_loop_\\: ,
+% \@@_grab_loop_\begin: ,
+% \@@_grab_loop_\end: ,
+% \@@_grab_loop_\ignorespaces: ,
+% \@@_grab_loop_\unskip: ,
+% \@@_grab_loop_\textonly@unskip:
+% }
+% Filter out the special cases: for performance reasons, use a hash table
+% approach rather than a loop (\emph{cf.}~\pkg{collcell}).
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_loop_token:N #1
+ {
+ \cs_if_exist_use:cF
+ { @@_grab_loop_ \token_to_str:N #1 : }
+ { \@@_grab_loop_store:n {#1} }
+ }
+\cs_new_protected:cpn { @@_grab_loop_ \token_to_str:N $ : }
+ { \@@_grab_loop_end: }
+\cs_new_protected:cpn { @@_grab_loop_ \token_to_str:N \\ : }
+ {
+ \int_compare:nNnTF \l_@@_grab_env_int = 0
+ { \@@_grab_loop_newline: }
+ { \@@_grab_loop_store:n { \\ } }
+ }
+% \end{macrocode}
+% In contrast to \pkg{collcell}, nesting is tracked by counting
+% \cs{begin}/\cs{end} pairs: this is needed in case there is a tabular-like
+% construct containing |\\| inside a cell. As a result, the end-of-tabular
+% can be detected without checking the name argument: if \cs{end} is
+% encountered at nesting level~0, we've hit the end of a cell. In that case,
+% end the row and leave the environment to clean up.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_grab_loop_ \token_to_str:N \begin : }
+ {
+ \int_incr:N \l_@@_grab_env_int
+ \@@_grab_loop_store:n { \begin }
+ }
+\cs_new_protected:cpn { @@_grab_loop_ \token_to_str:N \end : }
+ {
+ \int_compare:nNnTF \l_@@_grab_env_int = 0
+ {
+ \@@_grab_loop_newline:
+ \end
+ }
+ {
+ \int_decr:N \l_@@_grab_env_int
+ \@@_grab_loop_store:n { \end }
+ }
+ }
+\tl_map_inline:nn { \ignorespaces \unskip \textonly@unskip }
+ {
+ \cs_new_protected:cpn { @@_grab_loop_ \token_to_str:N #1 : }
+ { \@@_grab_loop: }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_grab_loop_newline:}
+% To allow collection of tokens in the part of the \tn{halign} template after
+% |#|, we need \TeX{} to see the primitive with the loop token in the right
+% place. That is done by re-defining \tn{cr} at present. Ideally there would
+% be a socket in the definition of \texttt{tabular}, etc., to handle this:
+% there is also the need to examine in interaction with \pkg{longtable}, which
+% also redefines \tn{cr}.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_loop_newline:
+ {
+ \if_false: { \fi:
+ \cs_set_protected:Npn \cr
+ {
+ \@@_grab_loop:
+ \tex_cr:D
+ }
+ \if_false: } \fi:
+ \\
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_grab_loop_end:}
+% Clean up and pass on.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_grab_loop_end:
+ {
+ \exp_args:NNV \group_end:
+ \@@_grab_dollar:n \l_@@_grabbed_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \subsection{Marking math environments}
%
% A general mechanism for math mode environments that do not grab their
@@ -1644,10 +2387,9 @@
}
{
% \typeout{==>A3}
- \__tag_tool_close_P:
+ \__tag_tool_close_P:
}
- \socket_use:nn{tagsupport/math/display/formula/begin}{}
- \tagpdfparaOff
+ \tag_socket_use:nn{math/display/formula/begin}{}{}
% \typeout{==>MC1}\ShowTagging{mc-current}
}
@@ -1655,14 +2397,14 @@
% \typeout{==>MC2}\ShowTagging{mc-current}
\para_raw_end:
\tagpdfparaOn
- \socket_use:n{tagsupport/math/display/formula/end}
+ \tag_socket_use:n{tagsupport/math/display/formula/end}
% \typeout{==>MC3}\ShowTagging{mc-current}
\@endpetrue
}
\cs_new_protected:Npn \math_register_env:n #1
{ \math_register_env:nn {#1} { } }
-
+
\NewDocumentCommand \RegisterMathEnvironment { O{} m }
{ \math_register_env:nn {#2} {#1} }
% \end{macrocode}
@@ -1749,7 +2491,7 @@
{
\cs_gset_protected:Npn \[ % \]
{
- \@@_grab_eqn:w
+ \@@_grab_eqn:w
% \bool_if:NTF \l_@@_collected_bool
% { \begin { equation* } }
% { \@@_grab_eqn:w }
@@ -1847,7 +2589,7 @@
% \end{macrocode}
%
% Tabulars currently contain a \$ that shouldn't trigger math
-% tagging.
+% tagging.
% \begin{macrocode}
\RequirePackage{array}
\tl_if_in:NnT\@tabular{$}
@@ -1856,11 +2598,15 @@
\leavevmode
\UseTaggingSocket{tbl/hmode/begin}%
\hbox \bgroup
- \bool_set_true:N \l_@@_collected_bool
+ \bool_set_true:N \l_@@_collected_bool
$
\bool_set_false:N \l_@@_collected_bool
\col@sep\tabcolsep \let\d@llarbegin\begingroup
\let\d@llarend\endgroup
+% \end{macrocode}
+% A proper switching mechanism is needed: for the present, do directly.
+% \begin{macrocode}
+ \cs_set_protected:Npn \@@_grab_dollar:w { \@@_grab_dollar_loop: }
\@tabarray}
}
% \end{macrocode}
@@ -1877,10 +2623,10 @@
}
% \end{macrocode}
% \end{macro}
-%
+%
% \subsection{Disable math grabbing in the begindocument hook}
% For example amsart uses math to measure text there.
-%
+%
% \begin{macrocode}
\tl_gput_right:Nn\@kernel@before@begindocument
{
@@ -1996,7 +2742,7 @@
% \end{macrocode}
% Also for "false?"
% \begin{macrocode}
-\def\measuring@true{\let\ifmeasuring@\iftrue\tag_stop:}
+\def\measuring@true{\let\ifmeasuring@\iftrue\tag_suspend:n{\measuring}}
% \end{macrocode}
%
% \begin{macrocode}
@@ -2004,7 +2750,7 @@
\math_register_halign_env:nn {align}{}
\math_register_halign_env:nn {align*}{}
\math_register_halign_env:nn {alignat}{}
- \math_register_halign_env:nn {alignat*}{}
+ \math_register_halign_env:nn {alignat*}{}
\math_register_halign_env:nn {flalign}{}
\math_register_halign_env:nn {flalign*}{}
\math_register_halign_env:nn {gather}{}
@@ -2085,8 +2831,8 @@
%
% \begin{macro}{\@@_split_at_nl:NN}
-% This splits grabbed math at newlines.
-%
+% This splits grabbed math at newlines.
+%
% \begin{macrocode}
\cs_new:Npn \@@_split_at_nl:NN #1#2 {
\tl_set:Nf \l_@@_tmpa_tl {
@@ -2105,14 +2851,14 @@
#2 \\ #3 \s_stop
}
}
-
+
\cs_new_protected:Npn \@@_split_at_nl_aux:nnNN #1 #2 #3 #4
{
\tl_gset:Nn #4 {#1}
\tl_gset:Nn #3 {#2}
}
-\cs_new:Npn \@@_split_chk_if_begin:ww
+\cs_new:Npn \@@_split_chk_if_begin:ww
#1 \begin #2 #3 \s_mark #4 \\ \q_nil \\ \s_stop
{
\quark_if_nil:nTF {#2}
@@ -2163,11 +2909,11 @@
{ \exp_end: { #4 #1 } }
{ \@@_split_final_cleanup:w #3 \s_mark { #4 #1 #2 } }
}
-
+
\cs_new:Npn \@@_split:n #1 {
\@@_split_at_nl_first:w #1 \\ \q_nil \\ \s_stop }
-
-% this looks unused.
+
+% this looks unused.
%\NewDocumentCommand \splitnl { mm +m }
% {
% \tl_set:Nf \l_@@_tmpa_tl { \split:n {#3} }
@@ -2179,12 +2925,12 @@
%
%
% \begin{macro}{\maybestartnewformulatag}
-%
+%
% \begin{macrocode}
\newif\if@subformulas
-\tl_new:N \result
-
+\tl_new:N \result
+
\cs_new_protected:Npn\grabaformulapartandstart {
\@@_split_at_nl:NN \g_@@_grabbed_math_tl \result
\typeout{====>first-result=\meaning\result}
@@ -2204,7 +2950,7 @@
% but we add a short text to satisfy the pdf/ua-2 validator
% \begin{macrocode}
% alt=\result,
- alt = subformula,
+ alt = subformula,
title-o=\resulttitle
}
}
@@ -2242,7 +2988,7 @@
%
\tl_if_empty:NF \g_@@_grabbed_math_tl
{
- \tagmcend
+ \tagmcend
\tagstructend
\grabaformulapartandmayberestart
}
@@ -2258,21 +3004,21 @@
% \typeout{===>~ in~ hook}
% \math_register_halign_env:nn {dmath}{}
% \math_register_halign_env:nn {dgroup*}{}
-%}
+%}
% \end{macrocode}
-%
+%
% \begin{macrocode}
\ExplSyntaxOff
% \end{macrocode}
-%
+%
% \begin{macrocode}
%<@@=>
% \end{macrocode}
-%
+%
% \begin{macrocode}
%</kernel>
% \end{macrocode}
%
% \Finale
%
-%
+%
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-math.pdf b/macros/latex-dev/required/latex-lab/latex-lab-math.pdf
index 355c1b35db..2a64f07652 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-math.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-math.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-mathpkg.pdf b/macros/latex-dev/required/latex-lab/latex-lab-mathpkg.pdf
index daa20cf2e2..28b9b70bd5 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-mathpkg.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-mathpkg.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-mathtools.dtx b/macros/latex-dev/required/latex-lab/latex-lab-mathtools.dtx
index aa27cbf01d..ed8b6e467e 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-mathtools.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-mathtools.dtx
@@ -18,12 +18,14 @@
%
% for those people who are interested or want to report an issue.
%
+\def\ltlabmathtoolsdate{2024-09-18}
+\def\ltlabmathtoolsversion{0.80a}
%<*driver>
\documentclass{l3doc}
\EnableCrossrefs
\CodelineIndex
\begin{document}
- \DocInput{latex-lab-amsmath.dtx}
+ \DocInput{latex-lab-mathtools.dtx}
\end{document}
%</driver>
%
@@ -32,7 +34,7 @@
%
% \title{The \texttt{latex-lab-mathtools} code\thanks{}}
% \author{\LaTeX{} Project}
-%
+% \date{v\ltlabmathtoolsversion\ \ltlabmathtoolsdate}
% \maketitle
%
% \newcommand\fmi[1]{\begin{quote} TODO: \itshape #1\end{quote}}
@@ -66,7 +68,7 @@
% \subsection{File declaration}
% \begin{macrocode}
\ProvidesFile{latex-lab-mathtools.ltx}
- [2023-01-05 v0.1a mathtools adaptions]
+ [2024-07-13 v0.1a mathtools adaptions]
% \end{macrocode}
% \subsection{Tagpdf support}
% To make the code independent from tagging being loaded and active
@@ -117,7 +119,7 @@
% \end{macrocode}
% Stop tagging when measuring:
% \begin{macrocode}
- \ifmeasuring@\tag_stop:\fi
+ \ifmeasuring@\tag_suspend:n{\measuring}\fi
\normalbaselines
\ifdim
\ifdim\@totalleftmargin=\z@
@@ -156,7 +158,7 @@
\noalign{%
\penalty\postdisplaypenalty\vskip\abovedisplayshortskip
\vbox{%
- \ifmeasuring@\tag_stop:\fi
+ \ifmeasuring@\tag_suspend:n{\measuring}\fi
\normalbaselines
\MH_if_dim:w
\MH_if_dim:w \@totalleftmargin=\z@
@@ -185,7 +187,7 @@
\vskip\normallineskiplimit
\vskip\l_MT_above_shortintertext_sep
\vbox{%
- \ifmeasuring@\tag_stop:\fi
+ \ifmeasuring@\tag_suspend:n{\measuring}\fi
\normalbaselines
\MH_if_dim:w
\MH_if_dim:w \@totalleftmargin=\z@
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-mathtools.pdf b/macros/latex-dev/required/latex-lab/latex-lab-mathtools.pdf
index aae05b3b63..d7f57e0379 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-mathtools.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-mathtools.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-minipage.dtx b/macros/latex-dev/required/latex-lab/latex-lab-minipage.dtx
index ffbe5357e7..eed595a531 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-minipage.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-minipage.dtx
@@ -18,8 +18,8 @@
%
% for those people who are interested or want to report an issue.
%
-\def\ltlabminipagedate{2023-10-30}
-\def\ltlabminipageversion{0.81c}
+\def\ltlabminipagedate{2024-09-18}
+\def\ltlabminipageversion{0.81e}
%<*driver>
\documentclass{l3doc}
\EnableCrossrefs
@@ -120,12 +120,18 @@
% \end{macrocode}
% insert the socket
% \begin{macrocode}
- \socket_use:n{tagsupport/minipage/before}% new
+ \UseTaggingSocket{minipage/before}% new
\setbox\@tempboxa\vbox\bgroup
\color@begingroup
\hsize\@tempdima
\textwidth\hsize \columnwidth\hsize
\@parboxrestore
+% \end{macrocode}
+% minipages are perhaps used in environments where the tagging of paragraphs
+% has been altered. So we try to restore this. TODO: this should
+% perhaps be done in \cs{@parboxrestore} directly.
+% \begin{macrocode}
+ \UseTaggingSocket{para/restore}
\def\@mpfn{mpfootnote}\def\thempfn{\thempfootnote}\c@mpfootnote\z@
\socket_assign_plug:nn{fntext/process}{mp}%
\let\@listdepth\@mplistdepth \@mplistdepth\z@
@@ -150,10 +156,10 @@
% As the parbox command is called, we must prevent that it adds its
% additional tagging commands:
% \begin{macrocode}
- \tag_stop:n{minipage}
+ \tag_suspend:n{minipage}
\expandafter\@iiiparbox\@mpargs{\unvbox\@tempboxa}%
- \tag_start:n{minipage}
- \socket_use:n{tagsupport/minipage/after} %new end ...
+ \tag_resume:n{minipage}
+ \UseTaggingSocket{minipage/after} %new end ...
}
% \end{macrocode}
%
@@ -164,8 +170,15 @@
\leavevmode
\@pboxswfalse
\setlength\@tempdima{#4}%
- \socket_use:n{tagsupport/parbox/before}
- \@begin@tempboxa\vbox{\hsize\@tempdima\@parboxrestore#5\@@par}%
+ \UseTaggingSocket{parbox/before}
+ \@begin@tempboxa\vbox{\hsize\@tempdima\@parboxrestore
+% \end{macrocode}
+% parbox are perhaps used in environments where the tagging of paragraphs
+% has been altered. So we try to restore this. TODO: this should
+% perhaps be done in \cs{@parboxrestore} directly.
+% \begin{macrocode}
+ \UseTaggingSocket{para/restore}
+ #5\@@par}%
\ifx\relax#2\else
\setlength\@tempdimb{#2}%
\edef\@parboxto{to\the\@tempdimb}%
@@ -179,7 +192,7 @@
\csname bm@#3\endcsname}%
\if@pboxsw \m@th$\fi
\@end@tempboxa%
- \socket_use:n{tagsupport/parbox/after}
+ \UseTaggingSocket{parbox/after}
}
% \end{macrocode}
%
@@ -191,9 +204,11 @@
\socket_new_plug:nnn{tagsupport/minipage/before}{tag/dflt}
{
% \end{macrocode}
-% As there was a \cs{leavevmode} before that is a P/text open that we have to close.
+% As there was a \cs{leavevmode} before that is a P/text open that we have to close
+% if para tagging is active:
% \begin{macrocode}
- \tag_mc_end_push:\tag_struct_end:
+ \tag_mc_end_push:
+ \bool_if:NT \l__tag_para_bool {\tag_struct_end:}
% \end{macrocode}
% TODO: the P can be further up, we need a proper method to test and handle this.
% \begin{macrocode}
@@ -203,13 +218,25 @@
% similar for the other sockets:
% \begin{macrocode}
\socket_new_plug:nnn{tagsupport/minipage/after}{tag/dflt}
- {\tag_struct_end:\tag_struct_begin:n{tag=\l__tag_para_tag_tl}\tag_mc_begin_pop:n{}}
+ {
+ \tag_struct_end:
+ \bool_if:NT \l__tag_para_bool {\tag_struct_begin:n{tag=\l__tag_para_tag_tl}}
+ \tag_mc_begin_pop:n{}
+ }
\socket_new_plug:nnn{tagsupport/parbox/before}{tag/dflt}
- {\tag_mc_end_push:\tag_struct_end:\tag_struct_begin:n{tag=\l__ltboxes_tag_tl}}
+ {
+ \tag_mc_end_push:
+ \bool_if:NT \l__tag_para_bool {\tag_struct_end:}
+ \tag_struct_begin:n{tag=\l__ltboxes_tag_tl}
+ }
\socket_new_plug:nnn{tagsupport/parbox/after}{tag/dflt}
- {\tag_struct_end:\tag_struct_begin:n{tag=\l__tag_para_tag_tl}\tag_mc_begin_pop:n{}}
+ {
+ \tag_struct_end:
+ \bool_if:NT \l__tag_para_bool {\tag_struct_begin:n{tag=\l__tag_para_tag_tl}}
+ \tag_mc_begin_pop:n{}
+ }
% \end{macrocode}
% Activate the default tagging plug
% \begin{macrocode}
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-minipage.pdf b/macros/latex-dev/required/latex-lab/latex-lab-minipage.pdf
index 68aeacb9ec..c161e1a99c 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-minipage.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-minipage.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-namespace.dtx b/macros/latex-dev/required/latex-lab/latex-lab-namespace.dtx
index cfc06c7b09..d76dd8d489 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-namespace.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-namespace.dtx
@@ -26,7 +26,7 @@
% \fi
% \title{Prototype reimplementation of \LaTeXe{}'s role mapping}
% \author{\LaTeX{} Project, initial implementation Ulrike Fischer}
-% \date{v0.8b 2024-03-24}
+% \date{v0.8b 2024-07-05}
%
% \maketitle
%
@@ -37,7 +37,7 @@
% \section{Introduction}
%
% This short file collects tag names from the \LaTeX{} namespace and their role mapping used
-% in the latex-lab files. The names and the roles are not necessarly the final ones!
+% in the latex-lab files. The names and the roles are not necessarily the final ones!
%
% Later settings of the same tag overwrite previous settings.
% The syntax of a line is a list of three strings ending with commas:
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-namespace.pdf b/macros/latex-dev/required/latex-lab/latex-lab-namespace.pdf
index c172554fd8..39d9513435 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-namespace.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-namespace.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-new-or-1.dtx b/macros/latex-dev/required/latex-lab/latex-lab-new-or-1.dtx
index 9994b15cb8..4d4994262f 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-new-or-1.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-new-or-1.dtx
@@ -9,8 +9,8 @@
%
% https://www.latex-project.org/lppl.txt
%
-\def\ltlabneworIdate{2023-07-20}
-\def\ltlabneworIversion{0.85a}
+\def\ltlabneworIdate{2024-11-12}
+\def\ltlabneworIversion{0.85b}
%<*driver>
\documentclass{l3doc}
@@ -70,7 +70,7 @@
\providecommand\@kernel@before@foot{}
\providecommand\@kernel@after@head{}
\providecommand\@kernel@after@foot{}
-\providecommand\@mult@ptagging@hook{}% multicol
+\providecommand\@mult@ptagging@hook{}% should be replaced with a socket, eventually
% \end{macrocode}
%
% \begin{macrocode}
@@ -143,20 +143,22 @@
% \item
% \end{itemize}
%
+% This is now directly provided in \pkg{multicol} so the patch below is no longer necessary.
+%
% \begin{macrocode}
-\AddToHook{package/multicol/after}
- {% multicol needs later loading
+%\AddToHook{package/multicol/after}
+% {% multicol needs later loading
% \end{macrocode}
%
% \begin{macrocode}
- \patchcmd\page@sofar
- {\global\dimen\tw@\dp\z@}%
- {%
- \global\dimen\tw@\dp\z@
- \@mult@ptagging@hook
- }%
- {\typeout{Patching \string\page@sofar\space for tagging}}{\PATCHerror}%
-}
+% \patchcmd\page@sofar
+% {\global\dimen\tw@\dp\z@}%
+% {%
+% \global\dimen\tw@\dp\z@
+% \@mult@ptagging@hook
+% }%
+% {\typeout{Patching \string\page@sofar\space for tagging}}{\PATCHerror}%
+%}
% \end{macrocode}
%
% \subsection{Interrupt hooks}
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-new-or-1.pdf b/macros/latex-dev/required/latex-lab/latex-lab-new-or-1.pdf
index ae453a241c..42a2f267c3 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-new-or-1.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-new-or-1.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-new-or-2.pdf b/macros/latex-dev/required/latex-lab/latex-lab-new-or-2.pdf
index 87d097a831..216a1171fe 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-new-or-2.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-new-or-2.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-sec.dtx b/macros/latex-dev/required/latex-lab/latex-lab-sec.dtx
index f3786c2ddb..936eee9ed2 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-sec.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-sec.dtx
@@ -16,8 +16,8 @@
%
% for those people who are interested or want to report an issue.
%
-\def\ltlabsecdate{2024-02-12}
-\def\ltlabsecversion{0.84c}
+\def\ltlabsecdate{2024-10-04}
+\def\ltlabsecversion{0.84f}
%<*driver>
\documentclass[kernel]{l3doc}
\EnableCrossrefs
@@ -121,7 +121,7 @@
% commands must be at the right grouping level.
% \end{itemize}
%
-% \subsection{Funktions and keys}
+% \subsection{Functions and keys}
%
% \begin{function}{\tag_tool:n,\tagtool}
%
@@ -138,7 +138,7 @@
% to allow e.g. to put an epigraph or similar in front.
%
% \item The number in \cs{part} and \cs{chapter} is currently not correctly
-% tagged as a \texttt{Lbl} as this requires to redefine the internal (class dependant)
+% tagged as a \texttt{Lbl} as this requires to redefine the internal (class dependent)
% commands too.
%
% \end{itemize}
@@ -198,28 +198,31 @@
% We must ensure that manual targets (e.g. in unnumbered sections)
% correctly update \cs{@currentHref}. For this we extend the kernel definition of
% \cs{MakeLinkTarget}
-%
+% TODO: remove after release 2024/11
% \begin{macrocode}
%<*kernelchange>
\ExplSyntaxOn
-\int_new:N\g__kernel_target_int
-\RenewDocumentCommand\MakeLinkTarget{sO{}m}
- {%
- \ifvmode
- \special{}%
- \else
- \@savsf\spacefactor
- \smash{}%
- \spacefactor\@savsf
- \fi
- \IfBooleanTF {#1}
- {
- \tl_gset:Ne \@currentHref {#3}
+\str_if_exist:cF { l__socket_tagsupport/recordtarget_plug_str }
+ {
+ \int_new:N\g__kernel_target_int
+ \RenewDocumentCommand\MakeLinkTarget{sO{}m}
+ {%
+ \ifvmode
+ \special{}%
+ \else
+ \@savsf\spacefactor
+ \smash{}%
+ \spacefactor\@savsf
+ \fi
+ \IfBooleanTF {#1}
+ {
+ \tl_gset:Ne \@currentHref {#3}
+ }
+ {
+ \int_gincr:N\g__kernel_target_int
+ \tl_gset:Ne \@currentHref {target*.\int_use:N\g__kernel_target_int}
+ }
}
- {
- \int_gincr:N\g__kernel_target_int
- \tl_gset:Ne \@currentHref {target*.\int_use:N\g__kernel_target_int}
- }
}
\ExplSyntaxOff
%</kernelchange>
@@ -227,45 +230,56 @@
%
% \begin{macrocode}
%<*package>
+%<@@=tag>
% \end{macrocode}
% \subsubsection{Tagging commands}
%
%
-% \begin{variable}{\g__tag_sec_stack_seq}
-% The stack holds the tag and the level.
+% \begin{variable}{\g_@@_sec_stack_seq}
+% The stack holds the tag, the level and the structure number.
% \begin{macrocode}
-\seq_new:N \g__tag_sec_stack_seq
-\seq_gpush:Nn\g__tag_sec_stack_seq {{Document}{-100}}
+\seq_new:N \g_@@_sec_stack_seq
+\seq_gpush:Nn\g_@@_sec_stack_seq {{Document}{-100}{2}}
% \end{macrocode}
% \end{variable}
%
-% \begin{variable}{\l__tag_sec_Sect_bool}
+% \begin{macro}{\@@_get_data_current_Sect:}
+% This allows to retrieve the number of the current Sect structure (or
+% Document if we are outside any Sect) with |\tag_get:n{current_Sect}|
+% \begin{macrocode}
+\cs_new:Npn \@@_get_data_current_Sect:
+ {
+ \exp_last_unbraced:Ne\use_iii:nnn{\seq_item:Nn\g_@@_sec_stack_seq{1}}
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{variable}{\l_@@_sec_Sect_bool}
% This boolean controls if a Sect structure is opened.
% \begin{macrocode}
-\bool_new:N \l__tag_sec_Sect_bool
-\bool_set_true:N\l__tag_sec_Sect_bool
+\bool_new:N \l_@@_sec_Sect_bool
+\bool_set_true:N\l_@@_sec_Sect_bool
% \end{macrocode}
% \end{variable}
-
-%
-% \begin{macro}{\__tag_sec_begin:nn}
+%
+% \begin{macro}{\@@_sec_begin:nn}
% This starts a sectioning structure.
% Currently the tag is fix, either Sect or Part, depending on the level,
% but this will perhaps change. The second argument is currently unused.
% \begin{macrocode}
-\cs_new_protected:Npn\__tag_sec_begin:nn #1 #2 %#1 level #2 keyval
+\cs_new_protected:Npn\@@_sec_begin:nn #1 #2 %#1 level #2 keyval
{
\tag_struct_begin:n
{
tag= {\int_compare:nNnTF {#1}={-1}{Part}{Sect}}
,#2
}
- \seq_gpush:Ne \g__tag_sec_stack_seq {{\g__tag_struct_tag_tl}{\int_eval:n{#1}}}
+ \seq_gpush:Ne \g_@@_sec_stack_seq
+ {{\g_@@_struct_tag_tl}{\int_eval:n{#1}}{\g_@@_struct_stack_current_tl}}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\__tag_sec_end:n}
+% \begin{macro}{\@@_sec_end:n}
% \begin{macrocode}
\msg_new:nnn { tag } {wrong-sect-nesting}
{
@@ -273,65 +287,65 @@
It~is~not~equal~to~the~current~structure~#2~on~the~main~stack
}
-\cs_new_protected:Npn\__tag_sec_end:n #1 % #1 level
+\cs_new_protected:Npn\@@_sec_end:n #1 % #1 level
{
- \seq_get:NN \g__tag_sec_stack_seq \l__tag_tmpa_tl
- \int_compare:nNnT {#1}<{\exp_last_unbraced:NV\use_ii:nn\l__tag_tmpa_tl+1}
+ \seq_get:NN \g_@@_sec_stack_seq \l_@@_tmpa_tl
+ \int_compare:nNnT {#1}<{\exp_last_unbraced:NV\use_ii:nnn\l_@@_tmpa_tl+1}
{
- \seq_get:NN\g__tag_struct_tag_stack_seq \l__tag_tmpb_tl
+ \seq_get:NN\g_@@_struct_tag_stack_seq \l_@@_tmpb_tl
\exp_args:Nee
\tl_if_eq:nnTF
- {\exp_last_unbraced:NV\use_i:nn\l__tag_tmpa_tl}
- {\exp_last_unbraced:NV\use_i:nn\l__tag_tmpb_tl}
+ {\exp_last_unbraced:NV\use_i:nnn\l_@@_tmpa_tl}
+ {\exp_last_unbraced:NV\use_i:nn\l_@@_tmpb_tl}
{
- \seq_gpop:NN \g__tag_sec_stack_seq \l__tag_tmpa_tl
+ \seq_gpop:NN \g_@@_sec_stack_seq \l_@@_tmpa_tl
\tag_struct_end:
- \__tag_sec_end:n {#1}
+ \@@_sec_end:n {#1}
}
{
\msg_warning:nnee {tag}{wrong-sect-nesting}
- { \exp_last_unbraced:NV\use_i:nn \l__tag_tmpa_tl }
- { \exp_last_unbraced:NV\use_i:nn \l__tag_tmpb_tl }
+ { \exp_last_unbraced:NV\use_i:nnn \l_@@_tmpa_tl }
+ { \exp_last_unbraced:NV\use_i:nn \l_@@_tmpb_tl }
}
}
}
% \end{macrocode}
% \end{macro}
-% \begin{macro}{\__tag_tool_para_split:}
+% \begin{macro}{\@@_tool_para_split:}
% Runin-sectioning command must separate the heading from the following text.
%
% \begin{macrocode}
-\cs_new_protected:Npn \__tag_tool_para_split:
+\cs_new_protected:Npn \@@_tool_para_split:
{
\tag_mc_end:
\tag_struct_end:
- \tag_struct_begin:n{tag=\l__tag_para_tag_default_tl}
+ \tag_struct_begin:n{tag=\l_@@_para_tag_default_tl}
\tag_mc_begin:n{}
- \__tag_setup_restore_para_default:
+ \@@_setup_restore_para_default:
}
% \end{macrocode}
% \end{macro}
-% \begin{macro}{\__tag_setup_restore_para_default:}
+% \begin{macro}{\@@_setup_restore_para_default:}
% We change the para tagging in the sectioning code.
% This here restores the default. Currently it only resets the
% the tag, but perhaps more will be needed later.
% \begin{macrocode}
-\cs_new_protected:Npn \__tag_setup_restore_para_default:
+\cs_new_protected:Npn \@@_setup_restore_para_default:
{
- \tl_set:Nn \l__tag_para_main_tag_tl {text-unit}
- \tl_set_eq:NN\l__tag_para_tag_tl\l__tag_para_tag_default_tl
+ \tl_set:Nn \l_@@_para_main_tag_tl {text-unit}
+ \tl_set_eq:NN\l_@@_para_tag_tl\l_@@_para_tag_default_tl
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\__tag_sec_end_display:}
+% \begin{macro}{\@@_sec_end_display:}
% \begin{macrocode}
-\cs_new_protected:Npn \__tag_sec_end_display:
+\cs_new_protected:Npn \@@_sec_end_display:
{
\tag_struct_end: %P = Hn
- \__tag_setup_restore_para_default:
+ \@@_setup_restore_para_default:
}
% \end{macrocode}
% \end{macro}
@@ -339,17 +353,17 @@
% Open sec structures should be closed at the end of the document. This should
% be done before tagpdf closes the Document structure.
% \begin{macrocode}
-\hook_gput_code:nnn{tagpdf/finish/before}{tagpdf/sec}{\__tag_sec_end:n{-10}}
+\hook_gput_code:nnn{tagpdf/finish/before}{tagpdf/sec}{\@@_sec_end:n{-10}}
\hook_gset_rule:nnnn {tagpdf/finish/before}{tagpdf/sec}{before}{tagpdf}
% \end{macrocode}
%
% The commands \cs{mainmatter}, \cs{backmatter}, \cs{frontmatter} and
% \cs{appendix} close all \texttt{Sect} and \texttt{Part} structures.
% \begin{macrocode}
-\AddToHook{cmd/frontmatter/before}{\__tag_sec_end:n{-10}}
-\AddToHook{cmd/mainmatter/before} {\__tag_sec_end:n{-10}}
-\AddToHook{cmd/backmatter/before} {\__tag_sec_end:n{-10}}
-\AddToHook{cmd/appendix/before} {\__tag_sec_end:n{-10}}
+\AddToHook{cmd/frontmatter/before}{\@@_sec_end:n{-10}}
+\AddToHook{cmd/mainmatter/before} {\@@_sec_end:n{-10}}
+\AddToHook{cmd/backmatter/before} {\@@_sec_end:n{-10}}
+\AddToHook{cmd/appendix/before} {\@@_sec_end:n{-10}}
% \end{macrocode}
%
% \subsection{Tagging tools}
@@ -368,57 +382,57 @@
{
,sec-start-part .code:n =
{
- \bool_if:NT\l__tag_sec_Sect_bool
+ \bool_if:NT\l_@@_sec_Sect_bool
{
- \__tag_sec_end:n {-1}
- \__tag_sec_begin:nn{-1}{tag=Part}
+ \@@_sec_end:n {-1}
+ \@@_sec_begin:nn{-1}{tag=Part}
}
\tag_struct_begin:n{tag=part,title=#1}
% \end{macrocode}
% We remap here the text-unit from the paragraph to NonStruct.
-% It would be better to suppress it completly as with the other
+% It would be better to suppress it completely as with the other
% sectioning commands, but this would require to redefine \cs{@spart}
% and \cs{@part}, as there is the grouping, and these commands are
% all slightly different in the standard classes. So this is delayed
% to the time when sectioning commands are redefined with templates.
% \begin{macrocode}
- \tl_set:Nn\l__tag_para_main_tag_tl {NonStruct}
- \tl_set:Nn\l__tag_para_tag_tl {Span}
+ \tl_set:Nn\l_@@_para_main_tag_tl {NonStruct}
+ \tl_set:Nn\l_@@_para_tag_tl {Span}
}
- ,sec-stop-part .code:n = {\__tag_sec_end_display:}
+ ,sec-stop-part .code:n = {\@@_sec_end_display:}
,sec-start-chapter .code:n =
{
- \bool_if:NT\l__tag_sec_Sect_bool
+ \bool_if:NT\l_@@_sec_Sect_bool
{
- \__tag_sec_end:n {0}
- \__tag_sec_begin:nn{0}{tag=Sect}
+ \@@_sec_end:n {0}
+ \@@_sec_begin:nn{0}{tag=Sect}
}
\tag_struct_begin:n{tag=chapter,title=#1}
% \end{macrocode}
% similar to part we remap to NonStruct for now ...
% \begin{macrocode}
- \tl_set:Nn\l__tag_para_main_tag_tl {NonStruct}
- \tl_set:Nn\l__tag_para_tag_tl {Span}
+ \tl_set:Nn\l_@@_para_main_tag_tl {NonStruct}
+ \tl_set:Nn\l_@@_para_tag_tl {Span}
}
,sec-stop-chapter .meta:n = { sec-stop-part}
,sec-start .code:n = % #1 is a name like "section"
{
- \bool_if:NT\l__tag_sec_Sect_bool
+ \bool_if:NT\l_@@_sec_Sect_bool
{
- \__tag_sec_end:n {\cs_if_exist_use:c{toclevel@#1}+0}
- \__tag_sec_begin:nn {\cs_if_exist_use:c{toclevel@#1}+0}{tag=Sect}
+ \@@_sec_end:n {\cs_if_exist_use:c{toclevel@#1}+0}
+ \@@_sec_begin:nn {\cs_if_exist_use:c{toclevel@#1}+0}{tag=Sect}
}
- \tl_set:Nn\l__tag_para_tag_tl{#1}
+ \tl_set:Nn\l_@@_para_tag_tl{#1}
}
,sec-start .value_required:n = true
- ,sec-split-para .code:n = {\__tag_tool_para_split:}
- ,restore-para .code:n = {\__tag_setup_restore_para_default:}
+ ,sec-split-para .code:n = {\@@_tool_para_split:}
+ ,restore-para .code:n = {\@@_setup_restore_para_default:}
,sec-stop .code:n =
{
- \par\__tag_sec_end:n {\cs_if_exist_use:c{toclevel@#1}+0}
+ \par\@@_sec_end:n {\cs_if_exist_use:c{toclevel@#1}+0}
}
,sec-stop .value_required:n = true
- ,sec-add-grouping .bool_set:N = \l__tag_sec_Sect_bool
+ ,sec-add-grouping .bool_set:N = \l_@@_sec_Sect_bool
}
% \end{macrocode}
%
@@ -433,6 +447,7 @@
% The tagging inside relies on the para tagging.
% We do not yet use keyval in the optional argument, as this requires latex-dev
% and the naming of the keys and their key family is unclear.
+% \changes{v0.84f}{2024/10/04}{Added braces around optional arg (tagging/725)}
% \begin{macrocode}
\AddToHook{class/after}
{
@@ -476,7 +491,7 @@
\IfBooleanTF
{#1}
{ \@spart {#3} }
- { \@part [#2]{#3} }
+ { \@part [{#2}]{#3} }
% \end{macrocode}
% and now the closing command for the tagging of the title.
% \begin{macrocode}
@@ -528,7 +543,7 @@
\IfBooleanTF
{#1}
{ \@schapter {#3} }
- { \@chapter [#2]{#3} }
+ { \@chapter [{#2}]{#3} }
% \end{macrocode}
% and now the closing command for the tagging of the title.
% \begin{macrocode}
@@ -583,7 +598,7 @@
\IfBooleanTF
{#1}
{ \@spart {#3} }
- { \@part [#2]{#3} }
+ { \@part [{#2}]{#3} }
% \end{macrocode}
% and now the closing command for the tagging of the title.
% \begin{macrocode}
@@ -669,8 +684,8 @@
% \begin{macrocode}
\cs_new_protected:Npn \@kernel@tag@hangfrom #1
{
- \tagstructbegin{tag=\l__tag_para_tag_tl}
- \cs_if_exist_use:N \__tag_gincr_para_begin_int:
+ \tagstructbegin{tag=\l_@@_para_tag_tl}
+ \cs_if_exist_use:N \@@_gincr_para_begin_int:
\tagstructbegin{tag=Lbl}
\setbox\@tempboxa
\hbox
@@ -680,7 +695,7 @@
% \begin{macrocode}
\bool_lazy_and:nnT
{\tag_if_active_p:}
- {\g__tag_mode_lua_bool}
+ {\g_@@_mode_lua_bool}
{\tagmcbegin{tag=Lbl}}
{#1}
}
@@ -689,12 +704,12 @@
% the paratagging. We do not disable paratagging completely, to
% avoid that the numbering goes wrong.
% \begin{macrocode}
- \tag_stop:n{hangfrom}
+ \tag_suspend:n{hangfrom}
\hangindent \wd\@tempboxa\noindent
% \end{macrocode}
% Restart tagging and insert the box.
% \begin{macrocode}
- \tag_start:n{hangfrom}
+ \tag_resume:n{hangfrom}
\tagmcbegin{}\box\@tempboxa\tagmcend\tagstructend\tagmcbegin{}}
% \end{macrocode}
% This command is used to tag the numbers of runin. We do not try
@@ -715,6 +730,7 @@
% \cs{@sect} is only changed to replace the hyperref patches
% and to use the new \cs{@kernel@tag@hangfrom} and \cs{@kernel@tag@svsec}
% \begin{macrocode}
+%<@@=>
\def\@sect#1#2#3#4#5#6[#7]#8{%
\ifnum #2>\c@secnumdepth
\def\@svsec{\@hyp@section@target@nnn{[section]}{}{#3}}
@@ -727,7 +743,7 @@
\@tempskipa #5\relax
\ifdim \@tempskipa>\z@
\begingroup
- \tagtool{para-flattened=true} % or \bool_set_true\l__tag_para_flattened_bool
+ \tagtool{para-flattened=true} % or \bool_set_true\l_@@_para_flattened_bool
#6{%
\ifnum #2>\c@secnumdepth
\@hangfrom {\hskip #3\relax\@svsec}%
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-sec.pdf b/macros/latex-dev/required/latex-lab/latex-lab-sec.pdf
index d7e97aa25c..3d17a34ffa 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-sec.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-sec.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-table.dtx b/macros/latex-dev/required/latex-lab/latex-lab-table.dtx
index 38596478ae..c65667e8ed 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-table.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-table.dtx
@@ -16,8 +16,8 @@
%
% for those people who are interested or want to report an issue.
%
-\def\ltlabtbldate{2024-05-25}
-\def\ltlabtblversion{0.85i}
+\def\ltlabtbldate{2024-09-18}
+\def\ltlabtblversion{0.85n}
%<*driver>
\documentclass{l3doc}
\EnableCrossrefs
@@ -100,6 +100,7 @@
% support for the tagging of tables. A list of the known limitations
% is shown below.
%
+% \subsection{Loading}
% The module is not loaded automatically (i.e., not yet integrated
% into any \texttt{phase-XX}) and by itself it doesn't activate
% tagging. For experimenting with table tagging it is therefore best
@@ -113,7 +114,26 @@
% It will then automatically tag all table environments it already supports with
% the exception of tables in the header and footer of the page (where tagging is disabled).
% Such tables can be nested.
+%
+% Inside cells the automatic tagging of paragraphs is disabled with the exception of
+% p/m/b-type cells.
%
+% Rows do not need to contain a full number of \&, missing cells are automatically
+% added with an empty TD-structure.
+%
+% You should not insert meaningful text with \verb+!{...}+ or \verb+@{...}+ or \cs{noalign}
+% between the rows or columns of the table.
+% With pdflatex such text will be unmarked, with lualatex it will be marked as artifact.
+% Either case means that it will be currently ignored in the
+% structure.\footnote{While it is theoretically possible
+% to collect such text and move it into a structure it would require manual markup
+% from the author to clarify where this text belongs too.}
+%
+% As mentioned below the \pkg{colortbl} doesn't work fully with the tagging,
+% but when it does, colors inside the table are currently ignored. If such a color
+% has a semantic meaning (like \enquote{important value}) this meaning will be lost.
+%
+% \subsection{Untagged and presentation tables}
% If a table should not be tagged as table, for example because it is merely used
% as a layout to ensure that the content is properly aligned
% or because it is a not yet (fully) supported table structure,
@@ -130,41 +150,43 @@
% The key should currently only be used in a group as there is no key (yet) to reset to the default
% tag names.
%
-% Inside cells the automatic tagging of paragraphs is disabled with the exception of
-% p/m/b-type cells.
-%
-% Rows do not need to contain a full number of \&, missing cells are automatically
-% added with an empty TD-structure.
-%
+% \subsection{Header rows and columns}
% There is some basic support\footnote{This is not meant to be the
% final interface, though.} for headers. With\footnote{The old key name \texttt{table-header-rows} still
% works but is deprecated.}
% \begin{quote}
% \verb|\tagpdfsetup{table/header-rows={|\meta{list of row numbers}\verb|}|
+% \verb|\tagpdfsetup{table/header-columns={|\meta{list of column numbers}\verb|}|
% \end{quote}
% you can
-% declare which (absolute) row numbers should be tagged as header rows.
-% It applies to all tables until it is changed to a different list of row numbers or undone by setting
-% the key to \meta{empty}.
-% A row number can be
-% negative, then the counting starts from the end of the table. There is no support
-% for header columns yet. In a \env{longtable} the code will currently use the \cs{endhead} or
+% declare which (absolute) row and column numbers should be tagged as header rows and header columns.
+% It applies to all tables until it is changed to a different list of row or
+% columns numbers or undone by setting
+% the keys to \meta{empty}.
+% A row or column number can be
+% negative, then the counting starts from the end of the table.
+% In a \env{longtable} the code will currently use the \cs{endhead} or
% \cs{endfirsthead} rows as header if one of these commands has been
% used and in that case the code
% ignores a \texttt{table/header-rows} setting.
%
-% You should not insert meaningful text with \verb+!{...}+ or \verb+@{...}+ or \cs{noalign}
-% between the rows or columns of the table.
-% With pdflatex such text will be unmarked, with lualatex it will be marked as artifact.
-% Either case means that it will be currently ignored in the
-% structure.\footnote{While it is theoretically possible
-% to collect such text and move it into a structure it would require manual markup
-% from the author to clarify where this text belongs too.}
+% \subsection{Spanning of cells}
%
-% As mentioned below the \pkg{colortbl} doesn't yet work properly with the tagging,
-% but once it does, then colors inside the table will probably be
-% simply ignored (at least initially). If such a color
-% has a semantic meaning (like \enquote{important value}) this meaning will be lost.
+% \cs{multicolumn} is supported out of the box and will create a structure with a
+% suitable \texttt{ColSpan} attribute\footnote{The code uses actually an attribute \emph{class}.
+% The validator PAC doesn't handle this correctly currently and complains about a missing attribute.}
+%
+% For cells spanning rows some preliminary support exists\footnote{The interface is bound to change!}:
+% If you add
+% \begin{quote}
+% \verb|\tagpdfsetup{table/multirow={|\meta{number of rows}\verb|}|
+% \end{quote}
+% to a cell the code will add the suitable \texttt{RowSpan} attribute and suppress the tagging of affected
+% cells in the following rows. This will also work if the current cell is a \cs{multicolumn}, then
+% the cell will span both rows and columns. It is the duty of the author to
+% ensure that all cells below and covered by a \texttt{RowSpan} are empty!
+% The code neither checks that nor does
+% it tries to suppress content.
%
% Feedback and problems with the code can be reported at
% \url{https://github.com/latex3/tagging-project} either in form of
@@ -183,19 +205,19 @@
% \item the \env{array} environment is assumed to be part of math and tagging as a table is disabled for
% it.
%
-% \item Row spans are not yet supported (and the \pkg{multirow} package is untested).
+% \item Row spans can only be added manually (the \pkg{multirow} package is untested).
%
-% \item The \pkg{colortbl} package breaks tagging if there are nested tables. It also breaks
-% the filling up of incomplete rows.
+% \item The \pkg{colortbl} package breaks tagging if there are nested tables.
%
% \item The \pkg{tabularray} package use a completed different
% method to create tables and will not be supported by this code.
%
% \item The \pkg{nicematrix} package is currently incompatible.
%
-% \item Most other packages related to tables in \LaTeX{} are not yet tested,
+% \item Most other packages related to tables in \LaTeX{} are not fully tested,
% that includes packages that change rules like \pkg{booktabs}, \pkg{hhline},
-% \pkg{arydshln}, \pkg{hvdashln}.
+% \pkg{arydshln}, \pkg{hvdashln}. Some problems have been resolved, either
+% in the packages or through a firstaid which can be loaded the \verb+testphase=firstaid+.
%
% \item \env{longtable} currently only works with lualatex.
% With other engines it breaks as its output
@@ -208,9 +230,9 @@
% the tagging of the table must be deactivated with \verb|\tagpdfsetup{table/tagging=false}|
% or \verb|\tagpdfsetup{table/tagging=presentation}|.
%
-% \item Only simple header rows are currently supported. Columns and complex headers with
+% \item Only simple header rows and columns are currently supported. Complex headers with
% subheaders will be handled later as that needs some syntax changes. Tables
-% with more than one header row are probably not pdf/UA as the headers array in
+% with more than one header row or column are probably not pdf/UA as the headers array in
% the cells is missing.
%
% \item A \pkg{longtable} \cs{caption} is currently simply formatted as a multicolumn and
@@ -259,9 +281,6 @@
%
% \item Longtable captions should be properly supported.
%
-% \item Handle p-cells better. para-tagging should probably be enabled,
-% but Part can't be a child of TD, so this should probably be changed to Div here.
-% Also there is a stray MC somewhere.
%
% \item More packages must be tested.
% \end{itemize}
@@ -292,8 +311,8 @@
% ,\l_@@_cellattribute_tl
% ,\l_@@_rowattribute_tl
% ,\l_@@_tmpa_clist
-% ,\l_@@_tmpa_seq
% ,\l_@@_tmpa_tl
+% ,\l_@@_tmpa_str
% }
% This is for the celltag, e.g. TD or TH:
% \begin{macrocode}
@@ -319,10 +338,16 @@
\tl_new:N \l_@@_rowattribute_tl
\tl_set:Nn \l_@@_rowattribute_tl {}
% \end{macrocode}
+% Variable to store cell info like which cell must be skipped when tagging multirows.
+% \begin{macrocode}
+\prop_new:N\g_@@_untagged_cells_prop
+\prop_new:N\l_@@_saved_untagged_cells_prop
+% \end{macrocode}
% Temp variables
% \begin{macrocode}
\clist_new:N \l_@@_tmpa_clist
\tl_new:N \l_@@_tmpa_tl
+\str_new:N \l_@@_tmpa_str
% \end{macrocode}
% \end{macro}
%
@@ -330,7 +355,41 @@
%
%
% This are the standard plugs for tagging of cells and rows.
-%
+%
+% The following two sockets are defined in lttagging, but we check
+% for their existence until the release 11/2024.
+% \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/tbl/init/celldata_plug_str }
+ {
+ \NewSocket{tagsupport/tbl/init/celldata}{0}
+ \NewSocket{tagsupport/tbl/restore/celldata}{0}
+ }
+% \end{macrocode}
+% \begin{plugdecl}{default}
+% This socket is used inside \cs{tbl_init_cell_data_for_table} for the
+% case that this a nested table in a cell.
+% \begin{macrocode}
+\NewSocketPlug{tagsupport/tbl/init/celldata}{default}
+ {
+ \prop_set_eq:NN\l_@@_saved_untagged_cells_prop \g_@@_untagged_cells_prop
+ \prop_gclear:N \g_@@_untagged_cells_prop
+ }
+\AssignSocketPlug{tagsupport/tbl/init/celldata}{default}
+% \end{macrocode}
+% \end{plugdecl}
+
+% \begin{plugdecl}{default}
+% This socket is used inside \cs{tbl_restore_outer_cell_data:} and restores
+% values when a nested table is ended.
+% \begin{macrocode}
+\NewSocketPlug{tagsupport/tbl/restore/celldata}{default}
+ {
+ \prop_gset_eq:NN\g_@@_untagged_cells_prop \l_@@_saved_untagged_cells_prop
+ }
+\AssignSocketPlug{tagsupport/tbl/restore/celldata}{default}
+% \end{macrocode}
+% \end{plugdecl}
+%
% \begin{plugdecl}{TD}
% \begin{macrocode}
\NewSocketPlug{tagsupport/tbl/cell/begin}{TD}
@@ -340,21 +399,44 @@
% always even if the noop plug is in force this needs a different solution.
% \begin{macrocode}
\@@_show_curr_cell_data:
- \tag_struct_begin:n
+% \end{macrocode}
+% We test if the cell should be tagged at all.
+% \begin{macrocode}
+ \@@_if_tag_cell:nnT {\g_@@_row_int } { \g_@@_col_int }
{
- tag =\l_@@_celltag_tl,
- attribute-class =\l_@@_cellattribute_tl
- }
- \seq_gput_right:Ne \g_@@_struct_cur_seq { \tag_get:n {struct_num} }
+% \end{macrocode}
+% this sets row headers
+% \begin{macrocode}
+ \clist_if_in:NVT \l_@@_header_columns_clist\g_@@_col_int
+ {
+ \tl_set:Nn \l_@@_celltag_tl {TH}
+ \tl_set:Ne \l_@@_cellattribute_tl {\l_@@_cellattribute_tl,TH-row}
+ }
+% \end{macrocode}
+% Here we handle negative value for row headers:
+% \begin{macrocode}
+ \tl_set:Ne \l_@@_tmpa_tl {\int_eval:n { \g_@@_col_int - 1 - \g_@@_table_cols_tl }}
+ \clist_if_in:NoT \l_@@_header_columns_clist { \l_@@_tmpa_tl }
+ {
+ \tl_set:Nn \l_@@_celltag_tl {TH}
+ \tl_set:Ne \l_@@_cellattribute_tl {\l_@@_cellattribute_tl,TH-row}
+ }
+ \tag_struct_begin:n
+ {
+ tag =\l_@@_celltag_tl,
+ attribute-class ={\l_@@_cellattribute_tl}
+ }
+ \seq_gput_right:Ne \g_@@_struct_cur_seq { \tag_get:n {struct_num} }
% \end{macrocode}
% we store the cells of multicolumns as negative number. This allow to skip them
% or to use them as needed.
% \begin{macrocode}
- \int_step_inline:nn { \g_@@_span_tl - 1 }
- {
- \seq_gput_right:Ne \g_@@_struct_cur_seq { -\tag_get:n {struct_num} }
- }
- \tag_mc_begin:n{}
+ \int_step_inline:nn { \g_@@_span_tl - 1 }
+ {
+ \seq_gput_right:Ne \g_@@_struct_cur_seq { -\tag_get:n {struct_num} }
+ }
+ \tag_mc_begin:n{}
+ }
}
% \end{macrocode}
% \end{plugdecl}
@@ -363,8 +445,11 @@
% \begin{macrocode}
\NewSocketPlug{tagsupport/tbl/cell/end}{TD}
{
- \tag_mc_end:
- \tag_struct_end:
+ \@@_if_tag_cell:nnT {\g__tbl_row_int } { \g__tbl_col_int }
+ {
+ \tag_mc_end:
+ \tag_struct_end:
+ }
}
% \end{macrocode}
% \end{plugdecl}
@@ -376,18 +461,26 @@
\NewSocketPlug{tagsupport/tbl/pcell/begin}{TDpbox}
{
\@@_show_curr_cell_data:
- \tag_struct_begin:n
+ \@@_if_tag_cell:nnT {\g__tbl_row_int } { \g__tbl_col_int }
{
- tag =\l__tbl_pcelltag_tl,
- attribute-class =\l__tbl_cellattribute_tl
- }
- \seq_gput_right:Ne \g__tbl_struct_cur_seq { \tag_get:n {struct_num} }
- \int_step_inline:nn { \g__tbl_span_tl - 1 }
- {
- \seq_gput_right:Ne \g__tbl_struct_cur_seq { -\tag_get:n {struct_num} }
- }
- \tagpdfparaOn
- \tl_set:Nn \l__tag_para_main_tag_tl {Div}
+ \clist_if_in:NVT \l_@@_header_columns_clist\g_@@_col_int
+ {
+ \tl_set:Nn \l_@@_celltag_tl {TH}
+ \tl_set:Ne \l_@@_cellattribute_tl {\l_@@_cellattribute_tl,TH-row}
+ }
+ \tag_struct_begin:n
+ {
+ tag =\l_@@_pcelltag_tl,
+ attribute-class ={\l_@@_cellattribute_tl}
+ }
+ \seq_gput_right:Ne \g_@@_struct_cur_seq { \tag_get:n {struct_num} }
+ \int_step_inline:nn { \g_@@_span_tl - 1 }
+ {
+ \seq_gput_right:Ne \g_@@_struct_cur_seq { -\tag_get:n {struct_num} }
+ }
+ \tagpdfparaOn
+ \tl_set:Nn \l__tag_para_main_tag_tl {Div}
+ }
}
% \end{macrocode}
% \end{plugdecl}
@@ -396,7 +489,12 @@
% \begin{macrocode}
\NewSocketPlug{tagsupport/tbl/pcell/end}{TDpbox}
{
- \tag_struct_end:
+ \@@_if_tag_cell:nnT {\g_@@_row_int } { \g_@@_col_int }
+ {
+ \tag_struct_end:
+ \legacy_if:nT {@endpe}{\par}
+ \mode_if_vertical:T{ \tagpdfparaOff }
+ }
}
% \end{macrocode}
% \end{plugdecl}
@@ -432,7 +530,7 @@
{
\@@_trace:n
{==>~
- stucture~stored~for~row~\int_use:N\g_@@_row_int :~
+ structure~stored~for~row~\int_use:N\g_@@_row_int :~
\seq_use:Nn \g_@@_struct_cur_seq {,}
}
}
@@ -447,21 +545,49 @@
% normal tables which can also be used inline and nested and
% \enquote{vmode} tables like longtable.
%
+% \begin{macro}{\l__tag_block_flattened_level_int}
+% Count the levels of nested blockenvs starting with the first that
+% is \enquote{flattened}. The counter is defined in lttagging.dtx,
+% but until the next release 11/24 we set it up here too so that we can
+% use it in the following socket
+% \begin{macrocode}
+\int_if_exist:NF \l__tag_block_flattened_level_int
+ {
+ \int_new:N \l__tag_block_flattened_level_int
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{plugdecl}{Table}
+% Inside a TD or TR Part is not allowed as child. For structures that restore
+% paragraph settings we therefore need a special plug that adjust the settings.
+% Currently we set the para main tag to Div. This leads to double Div-structures
+% but flattening the paragraph doesn't work, it errors if there is a list inside.
+% \begin{macrocode}
+\NewSocketPlug{tagsupport/para/restore}{Table}
+ {
+ \tl_set:Nn \l__tag_para_main_tag_tl {Div}
+ \tl_set_eq:NN \l__tag_para_tag_tl\l__tag_para_tag_default_tl
+ \bool_set_true:N \l__tag_para_bool
+ \bool_set_false:N \l__tag_para_flattened_bool
+ \int_zero:N \l__tag_block_flattened_level_int
+ }
+% \end{macrocode}
+% \end{plugdecl}
+%
% \begin{plugdecl}{Table}
% Inside a table we currently only disable paratagging. We assume
-% that these sockets are in an environment group, so there is no
+% that these sockets are called in a group, so there is no
% need to reenable paratagging.
% \begin{macrocode}
\NewSocketPlug{tagsupport/tbl/init}{Table}
{
- \tag_if_active:T
- {
- \bool_set_false:N \l__tag_para_bool
+ \bool_set_false:N \l__tag_para_bool
+ \AssignSocketPlug{tagsupport/para/restore}{Table}
% \end{macrocode}
% We also initialize the structure data variables a this point.
% \begin{macrocode}
- \@@_init_struct_data:
- }
+ \@@_init_struct_data:
}
% \end{macrocode}
% \end{plugdecl}
@@ -573,7 +699,7 @@
\prop_if_exist:cT
{ g__tag_struct_ \l_@@_tmpa_tl _prop }
{
- \exp_args:No \__tag_struct_prop_gput:nnn {\l_@@_tmpa_tl} {S}{/Artifact}
+ \__tag_struct_prop_gput:onn { \l_@@_tmpa_tl } {S}{/Artifact}
}
}
}
@@ -664,7 +790,7 @@
\prop_if_exist:cT
{ g__tag_struct_ \l_@@_tmpa_tl _prop }
{
- \exp_args:No\__tag_struct_prop_gput:nnn {\l_@@_tmpa_tl} {S}{/Artifact}
+ \__tag_struct_prop_gput:onn {\l_@@_tmpa_tl} {S}{/Artifact}
}
}
}
@@ -711,7 +837,7 @@
\tag_mc_end_push:
% \end{macrocode}
% Close the P-chunk. This assumes that para-tagging is active.
-% For nested tables that is not necessarly true, so we test for it.
+% For nested tables that is not necessarily true, so we test for it.
% \begin{macrocode}
\bool_lazy_and:nnT
{ \bool_if_exist_p:N \l__tag_para_bool } { \l__tag_para_bool }
@@ -729,7 +855,7 @@
\tag_struct_end:
% \end{macrocode}
% reopen the P-chunk. This assumes that para-tagging is active.
-% For nested tables that is not necessarly true, so we test for it.
+% For nested tables that is not necessarily true, so we test for it.
% \begin{macrocode}
\bool_lazy_and:nnT
{ \bool_if_exist_p:N \l__tag_para_bool } { \l__tag_para_bool }
@@ -778,15 +904,32 @@
{/O /Table /ColSpan~\int_eval:n{#1}}
}
\tl_set:Ne \l_@@_cellattribute_tl
- {colspan-\int_eval:n{#1}}
+ {\l_@@_cellattribute_tl,colspan-\int_eval:n{#1}}
}
}
% \end{macrocode}
-% TODO: move to tagpdf
+% \end{plugdecl}
+%
+%
+%
+%
+% \begin{plugdecl}{code}
+% The sockets will be in lttagging.dtx, but that may only happen in
+% the next main release, so for now we test if they are in the
+% format and if not define them now.
+% \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/tbl/leaders/end_plug_str }
+ {
+ \NewSocket{tagsupport/tbl/leaders/begin}{0}
+ \NewSocket{tagsupport/tbl/leaders/end}{0}
+ }
+% \end{macrocode}
+%
% \begin{macrocode}
-\tag_if_active:T
- { \cs_generate_variant:Nn \__tag_attr_new_entry:nn {ee} }
-
+\NewSocketPlug{tagsupport/tbl/leaders/begin}{code}
+ { \tag_mc_begin:n{artifact} }
+\NewSocketPlug{tagsupport/tbl/leaders/end}{code}
+ { \tag_mc_end: }
% \end{macrocode}
% \end{plugdecl}
%
@@ -810,8 +953,7 @@
% \subsection{Interfaces to tagging}
%
% \subsubsection{Tagging helper commands}
-%
-%
+
% \subsubsection{Disabling/enabling}
%
% For now we have only the option true/false but this will probably be extended
@@ -839,6 +981,8 @@
\AssignSocketPlug{tagsupport/tbl/vmode/begin}{noop}
\AssignSocketPlug{tagsupport/tbl/vmode/end}{noop}
\AssignSocketPlug{tagsupport/tbl/colspan}{noop}
+ \AssignSocketPlug{tagsupport/tbl/leaders/begin}{noop}
+ \AssignSocketPlug{tagsupport/tbl/leaders/end}{noop}
}
% \end{macrocode}
% \end{macro}
@@ -866,6 +1010,8 @@
\AssignSocketPlug{tagsupport/tbl/vmode/begin}{Table}
\AssignSocketPlug{tagsupport/tbl/vmode/end}{Table}
\AssignSocketPlug{tagsupport/tbl/colspan}{code}
+ \AssignSocketPlug{tagsupport/tbl/leaders/begin}{code}
+ \AssignSocketPlug{tagsupport/tbl/leaders/end}{code}
}
% \end{macrocode}
% \end{macro}
@@ -886,14 +1032,15 @@
\tl_set:Nn\l_@@_pcelltag_tl {NonStruct}
\tl_set:Nn\l_@@_celltag_tl {text}
\tl_set:Nn\l_@@_tabletag_tl {Div}
- \clist_clear:N \l_@@_header_rows_clist
+ \clist_clear:N \l_@@_header_rows_clist
+ \clist_clear:N \l_@@_header_columns_clist
},
table/tagging .default:n = true,
table/tagging .initial:n = true
}
% \end{macrocode}
% This are the old key names kept for now for
-% compability. They will got at some time.
+% compatibility. They will got at some time.
% \begin{macrocode}
\keys_define:nn { __tag / setup }
{
@@ -955,11 +1102,12 @@
% \end{macrocode}
%
-% \begin{variable}{\l_@@_header_rows_clist}
-% This holds the numbers of the header rows. Negative numbers are
+% \begin{variable}{\l_@@_header_rows_clist,\l_@@_header_columns_clist}
+% This holds the numbers of the header rows and columns. Negative numbers are
% possible and count from the last column backwards.
% \begin{macrocode}
\clist_new:N \l_@@_header_rows_clist
+\clist_new:N \l_@@_header_columns_clist
% \end{macrocode}
% \end{variable}
%
@@ -982,14 +1130,26 @@
{
\__tag_struct_prop_gput:nnn{ ####1 }{S}{/TH}
% \end{macrocode}
-% This need refinement once row headers (and perhaps other attributes)
-% are used too, but for now it should be ok.
+% This sets the scope class. If the header has already a row attribute
+% we replace by TH-both.
% \begin{macrocode}
\prop_get:cnNTF
{ g__tag_struct_####1_prop }
{ C }
\l_@@_tmpa_tl
- {\__tag_struct_prop_gput:nne{ ####1 }{C}{[/TH-col~\l_@@_tmpa_tl]} }
+ {
+ \str_set:Ne \l_@@_tmpa_str {\l_@@_tmpa_tl}
+ \str_remove_once:Nn \l_@@_tmpa_str {[}
+ \str_remove_once:Nn \l_@@_tmpa_str {]}
+ \str_if_in:NnTF\l_@@_tmpa_str{/TH-row}
+ {
+ \str_replace_once:Nnn \l_@@_tmpa_str {/TH-row}{/TH-both}
+ \__tag_struct_prop_gput:nne{ ####1 }{C}{[\l_@@_tmpa_str]}
+ }
+ {
+ \__tag_struct_prop_gput:nne{ ####1 }{C}{[/TH-col~\l_@@_tmpa_str]}
+ }
+ }
{\__tag_struct_prop_gput:nnn{ ####1 }{C}{/TH-col}}
}
}
@@ -1004,6 +1164,7 @@
\keys_define:nn { __tag / setup }
{
table/header-rows .clist_set:N = \l_@@_header_rows_clist,
+ table/header-columns .clist_set:N = \l_@@_header_columns_clist,
% \end{macrocode}
% obsolete older name:
% \begin{macrocode}
@@ -1011,8 +1172,114 @@
}
% \end{macrocode}
%
+% \subsection{Multirow support}
+%
+% \begin{macro}{\@@_multirow:n}
+% This command makes the current cell into a multirow cell:
+% it creates, if needed, an RowSpan-attribute, adds it to the attributes
+% of the cell structure, and marks all following cells spanned by the multirow
+% as cells that should not be tagged. The argument is the number of spanned row
+% (including the current row).
+% \begin{macrocode}
+\cs_if_exist:NT \__tag_struct_prop_gput:nnn
+ {
+ \cs_generate_variant:Nn \__tag_struct_prop_gput:nnn {one}
+ }
+\cs_new_protected:Npn \@@_multirow:n #1
+ {
+% \end{macrocode}
+% Create an attribute if needed:
+% \begin{macrocode}
+ \prop_get:NeNF \g__tag_attr_entries_prop
+ {rowspan-\int_eval:n{#1}}
+ \l_@@_tmpa_tl
+ {
+ \__tag_attr_new_entry:ee
+ {rowspan-\int_eval:n{#1}}
+ {/O /Table /RowSpan~\int_eval:n{#1}}
+ }
+% \end{macrocode}
+% ensure that the attribute is marked as used:
+% \begin{macrocode}
+ \seq_gput_left:Ne\g__tag_attr_class_used_seq
+ {\pdf_name_from_unicode_e:n{rowspan-\int_eval:n{#1}}}
+% \end{macrocode}
+% Get the structure number of the current cell
+% \begin{macrocode}
+ \seq_get_right:NN\g_@@_struct_cur_seq \l_@@_tmpb_tl
+% \end{macrocode}
+% If we are in a multicolumn the number can be negative and
+% this must be changed
+% \begin{macrocode}
+ \tl_set:Ne \l_@@_tmpb_tl { \int_abs:n{\l_@@_tmpb_tl} }
+% \end{macrocode}
+% no we must update an existing attribute.
+% TODO: simplify this ... (see also colspan handling).
+% \begin{macrocode}
+ \prop_get:cnNTF
+ { g__tag_struct_\l_@@_tmpb_tl _prop }
+ { C }
+ \l_@@_tmpa_tl
+ {
+ \tl_remove_once:Nn \l_@@_tmpa_tl {[}
+ \tl_remove_once:Nn \l_@@_tmpa_tl {]}
+ \__tag_struct_prop_gput:one{ \l_@@_tmpb_tl }
+ {C}
+ {[/rowspan-\int_eval:n{#1}~\l_@@_tmpa_tl]}
+ }
+ {
+ \__tag_struct_prop_gput:one{ \l_@@_tmpb_tl }
+ {C}
+ {[/rowspan-\int_eval:n{#1}]}
+ }
+% \end{macrocode}
+% Now mark the spanned cells that should be ignored.
+% \begin{macrocode}
+ \@@_gset_untagged_row_cells:nn {#1-1}{\g_@@_span_tl}
+ }
+% \end{macrocode}
+% \end{macro}
%
+% \begin{macrocode}
+\keys_define:nn{ __tag / setup }
+ { table/multirow .code:n = {\@@_multirow:n {#1} }
+ ,table/multirow .default:n = 1
+ }
+% \end{macrocode}
%
+% \begin{macro}{\@@_gset_untagged_row_cells:nn}
+% This command stores the row and column numbers of the cells in the following row(s)
+% that should not be tagged as they are a part of a rowspan.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_gset_untagged_row_cells:nn #1 #2 % #1 number of rows, #2 number of columns
+ {
+ \int_step_inline:nn {#1}
+ {
+ \int_step_inline:nn {#2}
+ {
+ \prop_gput:Nee \g_@@_untagged_cells_prop
+ { \int_eval:n {\g_@@_row_int + ##1},\int_eval:n{\g_@@_col_int + ####1 -1 } }{}
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_if_tag_cell:nn}
+% We must be able to detect if a cell should be tagged. For this
+% we define a conditional --- if more options are needed it can be extended.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn\@@_if_tag_cell:nn #1 #2 %#1 row, #2 col
+ { T,TF }
+ {
+ \prop_get:NeNTF \g_@@_untagged_cells_prop
+ {\int_eval:n{#1},\int_eval:n{#2}}\l__tbl_tmpa_tl
+ { \prg_return_false:}
+ { \prg_return_true: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \subsection{Misc stuff}
%
% \begin{macro}{\@@_show_curr_cell_data:}
@@ -1037,13 +1304,6 @@
% cell of a row, but still inside that cell, so we use two
% commands. The one adding is used in the row/end socket.
% \begin{macrocode}
-\NewSocket{tbl/celldata/missingcount}{1}
-\NewSocketPlug{tbl/celldata/missingcount}{code}{\tbl_count_missing_cells:n{#1}}
-\AssignSocketPlug{tbl/celldata/missingcount}{code}
-
-% \end{macrocode}
-%
-% \begin{macrocode}
\cs_new:Npn \@@_add_missing_cells:
{
% \end{macrocode}
@@ -1058,6 +1318,7 @@
additional~cell(s)~into~previous~row:}
\int_step_inline:nn { \g_@@_missing_cells_int }
{
+ \int_gincr:N\g_@@_col_int
\UseTaggingSocket{tbl/cell/begin}
\UseTaggingSocket{tbl/cell/end}
}
@@ -1164,9 +1425,9 @@
}
\hbox to\z@{\hss\parbox[t]\LTcapwidth{%
\reset@font
- \tag_stop:n{caption}
+ \tag_suspend:n{caption}
\sbox\@tempboxa{#1{#2:~}#3}%
- \tag_start:n{caption}
+ \tag_resume:n{caption}
\ifdim\wd\@tempboxa>\hsize
#1{#2:~}#3%
\else
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-table.pdf b/macros/latex-dev/required/latex-lab/latex-lab-table.pdf
index 199232ce63..dcea7bcb82 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-table.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-table.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-testphase.dtx b/macros/latex-dev/required/latex-lab/latex-lab-testphase.dtx
index f0a6fe65d0..1134654cd6 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-testphase.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-testphase.dtx
@@ -47,7 +47,7 @@
%
% Currently the values |phase-I|, |phase-II|, |phase-III| and |new-or| (bundles |new-or-1|
% and |new-or-2|) are provided.
-% |tagpdf| is an undocumented alias for |phase-II| which is kept for compability.
+% |tagpdf| is an undocumented alias for |phase-II| which is kept for compatibility.
% The value |math| combines various math related files.
%
% \StopEventually{\setlength\IndexMin{200pt} \PrintIndex }
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-testphase.pdf b/macros/latex-dev/required/latex-lab/latex-lab-testphase.pdf
index 531eff4508..8c3e5d76f7 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-testphase.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-testphase.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-text.dtx b/macros/latex-dev/required/latex-lab/latex-lab-text.dtx
index fe9b6ababc..7ca99191dc 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-text.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-text.dtx
@@ -16,8 +16,8 @@
%
% for those people who are interested or want to report an issue.
%
-\def\ltlabtextdate{2023-07-20}
-\def\ltlabtextversion{0.85a}
+\def\ltlabtextdate{2024-09-18}
+\def\ltlabtextversion{0.85b}
%<*driver>
\documentclass{l3doc}
@@ -78,11 +78,11 @@
\tag_mc_end_push:
\tag_struct_begin:n{tag=Span,actualtext=LaTeX}
\tag_mc_begin:n{}
- \tag_stop:n{LaTeX}
+ \tag_suspend:n{LaTeX}
}
\AddToHook{cmd/LaTeX/after}
{
- \tag_start:n{LaTeX}
+ \tag_resume:n{LaTeX}
\tag_mc_end:
\tag_struct_end:
\tag_mc_begin_pop:n{}
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-text.pdf b/macros/latex-dev/required/latex-lab/latex-lab-text.pdf
index ded11a05be..7473e1eb31 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-text.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-text.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-title.pdf b/macros/latex-dev/required/latex-lab/latex-lab-title.pdf
index 934b25bdda..3b2e8cb994 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-title.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-title.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-toc-hyperref-changes.pdf b/macros/latex-dev/required/latex-lab/latex-lab-toc-hyperref-changes.pdf
index 58690a8fa9..489a3aba9a 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-toc-hyperref-changes.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-toc-hyperref-changes.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-toc-kernel-changes.dtx b/macros/latex-dev/required/latex-lab/latex-lab-toc-kernel-changes.dtx
index bb88ffdcb0..2934a26168 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-toc-kernel-changes.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-toc-kernel-changes.dtx
@@ -17,8 +17,8 @@
% for those people who are interested or want to report an issue.
%
% dates for latex-lab-kernel-changes.sty (pulled from various sources, see ins)
-\def\ltlabkerneldate{2024-02-12}
-\def\ltlabkernelversion{0.85c}
+\def\ltlabkerneldate{2024-07-11}
+\def\ltlabkernelversion{0.85d}
%<*driver>
\documentclass{l3doc}
\EnableCrossrefs
@@ -44,6 +44,11 @@
%
% \providecommand\hook[1]{\texttt{#1}}
%
+%
+% \ProvideDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl}
+% \ProvideDocElement[printtype=\textit{hook},idxtype=hook,idxgroup=Hooks]{Hook}{hookdecl}
+% \ProvideDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl}
+%
% \begin{abstract}
% \end{abstract}
%
@@ -68,67 +73,14 @@
% \end{macrocode}
%
% \subsection{Providing the counter representation \cs{theHxx} generally}
-% [kernel?]
-%
-% The \cs{theHxx} representation allows to create a unique representation of a counter
-% that is for example used to create destination names. It will also be needed
-% to add |/Ref| keys to various tagging structures. It makes therefore sense
-% to provide it by default as soon as a counter is created. The |\@addtoreset| change
-% (taken also from hyperref) tries to ensure the counter stays unique if it is reset.
-%
-% At first we suppress the patches from hyperref:
+%
+% This has been moved to base.
+%
+% We still suppress the patches from hyperref:
% \begin{macrocode}
\def\hyper@nopatch@counter{}
% \end{macrocode}
-%
-% \begin{macrocode}
-\def\@definecounter#1{\expandafter\newcount\csname c@#1\endcsname
- \setcounter{#1}\z@
- \global\expandafter\let\csname cl@#1\endcsname\@empty
- \@addtoreset{#1}{@ckpt}%
- \global\expandafter\let\csname p@#1\endcsname\@empty
- \expandafter\gdef\csname theH#1\endcsname{\the\value{#1}}%new
- \expandafter
- \gdef\csname the#1\expandafter\endcsname\expandafter
- {\expandafter\@arabic\csname c@#1\endcsname}}
-\def\@addtoreset#1#2{\expandafter\@cons\csname cl@#2\endcsname {{#1}}%
- \expandafter\gdef\csname theH#1\endcsname{\csname theH#2\endcsname.\the\value{#1}}%
-}
-% \end{macrocode}
-% The following counters are defined in the kernel
-% \begin{macrocode}
-\gdef\theHenumi{\the\value{enumi}}
-\gdef\theHenumii{\the\value{enumii}}
-\gdef\theHenumiii{\the\value{enumiii}}
-\gdef\theHenumiv{\the\value{enumiv}}
-\gdef\theHequation{\the\value{equation}}
-\gdef\theHfootnote{\the\value{footnote}}
-\gdef\theHmpfootnote{\the\value{mpfootnote}}
-% \end{macrocode}
-%
-% \subsection{Providing and updating \cs{@currentHref}}
-% [kernel?]
-%
-% \cs{@currentHref} contains the current unique representation of a counter.
-% It is useful also without hyperref as it allows to connect with a |/Ref|
-% key a toc entry with the heading it refers too. So \cs{refstepcounter}
-% is extended to update the command. This is done at the begin so that the
-% hyperref code can still adapt it later (using the cmd/refstepcounter/after hook
-% would be too late, and could also break with cleverref.)
-%
-% We also provide a kernel version that hyperref doesn't touch and so will never
-% set a target.
-% \begin{macrocode}
-\def\@currentHref{}
-\def\refstepcounter#1{\stepcounter{#1}%
- \edef\@currentcounter{#1}%
- \xdef\@currentHref {#1.\csname theH#1\endcsname}%
- \protected@edef\@currentlabel
- {\csname p@#1\expandafter\endcsname\csname the#1\endcsname}%
-}
-\let\@kernel@refstepcounter\refstepcounter
-% \end{macrocode}
-%
+
% \subsection{Assigning the headings level numbers}
% [kernel?]
%
@@ -160,17 +112,21 @@
% catch as much as possible, see also tagging issue \#20. This should work also
% without hyperref. The property is defined in tagpdf-base, so the code would
% work also without tagging but we add a test anyway, this is probably faster.
+% TODO: remove
% \begin{macrocode}
\ExplSyntaxOn
-\AddToHookWithArguments{cmd/MakeLinkTarget/after}
- {
- \tag_if_active:T
- {
- \tl_if_blank:VF \@currentHref
- {
- \prop_gput:Nee \g__tag_struct_dest_num_prop {\@currentHref}{\tag_get:n{struct_num}}
- }
- }
+\str_if_exist:cF { l__socket_tagsupport/recordtarget_str }
+ {
+ \AddToHookWithArguments{cmd/MakeLinkTarget/after}
+ {
+ \tag_if_active:T
+ {
+ \tl_if_blank:VF \@currentHref
+ {
+ \prop_gput:Nee \g__tag_struct_dest_num_prop {\@currentHref}{\tag_get:n{struct_num}}
+ }
+ }
+ }
}
\ExplSyntaxOff
% \end{macrocode}
@@ -187,12 +143,24 @@
% \subsection{\cs{contentsline} extension}
% [latex-lab]
% The tagging code must add code at the begin and end of \cs{contentsline}.
-% This code must have access to the arguments. We set it up as config point
-% for now.
+% This code must have access to the arguments. They are passed
+% together in tagging socket.
+% \begin{socketdecl}{tagsupport/toc/contentsline/before,
+% tagsupport/toc/contentsline/after}
+% Tagging sockets at the begin and end of contentsline.
+% They receive \emph{all} contentsline arguments as one argument
+% in four brace groups. The socket code should then use the parts it needs.
+% The sockets will be in lttagging.dtx, but that may only happen in
+% the next main release, so for now we test if they are in the
+% format and if not define them now.
% \begin{macrocode}
-\def\@contentsline@cfgpoint@before#1#2#3#4{}
-\def\@contentsline@cfgpoint@after#1#2#3#4{}
+\str_if_exist:cF { l__socket_tagsupport/toc/contentsline/before_plug_str }
+ {
+ \NewSocket{tagsupport/toc/contentsline/before}{1}
+ \NewSocket{tagsupport/toc/contentsline/after}{1}
+ }
% \end{macrocode}
+% \end{socketdecl}
% for the hooks we need that the \cs{l@XX} pass also the destination and
% that \cs{l@XX} takes three arguments.
% TODO: test that, if there are two many problems we should pass the
@@ -200,10 +168,10 @@
% \begin{macrocode}
\def\contentsline#1#2#3#4%
{%
- \@contentsline@cfgpoint@before{#1}{#2}{#3}{#4}%
+ \UseTaggingSocket{toc/contentsline/before}{{#1}{#2}{#3}{#4}}%
\gdef\@contentsline@destination{#4}%
\csname l@#1\endcsname{#2}{#3}%
- \@contentsline@cfgpoint@after{#1}{#2}{#3}{#4}%
+ \UseTaggingSocket{toc/contentsline/after}{{#1}{#2}{#3}{#4}}%
}
% \end{macrocode}
%
@@ -225,17 +193,33 @@
% \subsection{\cs{@starttoc}}
% [kernel?]
%
-% We add a configuration point before and after reading the file
+% We add a tagging socket before and after reading the file
% for the tagging.
+% \begin{socketdecl}{tagsupport/toc/starttoc/before,
+% tagsupport/toc/starttoc/after}
+% Tagging sockets for the begin and end of start of \cs{@starttoc}.
+% They take one argument, the extension.
+% The sockets will be in lttagging.dtx, but that may only happen in
+% the next main release, so for now we test if they are in the
+% format and if not define them now.
+% \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/toc/starttoc/before_plug_str }
+ {
+ \NewSocket{tagsupport/toc/starttoc/before}{1}
+ \NewSocket{tagsupport/toc/starttoc/after}{1}
+ }
+% \end{macrocode}
+% \begin{macrocode}
+% \end{macrocode}
+% \end{socketdecl}
+%
% \begin{macrocode}
-\def\@starttoc@cfgpoint@before#1{}
-\def\@starttoc@cfgpoint@after#1{}
\def\@starttoc#1{%
\begingroup
\makeatletter
- \@starttoc@cfgpoint@before{#1}%
+ \UseTaggingSocket{toc/starttoc/before}{#1}%
\@input{\jobname.#1}%
- \@starttoc@cfgpoint@after{#1}%
+ \UseTaggingSocket{toc/starttoc/after}{#1}%
\if@filesw
\expandafter\newwrite\csname tf@#1\endcsname
\immediate\openout \csname tf@#1\endcsname \jobname.#1\relax
@@ -269,15 +253,32 @@
\NewMirroredHookPairWithArguments{contentsline/page/before}{contentsline/page/after}{4}%
% \end{macrocode}
%
-% The dot in the leader must be set as artifact.
+% The dots in the leader must be set as artifact.
% But luatex requires that the mc are set outside the leaders.
-% So we need a config point.
+% So we need sockets.
%
% \cs{@dottedtocline} needs hooks and formatting commands.
-% We add a sixth argument so that it can grab the destination too.
+% To make the leaders into artifact we use tagging sockets.
+% The declaration should perhaps be moved into lttagging so that
+% it can be used also by external packages even if the tagging code is not
+% loaded?
+% \begin{socketdecl}{tagsupport/toc/leaders/before,
+% tagsupport/toc/leaders/after}
+% Tagging sockets to make the dot leaders an artifact.
+% They do not take an argument.
+% The sockets will be in lttagging.dtx, but that may only happen in
+% the next main release, so for now we test if they are in the
+% format and if not define them now.
+% \begin{macrocode}
+\str_if_exist:cF { l__socket_tagsupport/toc/leaders/before_plug_str }
+ {
+ \NewSocket{tagsupport/toc/leaders/before}{0}
+ \NewSocket{tagsupport/toc/leaders/after}{0}
+ }
+% \end{macrocode}
+% \end{socketdecl}
+% The destination is accessed through \cs{@contentsline@destination}.
% \begin{macrocode}
-\def\@dottedtocline@cfgpoint@leaders#1{#1}
-
\def\@dottedtocline#1#2#3#4#5{%
\ifnum #1>\c@tocdepth \else
\vskip \z@ \@plus.2\p@
@@ -291,10 +292,11 @@
\csname contentsline@text@#1@format\endcsname{#4}%
\UseHookWithArguments{contentsline/text/after}{4}{#1}{#4}{#5}{\@contentsline@destination}%
\nobreak
- \@dottedtocline@cfgpoint@leaders{%
+ \UseTaggingSocket{toc/leaders/before}\SuspendTagging{toc/leaders}%
\leaders\hbox{$\m@th
\mkern \@dotsep mu\hbox{.}\mkern \@dotsep
- mu$}\hfill}%
+ mu$}\hfill
+ \ResumeTagging{toc/leaders}\UseTaggingSocket{toc/leaders/after}%
\nobreak
\hb@xt@\@pnumwidth{\hfil\normalfont \normalcolor
\UseHookWithArguments{contentsline/page/before}{4}{#1}{#4}{#5}{\@contentsline@destination}%
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-toc-kernel-changes.pdf b/macros/latex-dev/required/latex-lab/latex-lab-toc-kernel-changes.pdf
index c3dc4523e5..6b735d89c5 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-toc-kernel-changes.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-toc-kernel-changes.pdf
Binary files differ
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-toc.dtx b/macros/latex-dev/required/latex-lab/latex-lab-toc.dtx
index 7235eb9ed9..15dd403bdf 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-toc.dtx
+++ b/macros/latex-dev/required/latex-lab/latex-lab-toc.dtx
@@ -16,8 +16,8 @@
%
% for those people who are interested or want to report an issue.
%
-\def\ltlabtocdate{2023-10-16}
-\def\ltlabtocversion{0.85b}
+\def\ltlabtocdate{2024-09-26}
+\def\ltlabtocversion{0.85e}
%<*driver>
\documentclass{l3doc}
\EnableCrossrefs
@@ -42,7 +42,10 @@
% \newcommand{\docclass}{document class \marginpar{\raggedright document class
% customizations}}
%
-% \providecommand\hook[1]{\texttt{#1}}
+%
+% \ProvideDocElement[printtype=\textit{socket},idxtype=socket,idxgroup=Sockets]{Socket}{socketdecl}
+% \ProvideDocElement[printtype=\textit{hook},idxtype=hook,idxgroup=Hooks]{Hook}{hookdecl}
+% \ProvideDocElement[printtype=\textit{plug},idxtype=plug,idxgroup=Plugs]{Plug}{plugdecl}
%
% \begin{abstract}
% \end{abstract}
@@ -111,66 +114,32 @@
% Defined by tagpdf.
% \end{variable}
%
-% \cs{refstepcounter} doesn't use \cs{MakeLinkTarget} (yet) so
-% we have to patch it too to store the relation between
-% destination names/\cs{@currentHref} and structure numbers
+% We have to to store the relation between
+% destination names/\cs{@currentHref} and structure numbers.
+% With a current kernel this is done in \cs{refstepcounter}
+% through the |recordtarget| socket. If that doesn't exist yet
+% we patch:
%
-% The property is set up in tagpdf-test so that one
-% doesn't has to check if the prop exists or not.
+% TODO remove after release 2024/11
% \begin{macrocode}
-\AddToHook{cmd/refstepcounter/after}
- {
- \tl_if_blank:VF \@currentHref
- {
- \prop_gput:Nee \g_@@_struct_dest_num_prop {\@currentHref}{\tag_get:n{struct_num}}
- }
- }
-\AddToHook{cmd/H@refstepcounter/after}
- {
- \tl_if_blank:VF \@currentHref
- {
- \prop_gput:Nee \g_@@_struct_dest_num_prop {\@currentHref}{\tag_get:n{struct_num}}
- }
- }
-% \end{macrocode}
-% \begin{variable}{\g_@@_struct_ref_by_dest_prop}
-% This variable contains structures whose Ref key should be updated
-% at the end to point to structured related with this destination.
-% As this is probably need in other places too, it is not only a toc-variable.
-% Moved into tagpdf!
-% \end{variable}
-%
-% \begin{macro}{\g_@@_struct_ref_by_dest:}
-% This command is executed and update the Ref keys
-% of the structures listed in |\g_@@_struct_ref_by_dest_prop|.
-% It is currently only relevant for the |TOCI|. But other structures
-% could need that later too.
-% The command is executed in the |tagpdf/finish/before| hook.
-% \begin{macrocode}
-\msg_new:nnn { tag } {struct-dest-unknown}
- {
- Destination~#1~has~no~related~structure.\\
- /Ref~for~structure~#2~not~updated
- }
-
-\cs_new_protected:Npn \g_@@_struct_ref_by_dest:
+\str_if_exist:cF { l__socket_tagsupport/recordtarget_plug_str }
{
- \prop_map_inline:Nn\g_@@_struct_ref_by_dest_prop
- {
- \prop_get:NnNTF \g_@@_struct_dest_num_prop {##2} \l_@@_tmpa_tl
- {
- \@@_struct_gput_data_ref:ee
- { ##1 }
- { \tag_struct_object_ref:e{ \l_@@_tmpa_tl }}
- }
- {
- \msg_warning:nnnn {tag}{struct-dest-unknown}{##2}{ ##1}
- }
- }
- }
-\hook_gput_code:nnn {tagpdf/finish/before}{tagpdf/struct/Ref}{\g_@@_struct_ref_by_dest:}
+ \AddToHook{cmd/refstepcounter/after}
+ {
+ \tl_if_blank:VF \@currentHref
+ {
+ \prop_gput:Nee \g_@@_struct_dest_num_prop {\@currentHref}{\tag_get:n{struct_num}}
+ }
+ }
+ \AddToHook{cmd/H@refstepcounter/after}
+ {
+ \tl_if_blank:VF \@currentHref
+ {
+ \prop_gput:Nee \g_@@_struct_dest_num_prop {\@currentHref}{\tag_get:n{struct_num}}
+ }
+ }
+ }
% \end{macrocode}
-% \end{macro}
%
% \section{Toc code}
% \begin{variable}{\g_@@_toc_level_int,\g_@@_toc_stack_seq}
@@ -196,14 +165,17 @@
\tag_struct_begin:n{tag=TOC,title=#1}
}
% \end{macrocode}
-% Now map it into the config point:
+% \end{macro}
+% Now define the tagging plug and assign it to the socket.
+% \begin{plugdecl}{default}
% \begin{macrocode}
-\cs_set_protected:Npn\@starttoc@cfgpoint@before#1
- {
- \@@_toc_starttoc_init:n{#1}
- }
+\NewSocketPlug{tagsupport/toc/starttoc/before}{default}
+ {
+ \@@_toc_starttoc_init:n{#1}
+ }
+\AssignSocketPlug{tagsupport/toc/starttoc/before}{default}
% \end{macrocode}
-% \end{macro}
+% \end{plugdecl}
% \begin{macro}{\@@_toc_starttoc_finalize:}
% \begin{macrocode}
\cs_new_protected:Npn \@@_toc_starttoc_finalize:
@@ -215,15 +187,18 @@
\seq_gclear:N \g_@@_toc_stack_seq
}
% \end{macrocode}
-% Now map it into the config point:
+% \end{macro}
+% Now define the tagging plug and assign it to the socket.
+% \begin{plugdecl}{default}
% \begin{macrocode}
-\cs_set_protected:Npn\@starttoc@cfgpoint@after#1
- {
- \@@_toc_starttoc_finalize:
- }
+\NewSocketPlug{tagsupport/toc/starttoc/after}{default}
+ {
+ \@@_toc_starttoc_finalize:
+ }
+\AssignSocketPlug{tagsupport/toc/starttoc/after}{default}
% \end{macrocode}
-% \end{macro}
-
+% \end{plugdecl}
+%
% \begin{macro}{\@@_toc_end:n}
% This commands ends all TOC on the stack with a level higher than the argument
% \begin{macrocode}
@@ -249,10 +224,11 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\@@_toc_contentsline_begin:nnn}
+% \begin{macro}{\@@_toc_contentsline_begin:nnnn}
% This is main command executed at the begin of a |\contentsline|.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_toc_contentsline_begin:nnn #1 #2 #3 %#1 level, #2 content, #3 destination
+\cs_new_protected:Npn \@@_toc_contentsline_begin:nnnn #1 #2 #3 #4
+ %#1 level, #2 content, #3 page number (unused) #4 destination
{
\tag_if_active:T
{
@@ -298,40 +274,44 @@
% \begin{macrocode}
\group_begin:
\text_declare_expand_equivalent:Nn \numberline \use_none:n
- \exp_args:Ne \tag_struct_begin:n{tag=TOCI,title={\text_purify:n {#2}}}
+ \exp_args:Ne
+ \tag_struct_begin:n{tag=TOCI,title={\text_purify:n {#2}}}
% \end{macrocode}
-% The TOCI structure should get a /Ref, so we put a request with its destination
-% name into the prop.
+% The TOCI structure should get a /Ref, we use a destination
+% to retrieve it.
% \begin{NOTE}{UF}
% This only works with hyperref currently. Without hyperref we
% need to store fake names.
% \end{NOTE}
% \begin{macrocode}
- \prop_gput:Nee \g_@@_struct_ref_by_dest_prop
- { \tag_get:n {struct_num} }{#3}
+ \tag_struct_gput:nnn { \tag_get:n {struct_num} }{ref_dest}{#4}
\seq_gpush:Ne \g_@@_toc_stack_seq {{TOCI}\use:c{toclevel@#1}}
\group_end:
}
}
}
% \end{macrocode}
-% Now map it into the config point:
+% \end{macro}
+% Now define the tagging plug and assign it to the socket.
+% \begin{plugdecl}{default}
% \begin{macrocode}
-\cs_set_protected:Npn\@contentsline@cfgpoint@before#1#2#3#4
+\NewSocketPlug{tagsupport/toc/contentsline/before}{default}
{
- \@@_toc_contentsline_begin:nnn {#1}{#2}{#4}
- }
+ \@@_toc_contentsline_begin:nnnn #1
+ }
+\AssignSocketPlug{tagsupport/toc/contentsline/before}{default}
% \end{macrocode}
-% \end{macro}
+% \end{plugdecl}
%
-% \begin{macro}{\@@_toc_contentsline_end:n}
+% \begin{macro}{\@@_toc_contentsline_end:nnnn}
% This is the closing code of a |\contentsline|.
% If the contentsline was actually printed, the code has to
% close the TOCI structure and to update the stack.
% \begin{macrocode}
\msg_new:nnn {tag}{toc-no-TOCI}{Missing~TOCI~structure~on~toc~stack}
-\cs_new_protected:Npn \@@_toc_contentsline_end:n #1 %#1 level name
+\cs_new_protected:Npn \@@_toc_contentsline_end:nnnn #1 #2 #3 #4
+% #1 level, #2 content (unused), #3 page number (unused) #4 destination (unused)
{
\int_compare:nNnF { \use:c{toclevel@#1} } > {\use:c{c@tocdepth}}
{
@@ -348,14 +328,17 @@
}
}
% \end{macrocode}
-% Now we map it to the config point
+% \end{macro}
+% Now define the tagging plug and assign it to the socket.
+% \begin{plugdecl}{default}
% \begin{macrocode}
-\cs_set_protected:Npn \@contentsline@cfgpoint@after #1#2#3#4
- {
- \@@_toc_contentsline_end:n {#1}
- }
+\NewSocketPlug{tagsupport/toc/contentsline/after}{default}
+ {
+ \@@_toc_contentsline_end:nnnn #1
+ }
+\AssignSocketPlug{tagsupport/toc/contentsline/after}{default}
% \end{macrocode}
-% \end{macro}
+% \end{plugdecl}
%
% \subsection{Tagging of the content}
% This need discussion.
@@ -380,12 +363,16 @@
\tag_struct_end:
\tag_mc_begin:n{tag=Reference}}
% \end{macrocode}
-%
+% \begin{plugdecl}{artifact}
% \begin{macrocode}
-\def\@dottedtocline@cfgpoint@leaders#1{%
- \tag_mc_begin:n{artifact}\tag_stop:n{leaders}\nobreak#1\nobreak\tag_start:n{leaders}\tag_mc_end:}
+\NewSocketPlug{tagsupport/toc/leaders/before}{artifact}
+ {\tag_mc_begin:n{artifact}\nobreak}
+\NewSocketPlug{tagsupport/toc/leaders/after}{artifact}
+ {\nobreak\tag_mc_end:}
+\AssignSocketPlug{tagsupport/toc/leaders/before}{artifact}
+\AssignSocketPlug{tagsupport/toc/leaders/after}{artifact}
% \end{macrocode}
-
+% \end{plugdecl}
%
% \begin{macrocode}
%</package>
diff --git a/macros/latex-dev/required/latex-lab/latex-lab-toc.pdf b/macros/latex-dev/required/latex-lab/latex-lab-toc.pdf
index ba23989257..3993734a6f 100644
--- a/macros/latex-dev/required/latex-lab/latex-lab-toc.pdf
+++ b/macros/latex-dev/required/latex-lab/latex-lab-toc.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/README.md b/macros/latex-dev/required/tools/README.md
index 69e0112887..abe5551e33 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 2024-11-01 pre-release 0
+Release 2025-06-01 pre-release 1
Overview
--------
diff --git a/macros/latex-dev/required/tools/afterpage.pdf b/macros/latex-dev/required/tools/afterpage.pdf
index a7679b78a3..e6f22df07f 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 e77ef0a3bf..f4c8ab28d8 100644
--- a/macros/latex-dev/required/tools/array.dtx
+++ b/macros/latex-dev/required/tools/array.dtx
@@ -39,7 +39,7 @@
% \begin{macrocode}
%<+package>\NeedsTeXFormat{LaTeX2e}[2024/06/01]
%<+package>\ProvidesPackage{array}
-%<+package> [2024/05/23 v2.6c Tabular extension package (FMi)]
+%<+package> [2024/10/17 v2.6g Tabular extension package (FMi)]
%
% \fi
%
@@ -259,7 +259,7 @@
% \begin{table}[!t]
% \begin{center}
% \setlength{\extrarowheight}{1pt}
-% \begin{tabular}{|>{\tt}c|m{9cm}|}
+% \begin{tabular}{|>{\ttfamily}c|m{9cm}|}
% \hline
% \multicolumn{2}{|c|}{Unchanged options}\\
% \hline
@@ -382,6 +382,20 @@
% \end{itemize}
%
%
+%
+% \subsection{A note on the allowed content of \texttt{>\{...\}} and
+% \texttt{<\{...\}}}
+%
+% These specifiers are meant to hold declarations, such as
+% \verb=>{\itshape}=. They cannot end in commands that take arguments
+% without providing these arguments as part of the \verb={...}=. It
+% would be a mistaken assumption that they pick up all or parts of the
+% alignment entry data if their argument is not provided. E.g.,
+% \verb=>{\textbf}= would not make the whole column bold nor would it
+% make the first character bold (technically it would try to
+% bolden \cs{ignorespaces}). Thus, it would not fail with an error,
+% but effectively the output would be wrong and not as expected.
+%
% \subsection{The behavior of the \texttt{\string\\} command}
%
% In the basic \texttt{tabular} implementation of \LaTeX{} the \cs{\bslash}
@@ -464,16 +478,16 @@
% "\newcolumntype{L}{>{$}l<{$}}" \\
% "\newcolumntype{R}{>{$}r<{$}}"
% \end{quote}
-% Then we can use \texttt{C} to get centred LR-mode in an
-% \texttt{array}, or centred math-mode in a \texttt{tabular}.
+% Then we can use \texttt{C} to get centered LR-mode in an
+% \texttt{array}, or centered math-mode in a \texttt{tabular}.
%
-% The example given above for `centred decimal points' could be
+% The example given above for `center decimal points' could be
% assigned to a \texttt{d} specifier with the following command.
% \begin{quote}
% "\newcolumntype{d}{>{\centerdots}c<{\endcenterdots}}"
% \end{quote}
%
-% The above solution always centres the dot in the
+% The above solution always centers the dot in the
% column. This does not look too good if the column consists of large
% numbers, but to only a few decimal places. An alternative definition
% of a \texttt{d} column is
@@ -715,7 +729,7 @@
%
% A similar problem happened when "\extrarowheight" was used. For that
% reason m-cells now manually position the cell content which
-% allows to ignore this extra space request during the vertical aligment.
+% allows to ignore this extra space request during the vertical alignment.
%
%
% \subsection{Bugs and Features}
@@ -734,7 +748,7 @@
% user the opportunity of overriding the settings of a
% "\newcolumntype" defined using these declarations. For example,
% suppose in an \texttt{array} environment we use a \texttt{C}
-% column defined as above. The \texttt{C} specifies a centred text
+% column defined as above. The \texttt{C} specifies a centered text
% column, however ">{\bfseries}C", which re-writes to
% ">{\bfseries}>{$}c<{$}" would not specify a bold column as might
% be expected, as the preamble would essentially expand to
@@ -896,14 +910,14 @@ Bug reports can be opened (category \texttt{#1}) at\\%
%
% \section{A note on the updates done December 2023}
%
-% We introduced support for tagged PDf and at the same time we added
+% We introduced support for tagged PDF and at the same time we added
% code to determine row and column numbers for each cell in
% preparation for supporting formatting or type specifications for individual
% cells (or group of cells) from the outside, e.g., \enquote{rows 1,
% 2, and 10 are header rows} (syntax to be decided).
%
% This new code is already written with L3 programming layer conventions
-% while most of the legay code is still as it was before. This make the code
+% while most of the legacy code is still as it was before. This make the code
% currently somewhat clattered, unfortunately. Eventually this will all move to L3
% programming layer but this will take time.
%
@@ -1345,7 +1359,7 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% of \textsf{token} register $15$ instead of $1$ later on.
%
% The example above referred to an older version of =\save@decl= which
-% inserted a =\relex= inside the token register. This is now moved to
+% inserted a =\relax= inside the token register. This is now moved to
% the places where the actual token registers are inserted (look for
% =\the@toks=) because the old version would still make =@=
% expressions to moving arguments since after expanding the second
@@ -1373,6 +1387,7 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% \begin{macro}{\insert@column}
% \begin{macro}{\@sharp}
% \begin{macro}{\textonly@unskip}
+% \begin{macro}{\@protected@firstofone}
% We now define the macro =\insert@column= which will do
% this work for us.
% \begin{macrocode}
@@ -1385,10 +1400,116 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% \begin{macrocode}
\UseTaggingSocket{tbl/cell/begin}%
% \end{macrocode}
-% Here, we assume that the \textsf{count} register
+% Next we have to insert the toks register holding the content of
+% \verb=>{...}=. Here, we assume that the \textsf{count} register
% =\@tempcnta= has saved the value $=\count@= - 1$.
+%
+% To keep \TeX{} happy if there is a look ahead in the tabular
+% preamble, i.e., starting in \verb=>{...}=, which uses the
+% Appendix~D trick (for example, anything with a trailing optional
+% argument defined by \pkg{ltcmd}), we wrap everything here in a
+% protected version of \cs{@firstofone}. \TeX{} otherwise can get
+% confused about the value of the master counter, and we get some
+% strange errors. We suspected that there was an underlying issue
+% is the \TeX{} engine, but it turned out to be rather hard to get
+% to the bottom of it, because the master counter is not accessible
+% through \TeX{}'s tracing tools. Thus, all we could do was
+% producing various example documents, observing results, as well
+% as staring at a printout of the \TeX{} program. As an example,
+% without this approach, something like
+% \begin{verbatim}
+% \NewDocumentCommand\foo{o}{x}
+% \begin{tabular}{>{\foo}l}
+% Foo
+% \end{tabular}
+% \end{verbatim}
+% failed. That can be fixed by adding a \cs{relax} after the
+% \cs{@tempcnta}, but that then leads to issues if you are
+% collecting whole cells (tagging code or \pkg{collcell}), where
+% you can no longer alter the meaning of \cs{cr} as the master
+% counter goes wrong due to an obscure bug (or perhaps, say, an
+% undocumented feature of \TeX{}). Eventually, we were able to pin
+% down the root cause and really understand why
+% \cs{@protected@firstofone} solves the problem, even though it
+% looks like a nonsense addition to the code that does nothing
+% useful.\footnote{So it is a \TeX{} engine bug that was in there
+% from day one, or if you like, it is a hidden feature that is not
+% explained; neither in the \TeX{}book nor in the program code. We
+% don't really expect this to change in \TeX{} after such a long
+% time, other than perhaps documenting it as a feature, so this is
+% a proper solution to the problem and not just a workaround.}
+%
+% The problem is that \TeX{} tries to conserve stack space, and
+% when the last token of an existing token list is a macro, then
+% this token list is \emph{first} removed from memory (reducing the
+% stack) \emph{before} the macro replacement text (as a new
+% token list) is given to the parser adding a new stack level. This
+% is done using the routine \texttt{end\_token\_list} in the \TeX{}
+% program and ending the u-part of an \cs{halign} column with this
+% routine immediately sets the \emph{master counter} used by alignments to
+% zero (see chapter~22 and Appendix~D of the \TeX{}book). This
+% means that technically the expansion of the last token in the u-part (if it
+% is a macro) is not executed in the context of the u-part, but in
+% the context of the alignment entry in the document. That normally
+% doesn't make any difference whatsoever --- unless you play
+% around (as we sometimes have to) with tricks like those from
+% Appendix~D.
+%
+% To illustrate the issue we show a bit of strange low-level plain
+% \TeX{} code.\footnote{If all of this looks mighty strange to you,
+% don't worry. You will be unlikely to need to know about it. It is
+% just there so that programmers at some point in the future do not
+% have to wonder too much why there is this odd
+% \cs{@protected@firstofone} that apparently does nothing
+% useful. It took us several nights of head scratching to come up
+% with these minimal examples and then some more time to understand
+% what the heck is going on inside \TeX{}---thanks to Bruno for the
+% right ideas on the latter.} Below are two very special grouping
+% commands that are like \cs{bgroup} and \cs{egroup} but also
+% affect the alignment master counter when expanded (see
+% \TeX{}book p.385). If one of them is used as the
+% last macro in the u-part of a column, then you get strange errors
+% that you shouldn't get.
+% \begin{verbatim}
+% \def\bbgroup{{\ifnum0=`}\fi}
+% \def\eegroup{\ifnum0=`{\fi}}
+%
+% % Fails with an error message, but there should be none:
+% \halign{%
+% \message{u-part^^J}%
+% \bbgroup % <-- in the u-part
+% \eegroup % <-- in the u-part
+% #%
+% \message{v-part^^J}%
+% \hfill\cr
+% \message{body^^J}x
+% \cr
+% }
+%
+% % Fails but should work, the v-part is never reached:
+% \halign{%
+% \message{u-part^^J}%
+% \bbgroup % <-- in the u-part
+% #%
+% \message{v-part^^JJ}%
+% \eegroup % <-- in the v-part
+% \hfill\cr
+% \message{body^^J}x
+% \cr
+% }
+% \end{verbatim}
+%
+% So the trick we use now is making \cs{@protected@firstofone} the
+% last macro in the u-part, i.e., before the \cs{@sharp}. That way
+% its argument is always fully expanded as part of the alignment
+% entry and not as part of the u-part and this way we know exactly
+% what the master counter value is at this point, regardless of the content of
+% \verb=>{...}=.
+%
+% \changes{v2.6f}{2024/09/13}{Stop parsing for optional argument (gh/1468)}
+% \changes{v2.6g}{2024/10/12}{Further work to support optional args in preamble (gh/1468)}
% \begin{macrocode}
- \the@toks \the \@tempcnta
+ \@protected@firstofone { \the@toks \the \@tempcnta \ignorespaces }
% \end{macrocode}
% Next follows the =#= sign which specifies the place
% where the text of the column shall be inserted. To avoid
@@ -1396,14 +1517,16 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% =\@addtopreamble= we hide this sign in the command
% =\@sharp= which is temporarily occupied with
% =\relax= during the build-up of the preamble.
-% To remove unwanted spaces before and after the column text, we set
-% an =\ignorespaces= in front and a =\unskip= afterwards.
+% To remove unwanted spaces before and after the column in text mode,
+% we set an =\ignorespaces= in front (see above) and a =\unskip=
+% afterwards; in math mode, the latter is suppressed while the
+% \cs{ignorespaces} makes no difference.
% \changes{v2.0e}{1991/02/07}{Added \{\} around \cs{@sharp} for new ftsel}
-% \changes{v2.0h}{1992/06/22}{Removed \{\} again in favour of
+% \changes{v2.0h}{1992/06/22}{Removed \{\} again in favor of
% \cs{d@llarbegin}}
% \changes{v2.6b}{2024/04/08}{Do not \cs{unskip} if in math mode (gh/1323)}
% \begin{macrocode}
- \ignorespaces \@sharp \textonly@unskip
+ \@sharp \textonly@unskip
% \end{macrocode}
% Then the second \textsf{token} register follows whose number should
% be saved in =\count@=.
@@ -1428,10 +1551,15 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% \begin{macrocode}
\protected\def\textonly@unskip{\ifhmode\unskip\fi}
% \end{macrocode}
+% \changes{v2.6g}{2024/10/12}{Further work to support optional args in preamble (gh/1468)}
+% We need an engine-protected function that is just \cs{@firstofone}:
+% \begin{macrocode}
+\protected\long\def\@protected@firstofone#1{#1}
+% \end{macrocode}
+% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
-%
%
% \begin{macro}{\insert@pcolumn}
% Handling pcolumn-cells needs slightly different handling when
@@ -1442,7 +1570,10 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% \begin{macrocode}
\def\insert@pcolumn{%
\UseTaggingSocket{tbl/pcell/begin}%
- \the@toks \the \@tempcnta
+% \end{macrocode}
+% \changes{v2.6f}{2024/09/13}{Stop parsing for optional argument (gh/1468)}
+% \begin{macrocode}
+ \the@toks \the \@tempcnta \relax
\ignorespaces \@sharp \unskip
\the@toks \the \count@ \relax
\UseTaggingSocket{tbl/pcell/end}%
@@ -1882,7 +2013,7 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% For that reason the new implementation does the centering
% manually: First we check the height of the cell and if that is
% less or equal to =\ht\strutbox= we assume that this is a
-% single line cell. In that case we don't do any vertical maneuvre
+% single line cell. In that case we don't do any vertical maneuver
% and simply output the box, i.e., make it behave like a single
% line p-cell.
%
@@ -1900,7 +2031,7 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% is how much do we need to move down? If there is any
% =\arraystretch= in place then the first line will have some
% unusual height and we don't want to consider that when finding
-% the middle point. So we substract from the cell height the height
+% the middle point. So we subtract from the cell height the height
% of that strut. But of course we want to include the normal height
% of the first line (which would be something like =\ht\strutbox=)
% so we need to add that. On the other hand, when centering around
@@ -2325,7 +2456,7 @@ Bug reports can be opened (category \texttt{#1}) at\\%
\lineskip \z@
\baselineskip \z@
% \end{macrocode}
-% Don't use \cs{m@th} here as that signals to the math taggingg
+% Don't use \cs{m@th} here as that signals to the math tagging
% code that this is fake math that should not be tagged.
% \changes{v2.6a}{2023/12/11}{Support for tagged PDF}
% \begin{macrocode}
@@ -2451,7 +2582,7 @@ Bug reports can be opened (category \texttt{#1}) at\\%
%
% We then start a special brace which I have directly
% copied from the original definition. It is
-% necessary, because the =\futurlet= in =\@ifnextchar=
+% necessary, because the =\futurelet= in =\@ifnextchar=
% might
% expand a following =&= \textsf{token} in a construction like
% =\\ &=. This would otherwise end the alignment template at a
@@ -2464,7 +2595,7 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% that a =&= will not be considered belonging to the current
% =\halign= while we are looking for a =*= or =[=.
% For further information see
-% \cite[Appendix D]{bk:knuth}.
+% \cite[Appendix~D]{bk:knuth}.
% \begin{macrocode}
\iffalse{\fi\ifnum 0=`}\fi
% \end{macrocode}
@@ -2649,14 +2780,14 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% \section{The Environment Definitions}
%
% After these preparations we are able to define the environments. They
-% only differ in the initialisations of =\d@llar...=, =\col@sep=
+% only differ in the initializations of =\d@llar...=, =\col@sep=
% and =\@halignto=.
%
% \begin{macro}{\@halignto}
% \begin{macro}{\d@llarbegin}
% \begin{macro}{\d@llarend}
% =\d@llar= has to be
-% locally asigned since otherwise nested \textsf{tabular} and \textsf{array}
+% locally assigned since otherwise nested \textsf{tabular} and \textsf{array}
% environments (via =\multicolumn=) are impossible.
% For 25 years or so =\@halignto= was set globally (to save space on the
% save stack, but that was a mistake: if there is a tabular in the
@@ -2664,7 +2795,7 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% able overwrite the =\@halignto=
% setting of a tabular in the main text resulting in a very weird error.
% \changes{v2.4d}{2016/10/06}{\cs{@halignto} set locally (pr/4488)}
-% \changes{v2.0g}{1992/06/18}{`d@llarbegin defined on toplevel.}
+% \changes{v2.0g}{1992/06/18}{`d@llarbegin defined on top-level.}
% When the new font selection scheme is in force we have to
% we surround all =\halign= entries
% with braces. See remarks in TUGboat 10\#2. Actually we are going
@@ -2714,7 +2845,7 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% \begin{macro}{\tabular}
% \begin{macro}{\tabular*}
% The environments \textsf{tabular} and \textsf{tabular$*$} differ
-% only in the initialisation of the command =\@halignto=. Therefore
+% only in the initialization of the command =\@halignto=. Therefore
% we define
% \changes{v2.4d}{2016/10/06}{\cs{@halignto} set locally (pr/4488)}
% \begin{macrocode}
@@ -2852,11 +2983,13 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% \end{macrocode}
%
% \begin{macro}{\@preamerr}
+% \changes{v2.6d}{2024/06/14}{Keep message sources out of L3 code (gh/1378)}
% We also have to redefine the error routine =\@preamerr= since
% new kind of errors are possible.
% The code for this macro is not perfect yet;
% it still needs too much memory.
% \begin{macrocode}
+\ExplSyntaxOff
\def\@preamerr#1{\def\@tempd{{..} at wrong position: }%
\PackageError{array}{%
\ifcase #1 Illegal pream-token (\@nextchar): `c' used\or %0
@@ -2905,7 +3038,6 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% to define letters, to be used in the same way as the primitive
% column specifiers, `c' `p' etc.
% \begin{macrocode}
-\ExplSyntaxOff % this is really oldstyle using \@tfor :=
\def\newcolumntype#1{%
% \end{macrocode}
% "\NC@char" was added in V2.01 so that active characters, like "@" in
@@ -2995,7 +3127,7 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% rewrites (in the token register "\NC@list") will look like
% "\NC@do *" "\NC@do C" "\NC@do L".
% So we need to define "\NC@do" as a one argument macro which
-% initialises the rewriting of the specified column. Let us assume that
+% initializes the rewriting of the specified column. Let us assume that
% `C' is the argument.
% \begin{macrocode}
\def\NC@do#1{%
@@ -3063,7 +3195,7 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% \end{macro}
%
% \subsection{The $*$--form}
-% We view the $*$-form as a slight generalisation of the system
+% We view the $*$-form as a slight generalization of the system
% described in the previous subsection. The idea is to define a $*$
% column by a command of the form:
% \begin{verbatim}
@@ -3439,7 +3571,7 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% \subsection{Implementing column types \texttt{w} and \texttt{W}}
%
% In TugBoat 38/2 an extension was presented that implemented two
-% aditional column types \texttt{w} and \texttt{W}. These have now
+% additional column types \texttt{w} and \texttt{W}. These have now
% been added to the package itself.
%
%
@@ -3501,7 +3633,7 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% the cell content is too wide.
% \changes{v2.4f}{2017/11/07}{Column type added}
% \changes{v2.5a}{2020/04/06}{Use \cs{d@llarbegin} and \cs{d@llarend} so
-% that cell is typeset in mathmode inside \texttt{array} (gh/297)}
+% that cell is typeset in math mode inside \texttt{array} (gh/297)}
% \begin{macrocode}
\newcolumntype{W}[2]
{>{\begin{lrbox}\ar@cellbox\d@llarbegin}%
@@ -3516,7 +3648,46 @@ Bug reports can be opened (category \texttt{#1}) at\\%
% \end{macro}
%
%
+% \subsection{Handling \cs{cline}}
+%
+% In the past \pkg{array} did not have to concern itself with
+% \cs{cline} but simply used the definition already provided in the
+% kernel. However, for tagged PDF output this definition is
+% insufficient, because it causes incorrect row counting and the rules
+% it generates would need to be marked as artifacts.
+% We therefore update it here.
+%
%
+% \begin{macro}{\@cline}
+% Tagging support for \cs{cline}
+% \changes{v2.6e}{2024/07/13}{Support for tagging \cs{cline} (tagging/134)}
+% \begin{macrocode}
+\ExplSyntaxOn
+\def\@cline#1-#2\@nil{
+ \omit
+ \@multicnt#1
+ \advance\@multispan\m@ne
+ \ifnum\@multicnt=\@ne\@firstofone{&\omit}\fi
+ \@multicnt#2
+ \advance\@multicnt-#1
+ \advance\@multispan\@ne
+% \end{macrocode}
+% The rule needs artifact tagging in tagged PDF.
+% \begin{macrocode}
+ \UseTaggingSocket{tbl/leaders/begin}
+ \leaders\hrule\@height\arrayrulewidth\hfill
+ \UseTaggingSocket{tbl/leaders/end}
+% \end{macrocode}
+% To the row counting the above appears like an extra row, so we
+% have to correct the count.
+% \begin{macrocode}
+ \tbl_gdecr_row_count:
+ \cr
+ \noalign{\vskip-\arrayrulewidth}
+}
+\ExplSyntaxOff
+% \end{macrocode}
+% \end{macro}
%
%
% \begin{macrocode}
diff --git a/macros/latex-dev/required/tools/array.pdf b/macros/latex-dev/required/tools/array.pdf
index 715f3284ec..19aa09df8d 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.pdf b/macros/latex-dev/required/tools/bm.pdf
index a92141480e..17631ae982 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.dtx b/macros/latex-dev/required/tools/calc.dtx
index 154c6ba26a..414d04df8c 100644
--- a/macros/latex-dev/required/tools/calc.dtx
+++ b/macros/latex-dev/required/tools/calc.dtx
@@ -40,7 +40,7 @@
%<driver> \ProvidesFile{calc.drv}
% \fi
% \ProvidesFile{calc.dtx}
- [2023/07/08 v4.3 Infix arithmetic (KKT,FJ)]
+ [2024/11/03 v4.3a Infix arithmetic (KKT,FJ)]
%
% \iffalse
%<*driver>
@@ -1323,6 +1323,8 @@
% \begin{macro}{\@settodim}
% \changes{v4.2}{2005/08/06}
% {Changed kernel macro}
+% \changes{v4.3a}{2024/11/03}
+% {Suspend Tagging}
% \begin{macro}{\settototalheight}
% \changes{v4.2}{2005/08/06}
% {Added macro}
@@ -1333,7 +1335,8 @@
% A search on the internet confirmed that some people do that kind of thing.
% \begin{macrocode}
\def\@settodim#1#2#3{%
- \setbox\@tempboxa\hbox{{#3}}%
+ \setbox\@tempboxa\hbox
+ {{\SuspendTagging{\@settodim}#3\ResumeTagging{\@settodim}}}%
\dimen@ii=\z@
\@tf@r\reserved@a #1\do{%
\advance\dimen@ii\reserved@a\@tempboxa}%
@@ -1354,4 +1357,3 @@
%
% \Finale
\endinput
-
diff --git a/macros/latex-dev/required/tools/calc.pdf b/macros/latex-dev/required/tools/calc.pdf
index c5424a2a9f..51d3fa6716 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 afd942a4e7..d5a605a663 100644
--- a/macros/latex-dev/required/tools/changes.txt
+++ b/macros/latex-dev/required/tools/changes.txt
@@ -5,12 +5,94 @@ completeness or accuracy and it contains some references to files that
are not part of the distribution.
=======================================================================
+2024-11-12 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+ * multicol.dtx (subsection{Tagging support}):
+ Added another socket to support tagging.
+
+2024-11-10 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+ * multicol.dtx (subsection{Supporting the new mark mechanism}):
+ Drop the legacy support for marks and use the new mark
+ mechanism throughout.
+ \usepackage{multicol}[=v1.9] reverts to previous approach.
+
+ Change the definition of \leftmark and \rightmark to use the new
+ mechanism and not any longer the legacy on.
+
+2024-11-03 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * calc.dtx: suspend tagging in \@settodim (tagging/628)
+
================================================================================
All changes above are only part of the development branch for the next release.
================================================================================
#########################
-# 2023-11-01 Release
+# 2024-11-01 Release
+#########################
+
+2024-10-30 David Carlisle <David.Carlisle@latex-project.org>
+
+ * amsmath.dtx: Guard the \protect tests from primitive if tokens
+ in the definition (gh/1448)
+
+2024-10-27 David Carlisle <David.Carlisle@latex-project.org>
+
+ * longtable.dtx Guard against increasing \pagegoal past \maxdimen (gh/1495)
+
+
+2024-10-12 Joseph Wright <Joseph.Wright@latex-project.org>
+
+ * array.dtx (section{The insertion of declarations ...}):
+ Further work on handling optional arguments in the argument
+ of >{...} to work around a master counter oddity (gh/1468)
+
+2024-09-18 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+
+ * array.dtx (section{The insertion of declarations ...}):
+ Stop parsing too far for an optional argument if >{...} ends in a command
+ with a trailing optional arg (gh/1468)
+
+2024-09-17 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+ * multicol.dtx: add tagging support (tagging/705)
+
+2024-09-12 David Carlisle <David.Carlisle@latex-project.org>
+
+ * build.lua, tools.ins:
+ Modify fileerr extraction to write rename-to-empty-base.tex rather than .tex
+ to comply with expected security change in texlive 2025
+ build.lua modified to rename rename-to-empty-base.tex to .tex after unpacking.
+
+2024-08-13 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+
+ * longtable.dtx:
+ store row number of head also if it ends with a \cr
+ (tagging-project-gh/554).
+
+2024-07-13 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+
+ * array.dtx (subsection{Handling \cs{cline}}):
+ Support for tagging \cline (tagging/134)
+
+2024-07-04 Ulrike Fischer <Ulrike.Fischer@latex-project.org>
+
+ * longtable.dtx:
+ Added \LTcaptype (from package ltcaption) to support other types
+ beside table and to support unnumbered longtables (gh/1377).
+
+
+2024-06-28 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
+
+ * multicol.dtx:
+ Update documentation to reflect that \sloppy isn't using
+ \tolerance=10000 any longer (it did in the early days of LaTeX)
+ (gh/1385)
+
+2024-06-14 David Carlisle <David.Carlisle@latex-project.org>
+
+ * array.dtx move \ExplSyntaxOff earlier so error message spaces preserved gh/1378
+
+
+#########################
+# 2024-06-01 Release
#########################
2024-05-23 Frank Mittelbach <Frank.Mittelbach@latex-project.org>
diff --git a/macros/latex-dev/required/tools/dcolumn.pdf b/macros/latex-dev/required/tools/dcolumn.pdf
index 537bc4d21c..981421b606 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 47b5a5fa9a..5800c8221a 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 fc9d77d6af..448b39b2ea 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 574edfdb38..e348693a3e 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 8d4fe68316..fa2b598728 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 9f2da32d26..a9865794c1 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 b2b7bc6adb..fd84a56012 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 c95cef137f..8250e6055e 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/l3sys-query.pdf b/macros/latex-dev/required/tools/l3sys-query.pdf
index e333418672..5d6c114e6a 100644
--- a/macros/latex-dev/required/tools/l3sys-query.pdf
+++ b/macros/latex-dev/required/tools/l3sys-query.pdf
Binary files differ
diff --git a/macros/latex-dev/required/tools/layout.pdf b/macros/latex-dev/required/tools/layout.pdf
index 6cbbc763ca..8573bfaf74 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 cc3a939e7a..061d7b5610 100644
--- a/macros/latex-dev/required/tools/longtable.dtx
+++ b/macros/latex-dev/required/tools/longtable.dtx
@@ -28,7 +28,7 @@
%</dtx>
%<package>\NeedsTeXFormat{LaTeX2e}[1995/06/01]
%<package>
-% Try the 2020 version for any rollback before that date:
+% Try the 2020 version for any rollback before that date:
%<package>\DeclareRelease{}{1994-06-01}{longtable-2020-01-07.sty}
%<package>
%<package>\DeclareRelease{v4.13}{2020-01-02}{longtable-2020-01-07.sty}
@@ -38,7 +38,7 @@
%<driver> \ProvidesFile{longtable.drv}
% \fi
% \ProvidesFile{longtable.dtx}
- [2024-04-26 v4.20 Multi-page Table package (DPC)]
+ [2024-10-27 v4.22 Multi-page Table package (DPC)]
%
% \iffalse
%<*driver>
@@ -179,7 +179,7 @@
% \env{longtable}, which has most of the features of the \env{tabular}
% environment, but produces tables which may be broken by \TeX's
% standard page-breaking algorithm. It also shares some features with
-% the \env{table} environment. In particular it uses the same counter,
+% the \env{table} environment. In particular it uses by default the same counter,
% \texttt{table}, and has a similar "\caption" command. Also, the
% standard "\listoftables" command lists tables produced by either the
% \env{table} or \env{longtable} environments.
@@ -335,6 +335,29 @@
% \caption{A floating table}
% \end{table}
%
+% \section{Counter and Caption Types}
+%
+% As mentioned in the introduction \env{longtable} uses and updates by default
+% the \texttt{table} counter, the "\caption" command creates a table caption
+% which is added to the list of tables.
+% Packages like \pkg{ltcaption} added more flexibility here by adding the
+% command "\LTcaptype" which allowed to change the type, e.g. to a listing.
+% Starting with version 4.21 \pkg{longtable} supports this command directly.
+% \DescribeMacro{\LTcaptype}%
+% By redefining this command it is possible to change the counter and caption type.
+% After "\renewcommand\LTcaptype{"\meta{counter}"}" \env{longtable} will update
+% the counter \meta{counter}, use "\fnum@"\meta{counter} in the caption (which
+% typically will make use of "\"\meta{counter}"name" and "\the"\meta{counter}), and
+% write content line entries into the file with the extension stored in the
+% command "\ext@"\meta{counter}. When \pkg{hyperref} is loaded the name of
+% the anchor will use \meta{counter} too. Packages or documents that change
+% "\LTcaptype" to some nonstandard value must ensure that the counter
+% \meta{counter} and the commands "\fnum@"\meta{counter}
+% and "\ext@"\meta{counter} exist and do not error.
+% If "\LTcaptype" is empty no counter is advanced and "\"\meta{counter}"name" in
+% the caption is suppressed.
+%
+%
% \section{Captions and Headings}
%
% At the start of the table one may specify lines which are to appear at
@@ -907,6 +930,15 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\LTcaptype}
+% The name used as counter, in caption, "\addcontentsline" and in targets.
+% "\providecommand" is used for compability with \pkg{ltcaption}
+% \changes{v4.21}{2024/07/04}
+% {Added \cs{LTcaptype} to support other types beside table.}
+% \begin{macrocode}
+\providecommand\LTcaptype{table}
+% \end{macrocode}
+% \end{macro}
% \subsection{Internal Parameters}
%
% \begin{macro}{\LT@head}
@@ -957,8 +989,11 @@
% are preserved correctly when "\includeonly" is used. In the rest of
% the file "\LT@tables" has been replaced by "\c@LT@tables" without
% further comment.
+% \changes{v4.21}{2024/07/04}
+% {Provide a \cs{theH}-representation for targets.}
% \begin{macrocode}
\newcounter{LT@tables}
+\providecommand\theHLT@tables{\theLT@tables}
% \end{macrocode}
% \end{macro}
%
@@ -1050,12 +1085,12 @@
\LT@err{longtable not in 1-column mode}\@ehc
\fi
% \end{macrocode}
-%
+%
% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
% \begin{macrocode}
\UseTaggingSocket{tbl/vmode/begin}%
% \end{macrocode}
-%
+%
% \begin{macrocode}
\begingroup
% \end{macrocode}
@@ -1080,6 +1115,9 @@
% Since Version 3.02, \package{longtable} has used the internal counter
% "\c@LT@tables". The \LaTeX\ counter "table" is still incremented
% so that "\caption" works correctly.
+% \changes{v4.21}{2024/07/04}
+% {Use \cs{LTcaptype} instead of \texttt{table} in various places
+% to support other types beside table.}
% \begin{macrocode}
\def\LT@array[#1]#2{%
% \end{macrocode}
@@ -1097,25 +1135,31 @@
% TODO: When a line is killed the structure subtree is there already
% too and must be removed. If hard to do, then maybe at first warn if the
% construction is used.
-%
+%
% \cs{LT@array} is executed in a group, so we can disable para-tagging here.
% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
% \begin{macrocode}
\UseTaggingSocket{tbl/init}
- \@kernel@refstepcounter{table}\stepcounter{LT@tables}
+ \tl_if_empty:eTF { \LTcaptype }
+ {
+ \tl_gset:Ne \@currentHref {LT@tables.\theHLT@tables}
+ }
+ {
+ \@kernel@refstepcounter{\LTcaptype}\stepcounter{LT@tables}
% \end{macrocode}
-% The target is created rather late and a \cs{label} can come earlier,
+% The target is created rather late and a \cs{label} can come earlier,
% so we have to define \cs{@currentHref} explicitly. We can't currently
% assume that \cs{theHtable} is defined always.
% \begin{macrocode}
- \tl_gset:Ne \@currentHref {table.\cs_if_exist_use:N\theHtable}
+ \tl_gset:Ne \@currentHref {\LTcaptype.\cs_if_exist_use:c {theH\LTcaptype}}
+ }
% \end{macrocode}
-%
+%
% \changes{v4.19}{2023/12/16}{Managing cell indexes}
% \begin{macrocode}
\tbl_gzero_row_count:
% \end{macrocode}
-%
+%
% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
% \begin{macrocode}
\UseTaggingSocket{tbl/longtable/init}
@@ -1225,7 +1269,7 @@
\begingroup
\@mkpream{#2}%
% \end{macrocode}
-%
+%
% \changes{v4.19}{2023/12/16}{Managing cell indexes}
% \begin{macrocode}
\tbl_count_table_cols:
@@ -1271,12 +1315,12 @@
\tabskip\z@ \@arstrut
% \end{macrocode}
% Insert the tagging socket to start the row and initialize the cell
-% data for the row.
+% data for the row.
% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
% \begin{macrocode}
\UseTaggingSocket{tbl/row/begin}%
% \end{macrocode}
-%
+%
% \changes{v4.19}{2023/12/16}{Managing cell indexes}
% \begin{macrocode}
\tbl_init_cell_data_for_row:
@@ -1314,7 +1358,7 @@
column:~ \the\g_@@_col_int
}
% \end{macrocode}
-%
+%
% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
% \begin{macrocode}
\tbl_if_row_was_started:T
@@ -1399,7 +1443,7 @@
% We also have to make sure that this breakpoint doesn't affect how the next
% page is broken, so we make the penalty 9999 (10000 is infinite and thus not
% a legal breakpoint) and cancel out the "\kern" with a new "\kern".
-%
+%
% I don't think this is the \emph{right} solution to the problem (that would be
% that the standard output routine has a feature for syncronizing with
% typesetting, as part of the preparations for switching output routine), but
@@ -1476,9 +1520,17 @@
\maxdepth\z@
\fi
% \end{macrocode}
-%
+% \changes{v4.21}{2024/07/04}
+% {Use \cs{LTcaptype} to support other types beside table and handle
+% the case if it is empty.}
% \begin{macrocode}
- \MakeLinkTarget{table}
+ \tl_if_empty:eTF{\LTcaptype}
+ {
+ \MakeLinkTarget{LT@tables}
+ }
+ {
+ \MakeLinkTarget{\LTcaptype}
+ }
% \end{macrocode}
% Put the table head on the page, and then switch to the new output
% routine.
@@ -1487,12 +1539,12 @@
% \begin{macrocode}
\ifvoid\LT@firsthead\copy\LT@head\else\box\LT@firsthead\fi\nobreak
% \end{macrocode}
-%
+%
% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
% \begin{macrocode}
\UseTaggingSocket{tbl/longtable/head}
% \end{macrocode}
-%
+%
% \begin{macrocode}
\output{\LT@output}}
\ExplSyntaxOff
@@ -1524,18 +1576,18 @@
% \begin{macrocode}
\tbl_crcr:n {endlongtable}
% \end{macrocode}
-%
+%
% \changes{v4.01}{1996/04/11}
% {(DPC) use \cs{noalign} to sneak in \cs{LT@entry@chop}}
% \begin{macrocode}
\noalign{%
% \end{macrocode}
-%
+%
% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
% \begin{macrocode}
\UseTaggingSocket{tbl/longtable/finalize}
% \end{macrocode}
-%
+%
% \begin{macrocode}
\let\LT@entry\LT@entry@chop
\xdef\LT@save@row{\LT@save@row}}%
@@ -1579,19 +1631,28 @@
\ifx\LT@save@row\LT@@@@save@row
\else
\LT@warn{Column~ widths~ have~ changed\MessageBreak
- in~ table~ \thetable}%
+ in~
+ \tl_if_empty:eTF{\LTcaptype}
+ {longtable~ \theLT@tables}
+ {\LTcaptype\c_space_tl\use:c{the\LTcaptype}}
+ }
\LT@final@warn
\fi
% \end{macrocode}
-% Force one more go with the \env{longtable} output routine.
+% Force one more go with the \env{longtable} output routine.
+% Guard the special start of page value of "\pagegoal".
% \changes{v4.14}{2020/02/07}
% {Rearrange vertical space tests for tools/3512 (floats on same page)}
+% \changes{v4.22}{2024/10/27}
+% {Keep \cs{pagegoal} below \cs{maxdimen} gh1495}
% \begin{macrocode}
\endgraf\penalty -\LT@end@pen
\ifvoid\LT@foot\else
\global\advance\vsize\ht\LT@foot
\global\advance\@colroom\ht\LT@foot
- \dimen@\pagegoal\advance\dimen@\ht\LT@foot\pagegoal\dimen@
+ \ifdim\pagegoal<\maxdimen
+ \dimen@\pagegoal\advance\dimen@\ht\LT@foot\pagegoal\dimen@
+ \fi
\fi
% \end{macrocode}
% Now close the group to return to the standard routine.
@@ -1613,7 +1674,7 @@
% \begin{macrocode}
\ifvoid\footins\else\insert\footins{}\fi
% \end{macrocode}
-%
+%
% \changes{v4.19}{2023/12/16}{Support for tagged PDF}
% \begin{macrocode}
\UseTaggingSocket{tbl/vmode/end}%
@@ -2161,7 +2222,6 @@
\tbl_gdecr_row_count:
\penalty\@M}
\@gtempa}
-\ExplSyntaxOff
%<@@=>
% \end{macrocode}
% \end{macro}
@@ -2187,14 +2247,22 @@
% {Add new control argument}
% \changes{v4.16}{2021/05/07}
% {use \cs{ext@table} gh/561}
-% \begin{macrocode}
-\def\LT@c@ption#1[#2]#3{%
- \LT@makecaption#1\fnum@table{#3}%
- \def\@tempa{#2}%
- \ifx\@tempa\@empty\else
- {\let\\\space
- \addcontentsline{\ext@table}{table}{\protect\numberline{\thetable}{#2}}}%
- \fi}
+% \changes{v4.21}{2024/07/04}
+% {Use \cs{LTcaptype} to support other types beside table.}
+% \begin{macrocode}
+\def\LT@c@ption#1[#2]#3{
+ \tl_if_empty:eTF{\LTcaptype}
+ {\LT@makecaption\@gobble{}{#3}}
+ {\LT@makecaption#1{\csname fnum@\LTcaptype\endcsname}{#3}
+ \def\@tempa{#2}
+ \ifx\@tempa\@empty\else
+ {\let\\\space
+ \addcontentsline
+ {\@nameuse{ext@\LTcaptype}}
+ {\LTcaptype}
+ {\protect\numberline{\@nameuse{the\LTcaptype}}{#2}}}
+ \fi}}
+\ExplSyntaxOff
% \end{macrocode}
% \end{macro}
%
@@ -2375,7 +2443,7 @@
\ExplSyntaxOn
\def\LT@end@hd@ft#1{%
% \end{macrocode}
-%
+%
% This command is used to store the head and foot boxes.
% We need to retrieve and store the row so that we can clean
% up the structure in the finalize code.
@@ -2388,7 +2456,7 @@
% \end{macrocode}
% TODO: This is exposing internal counters, so it should be encapsulated
% in some interface command (but I'm not sure what that should be
-% called, so not done yet.
+% called, so not done yet.
% \changes{v4.19}{2023/12/16}{Managing cell indexes}
% \begin{macrocode}
\tbl_count_missing_cells:n {head/foot}
@@ -2413,19 +2481,28 @@
% To get out of this trap we run \cs{crcr} (which would normally
% come inside \cs{LT@echunk}. That will then trigger \cs{everycr}
% and update row counter unnecessarily, but now we have a defined state, so
-% we can use \cs{noalign} to undo that.
+% we can use \cs{noalign} to undo that.
% We also change \cs{LT@rows} so that further \cs{cr}s do not do
% any harm (as explained above.
%
% The \cs{crcr} inside \cs{LT@echunk} will be bypassed in that case
% as we have just executed a \cs{crcr} and are still in scanning modus for
-% \cs{omit} or \cs{noalign}.
+% \cs{omit} or \cs{noalign}.
% \begin{macrocode}
{
\crcr
\noalign{
% \end{macrocode}
-%
+% \changes{v4.22}{2024/08/13}{Store header row numbers}
+% \begin{macrocode}
+ \int_step_inline:nn
+ { \LT@rows }
+ {
+ \seq_gput_left:ce
+ {g_@@_\cs_to_str:N #1 _rows_seq }
+ { \int_eval:n {\g_@@_row_int - ##1 } }
+ }
+% \end{macrocode}
% \changes{v4.19}{2023/12/16}{Managing cell indexes}
% \begin{macrocode}
\tbl_gdecr_row_count: % undo the increment
@@ -2442,7 +2519,7 @@
{Increase~ LTchunksize}%
\fi
\setbox#1\box\z@
- \@@_trace:n {-->>~ Saving~\noexpand#1}
+ \@@_trace:n {-->>~ Saving~\noexpand#1}
\LT@get@widths
\LT@bchunk}
% \end{macrocode}
@@ -2501,7 +2578,7 @@
\bgroup
% \end{macrocode}
% \changes{v4.12}{2019/02/06}{Color group to match array package}
-% \changes{v4.18}{2023/08/25}{Use \cs{everypar} to match array package, github 1128}%
+% \changes{v4.18}{2023/08/25}{Use \cs{everypar} to match array package, github 1128}
% \begin{macrocode}
\color@begingroup
\let\@footnotetext\LT@p@ftntext
@@ -2509,7 +2586,7 @@
\@arrayparboxrestore
\everypar{%
\vrule \@height \ht\@arstrutbox \@width \z@
- \everypar{}}%
+ \everypar{}}%
}
% \end{macrocode}
% \end{macro}
diff --git a/macros/latex-dev/required/tools/longtable.pdf b/macros/latex-dev/required/tools/longtable.pdf
index f0823ed03f..923872c0a8 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/manifest.txt b/macros/latex-dev/required/tools/manifest.txt
index 004245d1d5..c07b6cd831 100644
--- a/macros/latex-dev/required/tools/manifest.txt
+++ b/macros/latex-dev/required/tools/manifest.txt
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 1993-2021
+% Copyright (C) 1993-2024
% The LaTeX Project and any individual authors listed elsewhere
% in this file.
%
@@ -49,7 +49,7 @@ bm.dtx
Access bold math symbols.
calc.dtx
- Infix arithmetic expresions. Contributed to the distribution by
+ Infix arithmetic expressions. Contributed to the distribution by
Kresten Krab Thorup and Frank Jensen.
enumerate.dtx
@@ -60,7 +60,7 @@ fileerr.dtx
missing file error loop.
fontsmpl.dtx
- Package and test file for producing `font samples'
+ Package and test file for producing `font samples'.
ftnright.dtx
Place footnotes in the right hand column in two-column mode.
@@ -77,7 +77,7 @@ multicol.dtx
rawfonts.dtx
Preload fonts under the old internal font names of LaTeX2.09.
- Not recomended for new packages, but may help when updating old
+ Not recommended for new packages, but may help when updating old
files.
shellesc.dtx
@@ -103,7 +103,7 @@ verbatim.dtx
Flexible version of verbatim environment.
xr.dtx
- eXternall References. Extend \ref to access \label commands in
+ eXternal References. Extend \ref to access \label commands in
other documents.
xspace.dtx
diff --git a/macros/latex-dev/required/tools/multicol-2024-05-23.sty b/macros/latex-dev/required/tools/multicol-2024-05-23.sty
new file mode 100644
index 0000000000..ebe9ea853a
--- /dev/null
+++ b/macros/latex-dev/required/tools/multicol-2024-05-23.sty
@@ -0,0 +1,1144 @@
+%%
+%% This is file `multicol.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% multicol.dtx (with options: `package,badness,check,marktrace,nobalance')
+%%
+%% This is a generated file.
+%%
+%% The source is maintained by the LaTeX Project team and bug
+%% reports for it can be opened at https://latex-project.org/bugs/
+%% (but please observe conditions on bug reports sent to that address!)
+%%
+%% Copyright (C) 1993-2024
+%% The LaTeX Project and any individual authors listed elsewhere
+%% in this file.
+%%
+%% This file was generated from file(s) of the Standard LaTeX `Tools Bundle'.
+%% --------------------------------------------------------------------------
+%%
+%% It may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either version 1.3c
+%% of this license or (at your option) any later version.
+%% The latest version of this license is in
+%% https://www.latex-project.org/lppl.txt
+%% and version 1.3c or later is part of all distributions of LaTeX
+%% version 2005/12/01 or later.
+%%
+%% This file may only be distributed together with a copy of the LaTeX
+%% `Tools Bundle'. You may however distribute the LaTeX `Tools Bundle'
+%% without such generated files.
+%%
+%% The list of all files belonging to the LaTeX `Tools Bundle' is
+%% given in the file `manifest.txt'.
+%%
+%% Package `multicol' to use with LaTeX2e
+%% Copyright 1989-2023 Frank Mittelbach
+%%
+%% In addition to the terms of LPPL any distributed version
+%% (unchanged or modified) of multicol has to keep the statement
+%% about the moral obligation for using multicol. In case of major
+%% changes where this would not be appropriate the author of the
+%% changed version should contact the copyright holder.
+%%
+%%
+%% Moral obligation for using multicol:
+%% ------------------------------------
+%%
+%% Users of multicol who wish to include or use multicol or a modified
+%% version in a proprietary and commercially market product are asked
+%% under certain conditions (see below) for the payment of a license
+%% fee. The size of this fee is to be determined, in each instance,
+%% by the commercial user, depending on his/her judgment of the value of
+%% multicol for his/her product.
+%%
+%%
+%% The conditions for this are as follows:
+%%
+%% The producer of a proprietary and commercially market product
+%% that involves typesetting using multicol is asked to determine
+%% the value of a license fee for using multicol if
+%%
+%% - the product is a document and the producer has decided to
+%% include multicol to typeset (parts of) the document or has
+%% directed the author of the document to include multicol (for
+%% example, by providing a class file to be used by the author)
+%%
+%% - the product is a LaTeX class or package that includes multicol
+%%
+%%
+%% There is no moral obligation in case
+%%
+%% - the product is a document but producer has not directed
+%% the author to include multicol (in that case the moral obligation
+%% lies with the author of the document)
+%%
+%% - the product does not involve typesetting, e.g., consists, for
+%% example, of distributing multicol and its documentation.
+%%
+%% - the product is not proprietary, i.e., is made available as free
+%% software itself (which doesn't prohibit its commercial marketing)
+%%
+%% - multicol is used for non-commercial purposes
+%%
+%%
+%% Determining a license fee might result in a license fee of zero
+%% (i.e., no payment) in case a producer has determined that the use
+%% of multicol has no enhancing effect on the product. This is a
+%% plausible scenario, i.e., in the above two cases the producer is
+%% only asked to evaluate the value of multicol for the product
+%% not for the payment of a license fee per se (which might or might
+%% not follow from this evaluation).
+%%
+%% The license fee, if any, can be payed either to the LaTeX fund
+%% (see ltx3info.txt in the base LaTeX distribution) or to the author of
+%% the program who can be contacted at
+%%
+%% Frank.Mittelbach@latex-project.org
+%%
+
+\DeclareRelease{}{1994-06-01}{multicol-2017-04-11.sty}
+\DeclareRelease{}{2017-04-11}{multicol-2017-04-11.sty}
+\DeclareRelease{v1.8}{2019-10-01}{multicol-2019-10-01.sty}
+\DeclareCurrentRelease{}{2021-11-15}
+
+\ProvidesPackage{multicol}
+ [2024/05/23 v1.9h multicolumn formatting (FMi)]
+\DeclareOption{twocolumn}
+ {\PackageWarning{multicol}{May not work
+ with the twocolumn option}}
+\newcount\c@tracingmulticols
+\DeclareOption{errorshow}
+ {\c@tracingmulticols\z@}
+\DeclareOption{infoshow}
+ {\c@tracingmulticols\@ne}
+\DeclareOption{balancingshow}
+ {\c@tracingmulticols\tw@}
+\DeclareOption{markshow}
+ {\c@tracingmulticols\thr@@}
+\DeclareOption{debugshow}
+ {\c@tracingmulticols5\relax}
+\let\mc@gridwarn\maxdimen
+\DeclareOption{grid}
+ {\def\mc@gridwarn{\@maxdepth}}
+\DeclareOption{colaction}{%
+ \def\mc@col@status@write{%
+ \protected@write\@auxout{}%
+ {\string\mc@col@status
+ {\ifmc@firstcol 1\else 2\fi}}%
+ \mc@firstcolfalse}%
+ \def\mc@lastcol@status@write{%
+ \protected@write\@auxout{}%
+ {\string\mc@col@status{3}}}%
+}
+\let\mc@col@status@write\relax
+\let\mc@lastcol@status@write\relax
+\ProcessOptions
+\def\multicols#1{\col@number#1\relax
+ \ifnum\col@number<\tw@
+ \PackageWarning{multicol}%
+ {Using `\number\col@number'
+ columns doesn't seem a good idea.^^J
+ I therefore use two columns instead}%
+ \col@number\tw@ \fi
+ \ifnum\col@number>20
+ \PackageError{multicol}%
+ {Too many columns}%
+ {Current implementation doesn't
+ support more than 20 columns.%
+ \MessageBreak
+ I therefore use 20 columns instead}%
+ \col@number20 \fi
+ \ifx\@footnotetext\mult@footnotetext
+ \else
+ \let\orig@footnotetext\@footnotetext
+ \let\@footnotetext\mult@footnotetext
+ \fi
+ \@ifnextchar[\mult@cols{\mult@cols[]}}
+\long\def\mult@footnotetext#1{\begingroup
+ \columnwidth\textwidth
+ \orig@footnotetext{#1}\endgroup}
+\def\mult@cols[#1]{\@ifnextchar[%
+ {\mult@@cols{#1}}%
+ {\mult@@cols{#1}[\premulticols]}}
+\def\mult@@cols#1[#2]{%
+ \par
+ \ifinner \@boxedmulticolstrue
+ \else
+ \ifnum \doublecol@number>\z@
+ \@boxedmulticolstrue
+ \fi
+ \fi
+ \mult@info\z@
+ {Starting environment with
+ \the\col@number\space columns%
+ \if@boxedmulticols\MessageBreak
+ (boxed mode)\fi
+ }%
+ \enough@room{#2}%
+ #1\par\addvspace\multicolsep
+ \ifdim \prevdepth = -\@m\p@
+ \else
+ \@tempcnta\prevdepth
+ \@tempcntb\baselineskip
+ \divide\@tempcnta\@tempcntb
+ \advance\@tempcnta\@ne
+ \dimen@\prevdepth
+ \advance\dimen@ -\@tempcnta\baselineskip
+ \advance\dimen@ \topskip
+ \kern-\dimen@
+ \fi
+ \begingroup
+ \prepare@multicols
+ \if@boxedmulticols
+ \setbox\mult@box\vbox\bgroup
+ \color@setgroup
+ \fi
+ \ignorespaces}
+\newif\if@boxedmulticols
+\@boxedmulticolsfalse
+\newbox\mult@box
+\def\enough@room#1{%
+ \if@boxedmulticols\else
+ \par
+ \bgroup\@nobreakfalse\addpenalty\z@\egroup
+ \page@free \pagegoal
+ \advance \page@free -\pagetotal
+ \@tempskipa#1\relax
+ \mult@info\z@
+ {Current page:\MessageBreak
+ height=%
+ \the\pagegoal: used \the\pagetotal
+ \space -> free=\the\page@free
+ \MessageBreak
+ needed \the\@tempskipa
+ \space(for #1)}%
+ \ifdim \page@free <#1\newpage \fi
+ \fi}
+\def\prepare@multicols{%
+ \multicol@leftmargin\@totalleftmargin
+ \@totalleftmargin\z@
+ \parshape\z@
+ \doublecol@number\col@number
+ \multiply\doublecol@number\tw@
+ \advance\doublecol@number\mult@rightbox
+ \if@boxedmulticols
+ \let\l@kept@firstmark\kept@firstmark
+ \let\l@kept@botmark\kept@botmark
+ \global\let\kept@firstmark\@empty
+ \global\let\kept@botmark\@empty
+ \else
+ \nointerlineskip {\topskip\z@\null}%
+ \output{%
+ \global\setbox\partial@page\vbox
+ {%
+ \ifvoid\partial@page\else
+ \PackageError{multicol}%
+ {Error saving partial page}%
+ {The part of the page before
+ the multicols environment was
+ nearly full with^^Jthe result
+ that starting the environment
+ will produce an overfull
+ page. Some^^Jtext may be lost!
+ Please increase \premulticols
+ either generally or for this%
+ ^^Jenvironment by specifying a
+ suitable value in the second
+ optional argument to^^Jthe
+ multicols environment.}
+ \unvbox\partial@page
+ \box\last@line
+ \fi
+ \unvbox\@cclv
+ \global\setbox\last@line\lastbox
+ }%
+ \prep@keptmarks
+ \global\let\kept@topmark\firstmark
+ }\eject
+ \advance\@colroom-\ht\partial@page
+ \set@mult@vsize\relax
+ \output{\multi@column@out}%
+ \init@mult@footins
+ \reinsert@footnotes
+ \def\clearpage{%
+ \ifx\@deferlist\@empty\else
+ \PackageError{multicol}%
+ {Deferred floats not cleared}%
+ {A \string\clearpage\space inside
+ multicols acts like
+ \string\newpage\space and doesn't
+ clear floats.\MessageBreak
+ Move it before the multicols
+ environment if you need it.}%
+ \fi
+ \newpage}%
+ \fi
+ \vbadness\@Mi \hbadness5000
+ \tolerance\multicoltolerance
+ \pretolerance\multicolpretolerance
+ \setemergencystretch\col@number\hsize
+ \set@floatcmds
+ \advance\baselineskip\multicolbaselineskip
+ \hsize\linewidth \advance\hsize\columnsep
+ \advance\hsize-\col@number\columnsep
+ \divide\hsize\col@number
+ \full@width\linewidth
+ \linewidth\hsize
+ \columnwidth\hsize
+}
+\def\init@mult@footins{%
+ \multiply\count\footins\col@number
+ \multiply\skip \footins\col@number
+}
+\def\set@mult@vsize#1{%
+ \vsize\@colroom
+ \@tempdima\baselineskip
+ \advance\@tempdima-\topskip
+ \advance\vsize\@tempdima
+ \vsize\col@number\vsize
+ \advance\vsize-\@tempdima
+ \advance\vsize\col@number\baselineskip
+ #1\advance\vsize
+ \c@collectmore\baselineskip}
+\newdimen\multicol@leftmargin
+\mathchardef\@Mvi=10006 % 10005 is
+ % \columnbreak
+\def\endmulticols{\par
+ \if@boxedmulticols
+ \remove@discardable@items
+ \color@endgroup\egroup
+ \balance@columns
+ \return@nonemptymark{first}%
+ \kept@firstmark
+ \return@nonemptymark{bot}%
+ \kept@botmark
+ \global\setbox\mc@boxedresult\vbox{%
+ \page@sofar
+ \global\let\kept@firstmark
+ \l@kept@firstmark
+ \global\let\kept@botmark
+ \l@kept@botmark
+ }%
+ \mult@info\tw@
+ {Restore kept marks to\MessageBreak
+ first: \meaning\kept@firstmark
+ \MessageBreak bot\space\space:
+ \meaning\kept@botmark }%
+ \else
+ \ifdim\pagegoal=\maxdimen
+ \ifvoid\colbreak@box\else
+ \mult@info\@ne{Re-adding forced
+ break(s) for splitting}%
+ \unvbox\colbreak@box\fi
+ \fi
+ \penalty\z@
+ \penalty-\@Mvi
+ \ifvbox\partial@page
+ \unvbox\partial@page\fi
+ \global\let\kept@firstmark\@empty
+ \global\let\kept@botmark\@empty
+ \mult@info\tw@
+ {Make kept marks empty}%
+ \fi
+ \@checkend{multicols}%
+ \endgroup
+ \global\c@unbalance\z@
+ \if@boxedmulticols
+ \unvbox\mc@boxedresult
+ \mc@col@status@write
+ \else
+ \reinsert@footnotes
+ \ifdim \pagegoal=\maxdimen
+ \global\vsize\@colroom
+ \else
+ \enough@room\postmulticols
+ \fi
+ \fi
+ \addvspace\multicolsep
+ \prevdepth\z@
+ \mult@info\z@
+ {Ending environment
+ \if@boxedmulticols
+ \space(boxed mode)\fi
+ }}
+\newcount\c@unbalance
+\newcount\c@collectmore
+\newcount\doublecol@number
+\newcount\multicoltolerance
+\newcount\multicolpretolerance
+\newdimen\full@width
+\newdimen\page@free
+\newdimen\premulticols
+\newdimen\postmulticols
+\newskip\multicolsep
+\newskip\multicolbaselineskip
+\newbox\partial@page
+\newbox\last@line
+\newbox\mc@boxedresult
+\c@unbalance = 0
+\c@collectmore = 0
+\multicoltolerance = 9999
+\multicolpretolerance = -1
+\premulticols = 50pt
+\postmulticols= 20pt
+\multicolsep = 12pt plus 4pt minus 3pt
+\multicolbaselineskip=0pt
+\def\process@cols#1#2{\count@#1\relax
+ \loop
+ #2%
+ \advance\count@\tw@
+ \ifnum\count@<\doublecol@number
+ \repeat}
+\def\page@sofar{%
+ \process@cols\mult@rightbox
+ {\ifvoid\count@
+ \setbox\count@\hbox to\hsize{}%
+ \else
+ \wd\count@\hsize
+ \fi}%
+ \count@\col@number \advance\count@\m@ne
+ \mult@info\z@
+ {Column spec: \the\full@width\space = indent
+ + columns + sep =\MessageBreak
+ \the\multicol@leftmargin\space
+ + \the\col@number\space
+ x \the\hsize\space
+ + \the\count@\space
+ x \the\columnsep
+ }%
+\ifvmode\else\errmessage{Multicol Error}\fi
+ \nointerlineskip
+ \setbox\z@\hbox{\multicolmindepthstring}\global\dimen\tw@\dp\z@
+ \moveright\multicol@leftmargin
+ \hbox to\full@width{%
+ \mc@align@columns
+ \rlap{\phantom \multicolmindepthstring}%
+ }%
+ \prevdepth\z@
+ \kern-\dimen\tw@
+ \ifdim\dimen\tw@ > \mc@gridwarn
+ \PackageWarning{multicol}%
+ {Very deep columns!\MessageBreak
+ Grid alignment might be broken}%
+ \fi
+}
+\def\multicolmindepthstring{p}
+\def\columnseprulecolor{\normalcolor}
+\def\reinsert@footnotes{\ifvoid\footins\else
+ \insert\footins{}\fi}
+\def\vfilmaxdepth{\vskip \z@ \@plus .0001fil
+ \@minus \@maxdepth}
+\def\multi@column@out{%
+ \ifnum\outputpenalty <-\@M
+ \speci@ls \else
+ \ifvoid\colbreak@box\else
+ \mult@info\@ne{Re-adding forced
+ break(s) for splitting}%
+ \setbox\@cclv\vbox{%
+ \unvbox\colbreak@box
+ \penalty-\@Mv
+ \unvbox\@cclv}%
+ \fi
+ \splittopskip\topskip
+ \splitmaxdepth\@maxdepth
+ \boxmaxdepth\@maxdepth
+ \dimen@\@colroom
+ \divide\skip\footins\col@number
+ \ifvoid\footins \else
+ \leave@mult@footins
+ \fi
+ \ifvbox \@kludgeins
+ \advance \dimen@ -\ht\@kludgeins
+ \ifdim \wd\@kludgeins>\z@
+ \shr@nkingtrue
+ \fi
+ \fi
+ \process@cols\mult@firstbox{%
+ \setbox\count@
+ \vsplit\@cclv to\dimen@
+ \set@keptmarks
+ \setbox\count@
+ \vbox to\dimen@
+ {\unvbox\count@
+ \ifshr@nking
+ \vfilmaxdepth\fi}%
+ }%
+ \setbox\mult@rightbox
+ \vsplit\@cclv to\dimen@
+ \set@keptmarks
+ \setbox\mult@rightbox\vbox to\dimen@
+ {\unvbox\mult@rightbox
+ \ifshr@nking\vfilmaxdepth\fi}%
+ \ifvoid\@cclv \else
+ \unvbox\@cclv
+ \ifnum\outputpenalty=\@M
+ \else
+ \penalty\outputpenalty
+ \fi
+ \ifvoid\footins\else
+ \PackageWarning{multicol}%
+ {I moved some lines to
+ the next page.\MessageBreak
+ Footnotes on page
+ \thepage\space might be wrong}%
+ \fi
+ \ifnum \c@tracingmulticols>\thr@@
+ \hrule\allowbreak \fi
+ \fi
+ \ifx\@empty\kept@firstmark
+ \let\firstmark\kept@topmark
+ \let\botmark\kept@topmark
+ \else
+ \let\firstmark\kept@firstmark
+ \let\botmark\kept@botmark
+ \fi
+ \let\topmark\kept@topmark
+ \mult@info\tw@
+ {Use kept top mark:\MessageBreak
+ \meaning\kept@topmark
+ \MessageBreak
+ Use kept first mark:\MessageBreak
+ \meaning\kept@firstmark
+ \MessageBreak
+ Use kept bot mark:\MessageBreak
+ \meaning\kept@botmark
+ \MessageBreak
+ Produce first mark:\MessageBreak
+ \meaning\firstmark
+ \MessageBreak
+ Produce bot mark:\MessageBreak
+ \meaning\botmark
+ \@gobbletwo}%
+ \boxmaxdepth\maxdimen
+ \setbox\@cclv\vbox{\unvbox\partial@page
+ \page@sofar}%
+ \@makecol\@outputpage
+ \global\let\kept@topmark\botmark
+ \global\let\kept@firstmark\@empty
+ \global\let\kept@botmark\@empty
+ \mult@info\tw@
+ {(Re)Init top mark:\MessageBreak
+ \meaning\kept@topmark
+ \@gobbletwo}%
+ \global\@colroom\@colht
+ \global \@mparbottom \z@
+ \global \@textfloatsheight \z@
+ \process@deferreds
+ \@whilesw\if@fcolmade\fi{\@outputpage
+ \global\@colroom\@colht
+ \process@deferreds}%
+ \mult@info\@ne
+ {Colroom:\MessageBreak
+ \the\@colht\space
+ after float space removed
+ = \the\@colroom \@gobble}%
+ \set@mult@vsize \global
+ \fi}
+\def\leave@mult@footins{%
+ \advance\dimen@-\skip\footins
+ \advance\dimen@-\ht\footins
+}
+\def\speci@ls{%
+ \ifnum\outputpenalty <-\@Mi
+ \ifnum \outputpenalty<-\@MM
+ \PackageError{multicol}{Document end
+ inside multicols environment}\@ehd
+ \@specialoutput
+ \else
+ \ifnum\outputpenalty = -\@Mv
+ \mult@info\@ne{Forced column
+ break seen}%
+ \global\advance\vsize-\pagetotal
+ \global\setbox\colbreak@box
+ \vbox{%
+ \ifvoid\colbreak@box
+ \else
+ \unvbox\colbreak@box
+ \penalty-\@Mv
+ \fi
+ \boxmaxdepth\@maxdepth
+ \setbox\@cclv\vbox{%
+ \unvbox\@cclv
+ \remove@discardable@items}%
+ \dimen@\dp\@cclv
+ \unvbox\@cclv
+ \kern-\dimen@
+ }%
+ \reinsert@footnotes
+ \else
+ \ifnum\outputpenalty = -\@Mvi
+ \mult@info\@ne{End penalty of
+ multicols seen}%
+ \outputpenalty\@M % pretend we had
+ % a natural
+ % forced break
+ \balance@columns@out
+ \else
+ \PackageWarningNoLine{multicol}%
+ {Floats and marginpars not
+ allowed inside `multicols'
+ environment!}%
+ \unvbox\@cclv\reinsert@footnotes
+ \xdef\@freelist{\@freelist
+ \@currlist}%
+ \gdef\@currlist{}%
+ \fi
+ \fi
+ \fi
+ \else \@doclearpage \fi
+}
+\def\process@deferreds{%
+ \@floatplacement
+ \@tryfcolumn\@deferlist
+ \if@fcolmade\else
+ \begingroup
+ \let\@tempb\@deferlist
+ \gdef\@deferlist{}%
+ \let\@elt\@scolelt
+ \@tempb \endgroup
+ \fi}
+\newif\ifshr@nking
+\def\raggedcolumns{%
+ \@bsphack\shr@nkingtrue\@esphack}
+\def\flushcolumns{%
+ \@bsphack\shr@nkingfalse\@esphack}
+\def\balance@columns@out{%
+ \setbox\mult@box\vbox{%
+ \ifvoid\colbreak@box\else
+ \unvbox\colbreak@box
+ \penalty-\@Mv
+ \mult@info\@ne{Re-adding
+ forced break(s) in balancing}%
+ \fi
+ \unvbox\@cclv
+ \remove@discardable@items
+ }%
+ \balance@columns
+ \iftoo@bad
+ \mult@info\@ne
+ {Balancing failed ...
+ cut a normal page}%
+ \setbox\@cclv\vbox
+ {\vskip\topskip
+ \vskip-\splittopskip
+ \unvbox\mult@box
+ \penalty-\@Mvi
+ }%
+ \multi@column@out
+ \else
+ \global\vsize\@colroom
+ \global\advance\vsize\ht\partial@page
+ \ifvbox\@kludgeins
+ \insert\@kludgeins
+ {\unvbox\@kludgeins}\fi
+ \unvbox\partial@page
+ \return@nonemptymark{first}%
+ \kept@firstmark
+ \return@nonemptymark{bot}\kept@botmark
+ \page@sofar
+ \penalty\z@
+ \fi
+}
+\def\balance@columns{%
+ \get@keptmarks\mult@box
+ \setbox\mult@box\vbox{%
+ \penalty-\@M
+ \unvbox\mult@box
+ }%
+ \@tempdima\topskip
+ \splittopskip\@tempdima
+ \@plus\multicolundershoot
+ \@minus\multicolovershoot
+ \splitmaxdepth\@maxdepth
+ \boxmaxdepth\@maxdepth
+ \setbox\@tempboxa\vsplit\mult@box to\z@
+ \@tempdima\ht\mult@box
+ \advance\@tempdima\dp\mult@box
+ \divide\@tempdima\col@number
+ \count@\@tempdima
+ \divide\count@\baselineskip
+ \dimen@\count@\baselineskip
+ \advance\dimen@\topskip
+ \ifdim \dimen@ >\@tempdima
+ \advance\dimen@-\baselineskip
+ \fi
+ \@tempdima\dimexpr
+ \topskip +\c@minrows\baselineskip
+ -\baselineskip\relax
+ \ifnum\dimen@<\@tempdima
+ \mult@info\@ne
+ {Start value
+ \the\dimen@ \space ->
+ \the\@tempdima \space
+ (corrected for minrows)}%
+ \dimen@\@tempdima
+ \fi
+ \advance\dimen@\c@unbalance\baselineskip
+ \mult@info\@ne
+ {Balance columns\on@line:
+ \ifnum\c@unbalance=\z@\else
+ (off balance=\number\c@unbalance)\fi
+ \@gobbletwo}%
+ \ifnum\dimen@<\topskip
+ \mult@info\@ne
+ {Start value
+ \the\dimen@ \space ->
+ \the\topskip \space (corrected)}%
+ \dimen@\topskip
+ \fi
+ \vbadness\@M
+ \vfuzz \maxdimen
+ \last@try-\p@
+ \loop
+ {\process@cols\mult@grightbox
+ {\global\setbox\count@
+ \box\voidb@x}}%
+ \global\setbox\mult@grightbox
+ \copy\mult@box
+ \too@badfalse
+ \forcedbreak@leftoverfalse
+ {\process@cols\mult@gfirstbox{%
+ \global\setbox\count@
+ \vsplit\mult@grightbox to\dimen@
+ \global\setbox\count@
+ \vbox to\dimen@
+ {\unvbox\count@}%
+ \ifnum\c@tracingmulticols>\@ne
+ \@tempcnta\count@
+ \advance\@tempcnta-\mult@grightbox
+ \divide\@tempcnta \tw@
+ \message{^^JColumn
+ \number\@tempcnta\space
+ badness: \the\badness\space}%
+ \fi
+ \ifnum\badness>\c@columnbadness
+ \ifnum\c@tracingmulticols>\@ne
+ \message{too bad
+ (>\the\c@columnbadness)}%
+ \fi
+ \too@badtrue
+ \fi
+ }}%
+ \global\setbox\mult@grightbox
+ \vbox{\unvbox\mult@grightbox}%
+ \setbox\mult@nat@firstbox
+ \vbox{\unvcopy\mult@gfirstbox}%
+ \ifnum\c@tracingmulticols>\@ne
+ \message{^^JFirst column
+ = \the\dimen@\space
+ (\the\ht\mult@nat@firstbox)}\fi
+ \ifnum\c@tracingmulticols>\@ne
+ \message{<> last column =
+ \the\ht\mult@grightbox^^J}%
+ \fi
+ \ifdim\ht\mult@grightbox >\dimen@
+ \too@badtrue
+ \ifnum\c@tracingmulticols>\@ne
+ \typeout{Rejected: last
+ column too large!}%
+ \fi
+ \else
+ \setbox\@tempboxa
+ \copy\mult@grightbox
+ \setbox\z@\vsplit\@tempboxa to\maxdimen
+ \ifvoid\@tempboxa
+ \global\setbox\mult@grightbox
+ \vbox to\dimen@
+ {\unvbox\mult@grightbox}%
+ \ifnum\c@tracingmulticols>\@ne
+ \message{Final badness:
+ \the\badness}%
+ \fi
+ \ifnum\badness>\c@finalcolumnbadness
+ \global\setbox\mult@grightbox
+ \vbox to\dimen@
+ {\unvbox\mult@grightbox\vfil}%
+ \ifnum\c@tracingmulticols>\@ne
+ \message{ setting natural
+ (> \the\c@finalcolumnbadness)}%
+ \fi
+ \fi
+ \else
+ \@tempdima\@colroom
+ \advance\@tempdima \maxbalancingoverflow
+ \ifdim \dimen@ < \@tempdima
+ \too@badtrue
+ \ifnum\c@tracingmulticols>\@ne
+ \typeout{Rejected: unprocessed
+ forced break(s) in last column!}%
+ \fi
+ \else
+ \forcedbreak@leftovertrue
+ \ifnum\c@tracingmulticols>\@ne
+ \typeout{Failed: columns too large
+ with unprocessed forced break(s)!}%
+ \fi
+ \fi
+ \fi
+ \fi
+ \ifdim\ht\mult@nat@firstbox<\dimen@
+ \ifdim\ht\mult@nat@firstbox>\last@try
+ \too@badtrue
+ \ifnum\c@tracingmulticols>\@ne
+ \typeout{Retry: using natural
+ height of first column!}%
+ \fi
+ \dimen@\ht\mult@nat@firstbox
+ \last@try\dimen@
+ \advance\dimen@-\p@
+ \fi
+ \fi
+ \iftoo@bad
+ \advance\dimen@\p@
+ \repeat
+ \ifforcedbreak@leftover
+ \too@badtrue
+ \else
+ \if@boxedmulticols\else
+ \ifdim\dimen@>\@colroom
+ \dimen@\@colroom
+ \fi
+ \fi
+ \process@cols\mult@rightbox
+ {\@tempcnta\count@
+ \advance\@tempcnta\@ne
+ \vfuzz\z@
+ \setbox\count@\vbox to\dimen@
+ {%
+ \vskip \z@
+ \@plus-\multicolundershoot
+ \@minus-\multicolovershoot
+ \unvbox\@tempcnta
+ \ifshr@nking\vfilmaxdepth\fi
+ }%
+ \ifnum\badness>\@M
+ \vfuzz\maxdimen % no overfull warning
+ \setbox\@tempboxa \vbox to\dimen@
+ {\vskip-\maxbalancingoverflow
+ \unvcopy\count@}%
+ \ifnum\badness>\@M
+ \mult@info\@ne
+ {Balanced column more than
+ \the\maxbalancingoverflow\space
+ too large}%
+ \too@badtrue
+ \else
+ \mult@info\@ne
+ {Balanced column
+ too large, but less than
+ \the\maxbalancingoverflow}%
+ \fi
+ \fi
+ }%
+ \fi
+}
+\newdimen\maxbalancingoverflow
+\maxbalancingoverflow=12pt
+
+\ifnum\numexpr
+ \count20-\count14-1<40
+ % this is = 2 * 20
+ \count14=\@cclv
+\fi
+\newbox\mult@rightbox
+\newbox\mult@grightbox
+\newbox\mult@firstbox
+\newbox\mult@gfirstbox
+\newbox\@tempa\newbox\@tempa
+\newbox\@tempa\newbox\@tempa
+\newbox\@tempa\newbox\@tempa
+\newbox\@tempa\newbox\@tempa
+\newbox\@tempa\newbox\@tempa
+\newbox\@tempa\newbox\@tempa
+\newbox\@tempa\newbox\@tempa
+\newbox\@tempa\newbox\@tempa
+\newbox\@tempa\newbox\@tempa
+\newbox\@tempa\newbox\@tempa
+\newbox\@tempa\newbox\@tempa
+\newbox\@tempa\newbox\@tempa
+\newbox\@tempa\newbox\@tempa
+\newbox\@tempa\newbox\@tempa
+\newbox\@tempa\newbox\@tempa
+\newbox\@tempa\newbox\@tempa
+\newbox\@tempa\newbox\@tempa
+\newbox\@tempa\newbox\@tempa
+\let\@tempa\relax
+\@ifundefined{emergencystretch}
+ {\newdimen\emergencystretch}{}
+\def\setemergencystretch#1#2{%
+ \emergencystretch 4pt
+ \multiply\emergencystretch#1}
+
+\def\set@floatcmds{%
+ \let\@dblfloat\@dbflt
+ \def\end@dblfloat{\@endfloatbox
+ \@largefloatcheck
+ \outer@nobreak
+ \ifnum\@floatpenalty<\z@
+ \@cons\@deferlist\@currbox
+ \fi
+ \ifnum\@floatpenalty=-\@Mii
+ \@Esphack
+ \fi}}
+\def\kept@topmark{{}{}}
+\let\kept@firstmark\@empty
+\let\kept@botmark\@empty
+\def\return@nonemptymark#1#2{%
+ \ifx#2\@empty
+ \else
+ \mult@info\tw@
+ {Returned #1 mark:\MessageBreak
+ \meaning#2}%
+ \toks@\expandafter{#2}%
+ \mark{\the\toks@}%
+ \nobreak
+ \fi}
+\def\get@keptmarks#1{%
+ \begingroup
+ \vbadness\@M
+ \setbox#1\copy#1%
+ \mc@get@all@box@marks #1%
+ \set@keptmarks
+ \endgroup
+}
+\def\mc@get@all@box@marks #1{%
+ \setbox\@tempboxa\vsplit#1to\maxdimen
+ \ifvoid#1\else
+ \setbox#1\vbox{\unvbox\@tempboxa \unvbox#1}%
+ \mc@get@all@box@marks #1%
+ \fi
+}
+\def\set@keptmarks{%
+ \ifx\kept@firstmark\@empty
+ \expandafter\gdef\expandafter
+ \kept@firstmark
+ \expandafter{\splitfirstmark}%
+ \ifx\kept@firstmark\@empty\else
+ \mult@info\tw@
+ {Set kept first mark:\MessageBreak
+ \meaning\kept@firstmark%
+ \@gobbletwo}%
+ \fi
+ \fi
+ \expandafter\def\expandafter\@tempa
+ \expandafter{\splitbotmark}%
+ \ifx\@tempa\@empty\else
+ \global\let\kept@botmark\@tempa
+ \mult@info\tw@
+ {Set kept bot mark:\MessageBreak
+ \meaning\kept@botmark%
+ \@gobbletwo}%
+ \fi}%
+\def\prep@keptmarks{%
+ \if@boxedmulticols \else
+ \get@keptmarks\partial@page
+ \fi}
+\skip0=0pt
+\edef\the@zero@skip{\the\skip0}
+\def\remove@discardable@items{%
+ \unpenalty
+ \edef\@tempa{\the\lastskip}%
+ \unskip
+ \ifx\@tempa\the@zero@skip
+ \edef\@tempb{\the\lastskip}%
+ \ifx\@tempb\the@zero@skip
+ \else
+ \unskip
+ \ifnum \lastpenalty=\@M
+ \vskip\@tempb\vskip\@tempa\relax
+ \else
+ \remove@discardable@items
+ \fi
+ \fi
+ \else
+ \remove@discardable@items
+ \fi
+}
+\newif\iftoo@bad
+\def\too@badtrue{\global\let\iftoo@bad\iftrue}
+\def\too@badfalse{\global\let\iftoo@bad\iffalse}
+\newif\ifforcedbreak@leftover
+\newcount\c@minrows
+\c@minrows=1
+\newcount\c@columnbadness
+\c@columnbadness=10000
+\newcount\c@finalcolumnbadness
+\c@finalcolumnbadness=9999
+
+\newdimen\last@try
+
+\newdimen\multicolovershoot
+\newdimen\multicolundershoot
+\multicolovershoot=0pt
+\multicolundershoot=2pt
+\newbox\mult@nat@firstbox
+\def\mult@info#1#2{%
+ \ifnum\c@tracingmulticols>#1%
+ \GenericWarning
+ {(multicol)\@spaces\@spaces}%
+ {Package multicol: #2}%
+ \fi
+}
+ \@namedef{multicols*}{%
+ \ifinner
+ \PackageWarning{multicol}%
+ {multicols* inside a box does
+ not make sense.\MessageBreak
+ Going to balance anyway}%
+ \else
+ \def\balance@columns@out
+ {\multi@column@out \penalty-\@Mvi }%
+ \fi
+ \begin{multicols}
+}
+\@namedef{endmulticols*}{%
+ \par
+ \ifdim\lastskip>\z@ \vskip-\lastskip \fi
+ \ifdim \prevdepth>\z@
+ \vskip-\ifdim\prevdepth>\boxmaxdepth
+ \boxmaxdepth
+ \else \prevdepth \fi
+ \fi
+ \ifshr@nking\else
+ \vfil
+ \fi
+ \end{multicols}}
+\mathchardef\@Mv=10005
+\newcommand\columnbreak[1][4]{%
+ \ifnum\col@number<\tw@
+ \PackageError{multicol}%
+ {\noexpand\columnbreak outside multicols}%
+ {This command can only be used within
+ a multicols or multicols* environment.}%
+ \else
+ \edef\mc@break@pen
+{-\ifcase#1\@m\or 3333\or 6666\or 9999\else\@Mv\fi\relax}%
+ \ifvmode
+ \penalty \mc@break@pen
+ \else
+ \@bsphack
+ \vadjust{\penalty \mc@break@pen}%
+ \@esphack
+ \fi
+ \fi}
+\newcommand\newcolumn{%
+ \ifnum\col@number<\tw@
+ \PackageError{multicol}%
+ {\noexpand\newcolumn outside multicols}%
+ {This command can only be used within
+ a multicols or multicols* environment.}%
+ \else
+ \ifvmode
+ \nobreak\vfill\kern\z@\penalty -\@Mv\relax
+ \else
+ \@bsphack
+ \vadjust{\nobreak\vfill\kern\z@\penalty -\@Mv\relax}%
+ \@esphack
+ \fi
+ \fi}
+\newbox\colbreak@box
+\def\LR@column@boxes{%
+ \process@cols\mult@firstbox{%
+ \ifdim\dp\count@>\dimen\tw@
+ \global\dimen\tw@\dp\count@ \fi
+ \mc@col@status@write
+ \box\count@
+ \hss{\columnseprulecolor\vrule
+ \@width\columnseprule}\hss}%
+ \ifdim\dp\mult@rightbox>\dimen\tw@
+ \global\dimen\tw@\dp\mult@rightbox \fi
+ \mc@lastcol@status@write
+ \box\mult@rightbox
+}
+
+\def\RL@column@boxes{%
+ \process@cols\mult@firstbox{%
+ \hskip\hsize
+ \hss{\columnseprulecolor\vrule
+ \@width\columnseprule}\hss
+ }%
+ \hskip\hsize
+ \process@cols\mult@firstbox{%
+ \ifdim\dp\count@>\dimen\tw@
+ \global\dimen\tw@\dp\count@ \fi
+ \hskip-\hsize
+ \mc@col@status@write
+ \box\count@
+ \hskip-\hsize
+ \hskip-\columnsep
+ }%
+ \ifdim\dp\mult@rightbox>\dimen\tw@
+ \global\dimen\tw@\dp\mult@rightbox \fi
+ \hskip-\hsize
+ \mc@lastcol@status@write
+ \box\mult@rightbox
+ \hskip-\hsize
+ \hskip\full@width
+ }
+\newcommand\RLmulticolcolumns
+ {\let\mc@align@columns
+ \RL@column@boxes}
+\newcommand\LRmulticolcolumns
+ {\let\mc@align@columns
+ \LR@column@boxes}
+\LRmulticolcolumns
+\newcount\mc@col@check@num
+
+\newcommand\docolaction{%
+ \ifx\mc@col@status@write\relax
+ \PackageError{multicol}%
+ {Option 'colaction' not selected}%
+ {\string\docolaction\space
+ requires the use of the 'colaction'
+ option on the package}%
+ \fi
+ \global\advance\mc@col@check@num\@ne
+ \edef\mc@col@type{\expandafter\ifx
+ \csname mc@col-\the\mc@col@check@num
+ \endcsname\relax
+ 0\else
+ \csname mc@col-\the\mc@col@check@num
+ \endcsname
+ \fi}%
+ \@ifstar
+ {\@docolactionstartrue \@docolaction}%
+ {\@docolactionstarfalse\@docolaction}%
+}
+\newcommand\@docolaction[4][1]{%
+ \edef\@docolactioncheck{\write\@auxout
+ {\string\mc@set@col@status
+ {mc@col-\the\mc@col@check@num}%
+ {\mc@col@type}}}%
+ \if@docolactionstar \@docolactioncheck \fi
+ \ifcase \mc@col@type\relax
+ \ifcase #1\or #2\or#3\or#4\fi
+ \or
+ #2% % 1 First col
+ \or
+ #3% % 2 any middle col
+ \or
+ #4% % 3 last col
+ \else
+ \ERRORwrongdefaultgiven
+ \fi
+ \if@docolactionstar \else \@docolactioncheck \fi
+}
+\newif\if@docolactionstar
+\def\mc@col@status#1{%
+ \gdef\mc@curr@col@status{#1}}
+\def\mc@set@col@status#1#2{%
+ \global\expandafter\let\csname #1\endcsname
+ \mc@curr@col@status}
+\AtEndDocument{\def\mc@set@col@status#1#2{%
+ \ifnum #2=\mc@curr@col@status\else
+ \@tempswatrue
+ \fi}%
+}
+\newif\ifmc@firstcol
+\mc@firstcoltrue
+\endinput
+%%
+%% End of file `multicol.sty'.
diff --git a/macros/latex-dev/required/tools/multicol.dtx b/macros/latex-dev/required/tools/multicol.dtx
index 4d86448002..1cb322ea6d 100644
--- a/macros/latex-dev/required/tools/multicol.dtx
+++ b/macros/latex-dev/required/tools/multicol.dtx
@@ -20,7 +20,7 @@
% \iffalse This is a METACOMMENT
%
%% Package `multicol' to use with LaTeX2e
-%% Copyright 1989-2023 Frank Mittelbach
+%% Copyright 1989-2024 Frank Mittelbach
%%
%% In addition to the terms of LPPL any distributed version
%% (unchanged or modified) of multicol has to keep the statement
@@ -77,7 +77,7 @@
%% not for the payment of a license fee per se (which might or might
%% not follow from this evaluation).
%%
-%% The license fee, if any, can be payed either to the LaTeX fund
+%% The license fee, if any, can be paid either to the LaTeX fund
%% (see ltx3info.txt in the base LaTeX distribution) or to the author of
%% the program who can be contacted at
%%
@@ -92,13 +92,14 @@
%
%<package>\DeclareRelease{}{2017-04-11}{multicol-2017-04-11.sty}
%<package>\DeclareRelease{v1.8}{2019-10-01}{multicol-2019-10-01.sty}
+%<package>\DeclareRelease{v1.9}{2021-11-15}{multicol-2024-05-23.sty}
%<package>\DeclareCurrentRelease{}{2021-11-15}
%<package>
%<package>\ProvidesPackage{multicol}
%<driver> \ProvidesFile{multicol.drv}
% \fi
% \ProvidesFile{multicol.dtx}
- [2024/05/23 v1.9h multicolumn formatting (FMi)]
+ [2024/11/21 v2.0a multicolumn formatting (FMi)]
%
%
%
@@ -181,6 +182,23 @@
% the scope of the environment.
% \end{abstract}
%
+% \begin{multicols}{3}[\section*{Preface to versions 1.9 + 2.0}]
+%
+% Version 1.9 added tagging support and also a number of smaller
+% enhancements, such as an optional argument to
+% \cs{columnbreak} to allow for conditional breaks instead of
+% forced ones. The min column depth was also made customizable
+% (previously it was hardwired to the depth of \enquote{p}) to support
+% special cases and in particular languages that do not have
+% characters with any noticeable depth such as, for example, Japanese.
+%
+% Verson 2.0 then simplified and improved the mark handling, by
+% fully supporting the new mark mechanism of \LaTeX.
+%
+% \end{multicols}
+%
+%
+%
% \begin{multicols}{3}[\section*{Preface to version 1.8}]
% The 1.8 release improves on the balancing approach. If due to a
% limited number of break points (e.g., due to large objects) the
@@ -403,12 +421,17 @@
% the most important is called |\tolerance|: this controls the
% allowed `looseness' (i.e.\ the amount of blank space between words).
% Its default value is 200 (the \LaTeX{} |\fussy|) which is too
-% small for narrow columns. On the other hand the |\sloppy|
-% declaration (which sets |\tolerance| to $10000=\infty$) is too
-% large, allowing really bad spacing.\footnote{Look at the next
-% paragraph, it was set with the \cs{sloppy} declaration.}
-%
-% \begin{sloppypar}
+% small for narrow columns.
+
+% Setting it to \texttt{10000} (a.k.a.\ $\infty$) means arbitrary bad
+% lines are possible. With that setting \LaTeX{} will make most lines
+% perfect but intermix them with really bad lines. This was the
+% setting originally used by \cs{sloppy} (nowadays it is a bit more
+% cautious and used \texttt{9999} which makes a huge
+% difference).\footnote{Look at the next paragraph, it was set with
+% the \cs{tolerance}\texttt{=10000}.}
+%
+% \begin{sloppypar}\tolerance=10000
% \DescribeMacro\multicoltolerance \DescribeMacro\multicolpretolerance
% We therefore use a |\multicoltolerance| parameter for the
% |\tolerance| value inside the \mc{} environment. Its default value
@@ -417,10 +440,10 @@
% be done outside the \mc{} environment. Since |\tolerance| is set
% to |\multicoltolerance| at the beginning of every \textsf{multicols}
% environment one can locally overwrite this default by assigning
-% \verb*+\tolerance = +\meta{desired value}. There also exists a
+% \cs{tolerance}\texttt{=}\meta{desired value}. There also exists a
% |\multicolpretolerance| parameter holding the value for
% |\pretolerance| within a \mc{} environment. Both parameters are
-% usually used only by package designers.
+% usually used only by package or class designers.
% \end{sloppypar}
%
% Generation of multicolumn output can be divided into two parts. In
@@ -679,7 +702,7 @@
% this value will additionally trace the mark handling
% algorithm. It will show what marks are found, what marks are
% considered, etc. To fully understand this information you will
-% probably have to read carefully trough the implementation.
+% probably have to read carefully through the implementation.
% \item[$\meta{number}\geq 4$.] Setting \meta{number}\pagebreak[2] to
% such a high value will additionally place an |\hrule| into your
% output, separating the part of text which had already been
@@ -741,15 +764,7 @@
% |\mult@firstbox|, the next
% in register |\mult@firstbox|${}+2$, \ldots,
% only the last one as an exception in
-% register |\mult@grightbox|. Furthermore it has to set up
-% the two macros
-% |\kept@firstmark| and |\kept@botmark| to hold the values for the
-% first and bottom mark as found in the individual columns. There
-% are some helper functions defined in section \ref{sec:v14} which
-% may be used for this. Getting the marks right ``by hand'' is
-% non-trivial and it may pay off to first take a look at the
-% documentation and implementation of |\balance@columns| below
-% before trying anew.
+% register |\mult@grightbox|.
% \end{multicols}
% \end{quote}
% \vspace*{-3ex}
@@ -922,7 +937,7 @@
%
% The following redefinitions have to be moved until after the
% preamble because version 3 of \pkg{doc} resets them after the
-% premable (this is tmp, because \pkg{hypdoc} is not yet
+% preamble (this is tmp, because \pkg{hypdoc} is not yet
% integrated, but as we all know, tmp solutions have a tendency to
% survive for a long time\ldots).
% \begin{macrocode}
@@ -971,6 +986,7 @@
% v... multicolumn formatting]
% \end{macrocode}
%
+%
%^^A \subsection{Option processing}
%
% Next we declare options supported by \mc{}. Two-column mode
@@ -993,10 +1009,18 @@
{\c@tracingmulticols\@ne}
\DeclareOption{balancingshow}
{\c@tracingmulticols\tw@}
+% \end{macrocode}
+%
+% \changes{v2.0a}{2024/11/10}{Add \cs{DebugMarksOn} to the show options}
+% \begin{macrocode}
\DeclareOption{markshow}
- {\c@tracingmulticols\thr@@}
+ {\c@tracingmulticols\thr@@
+ \DebugMarksOn
+ }
\DeclareOption{debugshow}
- {\c@tracingmulticols5\relax}
+ {\c@tracingmulticols5\relax
+ \DebugMarksOn
+ }
% \end{macrocode}
% The next option is intended for typesetting on a |\baselineskip|
% grid. Right now it doesn't do anything other than warning if it
@@ -1037,6 +1061,9 @@
% \begin{multicols}{2}[\subsection{Starting and
% Ending the \mc{} Environment}]
%
+%
+%
+%
% \begin{macro}{\multicols}
% As mentioned before, the \mc{} environment has one mandatory
% argument (the number of columns) and up to two optional ones. We
@@ -1384,13 +1411,13 @@
\multiply\doublecol@number\tw@
\advance\doublecol@number\mult@rightbox
% \end{macrocode}
+%
+% \begin{macrocode}
+ \mc@prepare@mark@regions
+% \end{macrocode}
%
% \begin{macrocode}
\if@boxedmulticols
- \let\l@kept@firstmark\kept@firstmark
- \let\l@kept@botmark\kept@botmark
- \global\let\kept@firstmark\@empty
- \global\let\kept@botmark\@empty
\else
% \end{macrocode}
% We add an empty box to the main vertical list to ensure that we
@@ -1451,30 +1478,7 @@
\unvbox\@cclv
\global\setbox\last@line\lastbox
}%
-% \end{macrocode}
-% Finally we need to record the marks that are present within the
-% |\partial@page| so that we can construct correct first and bottom
-% marks later on. This is done by the following code.
-% \changes{v1.4a}{1992/02/14}{kept marks initiated}
-% \begin{macrocode}
- \prep@keptmarks
-% \end{macrocode}
-% Finally we have to initialize |\kept@topmark| which should
-% ideally be initialized with the mark that is current on ``top''
-% of this page. Unfortunately we can't use |\topmark| because this
-% register will not always contain what its name promises because
-% \LaTeX{} sometimes calls the output routine for float
-% management.\footnote{During such a call the \cs{botmark}
-% gets globally copied to \cs{topmark} by the \TeX{}
-% program.} Therefore we use the second best solution by
-% initializing it with |\firstmark|. In fact, for our purpose this
-% doesn't matter as we use |\kept@topmark| only to initialize
-% |\firstmark| and |\botmark| of a following page if we don't find
-% any marks on the current one.
-% \changes{v1.4i}{1992/06/18}{\cs{kept@topmark} initialized.}
-% \begin{macrocode}
- \global\let\kept@topmark\firstmark
- }\eject
+ }\eject
% \end{macrocode}
% The next thing to do is to assign a new value to |\vsize|.
% \LaTeX{} maintains the free room on the page (i.e.\ the page
@@ -1765,14 +1769,7 @@
\balance@columns
% \end{macrocode}
% After balancing the result has to be returned by the command
-% |\page@sofar|. But before we do this we reinsert any marks found
-% in box |\mult@box|.
-% \begin{macrocode}
- \return@nonemptymark{first}%
- \kept@firstmark
- \return@nonemptymark{bot}%
- \kept@botmark
-% \end{macrocode}
+% |\page@sofar|.
% When the boxed multicol is returned to the page it can happen
% that it doesn't fit onto it and \LaTeX{} therefore breaks
% earlier. The problem in that case is that during the generation
@@ -1783,23 +1780,18 @@
% until we have left the group below.
% \changes{v1.9e}{2023/02/25}{Delay returning boxed multicols (gh/1002)}
% \begin{macrocode}
- \global\setbox\mc@boxedresult\vbox{%
- \page@sofar
+ \global\setbox\mc@boxedresult\vbox{%
% \end{macrocode}
-%
+% We first update the mark structures and collect all marks that
+% need reinsertion once \mc{} has finished. Then we output the boxed
+% columns and finally we reinsert the marks.
+% \changes{v2.0a}{2024/11/10}{Use new mark mechanism}
% \begin{macrocode}
- \global\let\kept@firstmark
- \l@kept@firstmark
- \global\let\kept@botmark
- \l@kept@botmark
+ \mc@handle@marks@and@reinserts
+ {in multicol (boxed mode)}%
+ \page@sofar
+ \mc@reinsert@marks
}%
-%<*marktrace>
- \mult@info\tw@
- {Restore kept marks to\MessageBreak
- first: \meaning\kept@firstmark
- \MessageBreak bot\space\space:
- \meaning\kept@botmark }%
-%</marktrace>
% \end{macrocode}
% This finishes the code for the ``boxed'' case.
% \begin{macrocode}
@@ -1864,17 +1856,7 @@
% \begin{macrocode}
\ifvbox\partial@page
\unvbox\partial@page\fi
-% \end{macrocode}
-% After the output routine has acted we restore
-% the kept marks to their initial value.
-% \begin{macrocode}
- \global\let\kept@firstmark\@empty
- \global\let\kept@botmark\@empty
-%<*marktrace>
- \mult@info\tw@
- {Make kept marks empty}%
-%</marktrace>
- \fi
+ \fi
% \end{macrocode}
% The output routine above will take care of the |\vsize| and
% reinsert the balanced columns, etc. But it can't reinsert the
@@ -1945,7 +1927,7 @@
% the balancing happened in the output routine then \TeX{} reverts
% to the |\prevdepth| that was current before the OR once the OR has
% finished. In short |\prevdepth| is something you can't set
-% globally it is alway local to the current list being built. Thus
+% globally it is always local to the current list being built. Thus
% we need to set it back to zero here to avoid incorrect spacing.
% \changes{v1.8h}{2014/09/12}{Set \cs{prevdepdth} for current vlist
% when returning from multicols environment}
@@ -2115,6 +2097,8 @@
% \begin{macrocode}
\ifvmode\else\errmessage{Multicol Error}\fi
% \end{macrocode}
+%
+%
% Now we put all columns together in an |\hbox| of width
% |\full@width| (shifting it by |\multicol@leftmargin| to the right
% so that it will be placed correctly if we are within a list
@@ -2152,6 +2136,14 @@
% \changes{v1.9f}{2023/03/30}{Make column min depth customizable (gh/698)}
% \begin{macrocode}
\setbox\z@\hbox{\multicolmindepthstring}\global\dimen\tw@\dp\z@
+% \end{macrocode}
+%
+% \changes{v2.0a}{2024/11/12}{Addedd tagging socket}
+% \begin{macrocode}
+ \UseTaggingSocket{page@sofar}%
+% \end{macrocode}
+%
+% \begin{macrocode}
\moveright\multicol@leftmargin
\hbox to\full@width{%
% \end{macrocode}
@@ -2216,7 +2208,7 @@
% \begin{macro}{\multicolmindepthstring}
% The default minimum depth of each column corresponds to the depth
% of a `p' in the current font. This makes sense for Latin-based
-% languages and was hard-wired intitially, but for Asian languages
+% languages and was hard-wired initially, but for Asian languages
% it is better to use a zero depth (and alternatively one might
% want to use the depth of a strut or a parentheses). So we now
% offer a way to adjust this while maintaining backward
@@ -2381,10 +2373,6 @@
\setbox\count@
\vsplit\@cclv to\dimen@
% \end{macrocode}
-% After splitting we update the kept marks.
-% \begin{macrocode}
- \set@keptmarks
-% \end{macrocode}
% If |\raggedcolumns| is in force we add a |vfill| at the bottom by
% unboxing the split box.
% But we need to unbox anyway to ensure that at the end of the box
@@ -2401,12 +2389,12 @@
% \changes{v1.8h}{2014/09/12}{Use \cs{vfilmaxdepth}}
% \changes{v1.8k}{2015/03/22}{\cs{remove@discardable@items} removed}
% \begin{macrocode}
- \setbox\count@
- \vbox to\dimen@
- {\unvbox\count@
- \ifshr@nking
- \vfilmaxdepth\fi}%
- }%
+ \setbox\count@
+ \vbox to\dimen@
+ {\unvbox\count@
+ \ifshr@nking
+ \vfilmaxdepth\fi}%
+ }%
% \end{macrocode}
% Then the last column follows.
% \changes{v1.5a}{1992/11/04}{New box mechanism}
@@ -2417,7 +2405,6 @@
% \begin{macrocode}
\setbox\mult@rightbox
\vsplit\@cclv to\dimen@
- \set@keptmarks
\setbox\mult@rightbox\vbox to\dimen@
{\unvbox\mult@rightbox
\ifshr@nking\vfilmaxdepth\fi}%
@@ -2450,6 +2437,7 @@
\thepage\space might be wrong}%
\fi
% \end{macrocode}
+%
% If the `\textsf{tracingmulticols}' counter is 4 or higher we also
% add a rule.
% \begin{macrocode}
@@ -2457,48 +2445,6 @@
\hrule\allowbreak \fi
\fi
% \end{macrocode}
-% To get a correct marks for the current page we have to (locally)
-% redefine |\firstmark| and |\botmark|.
-% If |\kept@firstmark| is non-empty then |\kept@botmark| must be
-% non-empty too so we can use their values. Otherwise we use the
-% value of |\kept@topmark| which was first initialized when we
-% gathered the |\partical@page| and later on was updated to the
-% |\botmark| for the preceding page.
-%
-% \changes{v1.4a}{1992/02/14}{\cs{botmark} set to \cs{splitbotmark}}
-% \begin{macrocode}
- \ifx\@empty\kept@firstmark
- \let\firstmark\kept@topmark
- \let\botmark\kept@topmark
- \else
- \let\firstmark\kept@firstmark
- \let\botmark\kept@botmark
- \fi
-% \end{macrocode}
-% We also initialize |\topmark| with |\kept@topmark|. This will make
-% this mark okay for all middle pages of the \mc{} environment.
-% \changes{v1.5d}{1993/09/15}{reinit \cs{topmark}}
-% \begin{macrocode}
- \let\topmark\kept@topmark
-%<*marktrace>
- \mult@info\tw@
- {Use kept top mark:\MessageBreak
- \meaning\kept@topmark
- \MessageBreak
- Use kept first mark:\MessageBreak
- \meaning\kept@firstmark
- \MessageBreak
- Use kept bot mark:\MessageBreak
- \meaning\kept@botmark
- \MessageBreak
- Produce first mark:\MessageBreak
- \meaning\firstmark
- \MessageBreak
- Produce bot mark:\MessageBreak
- \meaning\botmark
- \@gobbletwo}%
-%</marktrace>
-% \end{macrocode}
% With a little more effort we could have done better. If we had,
% for example, recorded the shrinkage of the material in
% |\partial@page| it would be now possible to try higher
@@ -2519,8 +2465,18 @@
% \changes{v1.8p}{2016/04/07}{Reset \cs{boxmaxdepth}}
% \begin{macrocode}
\boxmaxdepth\maxdimen
- \setbox\@cclv\vbox{\unvbox\partial@page
- \page@sofar}%
+ \setbox\@cclv\vbox
+ {%
+% \end{macrocode}
+% If we make a page while still inside the \mc{} environment we
+% have to handle column and page mark structures.
+% \changes{v2.0a}{2024/11/10}{Use new mark mechanism}
+% \begin{macrocode}
+ \mc@handle@col@andpage@marks
+ {in multicol OR (full page)}%
+ \unvbox\partial@page
+ \page@sofar
+ }%
% \end{macrocode}
% The macro |\@makecol| adds all floats assigned for the current
% page to this page. |\@outputpage| ships out the resulting box.
@@ -2529,24 +2485,6 @@
% \begin{macrocode}
\@makecol\@outputpage
% \end{macrocode}
-% After the page is shipped out we have to prepare the kept marks
-% for the following page. |\kept@firstmark| and |\kept@botmark|
-% reinitialized by setting them to |\@empty|. The value of
-% |\botmark| is then assigned to |\kept@topmark|.
-% \changes{v1.4g}{1992/06/03}{Only change \cs{kept@topmark} if
-% \cs{kept@botmark} non-empty}
-% \changes{v1.4i}{1992/06/18}{Set \cs{kept@topmark} to \cs{botmark}}
-% \begin{macrocode}
- \global\let\kept@topmark\botmark
- \global\let\kept@firstmark\@empty
- \global\let\kept@botmark\@empty
-%<*marktrace>
- \mult@info\tw@
- {(Re)Init top mark:\MessageBreak
- \meaning\kept@topmark
- \@gobbletwo}%
-%</marktrace>
-% \end{macrocode}
% Now we reset |\@colroom| to |\@colht| which is \LaTeX's
% saved value of |\textheight|.
% We also have to reset the recorded position of the last
@@ -2905,13 +2843,18 @@
% \begin{macrocode}
\unvbox\partial@page
% \end{macrocode}
-% Then we return the first and bottom mark and the gathered
-% material to the main vertical list.
-% \begin{macrocode}
- \return@nonemptymark{first}%
- \kept@firstmark
- \return@nonemptymark{bot}\kept@botmark
+% We then handle mark structures of the columns, return the gathered
+% material to the main vertical list and then also reinsert the
+% first and last marks that have been found in the columns.
+% \changes{v2.0a}{2024/11/10}{Use new mark mechanism}
+ % \begin{macrocode}
+ \mc@handle@marks@and@reinserts
+ {in multicol OR (balancing)}%
\page@sofar
+ \mc@reinsert@marks
+% \end{macrocode}
+%
+% \begin{macrocode}
% \end{macrocode}
% We need to add a penalty at this point which allows to break at
% this point since calling the output routine may have removed the
@@ -2934,21 +2877,7 @@
% \begin{macrocode}
\def\balance@columns{%
% \end{macrocode}
-% We start by setting the kept marks by updating them with any
-% marks from this box. This has to be done \emph{before} we add a
-% penalty of $-10000$ to the top of the box, otherwise only an
-% empty box will be considered. But even that is not enough: the box
-% may contain \cs{columnbreak}s in which case doing some artifical
-% splitting to get the marks out still fails to see all marks
-% unless we take some special precaution in \cs{get@keptmarks}
-% (which is now done).
-% \changes{v1.5h}{1994/08/26}{Get kept marks first}
-% \begin{macrocode}
- \get@keptmarks\mult@box
-% \end{macrocode}
-% We then continue by resetting trying to remove any discardable
-% stuff at the end of |\mult@box|. This is rather experimental. We
-% also add a forced break point at the very beginning, so that we
+% We start by adding a forced break point at the very beginning, so that we
% can split the box to height zero later on, thereby adding a known
% |\splittopskip| glue at the beginning.
% \changes{v1.8k}{2015/03/21}{\cs{remove@discardable@items} removed}
@@ -3625,12 +3554,15 @@
% \changes{v1.6g}{2006/02/23}{Added \cs{@minipagefalse}}
% \changes{v1.6h}{2008/12/05}{Use \cs{@endfloatbox} to better support
% the modifications done by the float package}
+% \changes{v1.9i}{2024/09/14}{Added tagging support}
% Even if this should be used as a hook we use a |@| in the
% name since it is more for experts.
+% For now we test if the socket is already defined
% \begin{macrocode}
\def\set@floatcmds{%
\let\@dblfloat\@dbflt
\def\end@dblfloat{\@endfloatbox
+ \UseTaggingSocket{float/end}%
\@largefloatcheck
\outer@nobreak
% \end{macrocode}
@@ -3652,243 +3584,11 @@
\fi
\ifnum\@floatpenalty=-\@Mii
\@Esphack
+ \UseTaggingSocket{float/hmode/end}%
\fi}}
% \end{macrocode}
% \end{macro}
%
-% \end{multicols}
-%
-% \begin{multicols}{2}[\subsection{Maintaining the mark registers}]
-% \label{sec:v14}
-%
-% This section contains the routines that set the marks so that they
-% will be handled correctly. They have been introduced with version~1.4.
-%
-% \begin{macro}{\kept@topmark}
-% \changes{v1.4h}{1992/06/04}{Init to double brace pair}
-% \begin{macro}{\kept@firstmark}
-% \begin{macro}{\kept@botmark}
-% First thing we do is to reserve three macro names to hold the
-% replacement text for \TeX's primitives |\firstmark|, |\botmark| and
-% |\topmark|. We initialize the first two to be empty and
-% |\kept@topmark| to contain two empty pair of braces. This is
-% necessary since |\kept@topmark| is supposed to contain the last
-% mark from a preceding page and in \LaTeX{} any ``real'' mark must
-% contain two parts representing left and right mark information.
-% \begin{macrocode}
-\def\kept@topmark{{}{}}
-\let\kept@firstmark\@empty
-\let\kept@botmark\@empty
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-% \begin{macro}{\return@nonemptymark}
-% Sometimes we want to return the value of a ``kept'' mark into a
-% |\mark| node on the main vertical list. This is done by the
-% function |\return@nonemptymark|. As the name suggests it only acts
-% if the replacement text of the kept mark is non-empty. This is done
-% to avoid adding an empty mark when no mark was actually present. If
-% we would nevertheless add such a mark it would be regarded as a
-% valid |\firstmark| later on.
-% \begin{macrocode}
-\def\return@nonemptymark#1#2{%
- \ifx#2\@empty
- \else
-% \end{macrocode}
-% For debugging purposes we take a look at the value of the kept mark
-% that we are about to return. This code will get stripped out for
-% production.
-% \begin{macrocode}
-%<*marktrace>
- \mult@info\tw@
- {Returned #1 mark:\MessageBreak
- \meaning#2}%
-% \nobreak
-% \fi
-%</marktrace>
-% \end{macrocode}
-% Since the contents of the mark may be arbitrary \LaTeX{} code we
-% better make sure that it doesn't get expanded any further. (Some
-% expansion have been done already during the execution of
-% |\markright| or |\markboth|.) We therefore use the usual mechanism
-% of a toks register to prohibit expansion.\footnote{Due to the
-% current definition of \cs{markright} etc.\ it wouldn't
-% help to define the \cs{protect} command to prohibit
-% expansion as any \cs{protect} has already vanished due to
-% earlier expansions.}
-% \changes{v1.4n}{1992/09/10}{Make marks robust}
-% \changes{v1.5t}{1999/03/22}{re-add \cs{mark} command which was commented out
-% by mistake at some point in 1998 (pr/2978)}
-% \begin{macrocode}
- \toks@\expandafter{#2}%
- \mark{\the\toks@}%
-% \end{macrocode}
-% We don't want any breakpoint between such a returned mark and the
-% following material (which is usually just the box where the mark
-% came from).
-% \begin{macrocode}
- \nobreak
- \fi}
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{\get@keptmarks}
-% If we have some material in a box register we may want to get the
-% first and the last mark out of this box. This can be done with
-% |\get@keptmarks| which takes one argument: the box register number
-% or its nick name defined by |\newbox|.
-% \begin{macrocode}
-\def\get@keptmarks#1{%
-% \end{macrocode}
-% For debugging purposes we take a look at the current dimensions
-% of the box since in earlier versions of the code I made some
-% mistakes in this area.
-% \begin{macrocode}
-%<*debug>
- \typeout{Mark box #1 before:
- ht \the\ht#1, dp \the\dp#1}%
-%</debug>
-% \end{macrocode}
-% Now we open a new group and locally copy the box to itself. As a
-% result any operation, i.e.\ |\vsplit|, will only have a local
-% effect. Without this trick the box content would get lost up to
-% the level where the last assignment to the box register was done.
-% \begin{macrocode}
- \begingroup
- \vbadness\@M
- \setbox#1\copy#1%
-% \end{macrocode}
-% Now we split the box to the maximal possible dimension. This
-% should split off the full contents of the box so that effectively
-% everything is split off. As a result |\splitfirstmark| and
-% |\splitbotmark| will contain the first and last mark in the box
-% respectively.
-%
-% Unfortunately, a simple \cs{vsplit} is not enough if the material
-% contains forced breaks in that case we first have to get rid of
-% those which is why we do this work in a separate macro that can
-% call itself recursively.
-% \changes{v1.9g}{2023/11/10}{Get rid of forced breaks for mark
-% extraction (gh/1130)}
-% \begin{macrocode}
- \mc@get@all@box@marks #1%
-% \end{macrocode}
-% Therefore we can now set the kept marks which is a global
-% operation and afterwards close the group. This will restore the
-% original box contents.
-% \begin{macrocode}
- \set@keptmarks
- \endgroup
-% \end{macrocode}
-% For debugging we take again a look at the box dimension which
-% shouldn't have changed.
-% \begin{macrocode}
-%<*debug>
- \typeout{Mark box #1 \space after:
- ht \the\ht#1, dp \the\dp#1}%
-%</debug>
-}
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{\mc@get@all@box@marks}
-% This macro splits a box to \cs{maxdimen} in order to get at the
-% marks inside. If it turns out that we have a remainder after the
-% split (e.g., if there was a \cs{columnbreak} in the material) we
-% stitch the two parts together again (which omits the forced
-% break) and recurse. Eventually, everything is split off and the
-% split marks will then have the appropriate values.
-% \changes{v1.9g}{2023/11/10}{Get rid of forced breaks for mark
-% extraction (gh/1130)}
-% \begin{macrocode}
-\def\mc@get@all@box@marks #1{%
- \setbox\@tempboxa\vsplit#1to\maxdimen
- \ifvoid#1\else
- \setbox#1\vbox{\unvbox\@tempboxa \unvbox#1}%
- \mc@get@all@box@marks #1%
- \fi
-}
-% \end{macrocode}
-% \end{macro}
-%
-%
-%
-%
-% \begin{macro}{\set@keptmarks}
-% The macro |\set@keptmarks| is responsible for setting
-% |\kept@firstmark| and |\kept@botmark|, by checking the current
-% values for |\splitfirstmark| and |\splitbotmark|.
-% \begin{macrocode}
-\def\set@keptmarks{%
-% \end{macrocode}
-% If |\kept@firstmark| is empty we assume that it isn't set. This
-% is strictly speaking not correct as we loose the ability to have
-% marks that are explicitly empty, but for standard \LaTeX{}
-% application it is sufficient. If it is non-empty we don't change
-% the value---within the output routines it will then be restored
-% to |\@empty|.
-% \begin{macrocode}
- \ifx\kept@firstmark\@empty
-% \end{macrocode}
-% We now put the contents of |\splitfirstmark| into
-% |\kept@firstmark|. In the case that there wasn't any mark at all
-% |\kept@firstmark| will not change by that operation.
-% \begin{macrocode}
- \expandafter\gdef\expandafter
- \kept@firstmark
- \expandafter{\splitfirstmark}%
-% \end{macrocode}
-% When debugging we show the assignment but only when something
-% actually happened.
-% \begin{macrocode}
-%<*marktrace>
- \ifx\kept@firstmark\@empty\else
- \mult@info\tw@
- {Set kept first mark:\MessageBreak
- \meaning\kept@firstmark%
- \@gobbletwo}%
- \fi
-%</marktrace>
- \fi
-% \end{macrocode}
-% We always try to set the bottom mark to the |\splitbotmark| but
-% of course only when there has been a |\splitbotmark| at all.
-% Again, we assume that an empty |\splitbotmark| means that the
-% split off box part didn't contain any marks at all.
-% \begin{macrocode}
- \expandafter\def\expandafter\@tempa
- \expandafter{\splitbotmark}%
- \ifx\@tempa\@empty\else
- \global\let\kept@botmark\@tempa
-%<*marktrace>
- \mult@info\tw@
- {Set kept bot mark:\MessageBreak
- \meaning\kept@botmark%
- \@gobbletwo}%
-%</marktrace>
- \fi}%
-% \end{macrocode}
-% \end{macro}
-%
-%
-% \begin{macro}{\prep@keptmarks}
-% The |\prep@keptmarks| function is used to initialize the kept
-% marks from the contents of |\partial@page|, i.e.\ the box that
-% holds everything from the top of the current page prior to
-% starting the \mc{} environment. However, such a box is only
-% available if we are not producing a boxed \mc{}.
-% \begin{macrocode}
-\def\prep@keptmarks{%
- \if@boxedmulticols \else
- \get@keptmarks\partial@page
- \fi}
-% \end{macrocode}
-% \end{macro}
%
%
% \begin{macro}{\remove@discardable@items}
@@ -4053,9 +3753,9 @@
% \end{multicols}
%
%
-% \begin{multicols*}{2}[\section{Further extensions}]
+% \section{Further extensions}
%
-% This section does contain code for extensions added to this package
+% This section contains code for extensions added to this package
% over time. Not all of them may be active, some might sit dormant and
% wait for being activated in some later release.
%
@@ -4205,8 +3905,8 @@
\else
% \end{macrocode}
% Increasingly lower penalty based on argument value. This is like
-% \cs{pagebreak} but we use other penalty values are the \LaTeX{}
-% defaults aree rather pointless for pagination.
+% \cs{pagebreak} but we use other penalty values as the \LaTeX{}
+% defaults are rather useless for pagination.
% \begin{macrocode}
\edef\mc@break@pen
{-\ifcase#1\@m\or 3333\or 6666\or 9999\else\@Mv\fi\relax}%
@@ -4454,7 +4154,9 @@
%
% The \verb=\docolaction= scans for a star and optional argument
% and 3 mandatory ones, but we do this in chunks (not having xparse
-% available).
+% available).\footnote{We can do better now, as
+% \cs{NewDocumentCommand} is part of the kernel. So this should be
+% cleaned up one day.}
%
% \changes{v1.8u}{2018/11/09}{Support star with \cs{docolaction}}
% \begin{macrocode}
@@ -4625,7 +4327,349 @@
\mc@firstcoltrue
% \end{macrocode}
% \end{macro}
-% \end{multicols*}
+%
+%
+%
+%
+% \subsection{Using the new mark mechanism}
+%
+% \subsubsection{Helpers}
+%
+% \changes{v2.0a}{2024/11/10}{Using the new mark mechanism}
+% \begin{macrocode}
+\ExplSyntaxOn
+%<@@=mc>
+% \end{macrocode}
+%
+%
+%
+% \begin{macro}{\g_@@_curr_col_int}
+% Counter for tracking the current column number. At the start of a
+% \mc{} environment is holds the number of columns for
+% which there is currently \texttt{mcol-...} data (i.e., the number
+% of columns in the last \mc{} environment).
+% \begin{macrocode}
+\int_new:N \g_@@_curr_col_int
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\@@_debug_marks:n}
+% For now we reuse the internal debugging interface of ltmarks,
+% this will probably change
+% \begin{macrocode}
+\cs_new:Npn \@@_debug_marks:n #1 { \__mark_debug:n {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_update_mcol_structures:}
+%
+% Helper function to update the \texttt{mcol-...} regions when we
+% finish a page while within a \mc{} environment or when we finish
+% the \mc{} and return the balanced columns back to the galley.
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_update_mcol_structures: {
+ \@@_debug_marks:n
+ { \typeout{Marks:~ update~ mcol~ structures~ (multicol)} }
+% \end{macrocode}
+% It might be possible that there was a previous \mc{} (either
+% before the current one, or a boxed one inside) and that one might
+% have had more columns than the current one. If so, we should make these
+% column structures an error as they are no longer valid (or at
+% least empty them, not sure what is better).
+% \begin{macrocode}
+ \int_step_inline:nnn {\col@number + 1} { \g_@@_curr_col_int }
+ { \mark_set_structure_to_err:n { mcol - ##1 } }
+% \end{macrocode}
+%
+% There is no need to do anything to \texttt{mcol-1} up to
+% \texttt{mcol-\meta{\cs{col@number}}} because those regions get
+% new data in a second.
+%
+% Once we have done this we reset the column counter for further
+% processing.
+% \begin{macrocode}
+ \int_gset:Nn \g_@@_curr_col_int {1}
+% \end{macrocode}
+% Now we loop through all the assembled column material, using the
+% \texttt{column} and \texttt{previous-column} regions as an
+% intermediate holding area.
+% \begin{macrocode}
+ \process@cols\mult@firstbox
+ {
+ \mark_update_structure_from_material:nn
+%fmi {mcol}
+ {column}
+ {\unvcopy\count@}
+% \end{macrocode}
+% Once the \texttt{column} region got updated we copy it to
+% \texttt{mcol-\meta{\cs{\detokenize{g_@@_curr_col_int}}}} and then increment
+% the counter.
+% \begin{macrocode}
+ \mark_copy_structure:nn
+ {mcol - \int_use:N\g_@@_curr_col_int }
+%fmi {mcol}
+ {column}
+ \int_gincr:N \g_@@_curr_col_int
+ }
+% \end{macrocode}
+% The above loop takes care of all columns, except for the last one
+% (which is stored in \cs{mult@rightbox}. So we have to do that separately.
+% \begin{macrocode}
+ \mark_update_structure_from_material:nn
+%fmi {mcol}
+ {column}
+ {\unvcopy\mult@rightbox}
+ \mark_copy_structure:nn
+ { mcol - \int_use:N\g_@@_curr_col_int }
+%fmi {mcol}
+ {column}
+% \end{macrocode}
+% Two more aliases to take care of: \texttt{first-column} and
+% \texttt{last-column} and we are done:
+% \begin{macrocode}
+ \mark_copy_structure:nn{first-column}{mcol-1}
+%fmi \mark_copy_structure:nn{last-column} {mcol}
+ \mark_copy_structure:nn{last-column} {column}
+}
+% \end{macrocode}
+% \end{macro}
+%
+
+
+% \begin{macro}{\@@_update_page_structures:}
+% If we are making a page while inside a \mc{} environment, we also
+% have to take care of the page region.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_update_page_structures: {
+ \@@_debug_marks:n
+ {
+ \typeout{Marks:~ update~ page~ structure~ (multicol)}
+ }
+% \end{macrocode}
+% Since for the \texttt{page} region we are only interested in the
+% top, first, and last marks on the whole page regardless in which
+% column they appear, we simply string together all columns in a big
+% box and update the structure from that.
+% \begin{macrocode}
+ \mark_update_structure_from_material:nn
+ {page}
+ {
+% \end{macrocode}
+% And we better not forget the \cs{partial@page} in case this is
+% the first page of the \mc{} (on later pages this box will be void).
+% \begin{macrocode}
+ \unvcopy\partial@page
+ \process@cols \mult@firstbox { \unvcopy\count@ }
+ \unvcopy\mult@rightbox
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+
+% \begin{macro}{\@@_prepare_mark_reinserts:}
+%
+% When finishing a \mc{} environment, we have to return marks (in
+% then boxed columns) to the current page so that they are
+% available when that page is produced.
+% This is what this helper does.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_prepare_mark_reinserts: {
+ \@@_debug_marks:n
+ { \typeout{Marks:~ prepare~ for~ reinserting~ marks~ (multicol)} }
+% \end{macrocode}
+% We are only interested in the top, first, and last marks of each
+% class regardless in which column they appeared, so we can copy
+% all column boxes together and process them in one go. The result
+% is returned in \cs{\detokenize{l_@@_first_marks_tl}} and
+% \cs{\detokenize{l_@@_last_marks_tl}} in form of \cs{\detokenize{mark_insert:nn}} statements
+% so we can later execute such token lists directly (and if there
+% were no marks they will be empty).
+% \begin{macrocode}
+ \mark_get_marks_for_reinsertion:nNN
+ {
+ \process@cols \mult@firstbox { \unvcopy\count@ }
+ \unvcopy\mult@rightbox
+ }
+ \l_@@_first_marks_tl
+ \l_@@_last_marks_tl
+}
+% \end{macrocode}
+% And here are the token lists used above.
+% \begin{macrocode}
+\tl_new:N \l_@@_first_marks_tl
+\tl_new:N \l_@@_last_marks_tl
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\mc@reinsert@marks}
+% So reinserting it just means executing the token lists (with some
+% surrounding debugging statements).
+% \begin{macrocode}
+\cs_new_protected:Npn \mc@reinsert@marks{
+ \@@_debug_marks:n
+ { \typeout{Marks:~ --~ reinsert~ marks~ (multicol)} }
+ \l_@@_first_marks_tl \l_@@_last_marks_tl
+ \@@_debug_marks:n
+ { \typeout{Marks:~ --~ finished~ reinserting~ marks~ (multicol)} }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \subsubsection{Interfaces used in the \mc{} code and its output routines}
+%
+%
+% \begin{macro}{\mc@prepare@mark@regions}
+% When a \mc{} environment starts we need to clear the column
+% region as it it may contain quite old data. Otherwise, that data
+% would be used to generate the top marks and that would be
+% obviously wrong for the first column.
+% \begin{macrocode}
+\cs_new_protected:Npn \mc@prepare@mark@regions {
+% \end{macrocode}
+% However, before we do this we need to save away the current
+% column data in case this is a boxed multicol, because when that
+% finishes we need to restore the previous state --- this is not
+% necessary for a normal \mc{} environment, because there the
+% \texttt{column} region is overwritten in the standard output
+% routine by copying the \texttt{page} region.
+% \begin{macrocode}
+ \legacy_if:nT { @boxedmulticols }
+ { \mark_copy_structure:nn{saved-column}{column} }
+ \@@_debug_marks:n
+ { \typeout{Marks:~ empty~ mcol~ regions~ (multicol)} }
+ \mark_clear_structure:n {column}
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\mc@handle@marks@and@reinserts}
+%
+% If a \mc{} ends the columns are balanced and then returned to the
+% galley. in that situation we do have to prepare the
+% \texttt{mcol-...} regions and also do this reinsertion.
+% \begin{macrocode}
+\cs_new_protected:Npn \mc@handle@marks@and@reinserts #1 {
+ \@@_update_mcol_structures:
+% \end{macrocode}
+% Show the current region status when debugging:
+% \begin{macrocode}
+ \@@_debug_marks:n { \__mark_status:nn {#1} {\the\col@number} }
+% \end{macrocode}
+% Then prepare for reinserting the marks:
+% \begin{macrocode}
+ \@@_prepare_mark_reinserts:
+% \end{macrocode}
+% Finally, we restore the \texttt{column} region in case this was a
+% boxed \mc{} environment.
+% \begin{macrocode}
+ \legacy_if:nT { @boxedmulticols }
+ { \mark_copy_structure:nn {column}{saved-column} }
+}
+
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\mc@handle@col@andpage@marks}
+% If a page is generated while we are processing a \mc{} then we
+% have to update the \texttt{mcol-...} regions but also the
+% \texttt{page} region.
+% \begin{macrocode}
+\cs_new_protected:Npn \mc@handle@col@andpage@marks #1 {
+ \@@_update_mcol_structures:
+ \@@_update_page_structures:
+% \end{macrocode}
+% Once done we display the current status of the marks.
+% \begin{macrocode}
+ \@@_debug_marks:n { \__mark_status:nn {#1} {\the\col@number} }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\leftmark,\rightmark}
+% We change the legacy \cs{leftmark} and \cs{rightmark} to use
+% the new mark mechanism. For now we do this only if pkg{multicol}
+% is loaded, but eventually this will move to the kernel which then
+% also simplifies the definitions for \cs{markboth} and friends.
+%
+% These commands should be expandable, so no protection.
+% \changes{v2.0a}{2024/11/10}{Use the new mark mechanism}
+% \begin{macrocode}
+\cs_set:Npn \leftmark {\mark_use_last:nn{page}{2e-left}}
+\cs_set:Npn \rightmark {\mark_use_first:nn{page}{2e-right}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macrocode}
+%<@@=>
+% \end{macrocode}
+%
+%
+%
+%
+%
+%
+%
+% \subsection{Tagging support}
+%
+% Here we collect adjustments necessary for tagging support, e.g.,
+% before the 2024-11-01 release it was necessary to allocate two
+% float sockets. By now they are part of the kernel and their plugs
+% are currently defined by \pkg{tagpdf}.
+% \begin{macrocode}
+%\str_if_exist:cF { l__socket_tagsupport/float/end_plug_str }
+% {
+% \NewSocket{tagsupport/float/end}{0}
+% \NewSocket{tagsupport/float/hmode/end}{0}
+% }
+% \end{macrocode}
+%
+% This one is only relevant for \pkg{multicol} so declared here.
+% \begin{macrocode}
+\NewSocket{tagsupport/page@sofar}{0}
+% \end{macrocode}
+%
+% The plug definition for now just uses the definition from
+% \pkg{tagpdf}. There has to be a decision where such plugs should be
+% implemented: in the package (like now) then they functions used
+% from tagpdf should become public, in \pkg{tagpdf}, or in
+% \texttt{lttagging} in the kernel.
+% \changes{v2.0a}{2024/11/12}{Added tagging socket and use public tagpdf function}
+% \begin{macrocode}
+\NewSocketPlug {tagsupport/page@sofar}{default}
+ {
+% \__tag_check_typeout_v:n {====>~In~\string\page@sofar} % some similar debug message if wanted.
+ \process@cols\mult@firstbox
+ { \tag_mc_add_missing_to_stream:Nn \count@ {multicol} }
+ \tag_mc_add_missing_to_stream:Nn \mult@rightbox {multicol}
+ }
+% \end{macrocode}
+% In the \LuaTeX{} engine there is no need to do anything special
+% in this socket.
+% \begin{macrocode}
+\sys_if_engine_luatex:TF
+ { \AssignSocketPlug{tagsupport/page@sofar}{noop} }
+ { \AssignSocketPlug{tagsupport/page@sofar}{default} }
+% \end{macrocode}
+%
+%
+%
+% \begin{macrocode}
+\ExplSyntaxOff
+% \end{macrocode}
+%
+%
%
% \Finale
%
diff --git a/macros/latex-dev/required/tools/multicol.pdf b/macros/latex-dev/required/tools/multicol.pdf
index 88f6d24fb9..b09f273392 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 4b70b5fb34..3d82908721 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 4a7b48325a..c73e961c9b 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 bc179092e4..ba09032c48 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 350af16103..07de70ad9e 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 3a9261846c..90a225fbc0 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.dtx b/macros/latex-dev/required/tools/theorem.dtx
index a9c3ccae3e..3fbba473ba 100644
--- a/macros/latex-dev/required/tools/theorem.dtx
+++ b/macros/latex-dev/required/tools/theorem.dtx
@@ -24,7 +24,7 @@
%%
%
%
-\def\FMithmInfo{2023/07/05 v2.2c Theorem extension package (FMi)}
+\def\FMithmInfo{2024/08/06 v2.2c Theorem extension package (FMi)}
%
% \ProvidesFile{theorem.dtx}[\FMithmInfo]
%\iffalse % this is a METACOMMENT !
@@ -952,7 +952,6 @@
%
% \subsubsection{The \texttt{changebreak} style}
%
-% \begin{macrocode}
% This style option is stored in the file |thcb.sty|.
% \begin{macrocode}
%<*thcb>
diff --git a/macros/latex-dev/required/tools/theorem.pdf b/macros/latex-dev/required/tools/theorem.pdf
index ef3fde6039..2604f7594f 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 fc09cbdfb7..99cbeb5666 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/tools-overview.tex b/macros/latex-dev/required/tools/tools-overview.tex
index 54f4b5ed63..3d45a5e2fc 100644
--- a/macros/latex-dev/required/tools/tools-overview.tex
+++ b/macros/latex-dev/required/tools/tools-overview.tex
@@ -132,7 +132,7 @@
Access bold math symbols.
}%
\entry{calc}{%
- Infix arithmetic expresions. Contributed to the distribution by
+ Infix arithmetic expressions. Contributed to the distribution by
Kresten Krab Thorup and Frank Jensen.
}%
\entry{dcolumn}{%
@@ -149,7 +149,7 @@
missing file error loop.
}%
\entry{fontsmpl}{%
- Package and test file for producing \emph{font samples}
+ Package and test file for producing \emph{font samples}.
}%
\entry{ftnright}{%
Place footnotes in the right hand column in two-column mode.
@@ -173,7 +173,7 @@
}%
\entry{rawfonts}{%
Preload fonts under the old internal font names of \LaTeX{}2.09.
- Not recomended for new packages, but may help when updating old
+ Not recommended for new packages, but may help when updating old
files.
}%
\entry{shellesc}{%
@@ -206,7 +206,7 @@
Flexible version of verbatim environment.
}%
\entry{xr}{%
- eXternall References. Extend \cs{ref} to access \cs{label} commands in
+ eXternal References. Extend \cs{ref} to access \cs{label} commands in
other documents.
}%
\entry{xspace}{%
diff --git a/macros/latex-dev/required/tools/tools.ins b/macros/latex-dev/required/tools/tools.ins
index 8687d49d7f..776215ff2e 100644
--- a/macros/latex-dev/required/tools/tools.ins
+++ b/macros/latex-dev/required/tools/tools.ins
@@ -195,6 +195,8 @@ given in the file `manifest.txt'.
\file{r.tex}{\from{fileerr.dtx}{run}}
\file{x.tex}{\from{fileerr.dtx}{exit}}}
+\generate{\file{rename-to-empty-base.tex}{\from{fileerr.dtx}{return}}}
+
\Msg{***********************************************************}
\Msg{*}
@@ -202,8 +204,9 @@ given in the file `manifest.txt'.
\Msg{* files into a directory searched by TeX:}
\Msg{*}
\Msg{* All the files with extension `.sty' and `.tex'}
-\Msg{* Note there also may be a file .tex which is `invisible'}
-\Msg{* on some operating systems.}
+\Msg{* TeX may be blocked from writing a file called `.tex',}
+\Msg{* so generated a file with name `rename-to-empty-base.tex'.}
+\Msg{* Rename that file to `.tex' after the docstrip generation.}
\Msg{*}
\Msg{* To produce the documentation run the .dtx files through LaTeX.}
\Msg{*}
@@ -211,14 +214,4 @@ given in the file `manifest.txt'.
\Msg{***********************************************************}
-\Msg{}
-\Msg{* Finally trying to make a file `.tex'.}
-\Msg{* (Placed at the end of this run, as this}
-\Msg{* may fail on some operating systems.)}
-
-\let\oldopenout\openout
-\def\openout{\batchmode\immediate\oldopenout}
-
-\generate{\file{.tex}{\from{fileerr.dtx}{return}}}
-
\endbatchfile
diff --git a/macros/latex-dev/required/tools/trace.pdf b/macros/latex-dev/required/tools/trace.pdf
index 986e0b9765..0f912fc59c 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 3888f90501..bccf589169 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 6158390d2b..dc355d0ed3 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 1c051e4a12..378c304dcc 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 cacc2639aa..28465fbc4f 100644
--- a/macros/latex-dev/required/tools/xspace.pdf
+++ b/macros/latex-dev/required/tools/xspace.pdf
Binary files differ