From 779e1e8aae671dfb73e0c5a19791be243af01cbe Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Sat, 10 Jun 2023 03:04:15 +0000 Subject: CTAN sync 202306100304 --- macros/latex/base/README.md | 2 +- macros/latex/base/alltt.dtx | 2 +- macros/latex/base/alltt.ins | 4 +- macros/latex/base/alltt.pdf | Bin 223831 -> 223828 bytes macros/latex/base/cfgguide.pdf | Bin 264112 -> 264157 bytes macros/latex/base/cfgguide.tex | 4 +- macros/latex/base/changes.txt | 227 ++- macros/latex/base/classes.dtx | 11 +- macros/latex/base/classes.ins | 4 +- macros/latex/base/classes.pdf | Bin 560611 -> 560996 bytes macros/latex/base/clsguide-historic.pdf | Bin 0 -> 415586 bytes macros/latex/base/clsguide-historic.tex | 1881 ++++++++++++++++++++ macros/latex/base/clsguide.pdf | Bin 414419 -> 452015 bytes macros/latex/base/clsguide.tex | 1957 ++++++++------------- macros/latex/base/cmextra.ins | 4 +- macros/latex/base/cmfonts.fdd | 6 +- macros/latex/base/cmfonts.ins | 4 +- macros/latex/base/cmfonts.pdf | Bin 292160 -> 292647 bytes macros/latex/base/cyrguide.pdf | Bin 257314 -> 257359 bytes macros/latex/base/cyrguide.tex | 4 +- macros/latex/base/doc-code.pdf | Bin 1077974 -> 1075705 bytes macros/latex/base/doc.dtx | 248 +-- macros/latex/base/doc.pdf | Bin 755564 -> 756114 bytes macros/latex/base/docstrip.dtx | 2 +- macros/latex/base/docstrip.ins | 4 +- macros/latex/base/docstrip.pdf | Bin 504635 -> 504300 bytes macros/latex/base/ec.ins | 4 +- macros/latex/base/encguide.pdf | Bin 1318126 -> 1318565 bytes macros/latex/base/encguide.tex | 2 +- macros/latex/base/exscale.dtx | 2 +- macros/latex/base/exscale.ins | 4 +- macros/latex/base/exscale.pdf | Bin 204711 -> 204710 bytes macros/latex/base/fix-cm.dtx | 2 +- macros/latex/base/fix-cm.ins | 4 +- macros/latex/base/fix-cm.pdf | Bin 287733 -> 287726 bytes macros/latex/base/fntguide.pdf | Bin 517838 -> 517658 bytes macros/latex/base/fntguide.tex | 25 +- macros/latex/base/fontdef.dtx | 2 +- macros/latex/base/format.ins | 8 +- macros/latex/base/graphpap.dtx | 2 +- macros/latex/base/graphpap.ins | 4 +- macros/latex/base/graphpap.pdf | Bin 161713 -> 161717 bytes macros/latex/base/idx.tex | 2 +- macros/latex/base/ifthen.dtx | 2 +- macros/latex/base/ifthen.ins | 4 +- macros/latex/base/ifthen.pdf | Bin 221211 -> 221207 bytes macros/latex/base/inputenc.dtx | 2 +- macros/latex/base/inputenc.ins | 4 +- macros/latex/base/inputenc.pdf | Bin 318204 -> 318162 bytes macros/latex/base/lablst.tex | 2 +- macros/latex/base/lamport-manual.pdf | Bin 170878 -> 170883 bytes macros/latex/base/latex209.dtx | 2 +- macros/latex/base/latex209.ins | 4 +- macros/latex/base/latexrelease.dtx | 13 +- macros/latex/base/latexrelease.ins | 4 +- macros/latex/base/latexrelease.pdf | Bin 281906 -> 282097 bytes macros/latex/base/latexsym.dtx | 2 +- macros/latex/base/latexsym.ins | 6 +- macros/latex/base/latexsym.pdf | Bin 200760 -> 200762 bytes macros/latex/base/lb2.err | 7 +- macros/latex/base/lb2.pdf | Bin 252140 -> 252516 bytes macros/latex/base/letter.dtx | 2 +- macros/latex/base/letter.ins | 4 +- macros/latex/base/letter.pdf | Bin 337717 -> 337757 bytes macros/latex/base/lgc2.err | 22 +- macros/latex/base/lgc2.pdf | Bin 215684 -> 217757 bytes macros/latex/base/lppl.pdf | Bin 132382 -> 132369 bytes macros/latex/base/ltalloc.dtx | 2 +- macros/latex/base/ltbibl.dtx | 2 +- macros/latex/base/ltboxes.dtx | 2 +- macros/latex/base/ltclass.dtx | 46 +- macros/latex/base/ltcmd.dtx | 157 +- macros/latex/base/ltcmdhooks-code.pdf | Bin 719498 -> 755572 bytes macros/latex/base/ltcmdhooks-doc.pdf | Bin 478988 -> 499063 bytes macros/latex/base/ltcmdhooks.dtx | 424 ++++- macros/latex/base/ltcntrl.dtx | 2 +- macros/latex/base/ltcounts.dtx | 2 +- macros/latex/base/ltdefns.dtx | 228 ++- macros/latex/base/ltdirchk.dtx | 2 +- macros/latex/base/lterror.dtx | 2 +- macros/latex/base/ltexpl.dtx | 2 +- macros/latex/base/ltfilehook-code.pdf | Bin 803237 -> 804144 bytes macros/latex/base/ltfilehook-doc.pdf | Bin 548101 -> 548729 bytes macros/latex/base/ltfilehook.dtx | 12 +- macros/latex/base/ltfiles.dtx | 78 +- macros/latex/base/ltfinal.dtx | 98 +- macros/latex/base/ltfloat.dtx | 2 +- macros/latex/base/ltfntcmd.dtx | 2 +- macros/latex/base/ltfssaxes.dtx | 2 +- macros/latex/base/ltfssbas.dtx | 15 +- macros/latex/base/ltfsscmp.dtx | 2 +- macros/latex/base/ltfssdcl.dtx | 2 +- macros/latex/base/ltfssini.dtx | 2 +- macros/latex/base/ltfsstrc.dtx | 2 +- macros/latex/base/lthooks-code.pdf | Bin 1091738 -> 1242512 bytes macros/latex/base/lthooks-doc.pdf | Bin 701793 -> 739628 bytes macros/latex/base/lthooks.dtx | 2823 +++++++++++++++++++++++++++---- macros/latex/base/lthyphen.dtx | 2 +- macros/latex/base/ltidxglo.dtx | 2 +- macros/latex/base/ltkeys.dtx | 2 +- macros/latex/base/ltlength.dtx | 2 +- macros/latex/base/ltlists.dtx | 9 +- macros/latex/base/ltlogos.dtx | 2 +- macros/latex/base/ltluatex.dtx | 6 +- macros/latex/base/ltluatex.pdf | Bin 325457 -> 325074 bytes macros/latex/base/ltmarks-code.pdf | Bin 715851 -> 716417 bytes macros/latex/base/ltmarks-doc.pdf | Bin 586219 -> 586530 bytes macros/latex/base/ltmarks.dtx | 5 +- macros/latex/base/ltmath.dtx | 25 +- macros/latex/base/ltmeta.dtx | 5 +- macros/latex/base/ltmiscen.dtx | 12 +- macros/latex/base/ltnews.cls | 42 +- macros/latex/base/ltnews.pdf | Bin 1243036 -> 1287055 bytes macros/latex/base/ltnews.tex | 20 +- macros/latex/base/ltnews01.pdf | Bin 161518 -> 169550 bytes macros/latex/base/ltnews01.tex | 2 +- macros/latex/base/ltnews02.pdf | Bin 159792 -> 151773 bytes macros/latex/base/ltnews02.tex | 2 +- macros/latex/base/ltnews03.pdf | Bin 159332 -> 151321 bytes macros/latex/base/ltnews03.tex | 2 +- macros/latex/base/ltnews04.pdf | Bin 152525 -> 152549 bytes macros/latex/base/ltnews04.tex | 2 +- macros/latex/base/ltnews05.pdf | Bin 174494 -> 175216 bytes macros/latex/base/ltnews05.tex | 2 +- macros/latex/base/ltnews06.pdf | Bin 142849 -> 142864 bytes macros/latex/base/ltnews06.tex | 2 +- macros/latex/base/ltnews07.pdf | Bin 137811 -> 138211 bytes macros/latex/base/ltnews07.tex | 2 +- macros/latex/base/ltnews08.pdf | Bin 155053 -> 155434 bytes macros/latex/base/ltnews08.tex | 2 +- macros/latex/base/ltnews09.pdf | Bin 129570 -> 130026 bytes macros/latex/base/ltnews09.tex | 2 +- macros/latex/base/ltnews10.pdf | Bin 169416 -> 169432 bytes macros/latex/base/ltnews10.tex | 2 +- macros/latex/base/ltnews11.pdf | Bin 111948 -> 112202 bytes macros/latex/base/ltnews11.tex | 2 +- macros/latex/base/ltnews12.pdf | Bin 156551 -> 156765 bytes macros/latex/base/ltnews12.tex | 2 +- macros/latex/base/ltnews13.pdf | Bin 182225 -> 182490 bytes macros/latex/base/ltnews13.tex | 2 +- macros/latex/base/ltnews14.pdf | Bin 170473 -> 170721 bytes macros/latex/base/ltnews14.tex | 2 +- macros/latex/base/ltnews15.pdf | Bin 130309 -> 130323 bytes macros/latex/base/ltnews15.tex | 2 +- macros/latex/base/ltnews16.pdf | Bin 138073 -> 138110 bytes macros/latex/base/ltnews16.tex | 2 +- macros/latex/base/ltnews17.pdf | Bin 166228 -> 166268 bytes macros/latex/base/ltnews17.tex | 2 +- macros/latex/base/ltnews18.pdf | Bin 38033 -> 39840 bytes macros/latex/base/ltnews18.tex | 2 +- macros/latex/base/ltnews19.pdf | Bin 230028 -> 225936 bytes macros/latex/base/ltnews19.tex | 3 +- macros/latex/base/ltnews20.pdf | Bin 318548 -> 318193 bytes macros/latex/base/ltnews20.tex | 3 +- macros/latex/base/ltnews21.pdf | Bin 244867 -> 245229 bytes macros/latex/base/ltnews21.tex | 2 +- macros/latex/base/ltnews22.pdf | Bin 317773 -> 318036 bytes macros/latex/base/ltnews22.tex | 2 +- macros/latex/base/ltnews23.pdf | Bin 286591 -> 286839 bytes macros/latex/base/ltnews23.tex | 2 +- macros/latex/base/ltnews24.pdf | Bin 265279 -> 265497 bytes macros/latex/base/ltnews24.tex | 2 +- macros/latex/base/ltnews25.pdf | Bin 204935 -> 205098 bytes macros/latex/base/ltnews25.tex | 2 +- macros/latex/base/ltnews26.pdf | Bin 379462 -> 379722 bytes macros/latex/base/ltnews26.tex | 2 +- macros/latex/base/ltnews27.pdf | Bin 250592 -> 251285 bytes macros/latex/base/ltnews27.tex | 3 +- macros/latex/base/ltnews28.pdf | Bin 376643 -> 376930 bytes macros/latex/base/ltnews28.tex | 2 +- macros/latex/base/ltnews29.pdf | Bin 455107 -> 455431 bytes macros/latex/base/ltnews29.tex | 2 +- macros/latex/base/ltnews30.pdf | Bin 511909 -> 512246 bytes macros/latex/base/ltnews30.tex | 2 +- macros/latex/base/ltnews31.pdf | Bin 526323 -> 526692 bytes macros/latex/base/ltnews31.tex | 3 +- macros/latex/base/ltnews32.pdf | Bin 546160 -> 546554 bytes macros/latex/base/ltnews32.tex | 2 +- macros/latex/base/ltnews33.pdf | Bin 522412 -> 522771 bytes macros/latex/base/ltnews33.tex | 2 +- macros/latex/base/ltnews34.pdf | Bin 508044 -> 508349 bytes macros/latex/base/ltnews34.tex | 3 +- macros/latex/base/ltnews35.pdf | Bin 563089 -> 563329 bytes macros/latex/base/ltnews35.tex | 20 +- macros/latex/base/ltnews36.pdf | Bin 517577 -> 517935 bytes macros/latex/base/ltnews36.tex | 11 +- macros/latex/base/ltnews37.pdf | Bin 0 -> 456936 bytes macros/latex/base/ltnews37.tex | 848 ++++++++++ macros/latex/base/ltoutenc.dtx | 2 +- macros/latex/base/ltoutenc.ins | 4 +- macros/latex/base/ltoutput.dtx | 10 +- macros/latex/base/ltpage.dtx | 2 +- macros/latex/base/ltpageno.dtx | 2 +- macros/latex/base/ltpar.dtx | 2 +- macros/latex/base/ltpara-code.pdf | Bin 667434 -> 672322 bytes macros/latex/base/ltpara-doc.pdf | Bin 560295 -> 560194 bytes macros/latex/base/ltpara.dtx | 71 +- macros/latex/base/ltpictur.dtx | 2 +- macros/latex/base/ltplain.dtx | 56 +- macros/latex/base/ltsect.dtx | 2 +- macros/latex/base/ltshipout-code.pdf | Bin 818839 -> 821760 bytes macros/latex/base/ltshipout-doc.pdf | Bin 563617 -> 566638 bytes macros/latex/base/ltshipout.dtx | 55 +- macros/latex/base/ltspace.dtx | 7 +- macros/latex/base/lttab.dtx | 2 +- macros/latex/base/lttextcomp.dtx | 2 +- macros/latex/base/ltthm.dtx | 2 +- macros/latex/base/ltvers.dtx | 33 +- macros/latex/base/ltx3info.pdf | Bin 219349 -> 219347 bytes macros/latex/base/ltx3info.tex | 2 +- macros/latex/base/ltxcheck.tex | 2 +- macros/latex/base/ltxdoc.dtx | 16 +- macros/latex/base/ltxdoc.pdf | Bin 243286 -> 244224 bytes macros/latex/base/ltxguide.cls | 2 +- macros/latex/base/ltxref.dtx | 95 +- macros/latex/base/makeindx.dtx | 2 +- macros/latex/base/makeindx.ins | 4 +- macros/latex/base/makeindx.pdf | Bin 165821 -> 165816 bytes macros/latex/base/manifest.txt | 6 +- macros/latex/base/minimal.cls | 2 +- macros/latex/base/modguide.pdf | Bin 257804 -> 257823 bytes macros/latex/base/modguide.tex | 4 +- macros/latex/base/newdc.ins | 4 +- macros/latex/base/newlfont.dtx | 2 +- macros/latex/base/nfssfont.dtx | 2 +- macros/latex/base/nfssfont.ins | 4 +- macros/latex/base/nfssfont.pdf | Bin 211180 -> 211175 bytes macros/latex/base/olddc.ins | 4 +- macros/latex/base/oldlfont.dtx | 2 +- macros/latex/base/preload.dtx | 2 +- macros/latex/base/proc.dtx | 2 +- macros/latex/base/proc.ins | 4 +- macros/latex/base/proc.pdf | Bin 227059 -> 227060 bytes macros/latex/base/slides.dtx | 2 +- macros/latex/base/slides.ins | 8 +- macros/latex/base/slides.pdf | Bin 375518 -> 375509 bytes macros/latex/base/slifonts.fdd | 2 +- macros/latex/base/slifonts.pdf | Bin 234191 -> 234183 bytes macros/latex/base/source2e.pdf | Bin 5771795 -> 6006329 bytes macros/latex/base/source2e.tex | 2 +- macros/latex/base/syntonly.dtx | 2 +- macros/latex/base/syntonly.ins | 4 +- macros/latex/base/syntonly.pdf | Bin 190118 -> 189842 bytes macros/latex/base/testpage.tex | 2 +- macros/latex/base/tlc2.err | 19 +- macros/latex/base/tlc2.pdf | Bin 290615 -> 291233 bytes macros/latex/base/tlc3.err | 848 ++++++++++ macros/latex/base/tlc3.pdf | Bin 0 -> 250362 bytes macros/latex/base/tulm.fdd | 2 +- macros/latex/base/tulm.ins | 4 +- macros/latex/base/tulm.pdf | Bin 162772 -> 162770 bytes macros/latex/base/unpack.ins | 2 +- macros/latex/base/usrguide-historic.pdf | Bin 438515 -> 438603 bytes macros/latex/base/usrguide-historic.tex | 4 +- macros/latex/base/usrguide.pdf | Bin 473980 -> 479599 bytes macros/latex/base/usrguide.tex | 122 +- macros/latex/base/utf8ienc.dtx | 2 +- macros/latex/base/utf8ienc.pdf | Bin 353664 -> 353564 bytes macros/latex/base/webcomp.pdf | Bin 146198 -> 146199 bytes 259 files changed, 8808 insertions(+), 2134 deletions(-) create mode 100644 macros/latex/base/clsguide-historic.pdf create mode 100644 macros/latex/base/clsguide-historic.tex create mode 100644 macros/latex/base/ltnews37.pdf create mode 100644 macros/latex/base/ltnews37.tex create mode 100644 macros/latex/base/tlc3.err create mode 100644 macros/latex/base/tlc3.pdf (limited to 'macros/latex/base') diff --git a/macros/latex/base/README.md b/macros/latex/base/README.md index eb19004b01..bccadab2d9 100644 --- a/macros/latex/base/README.md +++ b/macros/latex/base/README.md @@ -1,7 +1,7 @@ The LaTeX kernel ================ -Release 2022-11-01 patch level 1 +Release 2023-06-01 Overview -------- diff --git a/macros/latex/base/alltt.dtx b/macros/latex/base/alltt.dtx index 908fe92400..548b91bcea 100644 --- a/macros/latex/base/alltt.dtx +++ b/macros/latex/base/alltt.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/alltt.ins b/macros/latex/base/alltt.ins index f46404bcf4..3f40ddc0f0 100644 --- a/macros/latex/base/alltt.ins +++ b/macros/latex/base/alltt.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/alltt.pdf b/macros/latex/base/alltt.pdf index f2614d73e0..e01f937daa 100644 Binary files a/macros/latex/base/alltt.pdf and b/macros/latex/base/alltt.pdf differ diff --git a/macros/latex/base/cfgguide.pdf b/macros/latex/base/cfgguide.pdf index 724ae8aebe..4a9e45c7e4 100644 Binary files a/macros/latex/base/cfgguide.pdf and b/macros/latex/base/cfgguide.pdf differ diff --git a/macros/latex/base/cfgguide.tex b/macros/latex/base/cfgguide.tex index 53f53d90b4..e0f76b74fb 100644 --- a/macros/latex/base/cfgguide.tex +++ b/macros/latex/base/cfgguide.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -41,7 +41,7 @@ \author{\copyright~Copyright 1998, 2001, 2003 \LaTeX\ Project Team.\\ All rights reserved.% - \footnote{This file may distributed and/or modified under the + \footnote{This file may be distributed and/or modified under the conditions of the \LaTeX{} Project Public License, either version 1.3c of this license or (at your option) any later version. See the source \texttt{cfgguide.tex} for full details.}% diff --git a/macros/latex/base/changes.txt b/macros/latex/base/changes.txt index fed7e96be3..a8eabd5dd1 100644 --- a/macros/latex/base/changes.txt +++ b/macros/latex/base/changes.txt @@ -10,6 +10,231 @@ are not part of the distribution. All changes above are only part of the development branch for the next release. ================================================================================ +######################### +# 2023-06-01 Release +######################### + +2023-05-21 Phelype Oleinik + + * lthooks.dtx (subsection{Adding or removing hook code}): + Short-circuit when the hook is declared without args (gh1078). + +2023-05-31 Joseph Wright + + * usrguide.text + Correct syntax of opt. arg. for \DeclareLowercaseMapping, etc. + +2023-05-30 Joseph Wright + + * ltfinal.dtx + Fix implementation of \DeclareLowercaseMapping + +2023-05-26 Yukai Chou + + * ltcmd.dtx (subsection{Structure of \pkg{xparse} commands}): + Use simpler 'NNno' variant instead of 'NNVo' for + \cs_generate_from_arg_count:NNnn + +2023-05-22 Joseph Wright + + * usrguide.tex + Ensure url package is always loaded + +2023-05-21 Phelype Oleinik + + * lthooks.dtx, ltcmdhooks.dtx: + Add support for accessing arguments in 'cmd' hooks. + +2023-05-19 Joseph Wright + + * usrguide.tex (section Creating document commands and environments) + Add details of result of trailing optional arguments on + \inputlineno + +2023-05-12 Ulrike Fischer + + * ltxref.dtx + extend \label to store five values and add a hook with argument + +2023-05-17 Joseph Wright + + * usrguide.tex (section Creating document commands and environments) + Add details of brace stripping by \SplitList + Add guidance on creating commands to use at start of + tabular cells + +2023-05-15 Joseph Wright + + * ltfiles.dtx: + Use expl3-based file-existence test + +2023-05-13 David Carlisle + + * ltmath.dtx: Add \ignorespaces to \eqno (gh/1059) + +2023-04-19 Joseph Wright + + * ltfinal.dtx (subsection{Lccodes and uccodes}): + Add \DeclareLowercaseMapping, \DeclareTitlecaseMapping and + \DeclareUppercaseMapping (gh/1033) + +2023-04-19 Phelype Oleinik + + * lthooks.dtx (subsection{Specifying code for next invocation}): + Initialise hook structure when adding 'next' code (gh/1052) + +2023-04-17 Joseph Wright + + * ltfinal.dtx (subsubsection{Lccodes and uccodes}): + Add \BCPdata (gh/1035) + Adapt \MakeLowercase, \MakeTitlecase and \MakeLowercase + to use \BCPdata for locale info + +2023-04-16 Phelype Oleinik + + * lthooks.dtx (subsubsection{Setting hooks up}): + Use \@@_replacing_args_false: in \@@_include_legacy_code_chunk:n. + +2023-04-15 David Carlisle + + * ltplain.dtx: adjust \extrafloats so it does not error if thousands + of float boxes are allocated. github/1041 + +2023-04-14 Phelype Oleinik + + * ltclass.dtx (\@onefilewithoptions): + When in latexrelease.sty, define \load@onefilewithoptions (gh/992). + +2023-04-13 David Carlisle + + * cmfonts.fdd: add missing substitution for U/cmtt/bx/sl gh/1037 + +2023-04-12 Phelype Oleinik + + * ltcmd.dtx (subsection{Grabbing arguments}): + Set \tex_endlinechar:D earlier to correct parsing of newlines in + special catcode settings (e.g., \ExplSyntaxOn) (gh/876). + +2023-04-02 David Carlisle + + * ltfilehook.dtx: allow par as a filename. (gh/942) + +2023-04-06 Phelype Oleinik + + * lthooks.dtx, ltcmdhooks.dtx: + Add support for providing and using arguments in hooks: + - Modify hook data structures to allow access to arguments; + - Add commands to declare hooks with arguments; + - Add commands to add code that references hook arguments; + - Add commands to use hooks with arguments. + +2023-04-01 David Carlisle + + * ltfssbas.dtx: locally reset frozen mathversions when the math + version changes. (gh/1028) + +2023-03-28 Joseph Wright + + * ltclass.dtx: + Add \IfFileAtLeastTF (gh/1015) + +2023-03-28 Frank Mittelbach + + * ltxdoc.dtx (section{Options}): + Define \cs if doc is rolled back to v2 (gh/981) + +2023-03-28 David Carlisle + + * ltfinal.dtx: Restore groups to \MakeUppercase and + \MakeLowercase, and add a group to \MakeTitlecase. (gh/1021) + +2023-03-22 Frank Mittelbach + + * ltspace.dtx: + Add \predisplaypenalty setting of 10000 to \samepage in case + that was changed (gh/1022) + +2023-03-11 Yukai Chou + + * ltcmd.dtx (subsubsection{Showing the definition of a command}), + (subsubsection{Copying a command and its internal structure}): + Correctly recognize (non-expandable) document commands with empty or only + m-type arguments (gh/1009) + +2023-01-30 Frank Mittelbach + + * ltpara.dtx (subsection{Providing hooks for paragraphs}): + Backout \parskip at top of minipage if it shouldn't be there + but is due to whatsits (gh/989) + +2023-02-05 Yukai Chou + + * fntguide.tex: + Adjusted pagination due to recently added doc paragraphs (gh/994) + +2023-01-16 Yukai Chou + + * ltnews.cls: + Added full release date yyyy-mm-dd to _all_ ltnews issues (gh/982) + Added \publicationday{} to specify day in a month in ltnews.tex. + defaults to 01. + +2023-01-12 Joseph Joseph + + * clsguide.tex, clsguide-historic,tex + Pre-2023 source moved to new name, re-worked material which remains + relevant in updated file + +2023-01-19 Josef Friedrich + + * ltluatex.dtx: + Remove unused local variable tex_setattribute (gh/978) + +2022-11-24 Frank Mittelbach + + * ltdefns.dtx (subsubsection{Copying robust commands}): + Added \NewEnvironmentCopy, \RenewEnvironmentCopy, and \DeclareEnvironmentCopy (gh/963) + Also added \ShowEnvironment. + +2022-11-16 Frank Mittelbach + + * ltclass.dtx: + Introduce key 'nowarn' on filecontents (gh/958) + Do not show "current dir" in message (gh/917) + +2022-11-14 Frank Mittelbach + + * latexrelease.dtx (subsection{Ignoring \texttt{\string_new} errors when rolling back}): + Silence \cs{NewMarkClass} in rollback (gh/955) + +2022-11-13 Frank Mittelbach + + * doc.dtx: + Redefinitions of \verb removed as no longer needed (gh/953) + + Redefinitions of \@verbatim changed to match the kernel + definition (gh/953) + +2022-11-08 Frank Mittelbach + + * ltshipout.dtx: + Add a shipout hook to be executed just before we + actually do the shipout (gh/920) + +2022-11-07 Frank Mittelbach + + * ltvers.dtx (section{Version Identification}): + Store release data in \LaTeXReleaseInfo for reuse at the end of + the .log file (gh/944) + + * ltmiscen.dtx (subsection{Environments}): Add to a hook in + \end{document} to (re)display the LaTeX release information (gh/944) + +2022-11-03 Frank Mittelbach + + * doc.dtx: correctly handle \ and allow it to be excluded + from the index (gh/943) + ######################### # 2022-11-01 PL1 Release ######################### @@ -145,7 +370,7 @@ All changes above are only part of the development branch for the next release. * doc.dtx recast Package Option declarations using \DeclareKeys - + 2022-06-10 Ulrike Fischer * cmfonts.fdd diff --git a/macros/latex/base/classes.dtx b/macros/latex/base/classes.dtx index 188679d4d9..58690e8375 100644 --- a/macros/latex/base/classes.dtx +++ b/macros/latex/base/classes.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -53,7 +53,7 @@ %<*driver> \ProvidesFile{classes.drv} % - [2022/07/02 v1.4n + [2023/05/17 v1.4n % Standard LaTeX document class] %<10pt|11pt|12pt> Standard LaTeX file (size option)] % \end{macrocode} @@ -3688,9 +3688,8 @@ % % A |\caption| command in a `figure' environment writes % -% |\contentsline{figure}{\numberline{|\meta{num}|}{|% +% |\contentsline{figure}{\numberline{|\meta{num}|}{|^^A % \meta{caption}|}}{|\meta{page}|}| -% % on the .\file{lof} file, where \meta{num} is the number produced % by |\thefigure| and \meta{caption} is the figure caption. It % works similarly for a `table' environment. @@ -3707,8 +3706,8 @@ % \meta{title}|}{|\meta{page}|}| % % \begin{description} -% \item[\meta{level}] An entry is produced only if\meta{ level} -% $<=$ value of the \Lcount{tocdepth} counter. Note, +% \item[\meta{level}] An entry is produced only if \meta{level} +% $\leq$ value of the \Lcount{tocdepth} counter. Note, % |\chapter| is level 0, |\section| is level 1, etc. % \item[\meta{indent}] The indentation from the outer left margin % of the start of the contents line. diff --git a/macros/latex/base/classes.ins b/macros/latex/base/classes.ins index 1f7b331691..50a51ea666 100644 --- a/macros/latex/base/classes.ins +++ b/macros/latex/base/classes.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/classes.pdf b/macros/latex/base/classes.pdf index a8296800a3..5ce9be9aa0 100644 Binary files a/macros/latex/base/classes.pdf and b/macros/latex/base/classes.pdf differ diff --git a/macros/latex/base/clsguide-historic.pdf b/macros/latex/base/clsguide-historic.pdf new file mode 100644 index 0000000000..bc95e39dff Binary files /dev/null and b/macros/latex/base/clsguide-historic.pdf differ diff --git a/macros/latex/base/clsguide-historic.tex b/macros/latex/base/clsguide-historic.tex new file mode 100644 index 0000000000..d7a27e3c40 --- /dev/null +++ b/macros/latex/base/clsguide-historic.tex @@ -0,0 +1,1881 @@ +% \iffalse meta-comment +% +% Copyright (C) 1993-2023 +% The LaTeX Project and any individual authors listed elsewhere +% in this file. +% +% This file is part of the LaTeX base system. +% ------------------------------------------- +% +% It may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3c +% of this license or (at your option) any later version. +% The latest version of this license is in +% http://www.latex-project.org/lppl.txt +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008 or later. +% +% This file has the LPPL maintenance status "maintained". +% +% The list of all files belonging to the LaTeX base distribution is +% given in the file `manifest.txt'. See also `legal.txt' for additional +% information. +% +% The list of derived (unpacked) files belonging to the distribution +% and covered by LPPL is defined by the unpacking scripts (with +% extension .ins) which are part of the distribution. +% +% \fi +% Filename: clsguide-historic.tex + +\NeedsTeXFormat{LaTeX2e}[1995/12/01] + +\documentclass{ltxguide}[1995/11/28] + +\title{\LaTeXe~for class and package writers --- historic version} + +\author{Copyright \copyright~1995--2006 The \LaTeX\ Project\\ + All rights reserved.% + \footnote{This file may be distributed and/or modified under the + conditions of the \LaTeX{} Project Public License, either version 1.3c + of this license or (at your option) any later version. See the source + \texttt{clsguide.tex} for full details.}% +} + +\date{11 January 2023} + +\begin{document} + +\maketitle + +\tableofcontents + +\section{Introduction} + +This document is an introduction to writing classes and packages for +\LaTeX{}, with special attention given to upgrading existing +\LaTeX~2.09 packages to \LaTeXe{}. The latter subject is also +covered in an article by Johannes Braams published in TUGboat~15.3. + +It is somewhat of an historical document now, since \LaTeXe{} came into +existence in 1994. + +\subsection{Writing classes and packages for \LaTeXe} + +\LaTeX{} is a document preparation system that enables the document +writer to concentrate on the contents of their text, without bothering +too much about the formatting of it. For example, chapters are +indicated by |\chapter{}| rather than by selecting 18pt bold. + +The file that contains the information about how to turn logical +structure (like `|\chapter|') into formatting (like `18pt bold ragged +right') is a \emph{document class}. In addition, some features (such +as colour or included graphics) are independent of the document class +and these are contained in \emph{packages}. + +One of the largest differences between \LaTeX~2.09 and \LaTeXe{} is in +the commands used to write packages and classes. In \LaTeX~2.09, +there was very little support for writing |.sty| files, and so writers +had to resort to using low-level commands. + +\LaTeXe{} provides high-level commands for structuring packages. +It is also much easier to build classes and packages on top of each +other, for example writing a local technical report class |cetechr| +(for the Chemical Engineering department) based on |article|. + +\subsection{Overview} + +This document contains an overview of how to write classes and +packages for \LaTeX{}. It does \emph{not} introduce all of the +commands necessary to write packages: these can be found in either +\emph{\LaTeXbook} or \emph{\LaTeXcomp}. But it does describe the new +commands for structuring classes and packages. + +\begin{description} + +\item[Section~\ref{Sec:general}] contains some general advice about + writing classes and packages. It describes the difference between + classes and packages, the command naming conventions, the use of + |doc| and |docstrip|, how \TeX's primitive file and box commands + interact with \LaTeX{}. It also contains some hints about general + \LaTeX{} style. + +\item[Section~\ref{Sec:structure}] describes the structure of classes + and packages. This includes building classes and packages on top of + other classes and packages, declaring options and declaring + commands. It also contains example classes. + +\item[Section~\ref{Sec:commands}] lists the new class and package + commands. + + \item[Section~\ref{Sec:upgrade}] gives detailed advice on how to + upgrade existing \LaTeX~2.09 classes and packages to \LaTeXe{}. + +\end{description} + +\subsection{Further information} + +For a general introduction to \LaTeX{}, including the new features of +\LaTeXe{}, you should read \emph{\LaTeXbook} +by Leslie Lamport~\cite{A-W:LLa94}. + +A more detailed description of the new features of \LaTeX, including an +overview of more than 200 packages and nearly 1000 ready to run examples, is +to be found in \emph{\LaTeXcomp\ second edition} by Frank Mittelbach and +Michel Goossens~\cite{A-W:MG2004}. + +The \LaTeX{} system is based on \TeX{}, which is +described in \emph{The \TeX book} by Donald E.~Knuth~\cite{A-W:DEK91}. + +There are a number of documentation files which accompany every copy +of \LaTeX{}. A copy of \emph{\LaTeX{} News} will come out with each +six-monthly release of \LaTeX{}, and is found in the files +|ltnews*.tex|. The author's guide \emph{\usrguide} describes the new +\LaTeX{} document features; it is in |usrguide.tex|. The guide +\emph{\fntguide} describes the \LaTeX{} font selection scheme for +class- and package-writers; it is in |fntguide.tex|. Configuring +\LaTeX{} is covered by the guide \emph{\cfgguide} in +\texttt{cfgguide.tex} whilst the philosophy behind our policy on +modifying \LaTeX{} is described in \emph{\modguide} in +\texttt{modguide.tex}. + +The documented source code (from the files used to produce the kernel +format via |latex.ltx|) is now available as +\emph{The \LaTeXe\ Sources}. +This very large document also includes an index of +\LaTeX{} commands. It can be typeset from the \LaTeX{} file +|source2e.tex| in the |base| directory, using the source files and +the class file |ltxdoc.cls| from this directory. + +For more information about \TeX{} and \LaTeX{}, please contact your +local \TeX{} Users Group, or the international \TeX{} Users Group. +Addresses and other details can be found at: +\begin{quote}\small\label{addrs} + \texttt{http://www.tug.org/lugs.html} +\end{quote} + + +\subsection{Policy on standard classes} + +Many of the problem reports we receive concerning the standard classes +are not concerned with bugs but are suggesting, more or less politely, +that the design decisions embodied in them are `not optimal' and +asking us to modify them. + +There are several reasons why we should not make such changes to these +files. +\begin{itemize} +\item + However misguided, the current behaviour is clearly what was + intended when these classes were designed. +\item + It is not good practice to change such aspects of `standard classes' + because many people will be relying on them. +\end{itemize} + +We have therefore decided not to even consider making such +modifications, nor to spend time justifying that decision. This does +not mean that we do not agree that there are many deficiencies in the +design of these classes, but we have many tasks with higher priority +than continually explaining why the standard classes for \LaTeX{} +cannot be changed. + +We would, of course, welcome the production of better classes, or of +packages that can be used to enhance these classes. So your first +thought when you consider such a deficiency will, we hope, be ``what +can I do to improve this?'' + +Similar considerations apply to those parts of the kernel that are +implementing design decisions, many of which should be left to the +class file but are not in the current system. We realise that in such +cases it is much more difficult for you to rectify the problem +yourself but it is also the case that making such changes in the +kernel would probably be a major project for us; therefore such +enhancements will have to wait for \LaTeX3. + +\section{Writing classes and packages} +\label{Sec:writing} + +This section covers some general points concerned with writing +\LaTeX{} classes and packages. + + +\subsection{Old versions} + +If you are upgrading an existing \LaTeX~2.09 style file then we +recommend freezing the 2.09 version and no longer maintaining it. +Experience with the various dialects of \LaTeX{} which existed in the +early 1990's suggests that maintaining packages for different versions +of \LaTeX{} is almost impossible. It will, of course, be necessary +for some organisations to maintain both versions in parallel for some +time but this is not essential for those packages and classes +supported by individuals: they should support only the new standard +\LaTeXe{}, not obsolete versions of \LaTeX{}. + + +\subsection{Using `docstrip' and `doc'} + +If you are going to write a large class or package for \LaTeX{} then +you should consider using the |doc| software which comes with +\LaTeX{}. +\LaTeX{} classes and packages written using this can be +processed in two ways: they can be run through \LaTeX{}, to produce +documentation; and they can be processed with |docstrip|, to produce +the |.cls| or |.sty| file. + +The |doc| software can automatically generate indexes of definitions, +indexes of command use, and change-log lists. It is very useful for +maintaining and documenting large \TeX{} sources. + +The documented sources of the \LaTeX{} kernel itself, and of the +standard classes, etc, are |doc| documents; they are in the |.dtx| +files in the distribution. You can, in fact, typeset the source code +of the kernel as one long document, complete with index, by running +\LaTeX{} on |source2e.tex|. Typesetting these documents uses the +class file |ltxdoc.cls|. + +For more information on |doc| and |docstrip|, consult the files +|docstrip.dtx|, |doc.dtx|, and \emph{\LaTeXcomp}. For examples of its +use, look at the |.dtx| files. + +\subsection{Is it a class or a package?} +\label{Sec:classorpkg} + +The first thing to do when you want to put some new \LaTeX{} commands +in a file is to decide whether it should be a \emph{document class} or a +\emph{package}. The rule of thumb is: +\begin{quote} + If the commands could be used with any document class, then make + them a package; and if not, then make them a class. +\end{quote} + +There are two major types of class: those like |article|, |report| or +|letter|, which are free-standing; and those which are extensions or +variations of other classes---for example, the |proc| document class, +which is built on the |article| document class. + +Thus, a company might have a local |ownlet| class for printing letters +with their own headed note-paper. Such a class would build on top of +the existing |letter| class but it cannot be used with any other +document class, so we have |ownlet.cls| rather than |ownlet.sty|. + +The |graphics| package, in contrast, provides commands for including +images into a \LaTeX{} document. Since these commands can be used +with any document class, we have |graphics.sty| rather than +|graphics.cls|. + + +\subsection{Command names} + +\LaTeX{} has three types of command. + +There are the author commands, such as |\section|, |\emph| and +|\times|: most of these have short names, all in lower case. + +There are also the class and package writer commands: +most of these have long mixed-case names such as the following. +\begin{verbatim} + \InputIfFileExists \RequirePackage \PassOptionsToClass +\end{verbatim} + +Finally, there are the internal commands used in the \LaTeX{} +implementation, such as |\@tempcnta|, |\@ifnextchar| and |\@eha|: +most of these commands contain |@| in their name, which means they +cannot be used in documents, only in class and package files. + +Unfortunately, for historical reasons the distinction between these +commands is often blurred. For example, |\hbox| is an internal +command which should only be used in the \LaTeX{} kernel, whereas +|\m@ne| is the constant $-1$ and could have been |\MinusOne|. + +However, this rule of thumb is still useful: if a command has |@| in +its name then it is not part of the supported \LaTeX{} language---and +its behaviour may change in future releases! If a command is +mixed-case, or is described in \emph{\LaTeXbook}, then you can rely on +future releases of \LaTeXe{} supporting the command. + +\subsection{Box commands and colour} +\label{Sec:colour} + +Even if you do not intend to use colour in your own documents, by +taking note of the points in this section you can ensure that your +class or package is compatible with the |color| package. This may +benefit people using your class or package who have access to colour +printers. + +The simplest way to ensure `colour safety' is to always use \LaTeX{} +box commands rather than \TeX{} primitives, that is use |\sbox| rather +than |\setbox|, |\mbox| rather than |\hbox| and |\parbox| or +the |minipage| environment rather than |\vbox|. +The \LaTeX{} box commands have new options which mean that they are now +as powerful as the \TeX{} primitives. + +As an example of what can go wrong, consider that in +|{\ttfamily <text>}| +the font is restored just \emph{before} the |}|, whereas in the +similar looking construction +|{\color{green} <text>}| +the colour is restored just \emph{after} the final |}|. Normally this +distinction does not matter at all; but consider a primitive \TeX{} +box assignment such as: +\begin{verbatim} + \setbox0=\hbox{\color{green} <text>} +\end{verbatim} +Now the colour-restore occurs after the |}| and so is \emph{not} +stored in the box. Exactly what bad effects this can have depends on +how colour is implemented: it can range from getting the wrong +colours in the rest of the document, to causing errors in the +dvi-driver used to print the document. + +Also of interest is the command |\normalcolor|. This is +normally just |\relax| (i.e., does nothing) +but you can use it rather like |\normalfont| to +set regions of the page such as captions or section headings to the +`main document colour'. + + +\subsection{Defining text and math characters} +\label{Sec:chars} + +Because \LaTeXe{} supports different encodings, definitions of commands +for producing symbols, accents, composite glyphs, etc.\ must be +defined using the commands provided for this purpose and described in +\emph{\fntguide}. This part of the system is still under development +so such tasks should be undertaken with great caution. + +Also, |\DeclareRobustCommand| should be used for encoding-independent +commands of this type. + +Note that it is no longer possible to refer to the math font set-up +outside math mode: for example, neither |\textfont 1| nor +|\scriptfont 2| are guaranteed to be defined in other modes. + + +\subsection{General style} +\label{Sec:general} + +The new system provides many commands designed to help you produce +well-structured class and package files that are both robust and +portable. This section outlines some ways to make intelligent use of +these. + +\subsubsection{Loading other files} +\label{Sec:loading} + +\NEWdescription{1995/12/01} +\LaTeX{} provides these commands: +\begin{verbatim} + \LoadClass \LoadClassWithOptions + \RequirePackage \RequirePackageWithOptions +\end{verbatim} +for using classes or packages inside other classes or packages. We +recommend strongly that you use them, rather than the primitive +|\input| command, for a number of reasons. + +Files loaded with |\input <filename>| will not be listed in the +|\listfiles| list. + +If a package is always loaded with |\RequirePackage...| or |\usepackage| +then, even if its loading is requested several times, it will be +loaded only once. By contrast, if it is loaded with |\input| then it +can be loaded more than once; such an extra loading may waste time and +memory and it may produce strange results. + +If a package provides option-processing then, again, strange results +are possible if the package is |\input| rather than loaded by means of +|\usepackage| or |\RequirePackage...|. + +If the package |foo.sty| loads the package |baz.sty| by use of +|\input baz.sty| then the user will get a warning: +\begin{verbatim} + LaTeX Warning: You have requested package `foo', + but the package provides `baz'. +\end{verbatim} +Thus, for several reasons, using |\input| to load packages is not a +good idea. + +Unfortunately, if you are upgrading the file |myclass.sty| to a class +file then you have to make sure that any old files which contain +|\input myclass.sty| still work. + +This was also true for the standard classes (|article|, |book| and +|report|), since a lot of existing \LaTeX~2.09 document styles contain +|\input article.sty|. The approach which we use to solve this is +to provide minimal files |article.sty|, |book.sty| and |report.sty|, +which simply load the appropriate class files. + +For example, |article.sty| contains just the following lines: +\begin{verbatim} + \NeedsTeXFormat{LaTeX2e} + \@obsoletefile{article.cls}{article.sty} + \LoadClass{article} +\end{verbatim} +You may wish to do the same or, if you think that it is safe to do so, +you may decide to just remove |myclass.sty|. + +\subsubsection{Make it robust} + +We consider it good practice, when writing packages and classes, to use +\LaTeX{} commands as much as possible. + +Thus, instead of using |\def...| we recommend using one of +|\newcommand|, |\renewcommand| or |\providecommand|; |\CheckCommand| is +also useful. Doing this makes +it less likely that you will inadvertently redefine a command, giving +unexpected results. + +When you define an environment, use |\newenvironment| or +|\renewenvironment| instead |\def\foo{...}| and |\def\endfoo{...}|. + +If you need to set or change the value of a \m{dimen} or \m{skip} +register, use |\setlength|. + +To manipulate boxes, use \LaTeX{} commands such as |\sbox|, +|\mbox| and |\parbox| rather than |\setbox|, |\hbox| and |\vbox|. + +Use |\PackageError|, |\PackageWarning| or |\PackageInfo| (or the +equivalent class commands) rather than |\@latexerr|, |\@warning| or +|\wlog|. + +It is still possible to declare options by defining |\ds@<option>| and +calling |\@options|; but we recommend the |\DeclareOption| and +|\ProcessOptions| commands instead. These are more powerful and use +less memory. So rather than using: +\begin{verbatim} + \def\ds@draft{\overfullrule 5pt} + \@options +\end{verbatim} +you should use: +\begin{verbatim} + \DeclareOption{draft}{\setlength{\overfullrule}{5pt}} + \ProcessOptions\relax +\end{verbatim} + +The advantage of this kind of practice is that your code is more +readable and, more important, that it is less likely to break when +used with future versions of \LaTeX{}. + +\subsubsection{Make it portable} + +It is also sensible to make your files are as portable as possible. To +ensure this; they should contain only visible 7-bit text; and the +filenames should contain at most eight characters (plus the three +letter extension). Also, of course, it \textbf{must not} have the +same name as a file in the standard \LaTeX{} distribution, however +similar its contents may be to one of these files. + +It is also useful if local classes or packages have a common prefix, +for example the University of Nowhere classes might begin with |unw|. +This helps to avoid every University having its own thesis class, all +called |thesis.cls|. + +If you rely on some features of the \LaTeX{} kernel, or on a package, +please specify the release-date you need. For example, the package +error commands were introduced in the June 1994 release so, if you use +them then you should put: +\begin{verbatim} + \NeedsTeXFormat{LaTeX2e}[1994/06/01] +\end{verbatim} + +\subsubsection{Useful hooks} + +Some packages and document styles had to redefine the command +|\document| or |\enddocument| to achieve their goal. This is no +longer necessary. You can now use the `hooks' |\AtBeginDocument| and +|\AtEndDocument| (see Section~\ref{Sec:delays}). Again, using these +hooks makes it less likely that your code breaks with future versions +of \LaTeX{}. It also makes it more likely that your package can work +together with someone else's. + +\NEWdescription{1996/12/01} +However, note that code in the |\AtBeginDocument| hook is part of the +preamble. Thus there are restrictions on what can be put there; in +particular, no typesetting can be done. + +\section{The structure of a class or package} +\label{Sec:structure} + +\LaTeXe{} classes and packages have more structure than \LaTeX~2.09 +style files did. The outline of a class or package file is: +\begin{description} +\item[Identification] The file says that it is a \LaTeXe{} package or + class, and gives a short description of itself. +\item[Preliminary declarations] + Here the file declares some commands and can also load + other files. Usually these commands will be just those needed for + the code used in the declared options. +\item[Options] The file declares and processes its options. +\item[More declarations] This is where the file does most of its work: + declaring new variables, commands and fonts; and loading other files. +\end{description} + +\subsection{Identification} + +The first thing a class or package file does is identify itself. +Package files do this as follows: +\begin{verbatim} + \NeedsTeXFormat{LaTeX2e} + \ProvidesPackage{<package>}[<date> <other information>] +\end{verbatim} +For example: +\begin{verbatim} + \NeedsTeXFormat{LaTeX2e} + \ProvidesPackage{latexsym}[1994/06/01 Standard LaTeX package] +\end{verbatim} +Class files do this as follows: +\begin{verbatim} + \NeedsTeXFormat{LaTeX2e} + \ProvidesClass{<class-name>}[<date> <other information>] +\end{verbatim} +For example: +\begin{verbatim} + \NeedsTeXFormat{LaTeX2e} + \ProvidesClass{article}[1994/06/01 Standard LaTeX class] +\end{verbatim} +\NEWdescription{1998/06/19} +The \m{date} should be given in the form `\textsc{yyyy/mm/dd}' and +must be present if the optional argument is used (this is also true +for the |\NeedsTeXFormat| command). +Any derivation from this syntax will result in low-level \TeX{} +errors---the commands expect a valid syntax to speed up the daily +usage of the package or class and make no provision for the case that +the developer made a mistake! + +This date is checked whenever a user specifies a date in their +|\documentclass| or |\usepackage| command. For example, if you wrote: +\begin{verbatim} + \documentclass{article}[1995/12/23] +\end{verbatim} +then users at a different location +would get a warning that their copy of |article| was out of +date. + +The description of a class is displayed when the class is used. The +description of a package is put into the log file. These descriptions +are also displayed by the |\listfiles| command. The phrase +\texttt{Standard LaTeX} \textbf{must not} be used in the identification +banner of any file other than those in the standard \LaTeX{} +distribution. + + +\subsection{Using classes and packages} + +The first major difference between \LaTeX~2.09 style files and +\LaTeXe{} packages and classes is that \LaTeXe{} supports +\emph{modularity}, in the sense of building files from small +building-blocks rather than using large single files. + +A \LaTeX{} package or class can load a package as follows: +\begin{verbatim} + \RequirePackage[<options>]{<package>}[<date>] +\end{verbatim} +For example: +\begin{verbatim} + \RequirePackage{ifthen}[1994/06/01] +\end{verbatim} +This command has the same syntax as the author command |\usepackage|. +It allows packages or classes to use features provided by other +packages. For example, by loading the |ifthen| package, a package +writer can use the `if\dots then\dots else\dots' commands provided +by that package. + +A \LaTeX{} class can load one other class as follows: +\begin{verbatim} + \LoadClass[<options>]{<class-name>}[<date>] +\end{verbatim} +For example: +\begin{verbatim} + \LoadClass[twocolumn]{article} +\end{verbatim} +This command has the same syntax as the author command |\documentclass|. +It allows classes to be based on the syntax and appearance of another +class. For example, by loading the |article| class, a class writer +only has to change the bits of |article| they don't like, rather than +writing a new class from scratch. + +\NEWfeature{1995/12/01} +The following commands can be used in the common case that you want to +simply load a class or package file with exactly those options that +are being used by the current class. +\begin{verbatim} + \LoadClassWithOptions{<class-name>}[<date>] + \RequirePackageWithOptions{<package>}[<date>] +\end{verbatim} +For example: +\begin{verbatim} + \LoadClassWithOptions{article} + \RequirePackageWithOptions{graphics}[1995/12/01] +\end{verbatim} + +\subsection{Declaring options} + +\NEWdescription{1998/12/01} +The other major difference between \LaTeX~2.09 styles and \LaTeXe{} +packages and classes is in option handling. Packages and classes can +now declare options and these can be specified by authors; for +example, the |twocolumn| option is declared by the |article| class. +Note that the name of an option should contain only those characters +allowed in a `\LaTeX{} name'; in particular it must not contain any +control sequences. + +An option is declared as follows: +\begin{verbatim} + \DeclareOption{<option>}{<code>} +\end{verbatim} +For example, the |dvips| option (slightly simplified) +to the |graphics| package is implemented as: +\begin{verbatim} + \DeclareOption{dvips}{\input{dvips.def}} +\end{verbatim} +This means that when an author writes |\usepackage[dvips]{graphics}|, +the file |dvips.def| is loaded. As another example, the |a4paper| +option is declared in the |article| class to set the |\paperheight| +and |\paperwidth| lengths: +\begin{verbatim} + \DeclareOption{a4paper}{% + \setlength{\paperheight}{297mm}% + \setlength{\paperwidth}{210mm}% + } +\end{verbatim} +Sometimes a user will request an option which the class +or package has not explicitly declared. By default this will produce +a warning (for classes) or error (for packages); this behaviour +can be altered as follows: +\begin{verbatim} + \DeclareOption*{<code>} +\end{verbatim} +For example, to make the package |fred| produce a warning rather than +an error for unknown options, you could specify: +\begin{verbatim} + \DeclareOption*{% + \PackageWarning{fred}{Unknown option `\CurrentOption'}% + } +\end{verbatim} +Then, if an author writes |\usepackage[foo]{fred}|, they will get a +warning \texttt{Package fred Warning: Unknown option `foo'.} As +another example, the |fontenc| package tries to load a file +|<ENC>enc.def| whenever the \m{ENC} option is used. This +can be done by writing: +\begin{verbatim} + \DeclareOption*{% + \input{\CurrentOption enc.def}% + } +\end{verbatim} +\NEWdescription{1998/12/01} +It is possible to pass options on to another package or class, using +the command |\PassOptionsToPackage| or |\PassOptionsToClass| (note +that this is a specialised operation that works only for option +names). For example, to pass every unknown option on to the |article| +class, you can use: +\begin{verbatim} + \DeclareOption*{% + \PassOptionsToClass{\CurrentOption}{article}% + } +\end{verbatim} +If you do this then you should make sure you load the class at some +later point, otherwise the options will never be processed! + +So far, we have explained only how to declare options, not how to +execute them. To process the options with which the file was called, +you should use: +\begin{verbatim} + \ProcessOptions\relax +\end{verbatim} +This executes the \m{code} for each option that was both specified and +declared (see Section~\ref{Sec:commands.options} for details of how +this is done). + +For example, if the |jane| package file contains: +\begin{verbatim} + \DeclareOption{foo}{\typeout{Saw foo.}} + \DeclareOption{baz}{\typeout{Saw baz.}} + \DeclareOption*{\typeout{What's \CurrentOption?}} + \ProcessOptions\relax +\end{verbatim} +and an author writes |\usepackage[foo,bar]{jane}|, then they will see +the messages \texttt{Saw foo.} and \texttt{What's bar?} + +\subsection{A minimal class file} + +Most of the work of a class or package is in defining new commands, or +changing the appearance of documents. This is done in the body of the +package, using commands such as |\newcommand| or |\setlength|. + +\LaTeXe{} provides several new commands to help class and package +writers; these are described in detail in Section~\ref{Sec:commands}. + +There are four things that every class file \emph{must} contain: these +are a definition of |\normalsize|, values for |\textwidth| and +|\textheight| and a specification for page-numbering. So a minimal +document class file\footnote {This class is now in the standard +distribution, as \texttt{minimal.cls}.} looks like this: +\begin{verbatim} + \NeedsTeXFormat{LaTeX2e} + \ProvidesClass{minimal}[1995/10/30 Standard LaTeX minimal class] + \renewcommand{\normalsize}{\fontsize{10pt}{12pt}\selectfont} + \setlength{\textwidth}{6.5in} + \setlength{\textheight}{8in} + \pagenumbering{arabic} % needed even though this class will + % not show page numbers +\end{verbatim} +However, this class file will not support footnotes, marginals, +floats, etc., nor will it provide any of the 2-letter font commands +such as |\rm|; thus most classes will contain more than this minimum! + +\subsection{Example: a local letter class} + +A company may have its own letter class, for setting letters in the +company style. This section shows a simple implementation of such a +class, although a real class would need more structure. + +The class begins by announcing itself as |neplet.cls|. +\begin{verbatim} + \NeedsTeXFormat{LaTeX2e} + \ProvidesClass{neplet}[1995/04/01 NonExistent Press letter class] +\end{verbatim} +Then this next bit passes any options on to the |letter| class, which +is loaded with the |a4paper| option. +\begin{verbatim} + \DeclareOption*{\PassOptionsToClass{\CurrentOption}{letter}} + \ProcessOptions\relax + \LoadClass[a4paper]{letter} +\end{verbatim} +In order to use the company letter head, it redefines the +|firstpage| page style: this is the page style that is used on +the first page of letters. +\begin{verbatim} + \renewcommand{\ps@firstpage}{% + \renewcommand{\@oddhead}{<letterhead goes here>}% + \renewcommand{\@oddfoot}{<letterfoot goes here>}% + } +\end{verbatim} +And that's it! + +\subsection{Example: a newsletter class} + +A simple newsletter can be typeset with \LaTeX{}, using a variant of the +|article| class. +The class begins by announcing itself as |smplnews.cls|. +\begin{verbatim} + \NeedsTeXFormat{LaTeX2e} + \ProvidesClass{smplnews}[1995/04/01 The Simple News newsletter class] + + \newcommand{\headlinecolor}{\normalcolor} +\end{verbatim} +It passes most specified options on to the |article| class: apart from +the |onecolumn| option, which is switched off, and the |green| option, +which sets the headline in green. +\begin{verbatim} + \DeclareOption{onecolumn}{\OptionNotUsed} + \DeclareOption{green}{\renewcommand{\headlinecolor}{\color{green}}} + + \DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} + + \ProcessOptions\relax +\end{verbatim} +It then loads the class |article| with the option |twocolumn|. +\begin{verbatim} + \LoadClass[twocolumn]{article} +\end{verbatim} +Since the newsletter is to be printed in colour, it now loads the +|color| package. The class does not specify a device driver option +since this should be specified by the user of the |smplnews| class. +\begin{verbatim} + \RequirePackage{color} +\end{verbatim} +The class then redefines |\maketitle| to produce the title in 72pt +Helvetica bold oblique, in the appropriate colour. +\begin{verbatim} + \renewcommand{\maketitle}{% + \twocolumn[% + \fontsize{72}{80}\fontfamily{phv}\fontseries{b}% + \fontshape{sl}\selectfont\headlinecolor + \@title + ]% + } +\end{verbatim} +It redefines |\section| and switches off section numbering. +\begin{verbatim} + \renewcommand{\section}{% + \@startsection + {section}{1}{0pt}{-1.5ex plus -1ex minus -.2ex}% + {1ex plus .2ex}{\large\sffamily\slshape\headlinecolor}% + } + + \setcounter{secnumdepth}{0} +\end{verbatim} +It also sets the three essential things. +\begin{verbatim} + \renewcommand{\normalsize}{\fontsize{9}{10}\selectfont} + \setlength{\textwidth}{17.5cm} + \setlength{\textheight}{25cm} +\end{verbatim} +In practice, a class would need more than this: it would provide +commands for issue numbers, authors of articles, page styles and so +on; but this skeleton gives a start. The |ltnews| class file is not +much more complex than this one. + +\section{Commands for class and package writers} +\label{Sec:commands} + +This section describes briefly each of the new commands for class and +package writers. To find out about other aspects of the new system, +you should also read \emph{\LaTeXbook}, \emph{\LaTeXcomp} and +\emph{\usrguide}. + +\subsection{Identification} + +The first group of commands discussed here are those used +to identify your class or package file. + +\begin{decl} +|\NeedsTeXFormat| \arg{format-name} \oarg{release-date} +\end{decl} +This command tells \TeX{} that this file should be processed using a +format with name \m{format-name}. You can use the optional argument +\m{release-date} to further specify the earliest release date of the +format that is needed. When the release date of the format is older +than the one specified a warning will be generated. The standard +\m{format-name} is \texttt{LaTeX2e}. The date, if present, must be in +the form \textsc{yyyy/mm/dd}. + +Example: +\begin{verbatim} + \NeedsTeXFormat{LaTeX2e}[1994/06/01] +\end{verbatim} + +\begin{decl} +|\ProvidesClass| \arg{class-name} \oarg{release-info} \\ +|\ProvidesPackage| \arg{package-name} \oarg{release-info} +\end{decl} +This declares that the current file contains the definitions for the +document class \m{class-name} or package \m{package-name}. + +The optional \m{release-info}, if used, must contain: +\begin{itemize} + \item the release date of + this version of the file, in the form \textsc{yyyy/mm/dd}; +\item optionally followed by a space and a short description, possibly + including a version number. +\end{itemize} +The above syntax must be followed exactly so that this information +can be used by |\LoadClass| or |\documentclass| (for classes) or +|\RequirePackage| or |\usepackage| (for packages) to test that the +release is not too old. + +The whole of this \m{release-info} information is displayed by +|\listfiles| and should therefore not be too long. + +Example: +\begin{verbatim} + \ProvidesClass{article}[1994/06/01 v1.0 Standard LaTeX class] + \ProvidesPackage{ifthen}[1994/06/01 v1.0 Standard LaTeX package] +\end{verbatim} + +\begin{decl} + |\ProvidesFile| \arg{file-name} \oarg{release-info} +\end{decl} +This is similar to the two previous commands except that here the full +filename, including the extension, must be given. It is used for +declaring any files other than main class and package files. + +Example: +\begin{verbatim} + \ProvidesFile{T1enc.def}[1994/06/01 v1.0 Standard LaTeX file] +\end{verbatim} + +Note that the phrase \texttt{Standard LaTeX} \textbf{must not} be used +in the identification banner of any file other than those in the +standard \LaTeX{} distribution. + +\subsection{Loading files} +\label{Sec:loadf} + +\NEWfeature{1995/12/01} +This group of commands can be used to create your own document class or +package by building on existing classes or packages. +\begin{decl} + |\RequirePackage| \oarg{options-list} \arg{package-name} + \oarg{release-info}\\ + |\RequirePackageWithOptions| \arg{package-name} + \oarg{release-info} +\end{decl} +Packages and classes should use these commands to load other packages. + +The use of |\RequirePackage| is the same as the author command +|\usepackage|. + +Examples: +\begin{verbatim} + \RequirePackage{ifthen}[1994/06/01] + \RequirePackageWithOptions{graphics}[1995/12/01] +\end{verbatim} + +\begin{decl} + |\LoadClass| \oarg{options-list} \arg{class-name} + \oarg{release-info}\\ + |\LoadClassWithOptions| \arg{class-name} + \oarg{release-info} +\end{decl} +\NEWfeature{1995/12/01} +These commands are for use \emph{only} in class files, they cannot be +used in packages files; +they can be used at most once within a class file. + +The use of |\LoadClass| is the same as +the use of |\documentclass| to load a class file. + +Examples: +\begin{verbatim} + \LoadClass{article}[1994/06/01] + \LoadClassWithOptions{article}[1995/12/01] +\end{verbatim} + +\NEWfeature{1995/12/01} +The two |WithOptions| versions simply load the class (or package) file +with exactly those options that are being used by the current file +(class or package). See below, in \ref{Sec:opmove}, for further +discussion of their use. + + +\subsection{Option declaration} +\label{Sec:commands.options.dec} + +\NEWdescription{1998/12/01} +The following commands deal with the declaration and handling of +options to document classes and packages. Every option name must be a +`\LaTeX{} name'. + +There are some commands designed especially for use within the +\m{code} argument of these commands (see below). + +\begin{decl} + |\DeclareOption| \arg{option-name} \arg{code} +\end{decl} +This makes \m{option-name} a `declared option' of the class or package +in which it is put. + +The \m{code} argument contains the code to be executed if that option +is specified for the class or package; it can contain any valid +\LaTeXe{} construct. + +Example: +\begin{verbatim} + \DeclareOption{twoside}{\@twosidetrue} +\end{verbatim} + +\begin{decl} + |\DeclareOption*| \arg{code} +\end{decl} +This declares the \m{code} to be executed for every option which is +specified for, but otherwise not explicitly declared by, the class or +package; this code is called the `default option code' and it can +contain any valid \LaTeXe{} construct. + +If a class file contains no |\DeclareOption*| then, by default, all +specified but undeclared options for that class will be silently +passed to all packages (as will the specified and declared options for +that class). + +If a package file contains no |\DeclareOption*| then, by default, each +specified but undeclared option for that package will produce an error. + + +\subsection{Commands within option code} +\label{Sec:within.code} + +These two commands can be used only within the \m{code} argument of +either |\DeclareOption| or |\DeclareOption*|. Other commands commonly +used within these arguments can be found in the next few subsections. + +\begin{decl} + |\CurrentOption| +\end{decl} +This expands to the name of the current option. + +\begin{decl} + |\OptionNotUsed| +\end{decl} +This causes the current option to +be added to the list of `unused options'. + +\NEWfeature{1995/06/01} + You can now include hash marks (\texttt{\#}) within these \m{code} + arguments without special treatment (formerly, it had been + necessary to double them). + +\subsection{Moving options around} +\label{Sec:opmove} + +These two commands are also very useful within the \m{code} argument +of |\DeclareOption| or |\DeclareOption*|: +\begin{decl} + |\PassOptionsToPackage| \arg{options-list} \arg{package-name}\\ + |\PassOptionsToClass| \arg{options-list} \arg{class-name} +\end{decl} +The command |\PassOptionsToPackage| passes the option names in +\m{options-list} to package \m{package-name}. +This means that it adds the \m{option-list} to the +list of options used by any future |\RequirePackage| or |\usepackage| +command for package \m{package-name}. + +Example: +\begin{verbatim} + \PassOptionsToPackage{foo,bar}{fred} + \RequirePackage[baz]{fred} +\end{verbatim} +is the same as: +\begin{verbatim} + \RequirePackage[foo,bar,baz]{fred} +\end{verbatim} + +Similarly, |\PassOptionsToClass| may be used in a class file to pass +options to another class to be loaded with |\LoadClass|. + +\NEWdescription{1995/12/01} +The effects and use of these two commands should be contrasted with +those of the following two (documented above, in \ref{Sec:loadf}): +\begin{verbatim} + \LoadClassWithOptions + \RequirePackageWithOptions +\end{verbatim} +The command |\RequirePackageWithOptions| is similar to +|\RequirePackage|, but it always loads the required package with +exactly the same option list as that being used by the current class +or package, rather than with any option explicitly supplied or passed +on by |\PassOptionsToPackage|. + +The main purpose of |\LoadClassWithOptions| is to allow one class to +simply build on another, for example: +\begin{verbatim} + \LoadClassWithOptions{article} +\end{verbatim} +This should be compared with the slightly different construction +\begin{verbatim} + \DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} + \ProcessOptions\relax + \LoadClass{article} +\end{verbatim} +As used above, the effects are more or less the same, but the first is +a lot less to type; also the |\LoadClassWithOptions| method runs +slightly quicker. + +If, however, the class declares options of its own then +the two constructions are different. Compare, for example: +\begin{verbatim} + \DeclareOption{landscape}{\@landscapetrue} + \ProcessOptions\relax + \LoadClassWithOptions{article} +\end{verbatim} +with: +\begin{verbatim} + \DeclareOption{landscape}{\@landscapetrue} + \DeclareOption*{\PassOptionsToClass{\CurrentOption}{article}} + \ProcessOptions\relax + \LoadClass{article} +\end{verbatim} +In the first example, the \textsf{article} class will be loaded with +option |landscape| precisely when the current class is called with +this option. By contrast, in the second example it will never be +called with option \texttt{landscape} as in that case \textsf{article} +is passed options only by the default option handler, but this handler +is not used for |landscape| because that option is explicitly +declared. + +\subsection{Delaying code} +\label{Sec:delays} + +These first two commands are also intended primarily for use within +the \m{code} argument of |\DeclareOption| or |\DeclareOption*|. + +\begin{decl} + |\AtEndOfClass| \arg{code}\\ + |\AtEndOfPackage| \arg{code} +\end{decl} +These commands declare \m{code} that is saved away internally and then +executed after processing the whole of the current class or package +file. + +Repeated use of these commands is permitted: the code in the +arguments is stored (and later executed) in the order of their +declarations. + +\begin{decl} + |\AtBeginDocument| \arg{code}\\ + |\AtEndDocument| \arg{code} +\end{decl} +These commands declare \m{code} to be saved internally and executed +while \LaTeX{} is executing |\begin{document}| or |\end{document}|. + +The \m{code} specified in the argument to |\AtBeginDocument| is +executed near the end of the |\begin{document}| code, \emph{after} the +font selection tables have been set up. It is therefore a useful +place to put code which needs to be executed after everything has been +prepared for typesetting and when the normal font for the document is +the current font. + +\NEWdescription{1995/12/01} +The |\AtBeginDocument| hook should not be used for code that does any +typesetting since the typeset result would be unpredictable. + +The \m{code} specified in the argument to |\AtEndDocument| is +executed at the beginning of the |\end{document}| code, +\emph{before} the final page is finished and before any leftover +floating environments are processed. If some of the \m{code} is to be +executed after these two processes, you should include a |\clearpage| +at the appropriate point in \m{code}. + +Repeated use of these commands is permitted: the code in the +arguments is stored (and later executed) in the order of their +declarations. + +\begin{decl}[1994/12/01] + |\AtBeginDvi| \arg{specials} +\end{decl} +These commands save in a box register things which are written to the +|.dvi| file at the beginning of the `shipout' of the first page of the +document. + +This should not be used for anything that will add any typeset +material to the |.dvi| file. + +Repeated use of this command is permitted. + + +\subsection{Option processing} +\label{Sec:commands.options} + +\begin{decl} + |\ProcessOptions| +\end{decl} +This command executes the \m{code} for each selected option. + +We shall first describe how |\ProcessOptions| works in a package file, +and then how this differs in a class file. + +To understand in detail what |\ProcessOptions| does in a package file, +you have to know the difference between \emph{local} and \emph{global} +options. +\begin{itemize} +\item \textbf{Local options} are those which have been explicitly + specified for this particular package in the \m{options} argument of + any of these: +\begin{quote} + |\PassOptionsToPackage{<options>}| \ |\usepackage[<options>]|\\ + |\RequirePackage[<options>]| +\end{quote} +\item \textbf{Global options} are any other options that are specified + by the author in the \m{options} argument of + |\documentclass[<options>]|. +\end{itemize} +For example, suppose that a document begins: +\begin{verbatim} + \documentclass[german,twocolumn]{article} + \usepackage{gerhardt} +\end{verbatim} +whilst package |gerhardt| calls package |fred| with: +\begin{verbatim} + \PassOptionsToPackage{german,dvips,a4paper}{fred} + \RequirePackage[errorshow]{fred} +\end{verbatim} +then: +\begin{itemize} +\item |fred|'s local options are |german|, |dvips|, |a4paper| + and |errorshow|; +\item |fred|'s only global option is |twocolumn|. +\end{itemize} + +When |\ProcessOptions| is called, the following happen. +\begin{itemize} +\item \emph{First}, for each option so far declared in |fred.sty| + by |\DeclareOption|, it looks to see if that option is either a + global or a local option for |fred|: if it is then the corresponding + code is executed. + + This is done in the order in which these options + were declared in |fred.sty|. +\item \emph{Then}, for each remaining \emph{local} option, the command + |\ds@<option>| is executed if it has been defined somewhere (other + than by a |\DeclareOption|); otherwise, the `default option code' is + executed. If no default option code has been declared then an error + message is produced. + + This is done in the order in which these + options were specified. +\end{itemize} +Throughout this process, the system ensures that the code declared for +an option is executed at most once. + +Returning to the example, if |fred.sty| contains: +\begin{verbatim} + \DeclareOption{dvips}{\typeout{DVIPS}} + \DeclareOption{german}{\typeout{GERMAN}} + \DeclareOption{french}{\typeout{FRENCH}} + \DeclareOption*{\PackageWarning{fred}{Unknown `\CurrentOption'}} + \ProcessOptions\relax +\end{verbatim} +then the result of processing this document will be: +\begin{verbatim} + DVIPS + GERMAN + Package fred Warning: Unknown `a4paper'. + Package fred Warning: Unknown `errorshow'. +\end{verbatim} +Note the following: + +\begin{itemize} +\item the code for the |dvips| option is executed before that for the + |german| option, because that is the order in which they are declared + in |fred.sty|; +\item the code for the |german| option is executed only once, when the + declared options are being processed; +\item the |a4paper| and |errorshow| options produce the warning from + the code declared by |\DeclareOption*| (in the order in which they + were specified), whilst the |twocolumn| option does not: this is + because |twocolumn| is a global option. +\end{itemize} + +In a class file, |\ProcessOptions| works in the same way, except +that: \emph{all} options are local; and the default value for +|\DeclareOption*| is |\OptionNotUsed| rather than an error. + +\NEWdescription{1995/12/01} +Note that, because |\ProcessOptions| has a |*|-form, it is wise to +follow the non-star form with |\relax|, as in the previous examples, +since this prevents unnecessary look ahead and possibly misleading +error messages being issued. + +\begin{decl} + |\ProcessOptions*| \\ + |\@options| +\end{decl} +This is like |\ProcessOptions| but it executes the options in the +order specified in the calling commands, rather than in the order of +declaration in the class or package. For a package this means that the +global options are processed first. + +The |\@options| command from \LaTeX~2.09 has been made equivalent to +this in order to ease the task of updating old document styles to +\LaTeXe{} class files. + +\begin{decl} + |\ExecuteOptions| \arg{options-list} +\end{decl} + +For each option in the \m{options-list}, in order, +this command simply executes the command +|\ds@<option>| (if this command is not defined, then that option is +silently ignored). + +It can be used to provide a `default option list' just before +|\ProcessOptions|. For example, suppose that in a class file you want +to set up the default design to be: two-sided printing; 11pt fonts; +in two columns. Then it could specify: +\begin{verbatim} + \ExecuteOptions{11pt,twoside,twocolumn} +\end{verbatim} + + +\subsection{Safe file commands} + +These commands deal with file input; they ensure that the non-existence +of a requested file can be handled in a user-friendly way. + +\begin{decl} +|\IfFileExists| \arg{file-name} \arg{true} \arg{false} +\end{decl} +If the file exists then the code specified in \m{true} is +executed. + +If the file does not exist then the code specified in \m{false} is +executed. + +This command does \emph{not} input the file. + +\begin{decl} + |\InputIfFileExists| \arg{file-name} \arg{true} \arg{false} +\end{decl} +This inputs the file \m{file-name} if it exists and, immediately +before the input, the code specified in \m{true} is executed. + +If the file does not exist then the code specified in \m{false} is +executed. + +It is implemented using |\IfFileExists|. + + +\subsection{Reporting errors, etc} + +These commands should be used by third party classes and packages to +report errors, or to provide information to authors. + +\begin{decl} + |\ClassError| \arg{class-name} \arg{error-text} \arg{help-text}\\ + |\PackageError| \arg{package-name} \arg{error-text} \arg{help-text} +\end{decl} +These produce an error message. The \m{error-text} is displayed and the +|?| error prompt is shown. If the user types |h|, they will be shown +the \m{help-text}. + +Within the \m{error-text} and \m{help-text}: |\protect| can be used to +stop a command from expanding; |\MessageBreak| causes a line-break; +and |\space| prints a space. + +Note that the \m{error-text} will have a full stop added to it, so do +not put one into the argument. + +For example: +\begin{verbatim} + \newcommand{\foo}{FOO} + \PackageError{ethel}{% + Your hovercraft is full of eels,\MessageBreak + and \protect\foo\space is \foo + }{% + Oh dear! Something's gone wrong.\MessageBreak + \space \space Try typing \space <<return>> + \space to proceed, ignoring \protect\foo. + } +\end{verbatim} +produces this display: +\begin{verbatim} + ! Package ethel Error: Your hovercraft is full of eels, + (ethel) and \foo is FOO. + + See the ethel package documentation for explanation. +\end{verbatim} +If the user types |h|, this will be shown: +\begin{verbatim} + Oh dear! Something's gone wrong. + Try typing <<return>> to proceed, ignoring \foo. +\end{verbatim} + +\begin{decl} + |\ClassWarning| \arg{class-name} \arg{warning-text}\\ + |\PackageWarning| \arg{package-name} \arg{warning-text}\\ + |\ClassWarningNoLine| \arg{class-name} \arg{warning-text}\\ + |\PackageWarningNoLine| \arg{package-name} \arg{warning-text}\\ + |\ClassInfo| \arg{class-name} \arg{info-text}\\ + |\PackageInfo| \arg{package-name} \arg{info-text} +\end{decl} +The four |Warning| commands are similar to the error commands, except +that they produce only a warning on the screen, with no error prompt. + +The first two, |Warning| versions, also show the line number where the +warning occurred, whilst the second two, |WarningNoLine| versions, do +not. + +The two |Info| commands are similar except that they log the +information only in the transcript file, including the line number. +There are no |NoLine| versions of these two. + +Within the \m{warning-text} and \m{info-text}: |\protect| can be used to +stop a command from expanding; |\MessageBreak| causes a line-break; +and |\space| prints a space. +Also, these should not end with a full stop as one is +automatically added. + + +\subsection{Defining commands} +\label{Sec:commands.define} + +\LaTeXe{} provides some extra methods of (re)defining commands that are +intended for use in class and package files. + +\NEWfeature{1994/12/01} +The \texttt{*}-forms of these commands should be used to define +commands that are not, in \TeX{} terms, long. This can be useful for +error-trapping with commands whose arguments are not intended to +contain whole paragraphs of text. + +\begin{decl} + |\DeclareRobustCommand| \arg{cmd} \oarg{num} \oarg{default} + \arg{definition}\\ + |\DeclareRobustCommand*| \arg{cmd} \oarg{num} \oarg{default} + \arg{definition} +\end{decl} +This command takes the same arguments as |\newcommand| but it declares +a robust command, even if some code within the \m{definition} is +fragile. You can use this command to define new robust commands, or +to redefine existing commands and make them robust. A log is put into +the transcript file if a command is redefined. + +For example, if |\seq| is defined as follows: +\begin{verbatim} + \DeclareRobustCommand{\seq}[2][n]{% + \ifmmode + #1_{1}\ldots#1_{#2}% + \else + \PackageWarning{fred}{You can't use \protect\seq\space in text}% + \fi + } +\end{verbatim} +Then the command |\seq| can be used in moving arguments, even though +|\ifmmode| cannot, for example: +\begin{verbatim} + \section{Stuff about sequences $\seq{x}$} +\end{verbatim} + +Note also that there is no need to put a |\relax| before the +|\ifmmode| at the beginning of the definition; this is because the +protection given by this |\relax| against expansion at the wrong time +will be provided internally. + +\begin{decl} + |\CheckCommand| \arg{cmd} \oarg{num} \oarg{default} + \arg{definition}\\ + |\CheckCommand*| \arg{cmd} \oarg{num} \oarg{default} + \arg{definition} +\end{decl} +This takes the same arguments as |\newcommand| but, rather than define +\m{cmd}, it just checks that the current definition of \m{cmd} is +exactly as given by \m{definition}. An error is raised if these +definitions differ. + +This command is useful for checking the state of the system before +your package starts altering the definitions of commands. It allows +you to check, in particular, that no other package has redefined the +same command. + +\subsection{Moving arguments} + +\NEWdescription{1994/12/01} +The setting of protect whilst processing (i.e.~moving) moving arguments +has been reimplemented, as has the method of writing information from +the |.aux| file to other files such as the |.toc| file. Details can +be found in the file |ltdefns.dtx|. + +We hope that these changes will not affect many packages. + +\section{Miscellaneous commands, etc} +\label{Sec:commands.misc} + +\subsection{Layout parameters} + +\begin{decl} +|\paperheight|\\ +|\paperwidth| +\end{decl} +These two parameters are usually set by the class to be the size of +the paper being used. This should be actual paper size, unlike +|\textwidth| and |\textheight| which are the size of the main text +body within the margins. + + +\subsection{Case changing} +\label{sec:case} + +\begin{decl} + |\MakeUppercase| \arg{text} \\ + |\MakeLowercase| \arg{text} +\end{decl} + +\NEWfeature{1995/06/01} +\TeX{} provides two primitives |\uppercase| and |\lowercase| for +changing the case of text. These are sometimes used in document +classes, for example to set information in running heads in all +capitals. + +Unfortunately, these \TeX{} primitives do not change the case of +characters accessed by commands like |\ae| or |\aa|. To overcome this +problem, \LaTeX{} provides two new commands |\MakeUppercase| and +|\MakeLowercase| to do this. + +For example: +\begin{quotation} +\begin{tabular}{rl} + |\uppercase{aBcD\ae\AA\ss\OE}| & \uppercase{aBcD\ae\AA\ss\OE}\\ + |\lowercase{aBcD\ae\AA\ss\OE}| & \lowercase{aBcD\ae\AA\ss\OE}\\ + |\MakeUppercase{aBcD\ae\AA\ss\OE}| & + \MakeUppercase{aBcD\ae\AA\ss\OE}\\ + |\MakeLowercase{aBcD\ae\AA\ss\OE}| & \MakeLowercase{aBcD\ae\AA\ss\OE} +\end{tabular} +\end{quotation} + +The commands |\MakeUppercase| and |\MakeLowercase| themselves are +robust, but they have moving arguments. + +The commands use the \TeX{} primitives |\uppercase| and |\lowercase|, +and so have a number of unexpected `features'. In particular, they +change the case of everything (except characters in the names of +control-sequences) in their text argument: this includes mathematics, +environment names, and label names. + +For example: +\begin{verbatim} + \MakeUppercase{$x+y$ in \ref{foo}} +\end{verbatim} +produces $X+Y$ and the warning: +\begin{verbatim} + LaTeX Warning: Reference `FOO' on page ... undefined on ... +\end{verbatim} +In the long run, we would like to use all-caps fonts rather than any +command like |\MakeUppercase| but this is not possible at the moment +because such fonts do not exist. + +\NEWdescription{1995/12/01} +In order that upper/lower-casing will work reasonably well, and in +order to provide any correct hyphenation, \LaTeXe{} \emph{must} use, +throughout a document, the same fixed table for changing case. +The table used is designed for the font encoding |T1|; this works well +with the standard \TeX{} fonts for all Latin alphabets but will cause +problems when using other alphabets. + +\subsection{The `openany' option in the `book' class} + +\NEWdescription{1996/06/01} +The |openany| option allows chapter and similar openings to +occur on left hand pages. Previously this option affected only +|\chapter| and |\backmatter|. It now also affects +|\part|, |\frontmatter| and |\mainmatter|. + +\subsection{Better user-defined math display environments} + +\begin{decl} + |\ignorespacesafterend| +\end{decl} + +\NEWfeature{1996/12/01} +\NEWdescription{2003/12/01} +Suppose that you want to define an environment for displaying text +that is numbered as an equation. A straightforward way to do this is +as follows: +\begin{verbatim} + \newenvironment{texteqn} + {\begin{equation} + \begin{minipage}{0.9\linewidth}} + {\end{minipage} + \end{equation}} +\end{verbatim} +However, if you have tried this then you will probably have noticed +that it does not work perfectly when used in the middle of a paragraph +because an inter-word space appears at the beginning of the first +line after the environment. + +There is now an extra command (with a very long name) available that +you can use to avoid this problem; it should be inserted as shown here: +\begin{verbatim} + \newenvironment{texteqn} + {\begin{equation} + \begin{minipage}{0.9\linewidth}} + {\end{minipage} + \end{equation} + \ignorespacesafterend} +\end{verbatim} + +This command may also have other uses. + +\subsection{Normalising spacing} + +\begin{decl} + |\normalsfcodes| +\end{decl} + +\NEWfeature{1997/06/01} +This command should be used to restore the normal settings of the +parameters that affect spacing between words, sentences, etc. + +An important use of this feature is to correct a problem, reported by +Donald Arseneau, that punctuation in page headers has always (in all +known \TeX{} formats) been potentially wrong whenever a page break +happens while a local setting of the space codes is in effect. These +space codes are changed by, for example, the command +\verb|\frenchspacing|) and the \textsf{verbatim} environment. + +It is normally given the correct definition automatically in +|\begin{document}| and so need not be explicitly set; however, if it +is explicitly made nonempty in a class file then automatic +default setting will be over-ridden. + + +\section{Upgrading \LaTeX~2.09 classes and packages} +\label{Sec:upgrade} + +This section describes the changes you may need to make when you +upgrade an existing \LaTeX{} style to a package or class but we shall +start in optimistic mode. + +Many existing style files will run with \LaTeXe{} without any +modification to the file itself. When everything is running OK, +please put a note in the newly created package or class file to record +that it runs with the new standard \LaTeX{}; then distribute it to +your users. + +\subsection{Try it first!} +\label{Sec:try-it} + +The first thing you should do is to test your style in `compatibility +mode'. The only change you need to make in order to do this is, +possibly, to change the extension of the file to |.cls|: you should +make this change only if your file was used as a main document style. +Now, without any other modifications, run \LaTeXe{} on a document that +uses your file. This assumes that you have a suitable collection of +files that tests all the functionality provided by your style file. +(If you haven't, now is the time to make one!) + +You now need to change the test document files so that they are +\LaTeXe{} documents: see \emph{\usrguide} for details of how to do +this and then try them again. You have now tried the test documents +in both \LaTeXe{} native mode and \LaTeX~2.09 compatibility mode. + +\subsection{Troubleshooting} +\label{Sec:trouble} + +If your file does not work with \LaTeXe{}, there are two likely +reasons. +\begin{itemize} +\item \LaTeX{} now has a robust, well-defined designer's interface for + selecting fonts, which is very different from the \LaTeX~2.09 + internals. +\item Your style file may have used some \LaTeX~2.09 internal commands + which have changed, or which have been removed. +\end{itemize} + +When you are debugging your file, you will probably need more +information than is normally displayed by \LaTeXe. This is achieved +by resetting the counter |errorcontextlines| from its default value of +$-1$ to a much higher value, e.g.~999. + +\subsection{Accommodating compatibility mode} + +Sometimes an existing collection of \LaTeX~2.09 documents makes it +inconvenient or impossible to abandon the old commands entirely. +If this is the case, then it is possible to accommodate both conventions +by making special provision for documents processed in compatibility +mode. + +\begin{decl} +|\if@compatibility| +\end{decl} +This switch is set when a document begins with |\documentstyle| rather +than |\documentclass|. Appropriate code can be supplied for either +condition, as follows: +\begin{verbatim} + \if@compatibility + <code emulating LaTeX 2.09 behavior> + \else + <code suitable for LaTeX2e> + \fi +\end{verbatim} + + +\subsection{Font commands} + +Some font and size commands are now defined by the document class +rather than by the \LaTeX{} kernel. If you are upgrading a +\LaTeX~2.09 document style to a class that does not load one of the +standard classes, then you will probably need to add definitions for +these commands. + +\begin{decl} + |\rm| |\sf| |\tt| |\bf| |\it| |\sl| |\sc| +\end{decl} +None of these short-form font selection commands are defined in the +\LaTeXe{} kernel. They are defined by all the standard class files. + +If you want to define them in your class file, there are several +reasonable ways to do this. + +One possible definition is: +\begin{verbatim} + \newcommand{\rm}{\rmfamily} + ... + \newcommand{\sc}{\scshape} +\end{verbatim} +This would make the font commands orthogonal; for example +|{\bf\it text}| would produce bold italic, thus: \textbf{\textit{text}}. +It will also make them produce an error if used in math mode. + +Another possible definition is: +\begin{verbatim} + \DeclareOldFontCommand{\rm}{\rmfamily}{\mathrm} + ... + \DeclareOldFontCommand{\sc}{\scshape}{\mathsc} +\end{verbatim} +This will make |\rm| act like |\rmfamily| in text mode (see above) and +it will make |\rm| select the |\mathrm| math alphabet in math mode. + +Thus |${\rm math} = X + 1$| will produce `${\rm math} = X + 1$'. + +If you do not want font selection to be orthogonal then you can +follow the standard classes and define: +\begin{verbatim} + \DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm} + ... + \DeclareOldFontCommand{\sc}{\normalfont\scshape}{\mathsc} +\end{verbatim} +This means, for example, that |{\bf\it text}| will produce medium +weight (rather than bold) italic, thus: \textit{text}. + +\begin{decl} + |\normalsize| \\ + |\@normalsize| +\end{decl} +The command |\@normalsize| is retained for compatibility with +\LaTeX~2.09 packages which may have used its value; but redefining it +in a class file will have no effect since it is always reset to have +the same meaning as |\normalsize|. + +This means that classes \emph{must} now redefine |\normalsize| rather +than redefining |\@normalsize|; for example (a rather incomplete one): +\begin{verbatim} + \renewcommand{\normalsize}{\fontsize{10}{12}\selectfont} +\end{verbatim} +Note that |\normalsize| is defined by the \LaTeX{} kernel to be an +error message. + +\begin{decl} + |\tiny| |\footnotesize| |\small| |\large|\\ + |\Large| |\LARGE| |\huge| |\Huge| +\end{decl} +None of these other `standard' size-changing commands are defined in +the kernel: each needs to be defined in a class file if you need it. +They are all defined by the standard classes. + +This means you should use |\renewcommand| for |\normalsize| and +|\newcommand| for the other size-changing commands. + + +\subsection{Obsolete commands} + +Some packages will not work with \LaTeXe{}, normally because they relied +on an internal \LaTeX{} command which was never supported and has now +changed, or been removed. + +In many cases there will now be a robust, high-level means of +achieving what previously required low-level commands. Please consult +Section~\ref{Sec:commands} to see if you can now use the \LaTeXe{} +class and package writers commands. + +Also, of course, if your package or class redefined any of the kernel +commands (i.e.~those defined in the files |latex.tex|, |slitex.tex|, +|lfonts.tex|, |sfonts.tex|) then you will need to check it very +carefully against the new kernel in case the implementation has +changed or the command no longer exists in the \LaTeX2e{} kernel. + +Too many of the internal commands of \LaTeX~2.09 have been +re-implemented or removed to be able to list them all here. You must +check any that you have used or changed. + +We shall, however, list some of the more important commands which are +no longer supported. + +\begin{decl} + |\tenrm| |\elvrm| |\twlrm| \dots\\ + |\tenbf| |\elvbf| |\twlbf| \dots\\ + |\tensf| |\elvsf| |\twlsf| \dots\\ + \qquad$\vdots$ +\end{decl} +The (approximately) seventy internal commands of this form are no longer +defined. If your class or package uses them then \emph{please} +replace them with new font commands described in \emph{\fntguide}. + +For example, the command |\twlsf| should be replaced by: +\begin{verbatim} + \fontsize{12}{14}\normalfont\sffamily\selectfont +\end{verbatim} + +Another possibility is to use the |rawfonts| package, described in +\emph{\usrguide}. + +Also, remember that many of the fonts preloaded by \LaTeX~2.09 +are no longer preloaded. + +\begin{decl} + |\vpt| |\vipt| |\viipt| \dots +\end{decl} +These were the internal size-selecting commands in \LaTeX~2.09. +(They can still be used in \LaTeX~2.09 compatibility mode.) +Please use the command |\fontsize| instead: see \emph{\fntguide} for +details. + +For example, |\vpt| should be replaced by: +\begin{verbatim} + \fontsize{5}{6}\normalfont\selectfont +\end{verbatim} + +\begin{decl} + |\prm|, |\pbf|, |\ppounds|, |\pLaTeX| \dots +\end{decl} +\LaTeX~2.09 used several commands beginning with |\p| in order to +provide `protected' commands. For example, |\LaTeX| was defined to be +|\protect\pLaTeX|, and |\pLaTeX| was defined to produce the \LaTeX{} +logo. This made |\LaTeX| robust, even though |\pLaTeX| was not. + +These commands have now been reimplemented using +|\DeclareRobustCommand| +(described in Section~\ref{Sec:commands.define}). +If your package redefined one of the |\p|-commands then you must +remove the redefinition and use |\DeclareRobustCommand| to redefine the +non-|\p| command. + +\begin{decl} +|\footheight|\\ +|\@maxsep|\\ +|\@dblmaxsep| +\end{decl} +These parameters are not used by \LaTeXe{} so they have been removed, +except in \LaTeX~2.09 compatibility mode. Classes should no longer +set them. + +\begin{thebibliography}{1} + +\bibitem{A-W:DEK91} +Donald~E. Knuth. +\newblock {\em The \TeX book}. +\newblock Addison-Wesley, Reading, Massachusetts, 1986. +\newblock Revised to cover \TeX3, 1991. + +\bibitem{A-W:LLa94} +Leslie Lamport. +\newblock {\em {\LaTeX:} A Document Preparation System}. +\newblock Addison-Wesley, Reading, Massachusetts, second edition, 1994. + +\bibitem{A-W:MG2004} +Frank Mittelbach and Michel Goossens. +\newblock {\em The {\LaTeX} Companion second edition}. +\newblock With Johannes Braams, David Carlisle, and Chris Rowley. +\newblock Addison-Wesley, Reading, Massachusetts, 2004. + +\end{thebibliography} + +\newpage +\thispagestyle{empty} + +\section*{\LaTeXe{} Summary sheet: updating old styles} + +Section references below are to \emph{\clsguide}. + +\begin{enumerate} + +\item Should it become a class or a package? + See Section~\ref{Sec:classorpkg} for how to answer this question. + +\item If it uses another style file, then you will need to obtain an + updated version of this other file. Look at Section~\ref{Sec:loading} + for information on how to load other class and package files. + +\item Try it: see Section~\ref{Sec:try-it}. + +\item It worked? Excellent, but there are probably still some things + you should change in order to make your file into a well-structured + \LaTeXe{} file that is both robust and portable. So you should now + read Section~\ref{Sec:writing}, especially~\ref{Sec:general}. You + will also find some useful examples in Section~\ref{Sec:structure}. + + If your file sets up new fonts, font-changing commands or symbols, + you should also read \emph{\fntguide}. + +\item It did not work? There are three possibilities here: + \begin{itemize} + \item error messages are produced whilst reading your file; + \item error messages are produced whilst processing test documents; + \item there are no errors but the output is not as it should be. + \end{itemize} + Don't forget to check carefully for this last possibility. + + If you have got to this stage then you will need to read + Section~\ref{Sec:upgrade} to find the solutions that will make your + file work. +\end{enumerate} + +\end{document} diff --git a/macros/latex/base/clsguide.pdf b/macros/latex/base/clsguide.pdf index 14152ab987..aa9fe4f90a 100644 Binary files a/macros/latex/base/clsguide.pdf and b/macros/latex/base/clsguide.pdf differ diff --git a/macros/latex/base/clsguide.tex b/macros/latex/base/clsguide.tex index 0ed5e60817..7225425ec8 100644 --- a/macros/latex/base/clsguide.tex +++ b/macros/latex/base/clsguide.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -28,13 +28,13 @@ % \fi % Filename: clsguide.tex -\NeedsTeXFormat{LaTeX2e}[1995/12/01] +\documentclass{ltxguide} -\documentclass{ltxguide}[1995/11/28] +\usepackage[T1]{fontenc} % needed for \textbackslash in tt +\usepackage{csquotes} -\title{\LaTeXe~for class and package writers} - -\author{Copyright \copyright~1995--2006 The \LaTeX\ Project\\ +\title{\LaTeX\ for package and class authors --- current version} +\author{\copyright~Copyright 2023, \LaTeX\ Project Team.\\ All rights reserved.% \footnote{This file may distributed and/or modified under the conditions of the \LaTeX{} Project Public License, either version 1.3c @@ -42,7 +42,18 @@ \texttt{clsguide.tex} for full details.}% } -\date{15 February 2006} +\date{2023-01-12} + +\NewDocumentCommand\cs{m}{\texttt{\textbackslash\detokenize{#1}}} +\NewDocumentCommand\marg{m}{\arg{#1}} +\NewDocumentCommand\meta{m}{\ensuremath{\langle}\textit{#1}\ensuremath{\rangle}} +\NewDocumentCommand\pkg{m}{\textsf{#1}} +\NewDocumentCommand\text{m}{\ifmmode\mbox{#1}\else#1\fi} +% Fix a 'feature' +\makeatletter +\renewcommand \verbatim@font {\normalfont \ttfamily} +\makeatother +\providecommand\url[1]{\texttt{#1}} \begin{document} @@ -52,105 +63,74 @@ \section{Introduction} -This document is an introduction to writing classes and packages for -\LaTeX{}, with special attention given to upgrading existing -\LaTeX~2.09 packages to \LaTeXe{}. The latter subject is also -covered in an article by Johannes Braams published in TUGboat~15.3. - -\subsection{Writing classes and packages for \LaTeXe} - -\LaTeX{} is a document preparation system that enables the document -writer to concentrate on the contents of their text, without bothering -too much about the formatting of it. For example, chapters are -indicated by |\chapter{<title>}| rather than by selecting 18pt bold. +\LaTeXe{} was released in 1994 and added a number of then-new concepts to +\LaTeX{}. For package and class authors, these are described in +\texttt{clsguide-historic}, which has largely remained unchanged. Since then, +the \LaTeX{} team have worked on a number of ideas, firstly a programming +language for \LaTeX{} (L3 programming layer) and then a range of tools for +authors which build on that language. Here, we describe the current, stable set +of tools provided by the \LaTeX{} kernel for package and class developers. We +assume familiarity with general \LaTeX{} usage as a document author, and that +the material here is read in conjunction with \texttt{usrguide}, which provides +information for general \LaTeX{} users on up-to-date approaches to creating +commands, etc. -The file that contains the information about how to turn logical -structure (like `|\chapter|') into formatting (like `18pt bold ragged -right') is a \emph{document class}. In addition, some features (such -as colour or included graphics) are independent of the document class -and these are contained in \emph{packages}. - -One of the largest differences between \LaTeX~2.09 and \LaTeXe{} is in -the commands used to write packages and classes. In \LaTeX~2.09, -there was very little support for writing |.sty| files, and so writers -had to resort to using low-level commands. +\section{Writing classes and packages} +\label{Sec:writing} -\LaTeXe{} provides high-level commands for structuring packages. -It is also much easier to build classes and packages on top of each -other, for example writing a local technical report class |cetechr| -(for the Chemical Engineering department) based on |article|. +This section covers some general points concerned with writing +\LaTeX{} classes and packages. -\subsection{Overview} +\subsection{Is it a class or a package?} +\label{Sec:classorpkg} -This document contains an overview of how to write classes and -packages for \LaTeX{}. It does \emph{not} introduce all of the -commands necessary to write packages: these can be found in either -\emph{\LaTeXbook} or \emph{\LaTeXcomp}. But it does describe the new -commands for structuring classes and packages. +The first thing to do when you want to put some new \LaTeX{} commands +in a file is to decide whether it should be a \emph{document class} or a +\emph{package}. The rule of thumb is: +\begin{quote} + If the commands could be used with any document class, then make + them a package; and if not, then make them a class. +\end{quote} -\begin{description} +There are two major types of class: those like |article|, |report| or +|letter|, which are free-standing; and those which are extensions or +variations of other classes---for example, the |proc| document class, +which is built on the |article| document class. -\item[Section~\ref{Sec:general}] contains some general advice about - writing classes and packages. It describes the difference between - classes and packages, the command naming conventions, the use of - |doc| and |docstrip|, how \TeX's primitive file and box commands - interact with \LaTeX{}. It also contains some hints about general - \LaTeX{} style. +Thus, a company might have a local |ownlet| class for printing letters +with their own headed note-paper. Such a class would build on top of +the existing |letter| class but it cannot be used with any other +document class, so we have |ownlet.cls| rather than |ownlet.sty|. -\item[Section~\ref{Sec:structure}] describes the structure of classes - and packages. This includes building classes and packages on top of - other classes and packages, declaring options and declaring - commands. It also contains example classes. +The |graphics| package, in contrast, provides commands for including +images into a \LaTeX{} document. Since these commands can be used +with any document class, we have |graphics.sty| rather than +|graphics.cls|. -\item[Section~\ref{Sec:commands}] lists the new class and package - commands. +\subsection{Using `docstrip' and `doc'} - \item[Section~\ref{Sec:upgrade}] gives detailed advice on how to - upgrade existing \LaTeX~2.09 classes and packages to \LaTeXe{}. +If you are going to write a large class or package for \LaTeX{} then +you should consider using the |doc| software which comes with +\LaTeX{}. +\LaTeX{} classes and packages written using this can be +processed in two ways: they can be run through \LaTeX{}, to produce +documentation; and they can be processed with |docstrip|, to produce +the |.cls| or |.sty| file. -\end{description} +The |doc| software can automatically generate indexes of definitions, +indexes of command use, and change-log lists. It is very useful for +maintaining and documenting large \TeX{} sources. -\subsection{Further information} - -For a general introduction to \LaTeX{}, including the new features of -\LaTeXe{}, you should read \emph{\LaTeXbook} -by Leslie Lamport~\cite{A-W:LLa94}. - -A more detailed description of the new features of \LaTeX, including an -overview of more than 200 packages and nearly 1000 ready to run examples, is -to be found in \emph{\LaTeXcomp\ second edition} by Frank Mittelbach and -Michel Goossens~\cite{A-W:MG2004}. - -The \LaTeX{} system is based on \TeX{}, which is -described in \emph{The \TeX book} by Donald E.~Knuth~\cite{A-W:DEK91}. - -There are a number of documentation files which accompany every copy -of \LaTeX{}. A copy of \emph{\LaTeX{} News} will come out with each -six-monthly release of \LaTeX{}, and is found in the files -|ltnews*.tex|. The author's guide \emph{\usrguide} describes the new -\LaTeX{} document features; it is in |usrguide.tex|. The guide -\emph{\fntguide} describes the \LaTeX{} font selection scheme for -class- and package-writers; it is in |fntguide.tex|. Configuring -\LaTeX{} is covered by the guide \emph{\cfgguide} in -\texttt{cfgguide.tex} whilst the philosophy behind our policy on -modifying \LaTeX{} is described in \emph{\modguide} in -\texttt{modguide.tex}. - -The documented source code (from the files used to produce the kernel -format via |latex.ltx|) is now available as -\emph{The \LaTeXe\ Sources}. -This very large document also includes an index of -\LaTeX{} commands. It can be typeset from the \LaTeX{} file -|source2e.tex| in the |base| directory, using the source files and -the class file |ltxdoc.cls| from this directory. - -For more information about \TeX{} and \LaTeX{}, please contact your -local \TeX{} Users Group, or the international \TeX{} Users Group. -Addresses and other details can be found at: -\begin{quote}\small\label{addrs} - \texttt{http://www.tug.org/lugs.html} -\end{quote} +The documented sources of the \LaTeX{} kernel itself, and of the +standard classes, etc., are |doc| documents; they are in the |.dtx| +files in the distribution. You can, in fact, typeset the source code +of the kernel as one long document, complete with index, by running +\LaTeX{} on |source2e.tex|. Typesetting these documents uses the +class file |ltxdoc.cls|. +For more information on |doc| and |docstrip|, consult the files +|docstrip.dtx|, |doc.dtx|, and \emph{\LaTeXcomp}. For examples of its +use, look at the |.dtx| files. \subsection{Policy on standard classes} @@ -182,89 +162,10 @@ packages that can be used to enhance these classes. So your first thought when you consider such a deficiency will, we hope, be ``what can I do to improve this?'' -Similar considerations apply to those parts of the kernel that are -implementing design decisions, many of which should be left to the -class file but are not in the current system. We realise that in such -cases it is much more difficult for you to rectify the problem -yourself but it is also the case that making such changes in the -kernel would probably be a major project for us; therefore such -enhancements will have to wait for \LaTeX3. - -\section{Writing classes and packages} -\label{Sec:writing} - -This section covers some general points concerned with writing -\LaTeX{} classes and packages. - - -\subsection{Old versions} - -If you are upgrading an existing \LaTeX~2.09 style file then we -recommend freezing the 2.09 version and no longer maintaining it. -Experience with the various dialects of \LaTeX{} which existed in the -early 1990's suggests that maintaining packages for different versions -of \LaTeX{} is almost impossible. It will, of course, be necessary -for some organisations to maintain both versions in parallel for some -time but this is not essential for those packages and classes -supported by individuals: they should support only the new standard -\LaTeXe{}, not obsolete versions of \LaTeX{}. - - -\subsection{Using `docstrip' and `doc'} - -If you are going to write a large class or package for \LaTeX{} then -you should consider using the |doc| software which comes with -\LaTeX{}. -\LaTeX{} classes and packages written using this can be -processed in two ways: they can be run through \LaTeX{}, to produce -documentation; and they can be processed with |docstrip|, to produce -the |.cls| or |.sty| file. - -The |doc| software can automatically generate indexes of definitions, -indexes of command use, and change-log lists. It is very useful for -maintaining and documenting large \TeX{} sources. - -The documented sources of the \LaTeX{} kernel itself, and of the -standard classes, etc, are |doc| documents; they are in the |.dtx| -files in the distribution. You can, in fact, typeset the source code -of the kernel as one long document, complete with index, by running -\LaTeX{} on |source2e.tex|. Typesetting these documents uses the -class file |ltxdoc.cls|. - -For more information on |doc| and |docstrip|, consult the files -|docstrip.dtx|, |doc.dtx|, and \emph{\LaTeXcomp}. For examples of its -use, look at the |.dtx| files. - -\subsection{Is it a class or a package?} -\label{Sec:classorpkg} - -The first thing to do when you want to put some new \LaTeX{} commands -in a file is to decide whether it should be a \emph{document class} or a -\emph{package}. The rule of thumb is: -\begin{quote} - If the commands could be used with any document class, then make - them a package; and if not, then make them a class. -\end{quote} - -There are two major types of class: those like |article|, |report| or -|letter|, which are free-standing; and those which are extensions or -variations of other classes---for example, the |proc| document class, -which is built on the |article| document class. - -Thus, a company might have a local |ownlet| class for printing letters -with their own headed note-paper. Such a class would build on top of -the existing |letter| class but it cannot be used with any other -document class, so we have |ownlet.cls| rather than |ownlet.sty|. - -The |graphics| package, in contrast, provides commands for including -images into a \LaTeX{} document. Since these commands can be used -with any document class, we have |graphics.sty| rather than -|graphics.cls|. - - \subsection{Command names} -\LaTeX{} has three types of command. +Prior to the introduction of the L3~programming layer described in the next +section, \LaTeX{} had three types of command. There are the author commands, such as |\section|, |\emph| and |\times|: most of these have short names, all in lower case. @@ -289,117 +190,97 @@ However, this rule of thumb is still useful: if a command has |@| in its name then it is not part of the supported \LaTeX{} language---and its behaviour may change in future releases! If a command is mixed-case, or is described in \emph{\LaTeXbook}, then you can rely on -future releases of \LaTeXe{} supporting the command. - -\subsection{Box commands and colour} -\label{Sec:colour} - -Even if you do not intend to use colour in your own documents, by -taking note of the points in this section you can ensure that your -class or package is compatible with the |color| package. This may -benefit people using your class or package who have access to colour -printers. - -The simplest way to ensure `colour safety' is to always use \LaTeX{} -box commands rather than \TeX{} primitives, that is use |\sbox| rather -than |\setbox|, |\mbox| rather than |\hbox| and |\parbox| or -the |minipage| environment rather than |\vbox|. -The \LaTeX{} box commands have new options which mean that they are now -as powerful as the \TeX{} primitives. - -As an example of what can go wrong, consider that in -|{\ttfamily <text>}| -the font is restored just \emph{before} the |}|, whereas in the -similar looking construction -|{\color{green} <text>}| -the colour is restored just \emph{after} the final |}|. Normally this -distinction does not matter at all; but consider a primitive \TeX{} -box assignment such as: +future releases of \LaTeX{} supporting the command. + +\subsection{Programming support} + +As noted in the introduction, the \LaTeX{} kernel today loads dedicated support +from programming, here referred to as the L3 programming layer but also often +called \pkg{expl3}. Details of the general approach taken by the L3 +programming layer are given in the document \texttt{expl3}, while a reference +for all current code interfaces is available as \texttt{interface3}. This layer +contains two types of command: a documented set of commands making up the API +and a large number of private internal commands. The latter all start with two +underscores and should not be used outside of the code module which defines +them. This more structured approach means that using the L3 programming layer +does not suffer from the somewhat fluid situation mentioned above with +`\texttt{@} commands'. + +We do not cover the detail of using the L3 programming layer here. A good +introduction to the approach is provided at +\url{https://www.alanshawn.com/latex3-tutorial/}. + +\subsection{Box commands and color} +\label{Sec:color} + +Even if you do not intend to use color in your own documents, by taking note of +the points in this section you can ensure that your class or package is +compatible with the |color| package. This may benefit people using your class +or package and wish to use color. + +The simplest way to ensure `color safety' is to always use \LaTeX{} box +commands rather than \TeX{} primitives, that is use |\sbox| rather than +|\setbox|, |\mbox| rather than |\hbox| and |\parbox| or the |minipage| +environment rather than |\vbox|. The \LaTeX{} box commands have new options +which mean that they are now as powerful as the \TeX{} primitives. + +As an example of what can go wrong, consider that in |{\ttfamily <text>}| the +font is restored just \emph{before} the |}|, whereas in the similar looking +construction |{\color{green} <text>}| the color is restored just \emph{after} +the final |}|. Normally this distinction does not matter at all; but consider a +primitive \TeX{} box assignment such as: \begin{verbatim} \setbox0=\hbox{\color{green} <text>} \end{verbatim} -Now the colour-restore occurs after the |}| and so is \emph{not} -stored in the box. Exactly what bad effects this can have depends on -how colour is implemented: it can range from getting the wrong -colours in the rest of the document, to causing errors in the -dvi-driver used to print the document. - -Also of interest is the command |\normalcolor|. This is -normally just |\relax| (i.e., does nothing) -but you can use it rather like |\normalfont| to -set regions of the page such as captions or section headings to the -`main document colour'. - - -\subsection{Defining text and math characters} -\label{Sec:chars} - -Because \LaTeXe{} supports different encodings, definitions of commands -for producing symbols, accents, composite glyphs, etc.\ must be -defined using the commands provided for this purpose and described in -\emph{\fntguide}. This part of the system is still under development -so such tasks should be undertaken with great caution. - -Also, |\DeclareRobustCommand| should be used for encoding-independent -commands of this type. - -Note that it is no longer possible to refer to the math font set-up -outside math mode: for example, neither |\textfont 1| nor -|\scriptfont 2| are guaranteed to be defined in other modes. +Now the color-restore occurs after the |}| and so is \emph{not} stored in the +box. Exactly what bad effects this can have depends on how color is +implemented: it can range from getting the wrong colors in the rest of the +document, to causing errors in the dvi-driver used to print the document. +Also of interest is the command |\normalcolor|. This is normally just |\relax| +(i.e., does nothing) but you can use it rather like |\normalfont| to set +regions of the page such as captions or section headings to the `main document +color'. \subsection{General style} \label{Sec:general} -The new system provides many commands designed to help you produce -well-structured class and package files that are both robust and -portable. This section outlines some ways to make intelligent use of -these. +\LaTeX{} provides many commands designed to help you produce well-structured +class and package files that are both robust and portable. This section +outlines some ways to make intelligent use of these. \subsubsection{Loading other files} \label{Sec:loading} -\NEWdescription{1995/12/01} \LaTeX{} provides these commands: \begin{verbatim} \LoadClass \LoadClassWithOptions \RequirePackage \RequirePackageWithOptions \end{verbatim} -for using classes or packages inside other classes or packages. We -recommend strongly that you use them, rather than the primitive -|\input| command, for a number of reasons. +for using classes or packages inside other classes or packages. We recommend +strongly that you use them, rather than the primitive |\input| command, for a +number of reasons. -Files loaded with |\input <filename>| will not be listed in the -|\listfiles| list. +Files loaded with |\input <filename>| will not be listed in the |\listfiles| +list. -If a package is always loaded with |\RequirePackage...| or |\usepackage| -then, even if its loading is requested several times, it will be -loaded only once. By contrast, if it is loaded with |\input| then it -can be loaded more than once; such an extra loading may waste time and -memory and it may produce strange results. +If a package is always loaded with |\RequirePackage...| or |\usepackage| then, +even if its loading is requested several times, it will be loaded only once. By +contrast, if it is loaded with |\input| then it can be loaded more than once; +such an extra loading may waste time and memory and it may produce strange +results. -If a package provides option-processing then, again, strange results -are possible if the package is |\input| rather than loaded by means of +If a package provides option-processing then, again, strange results are +possible if the package is |\input| rather than loaded by means of |\usepackage| or |\RequirePackage...|. -If the package |foo.sty| loads the package |baz.sty| by use of -|\input baz.sty| then the user will get a warning: +If the package |foo.sty| loads the package |baz.sty| by use of |\input baz.sty| +then the user will get a warning: \begin{verbatim} LaTeX Warning: You have requested package `foo', but the package provides `baz'. \end{verbatim} -Thus, for several reasons, using |\input| to load packages is not a -good idea. - -Unfortunately, if you are upgrading the file |myclass.sty| to a class -file then you have to make sure that any old files which contain -|\input myclass.sty| still work. - -This was also true for the standard classes (|article|, |book| and -|report|), since a lot of existing \LaTeX~2.09 document styles contain -|\input article.sty|. The approach which we use to solve this is -to provide minimal files |article.sty|, |book.sty| and |report.sty|, -which simply load the appropriate class files. +Thus, for several reasons, using |\input| to load packages is not a good idea. For example, |article.sty| contains just the following lines: \begin{verbatim} @@ -407,93 +288,72 @@ For example, |article.sty| contains just the following lines: \@obsoletefile{article.cls}{article.sty} \LoadClass{article} \end{verbatim} -You may wish to do the same or, if you think that it is safe to do so, -you may decide to just remove |myclass.sty|. +You may wish to do the same or, if you think that it is safe to do so, you may +decide to just remove |myclass.sty|. \subsubsection{Make it robust} We consider it good practice, when writing packages and classes, to use \LaTeX{} commands as much as possible. -Thus, instead of using |\def...| we recommend using one of -|\newcommand|, |\renewcommand| or |\providecommand|; |\CheckCommand| is -also useful. Doing this makes -it less likely that you will inadvertently redefine a command, giving -unexpected results. +Thus, instead of using |\def...| we recommend using one of |\newcommand|, +|\renewcommand| or |\providecommand| for programming and for defining document +interfaces |\NewDocumentCommand|, etc. (see \texttt{usrguide} for details of +these commands). -When you define an environment, use |\newenvironment| or -|\renewenvironment| instead |\def\foo{...}| and |\def\endfoo{...}|. +When you define an environment, use |\NewDocumentEnvironment|, etc., (or +|\newenvironment|, etc., for simple cases) instead of using |\def\foo{...}| and +|\def\endfoo{...}|. -If you need to set or change the value of a \m{dimen} or \m{skip} -register, use |\setlength|. +If you need to set or change the value of a \m{dimen} or \m{skip} register, use +|\setlength|. -To manipulate boxes, use \LaTeX{} commands such as |\sbox|, -|\mbox| and |\parbox| rather than |\setbox|, |\hbox| and |\vbox|. +To manipulate boxes, use \LaTeX{} commands such as |\sbox|, |\mbox| and +|\parbox| rather than |\setbox|, |\hbox| and |\vbox|. -Use |\PackageError|, |\PackageWarning| or |\PackageInfo| (or the -equivalent class commands) rather than |\@latexerr|, |\@warning| or -|\wlog|. - -It is still possible to declare options by defining |\ds@<option>| and -calling |\@options|; but we recommend the |\DeclareOption| and -|\ProcessOptions| commands instead. These are more powerful and use -less memory. So rather than using: -\begin{verbatim} - \def\ds@draft{\overfullrule 5pt} - \@options -\end{verbatim} -you should use: -\begin{verbatim} - \DeclareOption{draft}{\setlength{\overfullrule}{5pt}} - \ProcessOptions\relax -\end{verbatim} +Use |\PackageError|, |\PackageWarning| or |\PackageInfo| (or the equivalent +class commands) rather than |\@latexerr|, |\@warning| or |\wlog|. -The advantage of this kind of practice is that your code is more -readable and, more important, that it is less likely to break when -used with future versions of \LaTeX{}. +The advantage of this kind of practice is that your code is more readable and +accessible to other experienced \LaTeX{} programmers. \subsubsection{Make it portable} -It is also sensible to make your files are as portable as possible. To -ensure this; they should contain only visible 7-bit text; and the -filenames should contain at most eight characters (plus the three -letter extension). Also, of course, it \textbf{must not} have the -same name as a file in the standard \LaTeX{} distribution, however -similar its contents may be to one of these files. +It is also sensible to make your files are as portable as possible. To ensure +this, files must not have the same name as a file in the standard \LaTeX{} +distribution, however similar its contents may be to one of these files. It is +also still lower risk to stick to file names which use only the ASCII range: +whilst \LaTeX{} works natively with UTF-8, the same cannot be said with +certainty for all tools. For the same reason, avoid spaces in file names. -It is also useful if local classes or packages have a common prefix, -for example the University of Nowhere classes might begin with |unw|. -This helps to avoid every University having its own thesis class, all -called |thesis.cls|. +It is also useful if local classes or packages have a common prefix, for +example the University of Nowhere classes might begin with |unw|. This helps to +avoid every University having its own thesis class, all called |thesis.cls|. If you rely on some features of the \LaTeX{} kernel, or on a package, please specify the release-date you need. For example, the package -error commands were introduced in the June 1994 release so, if you use +error commands were introduced in the June 2022 release so, if you use them then you should put: \begin{verbatim} - \NeedsTeXFormat{LaTeX2e}[1994/06/01] + \NeedsTeXFormat{LaTeX2e}[2022-06-01] \end{verbatim} \subsubsection{Useful hooks} -Some packages and document styles had to redefine the command -|\document| or |\enddocument| to achieve their goal. This is no -longer necessary. You can now use the `hooks' |\AtBeginDocument| and -|\AtEndDocument| (see Section~\ref{Sec:delays}). Again, using these -hooks makes it less likely that your code breaks with future versions -of \LaTeX{}. It also makes it more likely that your package can work -together with someone else's. - -\NEWdescription{1996/12/01} -However, note that code in the |\AtBeginDocument| hook is part of the -preamble. Thus there are restrictions on what can be put there; in -particular, no typesetting can be done. +It is sometimes necessary for a package to arrange for code to be +executed at the start or end of the preamble, at the end of the document +or at the start of every use of an environment. This can be carried +out by using hooks. As a document author, you will likely be familiar with +|\AtBeginDocument|, a wrapper around the more powerful command |\AddToHook|. +The \LaTeX{} kernel provides a large number of dedicated hooks (applying in +a pre-defined location) and generic hooks (applying to arbitrary commands): +the interface for using these is described in \texttt{lthooks} . There are +also hooks to apply to files, described in \texttt{ltfilehooks}. \section{The structure of a class or package} \label{Sec:structure} -\LaTeXe{} classes and packages have more structure than \LaTeX~2.09 -style files did. The outline of a class or package file is: +The outline of a class or package file is: \begin{description} \item[Identification] The file says that it is a \LaTeXe{} package or class, and gives a short description of itself. @@ -517,7 +377,7 @@ Package files do this as follows: For example: \begin{verbatim} \NeedsTeXFormat{LaTeX2e} - \ProvidesPackage{latexsym}[1994/06/01 Standard LaTeX package] + \ProvidesPackage{latexsym}[1998-08-17 Standard LaTeX package] \end{verbatim} Class files do this as follows: \begin{verbatim} @@ -527,54 +387,43 @@ Class files do this as follows: For example: \begin{verbatim} \NeedsTeXFormat{LaTeX2e} - \ProvidesClass{article}[1994/06/01 Standard LaTeX class] -\end{verbatim} -\NEWdescription{1998/06/19} -The \m{date} should be given in the form `\textsc{yyyy/mm/dd}' and -must be present if the optional argument is used (this is also true -for the |\NeedsTeXFormat| command). -Any derivation from this syntax will result in low-level \TeX{} -errors---the commands expect a valid syntax to speed up the daily -usage of the package or class and make no provision for the case that -the developer made a mistake! - -This date is checked whenever a user specifies a date in their -|\documentclass| or |\usepackage| command. For example, if you wrote: -\begin{verbatim} - \documentclass{article}[1995/12/23] -\end{verbatim} -then users at a different location -would get a warning that their copy of |article| was out of -date. - -The description of a class is displayed when the class is used. The -description of a package is put into the log file. These descriptions -are also displayed by the |\listfiles| command. The phrase -\texttt{Standard LaTeX} \textbf{must not} be used in the identification -banner of any file other than those in the standard \LaTeX{} -distribution. + \ProvidesClass{article}[2022-06-01 Standard LaTeX class] +\end{verbatim} +The \m{date} should be given in the form `\textsc{yyyy-mm-dd}' and must be +present if the optional argument is used (this is also true for the +|\NeedsTeXFormat| command). Any derivation from this syntax will result in +low-level \TeX{} errors---the commands expect a valid syntax to speed up the +daily usage of the package or class and make no provision for the case that the +developer made a mistake! + +This date is checked whenever a user specifies a date in their |\documentclass| +or |\usepackage| command. For example, if you wrote: +\begin{verbatim} + \documentclass{article}[2022-06-01] +\end{verbatim} +then users at a different location would get a warning that their copy of +|article| was out of date. +The description of a class is displayed when the class is used. The description +of a package is put into the log file. These descriptions are also displayed by +the |\listfiles| command. The phrase \texttt{Standard LaTeX} \textbf{must not} +be used in the identification banner of any file other than those in the +standard \LaTeX{} distribution. \subsection{Using classes and packages} -The first major difference between \LaTeX~2.09 style files and -\LaTeXe{} packages and classes is that \LaTeXe{} supports -\emph{modularity}, in the sense of building files from small -building-blocks rather than using large single files. - A \LaTeX{} package or class can load a package as follows: \begin{verbatim} \RequirePackage[<options>]{<package>}[<date>] \end{verbatim} For example: \begin{verbatim} - \RequirePackage{ifthen}[1994/06/01] + \RequirePackage{ifthen}[2022-06-01] \end{verbatim} -This command has the same syntax as the author command |\usepackage|. -It allows packages or classes to use features provided by other -packages. For example, by loading the |ifthen| package, a package -writer can use the `if\dots then\dots else\dots' commands provided -by that package. +This command has the same syntax as the author command |\usepackage|. It allows +packages or classes to use features provided by other packages. For example, by +loading the |ifthen| package, a package writer can use the `if\dots then\dots +else\dots' commands provided by that package. A \LaTeX{} class can load one other class as follows: \begin{verbatim} @@ -584,13 +433,12 @@ For example: \begin{verbatim} \LoadClass[twocolumn]{article} \end{verbatim} -This command has the same syntax as the author command |\documentclass|. -It allows classes to be based on the syntax and appearance of another -class. For example, by loading the |article| class, a class writer -only has to change the bits of |article| they don't like, rather than -writing a new class from scratch. +This command has the same syntax as the author command |\documentclass|. It +allows classes to be based on the syntax and appearance of another class. For +example, by loading the |article| class, a class writer only has to change the +bits of |article| they don't like, rather than writing a new class from +scratch. -\NEWfeature{1995/12/01} The following commands can be used in the common case that you want to simply load a class or package file with exactly those options that are being used by the current class. @@ -606,14 +454,20 @@ For example: \subsection{Declaring options} -\NEWdescription{1998/12/01} -The other major difference between \LaTeX~2.09 styles and \LaTeXe{} -packages and classes is in option handling. Packages and classes can -now declare options and these can be specified by authors; for -example, the |twocolumn| option is declared by the |article| class. -Note that the name of an option should contain only those characters -allowed in a `\LaTeX{} name'; in particular it must not contain any -control sequences. +Packages and classes can declare options and these can be specified by authors; +for example, the |twocolumn| option is declared by the |article| class. Note +that the name of an option should contain only those characters allowed in a +`\LaTeX{} name'; in particular it must not contain any control sequences. + +\LaTeX{} supports two methods for creating options: a key--value system and a +`simple text' approach. The key--value system is recommended for new classes +and packages, and is more flexible in handling of option classes than the +simple text approach. Both option methods use the same basic structure within +the \LaTeX{} source: declaration of options first then processing options in a +second step. Both also allow options to be passed on to other packages or an +underlying class. As the `classical' simple text approach is conceptually more +straight-forward to illustrate, it is used here to show the general structure: +see Section~\ref{Sec:opt:keyval} for full details of the key--value approach. An option is declared as follows: \begin{verbatim} @@ -624,63 +478,58 @@ to the |graphics| package is implemented as: \begin{verbatim} \DeclareOption{dvips}{\input{dvips.def}} \end{verbatim} -This means that when an author writes |\usepackage[dvips]{graphics}|, -the file |dvips.def| is loaded. As another example, the |a4paper| -option is declared in the |article| class to set the |\paperheight| -and |\paperwidth| lengths: +This means that when an author writes |\usepackage[dvips]{graphics}|, the file +|dvips.def| is loaded. As another example, the |a4paper| option is declared in +the |article| class to set the |\paperheight| and |\paperwidth| lengths: \begin{verbatim} \DeclareOption{a4paper}{% \setlength{\paperheight}{297mm}% \setlength{\paperwidth}{210mm}% } \end{verbatim} -Sometimes a user will request an option which the class -or package has not explicitly declared. By default this will produce -a warning (for classes) or error (for packages); this behaviour -can be altered as follows: +Sometimes a user will request an option which the class or package has not +explicitly declared. By default this will produce a warning (for classes) or +error (for packages); this behaviour can be altered as follows: \begin{verbatim} \DeclareOption*{<code>} \end{verbatim} -For example, to make the package |fred| produce a warning rather than -an error for unknown options, you could specify: +For example, to make the package |fred| produce a warning rather than an error +for unknown options, you could specify: \begin{verbatim} \DeclareOption*{% \PackageWarning{fred}{Unknown option `\CurrentOption'}% } \end{verbatim} -Then, if an author writes |\usepackage[foo]{fred}|, they will get a -warning \texttt{Package fred Warning: Unknown option `foo'.} As -another example, the |fontenc| package tries to load a file -|<ENC>enc.def| whenever the \m{ENC} option is used. This -can be done by writing: +Then, if an author writes |\usepackage[foo]{fred}|, they will get a warning +\texttt{Package fred Warning: Unknown option `foo'.} As another example, the +|fontenc| package tries to load a file |<ENC>enc.def| whenever the \m{ENC} +option is used. This can be done by writing: \begin{verbatim} \DeclareOption*{% \input{\CurrentOption enc.def}% } \end{verbatim} -\NEWdescription{1998/12/01} -It is possible to pass options on to another package or class, using -the command |\PassOptionsToPackage| or |\PassOptionsToClass| (note -that this is a specialised operation that works only for option -names). For example, to pass every unknown option on to the |article| -class, you can use: + +It is possible to pass options on to another package or class, using the +command |\PassOptionsToPackage| or |\PassOptionsToClass| (note that this is a +specialised operation that works only for option names): see +Section~\ref{Sec:opmove}. For example, to pass every unknown option on to the +|article| class, you can use: \begin{verbatim} \DeclareOption*{% \PassOptionsToClass{\CurrentOption}{article}% } \end{verbatim} -If you do this then you should make sure you load the class at some -later point, otherwise the options will never be processed! +If you do this then you should make sure you load the class at some later +point, otherwise the options will never be processed! -So far, we have explained only how to declare options, not how to -execute them. To process the options with which the file was called, -you should use: +So far, we have explained only how to declare options, not how to execute them. +To process the options with which the file was called, you should use: \begin{verbatim} \ProcessOptions\relax \end{verbatim} -This executes the \m{code} for each option that was both specified and -declared (see Section~\ref{Sec:commands.options} for details of how -this is done). +This executes the \m{code} for each option that was both specified and declared +(see Section~\ref{Sec:commands.options} for details of how this is done). For example, if the |jane| package file contains: \begin{verbatim} @@ -689,8 +538,8 @@ For example, if the |jane| package file contains: \DeclareOption*{\typeout{What's \CurrentOption?}} \ProcessOptions\relax \end{verbatim} -and an author writes |\usepackage[foo,bar]{jane}|, then they will see -the messages \texttt{Saw foo.} and \texttt{What's bar?} +and an author writes |\usepackage[foo,bar]{jane}|, then they will see the +messages \texttt{Saw foo.} and \texttt{What's bar?} \subsection{A minimal class file} @@ -698,9 +547,6 @@ Most of the work of a class or package is in defining new commands, or changing the appearance of documents. This is done in the body of the package, using commands such as |\newcommand| or |\setlength|. -\LaTeXe{} provides several new commands to help class and package -writers; these are described in detail in Section~\ref{Sec:commands}. - There are four things that every class file \emph{must} contain: these are a definition of |\normalsize|, values for |\textwidth| and |\textheight| and a specification for page-numbering. So a minimal @@ -708,7 +554,7 @@ document class file\footnote {This class is now in the standard distribution, as \texttt{minimal.cls}.} looks like this: \begin{verbatim} \NeedsTeXFormat{LaTeX2e} - \ProvidesClass{minimal}[1995/10/30 Standard LaTeX minimal class] + \ProvidesClass{minimal}[2022-06-01 Standard LaTeX minimal class] \renewcommand{\normalsize}{\fontsize{10pt}{12pt}\selectfont} \setlength{\textwidth}{6.5in} \setlength{\textheight}{8in} @@ -728,18 +574,17 @@ class, although a real class would need more structure. The class begins by announcing itself as |neplet.cls|. \begin{verbatim} \NeedsTeXFormat{LaTeX2e} - \ProvidesClass{neplet}[1995/04/01 NonExistent Press letter class] + \ProvidesClass{neplet}[2022-06-01 NonExistent Press letter class] \end{verbatim} -Then this next bit passes any options on to the |letter| class, which -is loaded with the |a4paper| option. +Then this next bit passes any options on to the |letter| class, which is loaded +with the |a4paper| option. \begin{verbatim} \DeclareOption*{\PassOptionsToClass{\CurrentOption}{letter}} \ProcessOptions\relax \LoadClass[a4paper]{letter} \end{verbatim} -In order to use the company letter head, it redefines the -|firstpage| page style: this is the page style that is used on -the first page of letters. +In order to use the company letter head, it redefines the |firstpage| page +style: this is the page style that is used on the first page of letters. \begin{verbatim} \renewcommand{\ps@firstpage}{% \renewcommand{\@oddhead}{<letterhead goes here>}% @@ -751,17 +596,16 @@ And that's it! \subsection{Example: a newsletter class} A simple newsletter can be typeset with \LaTeX{}, using a variant of the -|article| class. -The class begins by announcing itself as |smplnews.cls|. +|article| class. The class begins by announcing itself as |smplnews.cls|. \begin{verbatim} \NeedsTeXFormat{LaTeX2e} - \ProvidesClass{smplnews}[1995/04/01 The Simple News newsletter class] + \ProvidesClass{smplnews}[2022-06-01 The Simple News newsletter class] \newcommand{\headlinecolor}{\normalcolor} \end{verbatim} -It passes most specified options on to the |article| class: apart from -the |onecolumn| option, which is switched off, and the |green| option, -which sets the headline in green. +It passes most specified options on to the |article| class: apart from the +|onecolumn| option, which is switched off, and the |green| option, which sets +the headline in green. \begin{verbatim} \DeclareOption{onecolumn}{\OptionNotUsed} \DeclareOption{green}{\renewcommand{\headlinecolor}{\color{green}}} @@ -774,14 +618,14 @@ It then loads the class |article| with the option |twocolumn|. \begin{verbatim} \LoadClass[twocolumn]{article} \end{verbatim} -Since the newsletter is to be printed in colour, it now loads the -|color| package. The class does not specify a device driver option -since this should be specified by the user of the |smplnews| class. +Since the newsletter is to be printed in colour, it now loads the |color| +package. The class does not specify a device driver option since this should be +specified by the user of the |smplnews| class. \begin{verbatim} \RequirePackage{color} \end{verbatim} -The class then redefines |\maketitle| to produce the title in 72pt -Helvetica bold oblique, in the appropriate colour. +The class then redefines |\maketitle| to produce the title in 72\,pt Helvetica +bold oblique, in the appropriate colour. \begin{verbatim} \renewcommand{\maketitle}{% \twocolumn[% @@ -807,90 +651,91 @@ It also sets the three essential things. \setlength{\textwidth}{17.5cm} \setlength{\textheight}{25cm} \end{verbatim} -In practice, a class would need more than this: it would provide -commands for issue numbers, authors of articles, page styles and so -on; but this skeleton gives a start. The |ltnews| class file is not -much more complex than this one. +In practice, a class would need more than this: it would provide commands for +issue numbers, authors of articles, page styles and so on; but this skeleton +gives a start. The |ltnews| class file is not much more complex than this one. \section{Commands for class and package writers} \label{Sec:commands} -This section describes briefly each of the new commands for class and -package writers. To find out about other aspects of the new system, +This section describes briefly each of the commands for class and package +writers. To find out about other aspects of the system, you should also read \emph{\LaTeXbook}, \emph{\LaTeXcomp} and \emph{\usrguide}. \subsection{Identification} -The first group of commands discussed here are those used -to identify your class or package file. +The first group of commands discussed here are those used to identify your +class or package file. \begin{decl} |\NeedsTeXFormat| \arg{format-name} \oarg{release-date} \end{decl} -This command tells \TeX{} that this file should be processed using a -format with name \m{format-name}. You can use the optional argument -\m{release-date} to further specify the earliest release date of the -format that is needed. When the release date of the format is older -than the one specified a warning will be generated. The standard -\m{format-name} is \texttt{LaTeX2e}. The date, if present, must be in -the form \textsc{yyyy/mm/dd}. +This command tells \TeX{} that this file should be processed using a format +with name \m{format-name}. You can use the optional argument \m{release-date} +to further specify the earliest release date of the format that is needed. When +the release date of the format is older than the one specified a warning will +be generated. The standard \m{format-name} is \texttt{LaTeX2e}. The date, if +present, must be in the form \textsc{yyyy-mm-dd}. Example: \begin{verbatim} - \NeedsTeXFormat{LaTeX2e}[1994/06/01] + \NeedsTeXFormat{LaTeX2e}[2022-06-01] \end{verbatim} +People often don't know what date to put here. For the kernel, you can find out +the right one by consulting |changes.txt| and select the release date of a new +feature you are interested in. This is slightly different for packages as they +are released throughout the year: you will need to consult their change +history. \begin{decl} |\ProvidesClass| \arg{class-name} \oarg{release-info} \\ |\ProvidesPackage| \arg{package-name} \oarg{release-info} \end{decl} -This declares that the current file contains the definitions for the -document class \m{class-name} or package \m{package-name}. +This declares that the current file contains the definitions for the document +class \m{class-name} or package \m{package-name}. The optional \m{release-info}, if used, must contain: \begin{itemize} - \item the release date of - this version of the file, in the form \textsc{yyyy/mm/dd}; + \item the release date of this version of the file, in the form + \textsc{yyyy-mm-dd}; \item optionally followed by a space and a short description, possibly including a version number. \end{itemize} -The above syntax must be followed exactly so that this information -can be used by |\LoadClass| or |\documentclass| (for classes) or -|\RequirePackage| or |\usepackage| (for packages) to test that the -release is not too old. +The above syntax must be followed exactly so that this information can be used +by |\LoadClass| or |\documentclass| (for classes) or |\RequirePackage| or +|\usepackage| (for packages) to test that the release is not too old. -The whole of this \m{release-info} information is displayed by -|\listfiles| and should therefore not be too long. +The whole of this \m{release-info} information is displayed by |\listfiles| and +should therefore not be too long. Example: \begin{verbatim} - \ProvidesClass{article}[1994/06/01 v1.0 Standard LaTeX class] - \ProvidesPackage{ifthen}[1994/06/01 v1.0 Standard LaTeX package] + \ProvidesClass{article}[2022-06-01 v1.0 Standard LaTeX class] + \ProvidesPackage{ifthen}[2022-06-01 v1.0 Standard LaTeX package] \end{verbatim} \begin{decl} |\ProvidesFile| \arg{file-name} \oarg{release-info} \end{decl} This is similar to the two previous commands except that here the full -filename, including the extension, must be given. It is used for -declaring any files other than main class and package files. +filename, including the extension, must be given. It is used for declaring any +files other than main class and package files. Example: \begin{verbatim} - \ProvidesFile{T1enc.def}[1994/06/01 v1.0 Standard LaTeX file] + \ProvidesFile{T1enc.def}[2022-06-01 v1.0 Standard LaTeX file] \end{verbatim} -Note that the phrase \texttt{Standard LaTeX} \textbf{must not} be used -in the identification banner of any file other than those in the -standard \LaTeX{} distribution. +Note that the phrase \texttt{Standard LaTeX} \textbf{must not} be used in the +identification banner of any file other than those in the standard \LaTeX{} +distribution. \subsection{Loading files} \label{Sec:loadf} -\NEWfeature{1995/12/01} -This group of commands can be used to create your own document class or -package by building on existing classes or packages. +This group of commands can be used to create your own document class or package +by building on existing classes or packages. \begin{decl} |\RequirePackage| \oarg{options-list} \arg{package-name} \oarg{release-info}\\ @@ -899,13 +744,11 @@ package by building on existing classes or packages. \end{decl} Packages and classes should use these commands to load other packages. -The use of |\RequirePackage| is the same as the author command -|\usepackage|. - +The use of |\RequirePackage| is the same as the author command |\usepackage|. Examples: \begin{verbatim} - \RequirePackage{ifthen}[1994/06/01] - \RequirePackageWithOptions{graphics}[1995/12/01] + \RequirePackage{ifthen}[2022-06-01] + \RequirePackageWithOptions{graphics}[2022-06-01] \end{verbatim} \begin{decl} @@ -914,107 +757,153 @@ Examples: |\LoadClassWithOptions| \arg{class-name} \oarg{release-info} \end{decl} -\NEWfeature{1995/12/01} -These commands are for use \emph{only} in class files, they cannot be -used in packages files; -they can be used at most once within a class file. +These commands are for use \emph{only} in class files, they cannot be used in +packages files; they can be used at most once within a class file. -The use of |\LoadClass| is the same as -the use of |\documentclass| to load a class file. +The use of |\LoadClass| is the same as the use of |\documentclass| to load a +class file. Examples: \begin{verbatim} - \LoadClass{article}[1994/06/01] - \LoadClassWithOptions{article}[1995/12/01] + \LoadClass{article}[2022-06-01] + \LoadClassWithOptions{article}[2022-06-01] \end{verbatim} -\NEWfeature{1995/12/01} -The two |WithOptions| versions simply load the class (or package) file -with exactly those options that are being used by the current file -(class or package). See below, in \ref{Sec:opmove}, for further -discussion of their use. +The two |WithOptions| versions simply load the class (or package) file with +exactly those options that are being used by the current file (class or +package). See below, in \ref{Sec:opmove}, for further discussion of their use. +\subsection{Delaying code} +\label{Sec:delays} -\subsection{Option declaration} -\label{Sec:commands.options.dec} - -\NEWdescription{1998/12/01} -The following commands deal with the declaration and handling of -options to document classes and packages. Every option name must be a -`\LaTeX{} name'. +As noted earlier, a sophisticated hook system is available and described in +\texttt{lthooks}. Here, we document a small set of convenient short names for +common hooks. -There are some commands designed especially for use within the -\m{code} argument of these commands (see below). +These first two commands are also intended primarily for use within the +\m{code} argument of |\DeclareOption| or |\DeclareOption*|. \begin{decl} - |\DeclareOption| \arg{option-name} \arg{code} + |\AtEndOfClass| \arg{code}\\ + |\AtEndOfPackage| \arg{code} \end{decl} -This makes \m{option-name} a `declared option' of the class or package -in which it is put. +These commands declare \m{code} that is saved away internally and then executed +after processing the whole of the current class or package file. -The \m{code} argument contains the code to be executed if that option -is specified for the class or package; it can contain any valid -\LaTeXe{} construct. - -Example: -\begin{verbatim} - \DeclareOption{twoside}{\@twosidetrue} -\end{verbatim} +Repeated use of these commands is permitted: the code in the arguments is +stored (and later executed) in the order of their declarations. \begin{decl} - |\DeclareOption*| \arg{code} + |\AtBeginDocument| \arg{code}\\ + |\AtEndDocument| \arg{code} \end{decl} -This declares the \m{code} to be executed for every option which is -specified for, but otherwise not explicitly declared by, the class or -package; this code is called the `default option code' and it can -contain any valid \LaTeXe{} construct. +These commands declare \m{code} to be saved internally and executed while +\LaTeX{} is executing |\begin{document}| or |\end{document}|. -If a class file contains no |\DeclareOption*| then, by default, all -specified but undeclared options for that class will be silently -passed to all packages (as will the specified and declared options for -that class). +The \m{code} specified in the argument to |\AtBeginDocument| is executed near +the end of the |\begin{document}| code, \emph{after} the font selection tables +have been set up. It is therefore a useful place to put code which needs to be +executed after everything has been prepared for typesetting and when the normal +font for the document is the current font. -If a package file contains no |\DeclareOption*| then, by default, each -specified but undeclared option for that package will produce an error. +The |\AtBeginDocument| hook should not be used for code that does any +typesetting since the typeset result would be unpredictable. +The \m{code} specified in the argument to |\AtEndDocument| is executed at the +beginning of the |\end{document}| code, \emph{before} the final page is +finished and before any leftover floating environments are processed. If some +of the \m{code} is to be executed after these two processes, you should include +a |\clearpage| at the appropriate point in \m{code}. -\subsection{Commands within option code} -\label{Sec:within.code} +Repeated use of these commands is permitted: the code in the arguments is +stored (and later executed) in the order of their declarations. -These two commands can be used only within the \m{code} argument of -either |\DeclareOption| or |\DeclareOption*|. Other commands commonly -used within these arguments can be found in the next few subsections. +\subsection{Creating and using keyval options} +\label{Sec:opt:keyval} + +As with any key--value input, using key--value pairs as package or class +options has two parts: creating the key options and setting (using) them. +Options created in this way \emph{may} be used after package loading as general +key--value settings: this will depend on the nature of the underlying code. \begin{decl} - |\CurrentOption| + |\DeclareKeys| \oarg{family} \arg{declarations} \end{decl} -This expands to the name of the current option. +This command creates a series of options from a comma-separated +\m{declarations} list. Each entry in this list is a key--value pair, with the +\m{key} having one or more \m{properties}. A small number of `basic' +\m{properties} are described below. The full range of properties, provided by +\texttt{l3keys}, can also be used for more powerful processing. See +\texttt{interface3} for the full details. + +The basic properties provided here are +\begin{itemize} + \item \texttt{.code} --- execute arbitrary code + \item \texttt{.if} --- sets a \TeX{} |\if...| switch + \item \texttt{.ifnot} --- sets an inverted \TeX{} |\if...| switch + \item \texttt{.store} --- stores a value in a macro + \item \texttt{.usage} -- defines whether the option can be given only + when loading (\texttt{load}), in the preamble (\texttt{preamble}) or + has no limitation on scope (\texttt{general}) +\end{itemize} +The part of the \meta{key} before the \m{property} is the \m{name}, with the +\m{value} working with the \m{property} to define the behaviour of the option. + +For example, with +\begin{verbatim} +\DeclareKeys[mypkg] + { + draft.if = @mypkg@draft , + draft.usage = preamble , + name.store = \@mypkg@name , + name.usage = load , + second-name.store = \@mypkg@other@name + } +\end{verbatim} +three options would be created. The option \texttt{draft} can be given anywhere +in the preamble, and will set a switch called |\if@mypkg@draft|. The option +\texttt{name} can only be given during package loading, and will save whatever +value it is given in |\@mypkg@name|. Finally, the option \texttt{second-name} +can be given anywhere, and will save its value in |\@mypkg@other@name|. + +Keys created \emph{before} the use of |\ProcessKeyOptions| act as package +options. \begin{decl} - |\OptionNotUsed| + |\DeclareUnknownKeyHandler| \oarg{family} \arg{code} +\end{decl} +The command |\DeclareUnknownKeyHandler| may be used to define the behavior when +an undefined key is encountered. The \m{code} will receive the unknown key name +as |#1| and the value as |#2|. These can then be processed as appropriate, +e.g.~by forwarding to another package. + +\begin{decl} + |\ProcessKeyOptions| \oarg{family} \end{decl} -This causes the current option to -be added to the list of `unused options'. +The |\ProcessKeyOptions| function is used to check the current option list +against the keys defined for \m{family}. Global (class) options and local +(package) options are checked when this function is called in a package. -\NEWfeature{1995/06/01} - You can now include hash marks (\texttt{\#}) within these \m{code} - arguments without special treatment (formerly, it had been - necessary to double them). +\begin{decl} + |\SetKeys| \oarg{family} \arg{keyvals} +\end{decl} +Sets (applies) the explicit list of \m{keyvals} for the \m{family}: if the +latter is not given, the value of |\@currname| is used. This command may be used +within a package to set options before or after using |\ProcessKeyOptions|. -\subsection{Moving options around} +\subsection{Passing options around} \label{Sec:opmove} -These two commands are also very useful within the \m{code} argument -of |\DeclareOption| or |\DeclareOption*|: +These two commands are also very useful within the \m{code} argument of +options. \begin{decl} |\PassOptionsToPackage| \arg{options-list} \arg{package-name}\\ |\PassOptionsToClass| \arg{options-list} \arg{class-name} \end{decl} -The command |\PassOptionsToPackage| passes the option names in -\m{options-list} to package \m{package-name}. -This means that it adds the \m{option-list} to the -list of options used by any future |\RequirePackage| or |\usepackage| -command for package \m{package-name}. +The command |\PassOptionsToPackage| passes the option names in \m{options-list} +to package \m{package-name}. This means that it adds the \m{option-list} to the +list of options used by any future |\RequirePackage| or |\usepackage| command +for package \m{package-name}. Example: \begin{verbatim} @@ -1026,24 +915,22 @@ is the same as: \RequirePackage[foo,bar,baz]{fred} \end{verbatim} -Similarly, |\PassOptionsToClass| may be used in a class file to pass -options to another class to be loaded with |\LoadClass|. +Similarly, |\PassOptionsToClass| may be used in a class file to pass options to +another class to be loaded with |\LoadClass|. -\NEWdescription{1995/12/01} -The effects and use of these two commands should be contrasted with -those of the following two (documented above, in \ref{Sec:loadf}): +The effects and use of these two commands should be contrasted with those of +the following two (documented above, in \ref{Sec:loadf}): \begin{verbatim} \LoadClassWithOptions \RequirePackageWithOptions \end{verbatim} -The command |\RequirePackageWithOptions| is similar to -|\RequirePackage|, but it always loads the required package with -exactly the same option list as that being used by the current class -or package, rather than with any option explicitly supplied or passed -on by |\PassOptionsToPackage|. +The command |\RequirePackageWithOptions| is similar to |\RequirePackage|, but +it always loads the required package with exactly the same option list as that +being used by the current class or package, rather than with any option +explicitly supplied or passed on by |\PassOptionsToPackage|. -The main purpose of |\LoadClassWithOptions| is to allow one class to -simply build on another, for example: +The main purpose of |\LoadClassWithOptions| is to allow one class to simply +build on another, for example: \begin{verbatim} \LoadClassWithOptions{article} \end{verbatim} @@ -1053,12 +940,11 @@ This should be compared with the slightly different construction \ProcessOptions\relax \LoadClass{article} \end{verbatim} -As used above, the effects are more or less the same, but the first is -a lot less to type; also the |\LoadClassWithOptions| method runs -slightly quicker. +As used above, the effects are more or less the same, but the first is a lot +less to type; also the |\LoadClassWithOptions| method runs slightly quicker. -If, however, the class declares options of its own then -the two constructions are different. Compare, for example: +If, however, the class declares options of its own then the two constructions +are different. Compare, for example: \begin{verbatim} \DeclareOption{landscape}{\@landscapetrue} \ProcessOptions\relax @@ -1071,314 +957,239 @@ with: \ProcessOptions\relax \LoadClass{article} \end{verbatim} -In the first example, the \textsf{article} class will be loaded with -option |landscape| precisely when the current class is called with -this option. By contrast, in the second example it will never be -called with option \texttt{landscape} as in that case \textsf{article} -is passed options only by the default option handler, but this handler -is not used for |landscape| because that option is explicitly -declared. +In the first example, the \textsf{article} class will be loaded with option +|landscape| precisely when the current class is called with this option. By +contrast, in the second example it will never be called with option |landscape| +as in that case \textsf{article} is passed options only by the default option +handler, but this handler is not used for |landscape| because that option is +explicitly declared. -\subsection{Delaying code} -\label{Sec:delays} +\subsection{Safe file commands} -These first two commands are also intended primarily for use within -the \m{code} argument of |\DeclareOption| or |\DeclareOption*|. +These commands deal with file input; they ensure that the non-existence of a +requested file can be handled in a user-friendly way. \begin{decl} - |\AtEndOfClass| \arg{code}\\ - |\AtEndOfPackage| \arg{code} +|\IfFileExists| \arg{file-name} \arg{true} \arg{false} \end{decl} -These commands declare \m{code} that is saved away internally and then -executed after processing the whole of the current class or package -file. +If the file exists then the code specified in \m{true} is executed. + +If the file does not exist then the code specified in \m{false} is executed. -Repeated use of these commands is permitted: the code in the -arguments is stored (and later executed) in the order of their -declarations. +This command does \emph{not} input the file. \begin{decl} - |\AtBeginDocument| \arg{code}\\ - |\AtEndDocument| \arg{code} + |\InputIfFileExists| \arg{file-name} \arg{true} \arg{false} \end{decl} -These commands declare \m{code} to be saved internally and executed -while \LaTeX{} is executing |\begin{document}| or |\end{document}|. +This inputs the file \m{file-name} if it exists and, immediately before the +input, the code specified in \m{true} is executed. -The \m{code} specified in the argument to |\AtBeginDocument| is -executed near the end of the |\begin{document}| code, \emph{after} the -font selection tables have been set up. It is therefore a useful -place to put code which needs to be executed after everything has been -prepared for typesetting and when the normal font for the document is -the current font. +If the file does not exist then the code specified in \m{false} is executed. -\NEWdescription{1995/12/01} -The |\AtBeginDocument| hook should not be used for code that does any -typesetting since the typeset result would be unpredictable. +It is implemented using |\IfFileExists|. -The \m{code} specified in the argument to |\AtEndDocument| is -executed at the beginning of the |\end{document}| code, -\emph{before} the final page is finished and before any leftover -floating environments are processed. If some of the \m{code} is to be -executed after these two processes, you should include a |\clearpage| -at the appropriate point in \m{code}. +\subsection{Reporting errors, etc} -Repeated use of these commands is permitted: the code in the -arguments is stored (and later executed) in the order of their -declarations. +These commands should be used by third party classes and packages to report +errors, or to provide information to authors. -\begin{decl}[1994/12/01] - |\AtBeginDvi| \arg{specials} +\begin{decl} + |\ClassError| \arg{class-name} \arg{error-text} \arg{help-text}\\ + |\PackageError| \arg{package-name} \arg{error-text} \arg{help-text} \end{decl} -These commands save in a box register things which are written to the -|.dvi| file at the beginning of the `shipout' of the first page of the -document. +These produce an error message. The \m{error-text} is displayed and the |?| +error prompt is shown. If the user types |h|, they will be shown the +\m{help-text}. -This should not be used for anything that will add any typeset -material to the |.dvi| file. +Within the \m{error-text} and \m{help-text}: |\protect| can be used to stop a +command from expanding; |\MessageBreak| causes a line-break; and |\space| +prints a space. -Repeated use of this command is permitted. +Note that the \m{error-text} will have a full stop added to it, so do not put +one into the argument. +For example: +\begin{verbatim} + \newcommand{\foo}{FOO} + \PackageError{ethel}{% + Your hovercraft is full of eels,\MessageBreak + and \protect\foo\space is \foo + }{% + Oh dear! Something's gone wrong.\MessageBreak + \space \space Try typing \space <<return>> + \space to proceed, ignoring \protect\foo. + } +\end{verbatim} +produces this display: +\begin{verbatim} + ! Package ethel Error: Your hovercraft is full of eels, + (ethel) and \foo is FOO. -\subsection{Option processing} -\label{Sec:commands.options} + See the ethel package documentation for explanation. +\end{verbatim} +If the user types |h|, this will be shown: +\begin{verbatim} + Oh dear! Something's gone wrong. + Try typing <<return>> to proceed, ignoring \foo. +\end{verbatim} \begin{decl} - |\ProcessOptions| + |\ClassWarning| \arg{class-name} \arg{warning-text}\\ + |\PackageWarning| \arg{package-name} \arg{warning-text}\\ + |\ClassWarningNoLine| \arg{class-name} \arg{warning-text}\\ + |\PackageWarningNoLine| \arg{package-name} \arg{warning-text}\\ + |\ClassInfo| \arg{class-name} \arg{info-text}\\ + |\PackageInfo| \arg{package-name} \arg{info-text} \end{decl} -This command executes the \m{code} for each selected option. +The four |Warning| commands are similar to the error commands, except that they +produce only a warning on the screen, with no error prompt. -We shall first describe how |\ProcessOptions| works in a package file, -and then how this differs in a class file. +The first two, |Warning| versions, also show the line number where the warning +occurred, whilst the second two, |WarningNoLine| versions, do not. -To understand in detail what |\ProcessOptions| does in a package file, -you have to know the difference between \emph{local} and \emph{global} -options. -\begin{itemize} -\item \textbf{Local options} are those which have been explicitly - specified for this particular package in the \m{options} argument of - any of these: -\begin{quote} - |\PassOptionsToPackage{<options>}| \ |\usepackage[<options>]|\\ - |\RequirePackage[<options>]| -\end{quote} -\item \textbf{Global options} are any other options that are specified - by the author in the \m{options} argument of - |\documentclass[<options>]|. -\end{itemize} -For example, suppose that a document begins: -\begin{verbatim} - \documentclass[german,twocolumn]{article} - \usepackage{gerhardt} -\end{verbatim} -whilst package |gerhardt| calls package |fred| with: -\begin{verbatim} - \PassOptionsToPackage{german,dvips,a4paper}{fred} - \RequirePackage[errorshow]{fred} -\end{verbatim} -then: -\begin{itemize} -\item |fred|'s local options are |german|, |dvips|, |a4paper| - and |errorshow|; -\item |fred|'s only global option is |twocolumn|. -\end{itemize} - -When |\ProcessOptions| is called, the following happen. -\begin{itemize} -\item \emph{First}, for each option so far declared in |fred.sty| - by |\DeclareOption|, it looks to see if that option is either a - global or a local option for |fred|: if it is then the corresponding - code is executed. - - This is done in the order in which these options - were declared in |fred.sty|. -\item \emph{Then}, for each remaining \emph{local} option, the command - |\ds@<option>| is executed if it has been defined somewhere (other - than by a |\DeclareOption|); otherwise, the `default option code' is - executed. If no default option code has been declared then an error - message is produced. - - This is done in the order in which these - options were specified. -\end{itemize} -Throughout this process, the system ensures that the code declared for -an option is executed at most once. - -Returning to the example, if |fred.sty| contains: -\begin{verbatim} - \DeclareOption{dvips}{\typeout{DVIPS}} - \DeclareOption{german}{\typeout{GERMAN}} - \DeclareOption{french}{\typeout{FRENCH}} - \DeclareOption*{\PackageWarning{fred}{Unknown `\CurrentOption'}} - \ProcessOptions\relax -\end{verbatim} -then the result of processing this document will be: -\begin{verbatim} - DVIPS - GERMAN - Package fred Warning: Unknown `a4paper'. - Package fred Warning: Unknown `errorshow'. -\end{verbatim} -Note the following: - -\begin{itemize} -\item the code for the |dvips| option is executed before that for the - |german| option, because that is the order in which they are declared - in |fred.sty|; -\item the code for the |german| option is executed only once, when the - declared options are being processed; -\item the |a4paper| and |errorshow| options produce the warning from - the code declared by |\DeclareOption*| (in the order in which they - were specified), whilst the |twocolumn| option does not: this is - because |twocolumn| is a global option. -\end{itemize} - -In a class file, |\ProcessOptions| works in the same way, except -that: \emph{all} options are local; and the default value for -|\DeclareOption*| is |\OptionNotUsed| rather than an error. +The two |Info| commands are similar except that they log the information only +in the transcript file, including the line number. There are no |NoLine| +versions of these two. -\NEWdescription{1995/12/01} -Note that, because |\ProcessOptions| has a |*|-form, it is wise to -follow the non-star form with |\relax|, as in the previous examples, -since this prevents unnecessary look ahead and possibly misleading -error messages being issued. +Within the \m{warning-text} and \m{info-text}: |\protect| can be used to stop a +command from expanding; |\MessageBreak| causes a line-break; and |\space| +prints a space. Also, these should not end with a full stop as one is +automatically added. -\begin{decl} - |\ProcessOptions*| \\ - |\@options| -\end{decl} -This is like |\ProcessOptions| but it executes the options in the -order specified in the calling commands, rather than in the order of -declaration in the class or package. For a package this means that the -global options are processed first. +\section{Miscellaneous commands, etc.} +\label{Sec:commands.misc} -The |\@options| command from \LaTeX~2.09 has been made equivalent to -this in order to ease the task of updating old document styles to -\LaTeXe{} class files. +\subsection{Layout parameters} \begin{decl} - |\ExecuteOptions| \arg{options-list} +|\paperheight|\\ +|\paperwidth| \end{decl} +These two parameters are usually set by the class to be the size of the paper +being used. This should be actual paper size, unlike |\textwidth| and +|\textheight| which are the size of the main text body within the margins. -For each option in the \m{options-list}, in order, -this command simply executes the command -|\ds@<option>| (if this command is not defined, then that option is -silently ignored). - -It can be used to provide a `default option list' just before -|\ProcessOptions|. For example, suppose that in a class file you want -to set up the default design to be: two-sided printing; 11pt fonts; -in two columns. Then it could specify: -\begin{verbatim} - \ExecuteOptions{11pt,twoside,twocolumn} -\end{verbatim} - - -\subsection{Safe file commands} - -These commands deal with file input; they ensure that the non-existence -of a requested file can be handled in a user-friendly way. +\subsection{Case changing} +\label{sec:case} \begin{decl} -|\IfFileExists| \arg{file-name} \arg{true} \arg{false} + |\MakeUppercase| \arg{text} \\ + |\MakeLowercase| \arg{text} \\ + |\MakeTitlecase| \arg{text} \end{decl} -If the file exists then the code specified in \m{true} is -executed. -If the file does not exist then the code specified in \m{false} is -executed. +As described in \texttt{usrguide}, case changing for text should be carried out +using the commands |\MakeUppercase|, |\MakeLowercase| and +|\MakeTitlecase|. If you need to change the case of programmatic material, the +team strongly suggest using the L3 programming layer commands in the +\texttt{str} module. If you do not wish to do this, you should use the \TeX{} +|\uppercase| and |\lowercase| primitives \emph{in this situation only}. -This command does \emph{not} input the file. +\subsection{Better user-defined math display environments} \begin{decl} - |\InputIfFileExists| \arg{file-name} \arg{true} \arg{false} + |\ignorespacesafterend| \end{decl} -This inputs the file \m{file-name} if it exists and, immediately -before the input, the code specified in \m{true} is executed. -If the file does not exist then the code specified in \m{false} is -executed. - -It is implemented using |\IfFileExists|. +Suppose that you want to define an environment for displaying text that is +numbered as an equation. A straightforward way to do this is as follows: +\begin{verbatim} + \newenvironment{texteqn} + {\begin{equation} + \begin{minipage}{0.9\linewidth}} + {\end{minipage} + \end{equation}} +\end{verbatim} +However, if you have tried this then you will probably have noticed that it +does not work perfectly when used in the middle of a paragraph because an +inter-word space appears at the beginning of the first line after the +environment. +You can avoid this problem using |\ignorespacesafterend|; it should be +inserted as shown here: +\begin{verbatim} + \newenvironment{texteqn} + {\begin{equation} + \begin{minipage}{0.9\linewidth}} + {\end{minipage} + \end{equation} + \ignorespacesafterend} +\end{verbatim} -\subsection{Reporting errors, etc} +This command may also have other uses. -These commands should be used by third party classes and packages to -report errors, or to provide information to authors. +\subsection{Normalising spacing} \begin{decl} - |\ClassError| \arg{class-name} \arg{error-text} \arg{help-text}\\ - |\PackageError| \arg{package-name} \arg{error-text} \arg{help-text} + |\normalsfcodes| \end{decl} -These produce an error message. The \m{error-text} is displayed and the -|?| error prompt is shown. If the user types |h|, they will be shown -the \m{help-text}. -Within the \m{error-text} and \m{help-text}: |\protect| can be used to -stop a command from expanding; |\MessageBreak| causes a line-break; -and |\space| prints a space. +This command should be used to restore the normal settings of the +parameters that affect spacing between words, sentences, etc. -Note that the \m{error-text} will have a full stop added to it, so do -not put one into the argument. +An important use of this feature is to correct a problem, reported by Donald +Arseneau, that punctuation in page headers has always (in all known \TeX{} +formats) been potentially wrong whenever a page break happens while a local +setting of the space codes is in effect. These space codes are changed by, for +example, the command \verb|\frenchspacing|) and the \textsf{verbatim} +environment. + +It is normally given the correct definition automatically in |\begin{document}| +and so need not be explicitly set; however, if it is explicitly made non-empty +in a class file then automatic default setting will be over-ridden. + +\subsection{Querying localisation} + +Localisation information is needed to customise a range of outputs. The +\LaTeX{} kernel does not itself manage localisation, which is well-served by +the bundles \pkg{babel} and \pkg{polyglossia}. To allow the kernel and other +packages to access the current localisation information provided by \pkg{babel} +or \pkg{polyglossia}, the command \cs{BCPdata} is defined by the kernel. The +initial kernel definition expands to tag parts for \texttt{en-US}, as the +kernel does not track localisation but does start out with a broadly US~English +setup. However, if \pkg{babel} or \pkg{polyglossia} are loaded, it is redefined +expand to the BCP-47 information from the appropriate package. The supported +arguments are the BCP-47 tag breakdowns: +\begin{itemize} + \item \texttt{tag} The full BCP-47 tag (e.g.~\texttt{en-US}) + \item \texttt{language} (e.g.,~\texttt{de}) + \item \texttt{region} (e.g.,~\texttt{AT}) + \item \texttt{script} (e.g.,~\texttt{Latn}) + \item \texttt{variant} (e.g.,~\texttt{1901}) + \item \texttt{extension.t} (transformation, e.g.,~\texttt{en-t-ja}) + \item \texttt{extension.u} (additional locale + information, e.g.,~\texttt{ar-u-nu-latn}) + \item \texttt{extension.x} (private use area, e.g.,~\texttt{la-x-classic}) +\end{itemize} +The information for the \emph{main} language for a document is be provided +if these are prefixed by \texttt{main.}, e.g.~\texttt{main.language} will +expand to the main language even if another language is currently active. -For example: -\begin{verbatim} - \newcommand{\foo}{FOO} - \PackageError{ethel}{% - Your hovercraft is full of eels,\MessageBreak - and \protect\foo\space is \foo - }{% - Oh dear! Something's gone wrong.\MessageBreak - \space \space Try typing \space <<return>> - \space to proceed, ignoring \protect\foo. - } -\end{verbatim} -produces this display: -\begin{verbatim} - ! Package ethel Error: Your hovercraft is full of eels, - (ethel) and \foo is FOO. +In addition to the tag breakdown, the following semantic arguments are +supported +\begin{itemize} + \item \texttt{casing} The tag for case changing, e.g.~\texttt{el-x-iota} + could be selected rather than \texttt{el} to select a capital adscript + iota on uppercasing an \emph{ypogegrammeni} +\end{itemize} - See the ethel package documentation for explanation. -\end{verbatim} -If the user types |h|, this will be shown: +For example, the case changing command \cs{MakeUppercase} is (conceptually) +defined as \begin{verbatim} - Oh dear! Something's gone wrong. - Try typing <<return>> to proceed, ignoring \foo. +\ExpandArgs{e}\MakeUppercaseAux{\BCPdata{casing}}{#1} \end{verbatim} +where |#1| is the user input and the first argument to +\cs{MakeUppercaseAux} takes two arguments, the locale and input text. -\begin{decl} - |\ClassWarning| \arg{class-name} \arg{warning-text}\\ - |\PackageWarning| \arg{package-name} \arg{warning-text}\\ - |\ClassWarningNoLine| \arg{class-name} \arg{warning-text}\\ - |\PackageWarningNoLine| \arg{package-name} \arg{warning-text}\\ - |\ClassInfo| \arg{class-name} \arg{info-text}\\ - |\PackageInfo| \arg{package-name} \arg{info-text} -\end{decl} -The four |Warning| commands are similar to the error commands, except -that they produce only a warning on the screen, with no error prompt. - -The first two, |Warning| versions, also show the line number where the -warning occurred, whilst the second two, |WarningNoLine| versions, do -not. - -The two |Info| commands are similar except that they log the -information only in the transcript file, including the line number. -There are no |NoLine| versions of these two. - -Within the \m{warning-text} and \m{info-text}: |\protect| can be used to -stop a command from expanding; |\MessageBreak| causes a line-break; -and |\space| prints a space. -Also, these should not end with a full stop as one is -automatically added. +\section{Commands superseded for new material} +A small number of commands were introduced as part of \LaTeXe{} in the +mid-1990s, are widely used but have been superseded by more modern methods. +These are covered here as they are likely to be encountered routinely in +existing classes and packages. \subsection{Defining commands} -\label{Sec:commands.define} - -\LaTeXe{} provides some extra methods of (re)defining commands that are -intended for use in class and package files. -\NEWfeature{1994/12/01} The \texttt{*}-forms of these commands should be used to define commands that are not, in \TeX{} terms, long. This can be useful for error-trapping with commands whose arguments are not intended to @@ -1390,11 +1201,11 @@ contain whole paragraphs of text. |\DeclareRobustCommand*| \arg{cmd} \oarg{num} \oarg{default} \arg{definition} \end{decl} -This command takes the same arguments as |\newcommand| but it declares -a robust command, even if some code within the \m{definition} is -fragile. You can use this command to define new robust commands, or -to redefine existing commands and make them robust. A log is put into -the transcript file if a command is redefined. +This command takes the same arguments as |\newcommand| but it declares a robust +command, even if some code within the \m{definition} is fragile. You can use +this command to define new robust commands, or to redefine existing commands +and make them robust. A log is put into the transcript file if a command is +redefined. For example, if |\seq| is defined as follows: \begin{verbatim} @@ -1412,10 +1223,9 @@ Then the command |\seq| can be used in moving arguments, even though \section{Stuff about sequences $\seq{x}$} \end{verbatim} -Note also that there is no need to put a |\relax| before the -|\ifmmode| at the beginning of the definition; this is because the -protection given by this |\relax| against expansion at the wrong time -will be provided internally. +Note also that there is no need to put a |\relax| before the |\ifmmode| at the +beginning of the definition; this is because the protection given by this +|\relax| against expansion at the wrong time will be provided internally. \begin{decl} |\CheckCommand| \arg{cmd} \oarg{num} \oarg{default} @@ -1423,456 +1233,189 @@ will be provided internally. |\CheckCommand*| \arg{cmd} \oarg{num} \oarg{default} \arg{definition} \end{decl} -This takes the same arguments as |\newcommand| but, rather than define -\m{cmd}, it just checks that the current definition of \m{cmd} is -exactly as given by \m{definition}. An error is raised if these -definitions differ. - -This command is useful for checking the state of the system before -your package starts altering the definitions of commands. It allows -you to check, in particular, that no other package has redefined the -same command. - -\subsection{Moving arguments} - -\NEWdescription{1994/12/01} -The setting of protect whilst processing (i.e.~moving) moving arguments -has been reimplemented, as has the method of writing information from -the |.aux| file to other files such as the |.toc| file. Details can -be found in the file |ltdefns.dtx|. +This takes the same arguments as |\newcommand| but, rather than define \m{cmd}, +it just checks that the current definition of \m{cmd} is exactly as given by +\m{definition}. An error is raised if these definitions differ. -We hope that these changes will not affect many packages. +This command is useful for checking the state of the system before your package +starts altering the definitions of commands. It allows you to check, in +particular, that no other package has redefined the same command. -\section{Miscellaneous commands, etc} -\label{Sec:commands.misc} - -\subsection{Layout parameters} - -\begin{decl} -|\paperheight|\\ -|\paperwidth| -\end{decl} -These two parameters are usually set by the class to be the size of -the paper being used. This should be actual paper size, unlike -|\textwidth| and |\textheight| which are the size of the main text -body within the margins. +\subsection{Option declaration} +\label{Sec:commands.options.dec} +The following commands deal with the declaration and handling of options to +document classes and packages using a classical `simple text' approach. Every +option name must be a `\LaTeX{} name'. -\subsection{Case changing} -\label{sec:case} +There are some commands designed especially for use within the \m{code} +argument of these commands (see below). \begin{decl} - |\MakeUppercase| \arg{text} \\ - |\MakeLowercase| \arg{text} + |\DeclareOption| \arg{option-name} \arg{code} \end{decl} +This makes \m{option-name} a `declared option' of the class or package in which +it is put. -\NEWfeature{1995/06/01} -\TeX{} provides two primitives |\uppercase| and |\lowercase| for -changing the case of text. These are sometimes used in document -classes, for example to set information in running heads in all -capitals. - -Unfortunately, these \TeX{} primitives do not change the case of -characters accessed by commands like |\ae| or |\aa|. To overcome this -problem, \LaTeX{} provides two new commands |\MakeUppercase| and -|\MakeLowercase| to do this. +The \m{code} argument contains the code to be executed if that option is +specified for the class or package; it can contain any valid \LaTeXe{} +construct. -For example: -\begin{quotation} -\begin{tabular}{rl} - |\uppercase{aBcD\ae\AA\ss\OE}| & \uppercase{aBcD\ae\AA\ss\OE}\\ - |\lowercase{aBcD\ae\AA\ss\OE}| & \lowercase{aBcD\ae\AA\ss\OE}\\ - |\MakeUppercase{aBcD\ae\AA\ss\OE}| & - \MakeUppercase{aBcD\ae\AA\ss\OE}\\ - |\MakeLowercase{aBcD\ae\AA\ss\OE}| & \MakeLowercase{aBcD\ae\AA\ss\OE} -\end{tabular} -\end{quotation} - -The commands |\MakeUppercase| and |\MakeLowercase| themselves are -robust, but they have moving arguments. - -The commands use the \TeX{} primitives |\uppercase| and |\lowercase|, -and so have a number of unexpected `features'. In particular, they -change the case of everything (except characters in the names of -control-sequences) in their text argument: this includes mathematics, -environment names, and label names. - -For example: -\begin{verbatim} - \MakeUppercase{$x+y$ in \ref{foo}} -\end{verbatim} -produces $X+Y$ and the warning: +Example: \begin{verbatim} - LaTeX Warning: Reference `FOO' on page ... undefined on ... + \DeclareOption{twoside}{\@twosidetrue} \end{verbatim} -In the long run, we would like to use all-caps fonts rather than any -command like |\MakeUppercase| but this is not possible at the moment -because such fonts do not exist. - -\NEWdescription{1995/12/01} -In order that upper/lower-casing will work reasonably well, and in -order to provide any correct hyphenation, \LaTeXe{} \emph{must} use, -throughout a document, the same fixed table for changing case. -The table used is designed for the font encoding |T1|; this works well -with the standard \TeX{} fonts for all Latin alphabets but will cause -problems when using other alphabets. - -\subsection{The `openany' option in the `book' class} - -\NEWdescription{1996/06/01} -The |openany| option allows chapter and similar openings to -occur on left hand pages. Previously this option affected only -|\chapter| and |\backmatter|. It now also affects -|\part|, |\frontmatter| and |\mainmatter|. - -\subsection{Better user-defined math display environments} \begin{decl} - |\ignorespacesafterend| + |\DeclareOption*| \arg{code} \end{decl} +This declares the \m{code} to be executed for every option which is specified +for, but otherwise not explicitly declared by, the class or package; this code +is called the `default option code' and it can contain any valid \LaTeXe{} +construct. -\NEWfeature{1996/12/01} -\NEWdescription{2003/12/01} -Suppose that you want to define an environment for displaying text -that is numbered as an equation. A straightforward way to do this is -as follows: -\begin{verbatim} - \newenvironment{texteqn} - {\begin{equation} - \begin{minipage}{0.9\linewidth}} - {\end{minipage} - \end{equation}} -\end{verbatim} -However, if you have tried this then you will probably have noticed -that it does not work perfectly when used in the middle of a paragraph -because an inter-word space appears at the beginning of the first -line after the environment. +If a class file contains no |\DeclareOption*| then, by default, all specified +but undeclared options for that class will be silently passed to all packages +(as will the specified and declared options for that class). -There is now an extra command (with a very long name) available that -you can use to avoid this problem; it should be inserted as shown here: -\begin{verbatim} - \newenvironment{texteqn} - {\begin{equation} - \begin{minipage}{0.9\linewidth}} - {\end{minipage} - \end{equation} - \ignorespacesafterend} -\end{verbatim} +If a package file contains no |\DeclareOption*| then, by default, each +specified but undeclared option for that package will produce an error. -This command may also have other uses. +\subsection{Commands within option code} +\label{Sec:within.code} -\subsection{Normalising spacing} +These two commands can be used only within the \m{code} argument of either +|\DeclareOption| or |\DeclareOption*|. Other commands commonly used within +these arguments can be found in the next few subsections. \begin{decl} - |\normalsfcodes| + |\CurrentOption| \end{decl} - -\NEWfeature{1997/06/01} -This command should be used to restore the normal settings of the -parameters that affect spacing between words, sentences, etc. - -An important use of this feature is to correct a problem, reported by -Donald Arseneau, that punctuation in page headers has always (in all -known \TeX{} formats) been potentially wrong whenever a page break -happens while a local setting of the space codes is in effect. These -space codes are changed by, for example, the command -\verb|\frenchspacing|) and the \textsf{verbatim} environment. - -It is normally given the correct definition automatically in -|\begin{document}| and so need not be explicitly set; however, if it -is explicitly made nonempty in a class file then automatic -default setting will be over-ridden. - - -\section{Upgrading \LaTeX~2.09 classes and packages} -\label{Sec:upgrade} - -This section describes the changes you may need to make when you -upgrade an existing \LaTeX{} style to a package or class but we shall -start in optimistic mode. - -Many existing style files will run with \LaTeXe{} without any -modification to the file itself. When everything is running OK, -please put a note in the newly created package or class file to record -that it runs with the new standard \LaTeX{}; then distribute it to -your users. - -\subsection{Try it first!} -\label{Sec:try-it} - -The first thing you should do is to test your style in `compatibility -mode'. The only change you need to make in order to do this is, -possibly, to change the extension of the file to |.cls|: you should -make this change only if your file was used as a main document style. -Now, without any other modifications, run \LaTeXe{} on a document that -uses your file. This assumes that you have a suitable collection of -files that tests all the functionality provided by your style file. -(If you haven't, now is the time to make one!) - -You now need to change the test document files so that they are -\LaTeXe{} documents: see \emph{\usrguide} for details of how to do -this and then try them again. You have now tried the test documents -in both \LaTeXe{} native mode and \LaTeX~2.09 compatibility mode. - -\subsection{Troubleshooting} -\label{Sec:trouble} - -If your file does not work with \LaTeXe{}, there are two likely -reasons. -\begin{itemize} -\item \LaTeX{} now has a robust, well-defined designer's interface for - selecting fonts, which is very different from the \LaTeX~2.09 - internals. -\item Your style file may have used some \LaTeX~2.09 internal commands - which have changed, or which have been removed. -\end{itemize} - -When you are debugging your file, you will probably need more -information than is normally displayed by \LaTeXe. This is achieved -by resetting the counter |errorcontextlines| from its default value of -$-1$ to a much higher value, e.g.~999. - -\subsection{Accommodating compatibility mode} - -Sometimes an existing collection of \LaTeX~2.09 documents makes it -inconvenient or impossible to abandon the old commands entirely. -If this is the case, then it is possible to accommodate both conventions -by making special provision for documents processed in compatibility -mode. +This expands to the name of the current option. \begin{decl} -|\if@compatibility| + |\OptionNotUsed| \end{decl} -This switch is set when a document begins with |\documentstyle| rather -than |\documentclass|. Appropriate code can be supplied for either -condition, as follows: -\begin{verbatim} - \if@compatibility - <code emulating LaTeX 2.09 behavior> - \else - <code suitable for LaTeX2e> - \fi -\end{verbatim} - +This causes the current option to be added to the list of `unused options'. -\subsection{Font commands} - -Some font and size commands are now defined by the document class -rather than by the \LaTeX{} kernel. If you are upgrading a -\LaTeX~2.09 document style to a class that does not load one of the -standard classes, then you will probably need to add definitions for -these commands. +\subsection{Option processing} +\label{Sec:commands.options} \begin{decl} - |\rm| |\sf| |\tt| |\bf| |\it| |\sl| |\sc| + |\ProcessOptions| \end{decl} -None of these short-form font selection commands are defined in the -\LaTeXe{} kernel. They are defined by all the standard class files. +This command executes the \m{code} for each selected option. -If you want to define them in your class file, there are several -reasonable ways to do this. +We shall first describe how |\ProcessOptions| works in a package file, and then +how this differs in a class file. -One possible definition is: +To understand in detail what |\ProcessOptions| does in a package file, you have +to know the difference between \emph{local} and \emph{global} options. +\begin{itemize} +\item \textbf{Local options} are those which have been explicitly + specified for this particular package in the \m{options} argument of + any of these: +\begin{quote} + |\PassOptionsToPackage{<options>}| \ |\usepackage[<options>]|\\ + |\RequirePackage[<options>]| +\end{quote} +\item \textbf{Global options} are any other options that are specified + by the author in the \m{options} argument of + |\documentclass[<options>]|. +\end{itemize} +For example, suppose that a document begins: \begin{verbatim} - \newcommand{\rm}{\rmfamily} - ... - \newcommand{\sc}{\scshape} + \documentclass[german,twocolumn]{article} + \usepackage{gerhardt} \end{verbatim} -This would make the font commands orthogonal; for example -|{\bf\it text}| would produce bold italic, thus: \textbf{\textit{text}}. -It will also make them produce an error if used in math mode. - -Another possible definition is: +whilst package |gerhardt| calls package |fred| with: \begin{verbatim} - \DeclareOldFontCommand{\rm}{\rmfamily}{\mathrm} - ... - \DeclareOldFontCommand{\sc}{\scshape}{\mathsc} + \PassOptionsToPackage{german,dvips,a4paper}{fred} + \RequirePackage[errorshow]{fred} \end{verbatim} -This will make |\rm| act like |\rmfamily| in text mode (see above) and -it will make |\rm| select the |\mathrm| math alphabet in math mode. +then: +\begin{itemize} +\item |fred|'s local options are |german|, |dvips|, |a4paper| + and |errorshow|; +\item |fred|'s only global option is |twocolumn|. +\end{itemize} + +When |\ProcessOptions| is called, the following happen. +\begin{itemize} +\item \emph{First}, for each option so far declared in |fred.sty| + by |\DeclareOption|, it looks to see if that option is either a + global or a local option for |fred|: if it is then the corresponding + code is executed. -Thus |${\rm math} = X + 1$| will produce `${\rm math} = X + 1$'. + This is done in the order in which these options + were declared in |fred.sty|. +\item \emph{Then}, for each remaining \emph{local} option, the command + |\ds@<option>| is executed if it has been defined somewhere (other + than by a |\DeclareOption|); otherwise, the `default option code' is + executed. If no default option code has been declared then an error + message is produced. -If you do not want font selection to be orthogonal then you can -follow the standard classes and define: + This is done in the order in which these + options were specified. +\end{itemize} +Throughout this process, the system ensures that the code declared for +an option is executed at most once. + +Returning to the example, if |fred.sty| contains: \begin{verbatim} - \DeclareOldFontCommand{\rm}{\normalfont\rmfamily}{\mathrm} - ... - \DeclareOldFontCommand{\sc}{\normalfont\scshape}{\mathsc} + \DeclareOption{dvips}{\typeout{DVIPS}} + \DeclareOption{german}{\typeout{GERMAN}} + \DeclareOption{french}{\typeout{FRENCH}} + \DeclareOption*{\PackageWarning{fred}{Unknown `\CurrentOption'}} + \ProcessOptions\relax \end{verbatim} -This means, for example, that |{\bf\it text}| will produce medium -weight (rather than bold) italic, thus: \textit{text}. - -\begin{decl} - |\normalsize| \\ - |\@normalsize| -\end{decl} -The command |\@normalsize| is retained for compatibility with -\LaTeX~2.09 packages which may have used its value; but redefining it -in a class file will have no effect since it is always reset to have -the same meaning as |\normalsize|. - -This means that classes \emph{must} now redefine |\normalsize| rather -than redefining |\@normalsize|; for example (a rather incomplete one): +then the result of processing this document will be: \begin{verbatim} - \renewcommand{\normalsize}{\fontsize{10}{12}\selectfont} + DVIPS + GERMAN + Package fred Warning: Unknown `a4paper'. + Package fred Warning: Unknown `errorshow'. \end{verbatim} -Note that |\normalsize| is defined by the \LaTeX{} kernel to be an -error message. - -\begin{decl} - |\tiny| |\footnotesize| |\small| |\large|\\ - |\Large| |\LARGE| |\huge| |\Huge| -\end{decl} -None of these other `standard' size-changing commands are defined in -the kernel: each needs to be defined in a class file if you need it. -They are all defined by the standard classes. - -This means you should use |\renewcommand| for |\normalsize| and -|\newcommand| for the other size-changing commands. - - -\subsection{Obsolete commands} - -Some packages will not work with \LaTeXe{}, normally because they relied -on an internal \LaTeX{} command which was never supported and has now -changed, or been removed. - -In many cases there will now be a robust, high-level means of -achieving what previously required low-level commands. Please consult -Section~\ref{Sec:commands} to see if you can now use the \LaTeXe{} -class and package writers commands. +Note the following: -Also, of course, if your package or class redefined any of the kernel -commands (i.e.~those defined in the files |latex.tex|, |slitex.tex|, -|lfonts.tex|, |sfonts.tex|) then you will need to check it very -carefully against the new kernel in case the implementation has -changed or the command no longer exists in the \LaTeX2e{} kernel. +\begin{itemize} +\item the code for the |dvips| option is executed before that for the + |german| option, because that is the order in which they are declared + in |fred.sty|; +\item the code for the |german| option is executed only once, when the + declared options are being processed; +\item the |a4paper| and |errorshow| options produce the warning from + the code declared by |\DeclareOption*| (in the order in which they + were specified), whilst the |twocolumn| option does not: this is + because |twocolumn| is a global option. +\end{itemize} -Too many of the internal commands of \LaTeX~2.09 have been -re-implemented or removed to be able to list them all here. You must -check any that you have used or changed. +In a class file, |\ProcessOptions| works in the same way, except that: +\emph{all} options are local; and the default value for |\DeclareOption*| is +|\OptionNotUsed| rather than an error. -We shall, however, list some of the more important commands which are -no longer supported. +Note that, because |\ProcessOptions| has a |*|-form, it is wise to follow the +non-star form with |\relax|, as in the previous examples, since this prevents +unnecessary look ahead and possibly misleading error messages being issued. \begin{decl} - |\tenrm| |\elvrm| |\twlrm| \dots\\ - |\tenbf| |\elvbf| |\twlbf| \dots\\ - |\tensf| |\elvsf| |\twlsf| \dots\\ - \qquad$\vdots$ + |\ProcessOptions*| \end{decl} -The (approximately) seventy internal commands of this form are no longer -defined. If your class or package uses them then \emph{please} -replace them with new font commands described in \emph{\fntguide}. - -For example, the command |\twlsf| should be replaced by: -\begin{verbatim} - \fontsize{12}{14}\normalfont\sffamily\selectfont -\end{verbatim} - -Another possibility is to use the |rawfonts| package, described in -\emph{\usrguide}. - -Also, remember that many of the fonts preloaded by \LaTeX~2.09 -are no longer preloaded. +This is like |\ProcessOptions| but it executes the options in the order +specified in the calling commands, rather than in the order of declaration in +the class or package. For a package this means that the global options are +processed first. \begin{decl} - |\vpt| |\vipt| |\viipt| \dots + |\ExecuteOptions| \arg{options-list} \end{decl} -These were the internal size-selecting commands in \LaTeX~2.09. -(They can still be used in \LaTeX~2.09 compatibility mode.) -Please use the command |\fontsize| instead: see \emph{\fntguide} for -details. -For example, |\vpt| should be replaced by: +It can be used to provide a `default option list' just before +|\ProcessOptions|. For example, suppose that in a class file you want to set up +the default design to be: two-sided printing; 11pt fonts; in two columns. Then +it could specify: \begin{verbatim} - \fontsize{5}{6}\normalfont\selectfont + \ExecuteOptions{11pt,twoside,twocolumn} \end{verbatim} -\begin{decl} - |\prm|, |\pbf|, |\ppounds|, |\pLaTeX| \dots -\end{decl} -\LaTeX~2.09 used several commands beginning with |\p| in order to -provide `protected' commands. For example, |\LaTeX| was defined to be -|\protect\pLaTeX|, and |\pLaTeX| was defined to produce the \LaTeX{} -logo. This made |\LaTeX| robust, even though |\pLaTeX| was not. - -These commands have now been reimplemented using -|\DeclareRobustCommand| -(described in Section~\ref{Sec:commands.define}). -If your package redefined one of the |\p|-commands then you must -remove the redefinition and use |\DeclareRobustCommand| to redefine the -non-|\p| command. - -\begin{decl} -|\footheight|\\ -|\@maxsep|\\ -|\@dblmaxsep| -\end{decl} -These parameters are not used by \LaTeXe{} so they have been removed, -except in \LaTeX~2.09 compatibility mode. Classes should no longer -set them. - -\begin{thebibliography}{1} - -\bibitem{A-W:DEK91} -Donald~E. Knuth. -\newblock {\em The \TeX book}. -\newblock Addison-Wesley, Reading, Massachusetts, 1986. -\newblock Revised to cover \TeX3, 1991. - -\bibitem{A-W:LLa94} -Leslie Lamport. -\newblock {\em {\LaTeX:} A Document Preparation System}. -\newblock Addison-Wesley, Reading, Massachusetts, second edition, 1994. - -\bibitem{A-W:MG2004} -Frank Mittelbach and Michel Goossens. -\newblock {\em The {\LaTeX} Companion second edition}. -\newblock With Johannes Braams, David Carlisle, and Chris Rowley. -\newblock Addison-Wesley, Reading, Massachusetts, 2004. - -\end{thebibliography} - -\newpage -\thispagestyle{empty} - -\section*{\LaTeXe{} Summary sheet: updating old styles} - -Section references below are to \emph{\clsguide}. - -\begin{enumerate} - -\item Should it become a class or a package? - See Section~\ref{Sec:classorpkg} for how to answer this question. - -\item If it uses another style file, then you will need to obtain an - updated version of this other file. Look at Section~\ref{Sec:loading} - for information on how to load other class and package files. - -\item Try it: see Section~\ref{Sec:try-it}. - -\item It worked? Excellent, but there are probably still some things - you should change in order to make your file into a well-structured - \LaTeXe{} file that is both robust and portable. So you should now - read Section~\ref{Sec:writing}, especially~\ref{Sec:general}. You - will also find some useful examples in Section~\ref{Sec:structure}. - - If your file sets up new fonts, font-changing commands or symbols, - you should also read \emph{\fntguide}. - -\item It did not work? There are three possibilities here: - \begin{itemize} - \item error messages are produced whilst reading your file; - \item error messages are produced whilst processing test documents; - \item there are no errors but the output is not as it should be. - \end{itemize} - Don't forget to check carefully for this last possibility. - - If you have got to this stage then you will need to read - Section~\ref{Sec:upgrade} to find the solutions that will make your - file work. -\end{enumerate} - \end{document} diff --git a/macros/latex/base/cmextra.ins b/macros/latex/base/cmextra.ins index a2befb3aef..0fa45183fc 100644 --- a/macros/latex/base/cmextra.ins +++ b/macros/latex/base/cmextra.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/cmfonts.fdd b/macros/latex/base/cmfonts.fdd index 477085eaef..af898e47b2 100644 --- a/macros/latex/base/cmfonts.fdd +++ b/macros/latex/base/cmfonts.fdd @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -67,7 +67,7 @@ %<*driver, > \ProvidesFile{cmfonts.drv} %</driver, > - [2022/07/10 v2.5l Standard LaTeX font definitions] + [2023/04/13 v2.5m Standard LaTeX font definitions] % %<*driver> \documentclass{ltxdoc} @@ -1048,8 +1048,10 @@ % \end{macrocode} % % \changes{v2.5j}{2019/12/16}{Provide substitutions for cmtt/bx/sl} +% \changes{v2.5m}{2023/04/13}{Add missing substitution for U/cmtt/bx/sl} % \begin{macrocode} %<+OT1cmtt>\DeclareFontShape{OT1}{cmtt}{bx}{sl} +%<+Ucmtt>\DeclareFontShape{U}{cmtt}{bx}{sl} %<-nowarn> {<->sub*cmtt/m/n}{} %<+nowarn> {<->ssub*cmtt/m/n}{} %<+OT1cmtt>\DeclareFontShape{OT1}{cmtt}{bx}{ui} diff --git a/macros/latex/base/cmfonts.ins b/macros/latex/base/cmfonts.ins index 55af4759c5..af5ac7e5f8 100644 --- a/macros/latex/base/cmfonts.ins +++ b/macros/latex/base/cmfonts.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/cmfonts.pdf b/macros/latex/base/cmfonts.pdf index 01bd9f1fa2..e81f13eb78 100644 Binary files a/macros/latex/base/cmfonts.pdf and b/macros/latex/base/cmfonts.pdf differ diff --git a/macros/latex/base/cyrguide.pdf b/macros/latex/base/cyrguide.pdf index 6339438a02..2efa4eee4d 100644 Binary files a/macros/latex/base/cyrguide.pdf and b/macros/latex/base/cyrguide.pdf differ diff --git a/macros/latex/base/cyrguide.tex b/macros/latex/base/cyrguide.tex index 7304a586e4..394cd59e20 100644 --- a/macros/latex/base/cyrguide.tex +++ b/macros/latex/base/cyrguide.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -34,7 +34,7 @@ \author{\copyright~Copyright 1998--1999,\\ Vladimir Volovich, Werner Lemberg and \LaTeX\ Project Team.\\ All rights reserved.% - \footnote{This file may distributed and/or modified under the + \footnote{This file may be distributed and/or modified under the conditions of the \LaTeX{} Project Public License, either version 1.3c of this license or (at your option) any later version. See the source \texttt{cyrguide.tex} for full details.}% diff --git a/macros/latex/base/doc-code.pdf b/macros/latex/base/doc-code.pdf index 3b0c7bc965..9c17bbb77c 100644 Binary files a/macros/latex/base/doc-code.pdf and b/macros/latex/base/doc-code.pdf differ diff --git a/macros/latex/base/doc.dtx b/macros/latex/base/doc.dtx index d137038d63..75e04cc299 100644 --- a/macros/latex/base/doc.dtx +++ b/macros/latex/base/doc.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright 1993-2022 -% The LaTeX3 Project and any individual authors listed elsewhere +% Copyright (C) 1993-2023 +% The LaTeX Project and any individual authors listed elsewhere % in this file. % % This file is part of the LaTeX base system. @@ -45,7 +45,7 @@ %<+package> %<+package>\ProvidesPackage{doc} %<+shortvrb>\ProvidesPackage{shortvrb} -%<+package|shortvrb> [2022/07/03 v3.0k +%<+package|shortvrb> [2022/11/13 v3.0m %<+package|shortvrb> Standard LaTeX documentation package V3 (FMi)] %\catcode`\<=12 % @@ -82,6 +82,8 @@ % \changes{v1.9a}{1993/12/02}{Upgrade for LaTeX2e} % \changes{v1.9d}{1993/12/20}{Protected changes entry.} % \changes{v1.0p}{1994/05/21}{Use new error commands} +% \changes{v3.0m}{2022/11/13}{Redefinitions of \cs{verb} removed as +% no longer needed (gh/953)} % % % \hyphenation{make-index} @@ -1208,7 +1210,7 @@ % not to exceed this limit when describing the change. The actual % entry consists of the \meta{version}, the |\actualchar|, the current % macro name, a colon, the |\levelchar|, and, finally, the \meta{text}. -% The result is a glossaryentry for the \meta{version}, with the name of +% The result is a glossary entry for the \meta{version}, with the name of % the current macro as subitem. Outside the |macro| environment, the % text |\generalname| is used instead of the macro name. When % referring to macros in change descriptions it is conventional to use @@ -1216,6 +1218,13 @@ % and using up valuable characters in the entry with old \prg{makeindex} % versions. % +% Note that in the history listing, the entry is shown with the page number +% that corresponds to its place in the source, e.g., general changes put at the +% very beginning of the file will show up with page number ``1'', change entries +% placed elsewhere might have different numbers (not necessarily always +% very useful unless you are careful). +% +% % \changes{v1.7a}{1992/02/26}{Description of \cs{RecordChanges} etc. % added % to interface section.} \DescribeInterfaceMacro\RecordChanges To cause the @@ -1824,8 +1833,8 @@ % July 1989. % \bibitem{art:docstrip} \textsc{Frank Mittelbach, Denys Duchier and % Johannes Braams}. -% \newblock \texttt{docstrip.dtx} (to appear). -% \newblock The file is part of the DOC package. +% \newblock \texttt{docstrip.dtx}. +% \newblock The file is part of core \LaTeX{}. % \bibitem{book:Raspe} \textsc{R. E. Raspe} (*1737, \dag 1797). % \newblock Baron Münchhausens narrative of his marvelous % travels and campaigns in Russia. @@ -2686,12 +2695,16 @@ % first lines are copied literally from \texttt{latex.tex}. % \changes{v1.7i}{1992/07/12}{Added \cs{@@par} to clear possible % \cs{parshape}.} +% \changes{v3.0m}{2022/11/13}{Redefinitions of \cs{@verbatim} changed +% to match the kernel definition (gh/953)} % \begin{macrocode} -\def\@verbatim{\trivlist \item[]\if@minipage\else\vskip\parskip\fi - \leftskip\@totalleftmargin\rightskip\z@ - \parindent\z@\parfillskip\@flushglue\parskip\z@ - \@@par - \@tempswafalse +\def\@verbatim{\trivlist \item\relax + \if@minipage\else\vskip\parskip\fi + \leftskip\@totalleftmargin\rightskip\z@ + \parindent\z@\parfillskip\@flushglue\parskip\z@ + \language\l@nohyphenation + \@@par + \@tempswafalse % \end{macrocode} % |\@verbatim| sets |^^M|, the end of line character, to % be equal to |\par|. This control sequence is redefined @@ -2699,8 +2712,13 @@ % \changes{v1.7c}{1992/03/24}{Added \cs{interlinepenalty} to % \cs{par} from verbatim.sty} % \begin{macrocode} - \def\par{\if@tempswa\hbox{}\fi\@tempswatrue\@@par - \penalty\interlinepenalty + \def\par{% + \if@tempswa + \leavevmode \null \@@par\penalty\interlinepenalty + \else + \@tempswatrue + \ifhmode\@@par\penalty\interlinepenalty\fi + \fi % \end{macrocode} % We add a control sequence |\check@percent| to the definition % of |\par| whose task it is to check for a percent character. @@ -2713,9 +2731,10 @@ % \changes{v1.8b}{1993/09/21}{Changed to conform to new LaTeX verbatim, % which handles more ligatures.} % \begin{macrocode} - \obeylines - \let\do\do@noligs \verbatim@nolig@list - \let\do\@makeother \dospecials} + \let\do\@makeother \dospecials + \obeylines \verbatim@font \@noligs + \everypar \expandafter{\the\everypar \unpenalty}% +} % \end{macrocode} % \end{macro} % @@ -2744,83 +2763,12 @@ % \end{macrocode} % \end{macro} % -% \begin{imacro}{\verb} -% \changes{v1.7a}{1992/02/27}{Now warns about newlines (from -% newdoc with `@noligs added).} -% \changes{v1.8b}{1993/09/21}{Changed to conform to new LaTeX \cs{verb}} -% We re-define |\verb| to check for newlines in its argument since a -% missing delimiter is difficult to detect in \DOC{} source. -% The code is the same as in \texttt{latex.tex} of September 19, 1993. -% Perhaps there should be a font-changing -% hook rather than just using |\ttfamily|, but if so it probably should be -% different from |\MacroFont| since that normally includes |\small| -% and would look wrong inline. -% \changes{v1.7a}{1992/02/28}{Added math mode check (from verbatim.sty)} -% \begin{macrocode} -\def\verb{\relax\ifmmode\hbox\else\leavevmode\null\fi - \bgroup \let\do\do@noligs \verbatim@nolig@list - \ttfamily \verb@eol@error \let\do\@makeother \dospecials - \@ifstar{\@sverb}{\@vobeyspaces \frenchspacing \@sverb}} -% \end{macrocode} -% \end{imacro} -% -% \begin{macro}{\verb@balance@group} -% \begin{macro}{\verb@egroup} -% \begin{macro}{\verb@eol@error} -% \changes{v1.8b}{1993/09/21}{Renamed \cs{verb@err} to -% \cs{verb@eol@error}, as in new LaTeX verbatim.} -% \begin{macrocode} -\let\verb@balance@group\@empty -% \end{macrocode} -% -% \begin{macrocode} -\def\verb@egroup{\global\let\verb@balance@group\@empty\egroup} -% \end{macrocode} -% -% \begin{macrocode} -\begingroup - \obeylines% - \gdef\verb@eol@error{\obeylines% - \def^^M{\verb@egroup\@latex@error{% - \noexpand\verb command ended by end of line}\@ehc}}% -\endgroup -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\@sverb} -% \changes{v1.7a}{1992/02/27}{Added for \cs{verb} change.} -% \changes{v1.7a}{1992/02/28}{Now same as in verbatim.sty.} -% \changes{v1.8b}{1993/09/21}{Changed to conform to new LaTeX verbatim, -% which has better error trapping.} -% See \cite{art:verbatim} for commentary. -% \changes{v2.1j}{2019/11/03}{Use the kernel definition, no change needed (gh/205)} -% \begin{macrocode} -%\def\@sverb#1{% -% \catcode`#1\active \lccode`\~`#1% -% \gdef\verb@balance@group{\verb@egroup -% \@latex@error{Illegal use of \noexpand\verb command}\@ehc}% -% \aftergroup\verb@balance@group -% \lowercase{\let~\verb@egroup}} -% \end{macrocode} -% \end{macro} -% % -% \begin{macro}{\verbatim@nolig@list} -% \begin{macro}{\do@noligs} -% These macros replace the old |\@noligs| mechanism by an -% extensible version to allow more ligatures to be added. -% \begin{macrocode} -\def\verbatim@nolig@list{\do\`\do\<\do\>\do\,\do\'\do\-} -\def\do@noligs#1{% - \catcode`#1\active - \begingroup - \lccode`\~=`#1\relax - \lowercase{\endgroup\def~{\leavevmode\kern\z@\char`#1}}} -% \end{macrocode} -% \end{macro} -% \end{macro} +% In the early versions of the package it also redefined \cs{verb} +% because that didn't include the useful test for \enquote{newline} in +% the verbatim text. This is nowadays part of \LaTeX{} so we do not +% redefine it any longer (the original code is still kept in the file +% after \cs{endinput} to keep the long history intact). % % \begin{tcounter}{\macro@cnt} % \label{page:macro} The \env{macro} environment is implemented as @@ -3147,9 +3095,6 @@ % % \begin{macro}{\short@macro} % -% \fmi{this needs cleaning up too, the results in the index are -% currently wrong for cases like `\cs{ }' and the like.} -% % \changes{v1.5c}{1989/04/27}{Corrected bad bug by putting the % scan@allowedfalse macro before printing % the argument.} @@ -3164,17 +3109,14 @@ % done by the |\ifnot@excluded| macro which assumes that the % macro name is saved in |\macro@namepart|. The character % mustn't be stored with a special category code or exclusion from -% the index won't work, so we employ the case-changing trick used -% elsewhere. Since the argument might be an active character, -% |\string| is used to normalize it. +% the index won't work, so we we use \cs{string} to normalize it +% the same way it is done in \cs{DoNotIndex}, i.e. everything ends up catcode 12 +% except for the space character. % \changes{v2.0e}{1998/12/28}{Correctly use the case-changing trick.} +% \changes{v3.0l}{2022/11/03}{No longer using the case-changing trick.} % \begin{macrocode} -\begingroup -\catcode`\&=12 -\gdef\short@macro#1{\begingroup - \uccode`\&=\expandafter`\string#1% - \uppercase{\def\x{\def\macro@namepart{&}}}% - \expandafter\endgroup\x +\def\short@macro#1{% + \edef\macro@namepart{\string#1}% % \end{macrocode} % Any indexing is then delegated to % |\maybe@index@short@macro|. Depending on the actual character seen, @@ -3197,7 +3139,6 @@ % cross-referencing is globally disabled. % \begin{macrocode} \scan@allowedtrue } -\endgroup % \end{macrocode} % \end{macro} % @@ -3441,7 +3382,6 @@ \def \ShowIndexingState { \__doc_trace:x{Show~ doc~ indexing~ state:} \seq_show:N \l__doc_donotindex_seq -% \tl_analysis_show:N\l__doc_donotindex_seq \prop_show:N \g__doc_idxtype_prop } % \end{macrocode} @@ -3637,10 +3577,12 @@ % \begin{macro}{\maybe@index@short@macro} % \begin{macro}{\__doc_maybe_index_short:o} % Single character macros are handled similarly but there the -% indexing is done by \cs{SpecialShortIndex}. +% indexing is done by \cs{SpecialShortIndex} and it is simpler +% because we know that the argument contains a string token not letters. +% \changes{v3.0l}{2022/11/03}{We know the argument expands to a single string token} % \begin{macrocode} \cs_new:Npn \__doc_maybe_index_short:o #1 { - \exp_args:Nf \__doc_maybe_index_aux:nN { \tl_to_str:o {#1} } + \exp_args:No \__doc_maybe_index_aux:nN #1 \SpecialShortIndex } \cs_set_eq:NN \maybe@index@short@macro \__doc_maybe_index_short:o @@ -3715,7 +3657,12 @@ {\cs_to_str:N \^^M } {\def\reserved@a{ \string \space \actualchar } \def\reserved@b { \space } \let\reserved@c \@empty } - { } {\def\reserved@a{ \string \space \actualchar } +% \end{macrocode} +% With the fix for +% \verb*=\ = we now have to look for a real space to handle that command sequence. +% \changes{v3.0l}{2022/11/03}{look for the right token} +% \begin{macrocode} + { ~ } {\def\reserved@a{ \string \space \actualchar } \def\reserved@b { \space } \let\reserved@c \@empty } {\c_left_brace_str} { \def\reserved@a{ \bgroup \actualchar } @@ -6256,6 +6203,89 @@ % %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% \endinput +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +% \section{Code no longer used} +% +% \begin{imacro}{\verb} +% \changes{v1.7a}{1992/02/27}{Now warns about newlines (from +% newdoc with `@noligs added).} +% \changes{v1.8b}{1993/09/21}{Changed to conform to new LaTeX \cs{verb}} +% We re-define |\verb| to check for newlines in its argument since a +% missing delimiter is difficult to detect in \DOC{} source. +% The code is the same as in \texttt{latex.tex} of September 19, 1993. +% Perhaps there should be a font-changing +% hook rather than just using |\ttfamily|, but if so it probably should be +% different from |\MacroFont| since that normally includes |\small| +% and would look wrong inline. +% \changes{v1.7a}{1992/02/28}{Added math mode check (from verbatim.sty)} +% \begin{macrocode} +%\def\verb{\relax\ifmmode\hbox\else\leavevmode\null\fi +% \bgroup \let\do\do@noligs \verbatim@nolig@list +% \ttfamily \verb@eol@error \let\do\@makeother \dospecials +% \@ifstar{\@sverb}{\@vobeyspaces \frenchspacing \@sverb}} +% \end{macrocode} +% \end{imacro} +% +% \begin{macro}{\verb@balance@group} +% \begin{macro}{\verb@egroup} +% \begin{macro}{\verb@eol@error} +% \changes{v1.8b}{1993/09/21}{Renamed \cs{verb@err} to +% \cs{verb@eol@error}, as in new LaTeX verbatim.} +% \begin{macrocode} +%\let\verb@balance@group\@empty +% \end{macrocode} +% +% \begin{macrocode} +%\def\verb@egroup{\global\let\verb@balance@group\@empty\egroup} +% \end{macrocode} +% +% \begin{macrocode} +%\begingroup +% \obeylines% +% \gdef\verb@eol@error{\obeylines% +% \def^^M{\verb@egroup\@latex@error{% +% \noexpand\verb command ended by end of line}\@ehc}}% +%\endgroup +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@sverb} +% \changes{v1.7a}{1992/02/27}{Added for \cs{verb} change.} +% \changes{v1.7a}{1992/02/28}{Now same as in verbatim.sty.} +% \changes{v1.8b}{1993/09/21}{Changed to conform to new LaTeX verbatim, +% which has better error trapping.} +% See \cite{art:verbatim} for commentary. +% \changes{v2.1j}{2019/11/03}{Use the kernel definition, no change needed (gh/205)} +% \begin{macrocode} +%\def\@sverb#1{% +% \catcode`#1\active \lccode`\~`#1% +% \gdef\verb@balance@group{\verb@egroup +% \@latex@error{Illegal use of \noexpand\verb command}\@ehc}% +% \aftergroup\verb@balance@group +% \lowercase{\let~\verb@egroup}} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\verbatim@nolig@list} +% \begin{macro}{\do@noligs} +% These macros replace the old |\@noligs| mechanism by an +% extensible version to allow more ligatures to be added. +% \begin{macrocode} +%\def\verbatim@nolig@list{\do\`\do\<\do\>\do\,\do\'\do\-} +%\def\do@noligs#1{% +% \catcode`#1\active +% \begingroup +% \lccode`\~`#1\relax +% \lowercase{\endgroup\def~{\leavevmode\kern\z@\char`#1}}} +% \end{macrocode} +% \end{macro} +% \end{macro} + ^^A Needed for emacs ^^A diff --git a/macros/latex/base/doc.pdf b/macros/latex/base/doc.pdf index 75e804a9c9..8c86a55630 100644 Binary files a/macros/latex/base/doc.pdf and b/macros/latex/base/doc.pdf differ diff --git a/macros/latex/base/docstrip.dtx b/macros/latex/base/docstrip.dtx index de20073c48..be373499e6 100644 --- a/macros/latex/base/docstrip.dtx +++ b/macros/latex/base/docstrip.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/docstrip.ins b/macros/latex/base/docstrip.ins index e2187594a4..79d4c429dd 100644 --- a/macros/latex/base/docstrip.ins +++ b/macros/latex/base/docstrip.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -52,7 +52,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/docstrip.pdf b/macros/latex/base/docstrip.pdf index 83739ec6b3..7b09dba511 100644 Binary files a/macros/latex/base/docstrip.pdf and b/macros/latex/base/docstrip.pdf differ diff --git a/macros/latex/base/ec.ins b/macros/latex/base/ec.ins index 47823e7edf..15a7c3848c 100644 --- a/macros/latex/base/ec.ins +++ b/macros/latex/base/ec.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/encguide.pdf b/macros/latex/base/encguide.pdf index 5ddc6f4fc9..c2da6210d8 100644 Binary files a/macros/latex/base/encguide.pdf and b/macros/latex/base/encguide.pdf differ diff --git a/macros/latex/base/encguide.tex b/macros/latex/base/encguide.tex index 3c95cf30cc..1a0978267e 100644 --- a/macros/latex/base/encguide.tex +++ b/macros/latex/base/encguide.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/exscale.dtx b/macros/latex/base/exscale.dtx index bc884c4db0..89890a4198 100644 --- a/macros/latex/base/exscale.dtx +++ b/macros/latex/base/exscale.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/exscale.ins b/macros/latex/base/exscale.ins index d202aad7cf..ae75460ee5 100644 --- a/macros/latex/base/exscale.ins +++ b/macros/latex/base/exscale.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/exscale.pdf b/macros/latex/base/exscale.pdf index 30af0ff0a7..d9bad62abf 100644 Binary files a/macros/latex/base/exscale.pdf and b/macros/latex/base/exscale.pdf differ diff --git a/macros/latex/base/fix-cm.dtx b/macros/latex/base/fix-cm.dtx index 5f8983ed34..9e39cd192b 100644 --- a/macros/latex/base/fix-cm.dtx +++ b/macros/latex/base/fix-cm.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/fix-cm.ins b/macros/latex/base/fix-cm.ins index b688cd66cf..68c6792412 100644 --- a/macros/latex/base/fix-cm.ins +++ b/macros/latex/base/fix-cm.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/fix-cm.pdf b/macros/latex/base/fix-cm.pdf index 5d8487c2ea..21479fe3cb 100644 Binary files a/macros/latex/base/fix-cm.pdf and b/macros/latex/base/fix-cm.pdf differ diff --git a/macros/latex/base/fntguide.pdf b/macros/latex/base/fntguide.pdf index d4c88762f4..b7570a411e 100644 Binary files a/macros/latex/base/fntguide.pdf and b/macros/latex/base/fntguide.pdf differ diff --git a/macros/latex/base/fntguide.tex b/macros/latex/base/fntguide.tex index 65467339f1..619cc907b2 100644 --- a/macros/latex/base/fntguide.tex +++ b/macros/latex/base/fntguide.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % % The LaTeX Project and any individual authors listed elsewhere % in this file. @@ -42,17 +42,17 @@ \title{\LaTeXe{} font selection} -\author{\copyright~Copyright 1995--2022, \LaTeX\ Project +\author{\copyright~Copyright 1995--2023, \LaTeX\ Project Team.\thanks{Thanks to Arash Esbati for documenting the newer NFSS features of 2020}\\ All rights reserved.% - \footnote{This file may distributed and/or modified under the + \footnote{This file may be distributed and/or modified under the conditions of the \LaTeX{} Project Public License, either version 1.3c of this license or (at your option) any later version. See the source \texttt{fntguide.tex} for full details.}% } -\date{August 2022} +\date{May 2023} \begin{document} @@ -299,8 +299,6 @@ e.g., ``demi-bold'' is normally just another name for ``semi-bold'', so should get |sb| assigned, etc. -\newpage - \NEWdescription{2020/02/02} The most common values for the font shape are: \begin{center} @@ -325,7 +323,7 @@ A less common value for font shape is: \end{minipage} \end{center} and there is also |ui| for upright italic, i.e., an italic shape but -artifically turned upright. This is sometimes useful and available in +artificially turned upright. This is sometimes useful and available in some fonts. @@ -404,8 +402,6 @@ turned into \TeX{} font names. This is described in Section~\ref{Sec:install}. -\newpage - \subsection{Selection commands} @@ -955,7 +951,6 @@ Example: \DeclareMathSymbol{\alphld}{\mathalpha}{AMSb}{"0C} \end{verbatim} -\newpage \begin{decl} |\DeclareMathDelimiter| \arg{cmd} \arg{type} @@ -1382,7 +1377,7 @@ the `cmr' family). from this subsection. \NEWdescription{2019/07/10} -As an exception it may also contain a |\DeclareFontsubstitution| +As an exception it may also contain a |\DeclareFontSubstitution| declaration (described in \ref{sec:encoding-defaults}) to specify how font substitution for this encoding should be handled. In that case it is important that the values used point to a font that is guaranteed to @@ -1431,6 +1426,8 @@ executed whenever a math alphabet with this encoding is called. It also saves the value of \m{encoding} in the macro |\LastDeclaredEncoding|. +\newpage + Example: \begin{verbatim} \DeclareFontEncoding{OT1}{}{} @@ -1496,6 +1493,8 @@ For example, the definition of |\ss| in the |OT1| encoding is: It does not produce an error if the command has already been defined but logs the redefinition in the transcript file. +\newpage + \begin{decl} |\DeclareTextAccent| \arg{cmd} \arg{encoding} \arg{slot} \end{decl} @@ -1611,6 +1610,8 @@ defined with |\DeclareTextSymbol|. For more examples of these definitions, see |ltoutenc.dtx|. +\newpage + \begin{decl}[1994/12/01] |\ProvideTextCommandDefault| \arg{cmd} \arg{definition} \end{decl} @@ -2440,8 +2441,6 @@ become unavailable in the different sub-encodings. Again, the numbers are the slots in the |TS1| encoding, |acc| indicates a `constructed' accent. -\newpage - \begin{table}[!tbp] diff --git a/macros/latex/base/fontdef.dtx b/macros/latex/base/fontdef.dtx index 06af8feefd..5e88e55079 100644 --- a/macros/latex/base/fontdef.dtx +++ b/macros/latex/base/fontdef.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/format.ins b/macros/latex/base/format.ins index 369f01a7c5..74cd78ff4a 100644 --- a/macros/latex/base/format.ins +++ b/macros/latex/base/format.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. @@ -88,7 +88,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 2015-2022 +Copyright (C) 2015-2023 The LaTeX Project and any individual authors listed elsewhere in this file. @@ -123,7 +123,7 @@ extension .ins) which are part of the distribution. This is a generated file. -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/graphpap.dtx b/macros/latex/base/graphpap.dtx index 78bb688f83..6b7bc8b822 100644 --- a/macros/latex/base/graphpap.dtx +++ b/macros/latex/base/graphpap.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/graphpap.ins b/macros/latex/base/graphpap.ins index d82cbd6670..43ba83aae3 100644 --- a/macros/latex/base/graphpap.ins +++ b/macros/latex/base/graphpap.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/graphpap.pdf b/macros/latex/base/graphpap.pdf index d2385fa786..2460d68872 100644 Binary files a/macros/latex/base/graphpap.pdf and b/macros/latex/base/graphpap.pdf differ diff --git a/macros/latex/base/idx.tex b/macros/latex/base/idx.tex index bc0dd71021..04c8ef6959 100644 --- a/macros/latex/base/idx.tex +++ b/macros/latex/base/idx.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ifthen.dtx b/macros/latex/base/ifthen.dtx index d36042990d..aefc4a7666 100644 --- a/macros/latex/base/ifthen.dtx +++ b/macros/latex/base/ifthen.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ifthen.ins b/macros/latex/base/ifthen.ins index 88047e94f0..697a4a38b3 100644 --- a/macros/latex/base/ifthen.ins +++ b/macros/latex/base/ifthen.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/ifthen.pdf b/macros/latex/base/ifthen.pdf index 4802103db4..7437721f4d 100644 Binary files a/macros/latex/base/ifthen.pdf and b/macros/latex/base/ifthen.pdf differ diff --git a/macros/latex/base/inputenc.dtx b/macros/latex/base/inputenc.dtx index e056f8ffd7..02956a8c07 100644 --- a/macros/latex/base/inputenc.dtx +++ b/macros/latex/base/inputenc.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/inputenc.ins b/macros/latex/base/inputenc.ins index adacf9efce..3857827070 100644 --- a/macros/latex/base/inputenc.ins +++ b/macros/latex/base/inputenc.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/inputenc.pdf b/macros/latex/base/inputenc.pdf index 1ea351b1e7..4a7f1190f1 100644 Binary files a/macros/latex/base/inputenc.pdf and b/macros/latex/base/inputenc.pdf differ diff --git a/macros/latex/base/lablst.tex b/macros/latex/base/lablst.tex index 0821b0e4f0..b0a3ac1ab6 100644 --- a/macros/latex/base/lablst.tex +++ b/macros/latex/base/lablst.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/lamport-manual.pdf b/macros/latex/base/lamport-manual.pdf index 2d2e7d4f47..bf804f21a0 100644 Binary files a/macros/latex/base/lamport-manual.pdf and b/macros/latex/base/lamport-manual.pdf differ diff --git a/macros/latex/base/latex209.dtx b/macros/latex/base/latex209.dtx index 768f7237a5..b84564bb55 100644 --- a/macros/latex/base/latex209.dtx +++ b/macros/latex/base/latex209.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/latex209.ins b/macros/latex/base/latex209.ins index f530347a3c..0c90fa36ea 100644 --- a/macros/latex/base/latex209.ins +++ b/macros/latex/base/latex209.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/latexrelease.dtx b/macros/latex/base/latexrelease.dtx index 294007553d..4abde253e1 100644 --- a/macros/latex/base/latexrelease.dtx +++ b/macros/latex/base/latexrelease.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -40,7 +40,7 @@ %<*latexrelease> % \fi % \ProvidesFile{latexrelease.dtx} - [2022/02/28 v1.0o LaTeX release emulation and tests + [2022/11/14 v1.0p LaTeX release emulation and tests (including releases up to \latexreleaseversion)] % \iffalse %</latexrelease> @@ -746,8 +746,12 @@ of this package available from CTAN} % % Finally, redirect the error thrown by \cs{NewHook} to nowhere so it % can be safely reused (the hook isn't redeclared if it already exists). +% The same happens for \cs{NewMarkClass}. +% \changes{v1.0p}{2022/11/14} +% {Silence \cs{NewMarkClass} in rollback (gh/955)} % \begin{macrocode} \msg_redirect_name:nnn { hooks } { exists } { none } +\msg_redirect_name:nnn { mark } { class-already-defined }{ none } % \end{macrocode} % % Now a one-off for |ltcmd.dtx|: we need to make \cs{NewDocumentCommand} @@ -799,9 +803,12 @@ of this package available from CTAN} \tl_clear:N \l_@@_restores_tl % \end{macrocode} % -% And restore the hook error message. +% And restore the silenced error messages. +% \changes{v1.0p}{2022/11/14} +% {Unsilence \cs{NewMarkClass} error message after rollback (gh/955)} % \begin{macrocode} \msg_redirect_name:nnn { hooks } { exists } { } +\msg_redirect_name:nnn { mark } { class-already-defined } { } % \end{macrocode} % % \begin{macrocode} diff --git a/macros/latex/base/latexrelease.ins b/macros/latex/base/latexrelease.ins index b5e97a9479..61315f8e07 100644 --- a/macros/latex/base/latexrelease.ins +++ b/macros/latex/base/latexrelease.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/latexrelease.pdf b/macros/latex/base/latexrelease.pdf index 9ab51faa3b..e4217ba088 100644 Binary files a/macros/latex/base/latexrelease.pdf and b/macros/latex/base/latexrelease.pdf differ diff --git a/macros/latex/base/latexsym.dtx b/macros/latex/base/latexsym.dtx index 62fb097c0d..e4e1559e27 100644 --- a/macros/latex/base/latexsym.dtx +++ b/macros/latex/base/latexsym.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/latexsym.ins b/macros/latex/base/latexsym.ins index 468afddd67..12d658bca9 100644 --- a/macros/latex/base/latexsym.ins +++ b/macros/latex/base/latexsym.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. @@ -87,7 +87,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/latexsym.pdf b/macros/latex/base/latexsym.pdf index 8546f14f7d..aeb945867d 100644 Binary files a/macros/latex/base/latexsym.pdf and b/macros/latex/base/latexsym.pdf differ diff --git a/macros/latex/base/lb2.err b/macros/latex/base/lb2.err index 46958ae3a5..d2ea742f82 100644 --- a/macros/latex/base/lb2.err +++ b/macros/latex/base/lb2.err @@ -363,10 +363,15 @@ Bafög-Ausgabe (Softcover) die inhaltlich identisch ist: ) \end{verbatim} - \begin{list}{}{\setlength\leftmargin{0cm}\setlength\rightmargin{3cm}} \item[] +Beide Ausgaben sind nur noch antiquarisch erhältlich. Das englische +Original "`The \LaTeX{} Companion"' existiert in der dritten Ausgabe +(Erscheinungsdatum Mai 2023). + +\item[] + Diese Errata-Datei (\texttt{\jobname.err}) ist Teil der \LaTeX-Distribution und die neuste Version findet man auf der \LaTeX{} Project Webseite unter diff --git a/macros/latex/base/lb2.pdf b/macros/latex/base/lb2.pdf index c8f32233af..9913fca20c 100644 Binary files a/macros/latex/base/lb2.pdf and b/macros/latex/base/lb2.pdf differ diff --git a/macros/latex/base/letter.dtx b/macros/latex/base/letter.dtx index 4052c260c8..3e3c36d3d0 100644 --- a/macros/latex/base/letter.dtx +++ b/macros/latex/base/letter.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/letter.ins b/macros/latex/base/letter.ins index c078dc59ce..c522f39e59 100644 --- a/macros/latex/base/letter.ins +++ b/macros/latex/base/letter.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/letter.pdf b/macros/latex/base/letter.pdf index 51e1f40c55..b456935de8 100644 Binary files a/macros/latex/base/letter.pdf and b/macros/latex/base/letter.pdf differ diff --git a/macros/latex/base/lgc2.err b/macros/latex/base/lgc2.err index 45b440a7f4..cb1a382348 100644 --- a/macros/latex/base/lgc2.err +++ b/macros/latex/base/lgc2.err @@ -330,6 +330,26 @@ ) \end{verbatim} +Reprinted by Lehmanns in 2022: + +\begin{verbatim} +@book(Lehmanns:GMRRV2022, + author = {Michel Goossens and Frank Mittelbach and Sebastian Rahtz + and Denis Roegel and Herbert Vo{\ss}}, + title = {The {\LaTeX} Graphics Companion}, + edition = 2, + series = {Tools and Techniques for Computer Typesetting}, + publisher = {Lehmanns Media}, + address = {Köln}, + year = {2022}, + isbn = {978-3-96543-303-8 (softcover), 978-3-96543-299-4 (ebook)}, + originalyear = {2007}, + pagenums = {976}, + bibliography = {yes}, + index = {yes}, +) +\end{verbatim} + \begin{list}{}{\setlength\leftmargin{0cm}\setlength\rightmargin{3cm}} \item[] @@ -378,7 +398,7 @@ Good luck! Contest period ends & Winner \\[4pt] 2008/05 & Milan Vujtek & 16 suggestions\\ 2010/05 & & \\ -\ldots & contest no longer open +\ldots & -- contest no longer open -- \end{tabular} \end{center} \end{list} diff --git a/macros/latex/base/lgc2.pdf b/macros/latex/base/lgc2.pdf index 43ab034d38..339f3c46a3 100644 Binary files a/macros/latex/base/lgc2.pdf and b/macros/latex/base/lgc2.pdf differ diff --git a/macros/latex/base/lppl.pdf b/macros/latex/base/lppl.pdf index 81e00214b6..196e23d5cb 100644 Binary files a/macros/latex/base/lppl.pdf and b/macros/latex/base/lppl.pdf differ diff --git a/macros/latex/base/ltalloc.dtx b/macros/latex/base/ltalloc.dtx index 4530d4b07b..c3498fb9c7 100644 --- a/macros/latex/base/ltalloc.dtx +++ b/macros/latex/base/ltalloc.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltbibl.dtx b/macros/latex/base/ltbibl.dtx index 4c219657b8..8e34ca685a 100644 --- a/macros/latex/base/ltbibl.dtx +++ b/macros/latex/base/ltbibl.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltboxes.dtx b/macros/latex/base/ltboxes.dtx index b82f5bdb8e..ff1717caa9 100644 --- a/macros/latex/base/ltboxes.dtx +++ b/macros/latex/base/ltboxes.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltclass.dtx b/macros/latex/base/ltclass.dtx index a525b6f573..bb52148508 100644 --- a/macros/latex/base/ltclass.dtx +++ b/macros/latex/base/ltclass.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltclass.dtx} - [2022/10/22 v1.5e LaTeX Kernel (Class & Package Interface)] + [2023/04/14 v1.5h LaTeX Kernel (Class & Package Interface)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltclass.dtx} @@ -324,6 +324,7 @@ % % \DescribeMacro\IfPackageAtLeastTF % \DescribeMacro\IfClassAtLeastTF +% \DescribeMacro\IfFileAtLeastTF % \DescribeMacro\@ifpackagelater % \DescribeMacro\@ifclasslater % \changes{v1.1i}{2013/07/07}{Correctly describe how the date in @@ -890,12 +891,14 @@ % % \begin{macro}{\IfPackageAtLeastTF} % \begin{macro}{\IfClassAtLeastTF} +% \begin{macro}{\IfFileAtLeastTF} % \begin{macro}{\IfFormatAtLeastTF} % |\IfFormatAtLeastTF{YYYY/MM/DD}{|\meta{true % code}|}{|\meta{false code}|}| % Test if the format is later or equal to the given date. % \changes{v1.3k}{2020/04/07}{Macro added; also in rollback (gh/168)} % \changes{v1.4e}{2021/07/19}{Drop \cs{@onlypreamble}} +% \changes{v1.5g}{2023/03/28}{Added \cs{IfFileAtLeastTF} (gh/1015)} % \begin{macrocode} %</2ekernel> %<*2ekernel|latexrelease> @@ -904,6 +907,7 @@ \def\IfFormatAtLeastTF{\@ifl@t@r\fmtversion} \let\IfPackageAtLeastTF\@ifpackagelater \let\IfClassAtLeastTF\@ifclasslater +\def\IfFileAtLeastTF#1{\expandafter\@ifl@t@r\csname ver@#1\endcsname} % \end{macrocode} % For rollback pretend it was available since the beginning of dawn. % \begin{macrocode} @@ -914,12 +918,14 @@ %<latexrelease>\def\IfFormatAtLeastTF{\@ifl@t@r\fmtversion} %<latexrelease>\let\IfPackageAtLeastTF\@ifpackagelater %<latexrelease>\let\IfClassAtLeastTF\@ifclasslater +%<latexrelease>\def\IfFileAtLeastTF#1{\expandafter\@ifl@t@r\csname ver@#1\endcsname} %<latexrelease>\EndIncludeInRelease %<*2ekernel> % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % \begin{macro}{\@ifl@ter} % \changes{v1.4e}{2021/07/19}{Drop \cs{@onlypreamble}} @@ -2133,13 +2139,28 @@ % {Reset \cs{CurrentOption}} % \changes{v1.3d}{2019/10/18}{Initialize \cs{...-h@@k} only when loading % the package or class (gh/198)} +% \changes{v1.5h}{2023/04/14}{Define \cs{load@onefilewithoptions} when +% in \pkg{latexrelease} (gh/992)} % \begin{macrocode} %</2ekernel> %<*2ekernel|latexrelease> %<latexrelease>\IncludeInRelease{2020/10/01}% %<latexrelease> {\@onefilewithoptions}{Hooks and unused options issue}% +% \end{macrocode} +% +% Here this macro is called \cs{@onefilewithoptions}, but further +% ahead in this file it is renamed to \cs{load@onefilewithoptions}, +% and \cs{@onefilewithoptions} becomes a wrapper around this, used for +% bookkeeping when rolling back. Therefore, when in +% \pkg{latexrelease}, we need to define \cs{load@onefilewithoptions} +% instead, thus the extra guarded \cs{def} line below: +% \begin{macrocode} +%<*2ekernel> \def\@onefilewithoptions#1[#2][#3]#4{% +%</2ekernel> +%<latexrelease>\def\load@onefilewithoptions#1[#2][#3]#4{% % \end{macrocode} +% % We have to sanitise file names, so that something like % \begin{verbatim} % \usepackage{some/local/path/array} @@ -2813,6 +2834,7 @@ % unknown option. % \changes{v1.3h}{2020/01/28}{Allow spaces in option string and display % only unknown options not the whole option list (gh/256)} +% \changes{v1.5f}{2022/11/16}{Introduce key 'nowarn' on filecontents (gh/958)} % \begin{macrocode} \def\filec@ntents@opt[#1]{% \edef\@fortmp{\zap@space#1 \@empty}% @@ -2821,7 +2843,7 @@ \csname filec@ntents@\reserved@a\endcsname \else \@latex@error{Unknown filecontents option \reserved@a}% - {Valid options are force (or overwrite), nosearch, noheader}% + {Valid options are force (or overwrite), nosearch, noheader, nowarn}% \fi}% \filec@ntents } @@ -2849,6 +2871,18 @@ \let\filec@ntents@checkdir\@empty \def\filec@ntents@where{exists on the system} % \end{macrocode} +% Option \texttt{nowarn} does not show any warning on the terminal +% but still writes it to the \texttt{.log}. +% \changes{v1.5f}{2022/11/16}{Introduce key 'nowarn' on filecontents (gh/958)} +% \begin{macrocode} +\def\filec@ntents@nowarn{% + \let\filec@ntents@warning\@latex@note@no@line +} +% \end{macrocode} +% By default we show terminal warnings. +% \begin{macrocode} +\let\filec@ntents@warning\@latex@warning@no@line +% \end{macrocode} % % \begin{macrocode} \begingroup% @@ -2925,6 +2959,8 @@ % on the terminal. % \changes{v1.3g}{2020/01/27}{Fix typo in error message} % \changes{v1.3j}{2020/02/20}{Fix missing quotes around file name (gh/284)} +% \changes{v1.5f}{2022/11/16}{Introduce key 'nowarn' on filecontents (gh/958)} +% \changes{v1.5f}{2022/11/16}{Do not show "current dir" in message (gh/917)} % \begin{macrocode} \ch@ck7\reserved@c\write\relax% \if@filesw% % Foul ... trying to overwrite \jobname! @@ -2932,8 +2968,8 @@ write to the file you are reading from!\MessageBreak% Data is written to screen instead.}% \else% - \@latex@warning@no@line% - {Writing or overwriting file `\@currdir\@curr@file'}% + \filec@ntents@warning% + {Writing or overwriting file `\@curr@file'}% \immediate\openout\reserved@c\q@curr@file\relax% \fi% \fi% diff --git a/macros/latex/base/ltcmd.dtx b/macros/latex/base/ltcmd.dtx index 14d6756f5c..d6322ff3ee 100644 --- a/macros/latex/base/ltcmd.dtx +++ b/macros/latex/base/ltcmd.dtx @@ -1,8 +1,8 @@ % \iffalse meta-comment % % Copyright (C) 1999 Frank Mittelbach, Chris Rowley, David Carlisle -% Copyright (C) 2004-2008 Frank Mittelbach, The LaTeX3 Project -% Copyright (C) 2009-2022 +% Copyright (C) 2004-2008 Frank Mittelbach, The LaTeX Project +% Copyright (C) 2009-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -34,8 +34,8 @@ %%% From File: ltcmd.dtx % % \begin{macrocode} -\def\ltcmdversion{v1.1a} -\def\ltcmddate{2022-08-16} +\def\ltcmdversion{v1.1e} +\def\ltcmddate{2023-05-26} % \end{macrocode} % %<*driver> @@ -725,6 +725,9 @@ { \@@_environment_or_command: } } % \end{macrocode} +% +% \changes{v1.1e}{2023/05/26} +% {Use simpler variant \cs{cs_generate_from_arg_count:NNno}} % To construct \cs{@@_tmp:w}, first go through the arguments % found and the corresponding defaults, building a token list with % |{#|\meta{arg number}|}| for arguments found in the input (whose @@ -738,10 +741,10 @@ \int_zero:N \l_@@_current_arg_int \@@_tl_mapthread_function:NNN \l_@@_args_tl \l_@@_defaults_tl \@@_defaults_def:nn - \cs_generate_from_arg_count:NNVo \@@_tmp:w \cs_set:Npn + \cs_generate_from_arg_count:NNno \@@_tmp:w \cs_set:Npn \l_@@_current_arg_int \l_@@_tmpa_tl } -\cs_generate_variant:Nn \cs_generate_from_arg_count:NNnn { NNVo } +\cs_generate_variant:Nn \cs_generate_from_arg_count:NNnn { NNno } \cs_new_protected:Npn \@@_defaults_def:nn { \int_incr:N \l_@@_current_arg_int @@ -2123,8 +2126,8 @@ % and possibly another auxiliary % \cs{\meta{cmd}\textvisiblespace\textvisiblespace}, if the command % has both long and short arguments. Then, its signature also has -% several specific bits that are unique to that command; this is in contrast to -% non-expandable commands, which use a common set of parsing functions. +% several specific bits that are unique to that command; this is in contrast +% to non-expandable commands, which use a common set of parsing functions. % % We start by copying the basics, then call % \cs{@@_copy_expandable_signature:NnNNNNnnn} to parse the signature @@ -2132,7 +2135,24 @@ % then we call \cs{@@_copy_expandable:NnNNNNnnn} that will copy the % top-level definition of the command, with the proper internal % renames. +% % \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_copy:NN}% +%<latexrelease> {Support~\NewCommandCopy~in~ltcmd} +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \changes{v1.1c}{2023/03/12} +% {Distinguish (non-expandable) document commands starting with +% \cs{@@_start_expandable:nNNNNn}} +% There's one variant: a command begins with \cs{@@_start_expandable:nNNNNn} +% may still be un-expandable/protected if it's defined by +% \cs{NewDocumentCommand} and friends, with empty or only m-type arguments. +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_copy_expandable:nnNN}% +%<latexrelease> {Distinguish~non-expandable~document~commands} \cs_new_protected:Npn \@@_copy_expandable:nnNN #1 #2 #3 #4 { \cs_set_eq:cc { #1 ~ code } { #2 ~ code } @@ -2140,9 +2160,36 @@ \@@_set_eq_if_exist:cc { #1 ~ \c_space_tl } { #2 ~ \c_space_tl } \@@_set_eq_if_exist:cc { #1 ~ defaults } { #2 ~ defaults } \exp_after:wN \@@_copy_expandable_signature:NnNNNNnnn #4 {#1} {#2} - \cs_set_nopar:Npx #3 + \token_if_protected_macro:NTF #4 + { \cs_set_protected_nopar:Npx }{ \cs_set_nopar:Npx } + #3 { \exp_after:wN \@@_copy_expandable:NnNNNNnnn #4 {#1} {#2} } } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2021/11/15}{\@@_copy_expandable:nnNN}% +%<latexrelease> {Support~\NewCommandCopy~in~ltcmd} +%<latexrelease>\cs_new_protected:Npn \@@_copy_expandable:nnNN #1 #2 #3 #4 +%<latexrelease> { +%<latexrelease> \cs_set_eq:cc { #1 ~ code } { #2 ~ code } +%<latexrelease> \@@_set_eq_if_exist:cc { #1 ~ } { #2 ~ } +%<latexrelease> \@@_set_eq_if_exist:cc { #1 ~ \c_space_tl } { #2 ~ \c_space_tl } +%<latexrelease> \@@_set_eq_if_exist:cc { #1 ~ defaults } { #2 ~ defaults } +%<latexrelease> \exp_after:wN \@@_copy_expandable_signature:NnNNNNnnn #4 {#1} {#2} +%<latexrelease> \cs_set_nopar:Npx #3 +%<latexrelease> { \exp_after:wN \@@_copy_expandable:NnNNNNnnn #4 {#1} {#2} } +%<latexrelease> } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_copy_expandable:nnNN}% +%<latexrelease> {Support~\NewCommandCopy~in~ltcmd} +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2021/11/15}{\@@_copy:NN (part 2)}% +%<latexrelease> {Support~\NewCommandCopy~in~ltcmd} +% \end{macrocode} +% +% \begin{macrocode} \cs_new:Npn \@@_copy_expandable:NnNNNNnnn #1 #2 #3 #4 #5 #6 #7 #8 #9 { \exp_not:N #1 \exp_not:n { {#2} } @@ -2355,7 +2402,7 @@ % worth it. % \begin{macrocode} %<latexrelease>\EndIncludeInRelease -%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_copy:NN}% +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_copy:NN (part 2)}% %<latexrelease> {Support~\NewCommandCopy~in~ltcmd} %<latexrelease>\EndIncludeInRelease % \end{macrocode} @@ -2401,21 +2448,64 @@ % \@@_show_command:NnNNwN, % \@@_show_expandable:N, % \@@_show_expandable:NnNNNNnN, -% \@@_show_command_aux:nNNn, +% \@@_show_command_aux:NnNNn, % \@@_show_environment:N, +% \@@_show:x, % } % These commands just expand the command once to reveal its innards, % then pass the type of command, the control sequence, the signature, -% and the code macro to \cs{@@_show_command_aux:nNNn}. +% and the code macro to \cs{@@_show_command_aux:NnNNn}. % \begin{macrocode} \cs_new_protected:Npn \@@_show_command:N #1 { \exp_after:wN \@@_show_command:NnNNwN #1 \q_@@ #1 } \cs_new_protected:Npn \@@_show_command:NnNNwN #1 #2 #3 #4 #5 \q_@@ #6 - { \@@_show_command_aux:nNNn { document~command } #6 #4 {#2} } + { + \@@_show_command_aux:NnNNn \tl_show:x + { document~command } #6 #4 {#2} + } \cs_new_protected:Npn \@@_show_expandable:N #1 { \exp_after:wN \@@_show_expandable:NnNNNNnN #1 #1 } +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_show:N}% +%<latexrelease> {Support~\ShowCommand~in~ltcmd} +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \changes{v1.1c}{2023/03/12} +% {Distinguish (non-expandable) document commands starting with +% \cs{@@_start_expandable:nNNNNn}} +% There's one variant: a command begins with \cs{@@_start_expandable:nNNNNn} +% may still be un-expandable/protected if it's defined by +% \cs{NewDocumentCommand} and friends, with empty or only m-type arguments. +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_show_expandable:NnNNNNnN}% +%<latexrelease> {Distinguish~non-expandable~document~commands} \cs_new_protected:Npn \@@_show_expandable:NnNNNNnN #1 #2 #3 #4 #5 #6 #7 #8 - { \@@_show_command_aux:nNNn { expandable~document~command } #8 #5 {#2} } + { + \exp_args:NNe \@@_show_command_aux:NnNNn \tl_show:x + { \token_if_protected_macro:NF #8 { expandable~ } document~command } + #8 #5 {#2} + } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2021/11/15}{\@@_show_expandable:NnNNNNnN}% +%<latexrelease> {Support~\ShowCommand~in~ltcmd} +%<latexrelease>\cs_new_protected:Npn \@@_show_expandable:NnNNNNnN #1 #2 #3 #4 #5 #6 #7 #8 +%<latexrelease> { +%<latexrelease> \@@_show_command_aux:NnNNn \tl_show:x +%<latexrelease> { expandable~document~command } #8 #5 {#2} +%<latexrelease> } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_show_expandable:NnNNNNnN}% +%<latexrelease> {Support~\ShowCommand~in~ltcmd} +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2021/11/15}{\@@_show:N (part 2)}% +%<latexrelease> {Support~\ShowCommand~in~ltcmd} % \end{macrocode} % % Now just print everything in the required format. The auxiliary @@ -2423,27 +2513,31 @@ % \cs{l_@@_tmpa_tl}, so we ust use that here: % \changes{v1.0j}{2021/13/31} % {Make \cs{ShowCommand} stop for interaction} +% \changes{v1.1b}{2022/11/30} +% {Don't stop for the \cs{begin} part of an environment} % \begin{macrocode} -\cs_new_protected:Npn \@@_show_command_aux:nNNn #1 #2 #3 #4 +\cs_new_protected:Npn \@@_show_command_aux:NnNNn #1 #2 #3 #4 #5 { - \@@_split_signature:n {#4} - \tl_show:x + \@@_split_signature:n {#5} + #1 { - \token_to_str:N #2 = #1: \iow_newline: + \token_to_str:N #3 = #2: \iow_newline: \tl_use:N \l_@@_tmpa_tl - -> \cs_replacement_spec:N #3 + -> \cs_replacement_spec:N #4 } } % \end{macrocode} % % We can reuse most of the above to show an environment, except that % we need to ensure that the proper \cs[no-index]{environment~\ldots} -% are passed to \cs{@@_show_command_aux:nNNn}. Additionally, when +% are passed to \cs{@@_show_command_aux:NnNNn}. Additionally, when % |\ShowCommand\foo| is used (if |foo| is an environment), we show % |\endfoo| as well, and when |\ShowCommand\endfoo| is used, change % that to |\ShowCommand\foo| and do the same. % \changes{v1.0j}{2021/13/31} % {Make \cs{ShowCommand} stop for interaction} +% \changes{v1.1b}{2022/11/30} +% {Don't stop for the \cs{begin} part of an environment} % \begin{macrocode} \cs_new_protected:Npn \@@_show_environment:N #1 { @@ -2459,12 +2553,14 @@ { \use:x { - \@@_show_command_aux:nNNn { document~environment } + \@@_show_command_aux:NnNNn \@@_show:x { document~environment } { \exp_not:N \begin {#3} } \exp_not:c { environment~ #3 ~ code } {#2} } } +\cs_new_protected:Npn \@@_show:x #1 + { \iow_term:x { > ~ #1 . \iow_newline: } } \cs_new_protected:Npn \@@_show_environment_end:N #1 { \exp_args:NNx \@@_check_end:Nn \l_@@_tmpa_tl { \cs_to_str:N #1 } @@ -2473,10 +2569,15 @@ % \end{macrocode} % % And, of course, add \cs{__kernel_cmd_if_xparse:NTF} and -% \cs{@@_show:N} to \cs{@showcommandlisthook}: +% \cs{@@_show:N} to \cs{@showcommandlisthook} and to +% \cs{@showenvironmentlisthook} (\cs{@@_show:N} takes care of the +% environment case as well, so both entries are identical): +% \changes{v1.1b}{2022-11-29}{Add \cs{@showenvironmentlisthook}} % \begin{macrocode} \tl_gput_right:Nn \@showcommandlisthook { { \__kernel_cmd_if_xparse:NTF \@@_show:N } } +\tl_gput_right:Nn \@showenvironmentlisthook + { { \__kernel_cmd_if_xparse:NTF \@@_show:N } } % \end{macrocode} % \end{macro} % @@ -2657,7 +2758,7 @@ % \begin{macrocode} %<latexrelease>\EndIncludeInRelease % -%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_show:N}% +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_show:N (part 2)}% %<latexrelease> {Support~\ShowCommand~in~ltcmd} %<latexrelease>\EndIncludeInRelease % \end{macrocode} @@ -3200,6 +3301,10 @@ % \begin{macro}{\@@_grab_v_long:w} % \begin{macro}{\@@_grab_v_aux:w} % \begin{macro}{\@@_grab_v_group_end:} +% Firstly, it is necessary to change \cs{tex_endlinechar:D} so that +% newlines in different catcode regimes (e.g., \cs{ExplSyntaxOn}) are +% not misinterpreted as spaces. +% \changes{v1.1d}{2023/04/13}{Set \cs{tex_endlinechar:D} earlier (gh/876).} % The opening delimiter is the first non-space token, and is never % read verbatim. This is required by consistency with the case where % the preceding argument was optional and absent: then \TeX{} has @@ -3233,6 +3338,7 @@ \tl_set:Nn \l_@@_signature_tl {#1} \group_begin: \tex_escapechar:D = 92 \scan_stop: + \tex_endlinechar:D = `\^^M \scan_stop: \tl_clear:N \l_@@_v_arg_tl \peek_remove_spaces:n { @@ -3250,8 +3356,8 @@ } \cs_new_protected:Npn \@@_grab_v_group_end: { - \exp_args:NNNo - \group_end: + \exp_args:NNNo + \group_end: \tl_set:Nn \l_@@_v_arg_tl { \l_@@_v_arg_tl } } % \end{macrocode} @@ -3396,7 +3502,6 @@ { \cs_set_eq:NN \do \char_set_catcode_other:N \dospecials - \tex_endlinechar:D = `\^^M \scan_stop: \bool_if:NTF \l_@@_long_bool { \char_set_catcode_other:n { \tex_endlinechar:D } } { \char_set_catcode_parameter:n { \tex_endlinechar:D } } diff --git a/macros/latex/base/ltcmdhooks-code.pdf b/macros/latex/base/ltcmdhooks-code.pdf index 83670e4463..499194f3d6 100644 Binary files a/macros/latex/base/ltcmdhooks-code.pdf and b/macros/latex/base/ltcmdhooks-code.pdf differ diff --git a/macros/latex/base/ltcmdhooks-doc.pdf b/macros/latex/base/ltcmdhooks-doc.pdf index fa4ca35a07..51320b388e 100644 Binary files a/macros/latex/base/ltcmdhooks-doc.pdf and b/macros/latex/base/ltcmdhooks-doc.pdf differ diff --git a/macros/latex/base/ltcmdhooks.dtx b/macros/latex/base/ltcmdhooks.dtx index ccb5a35a71..27907af679 100644 --- a/macros/latex/base/ltcmdhooks.dtx +++ b/macros/latex/base/ltcmdhooks.dtx @@ -1,7 +1,8 @@ % \iffalse meta-comment % -%% File: ltcmdhooks.dtx (C) Copyright 2020-2021 -%% Frank Mittelbach, Phelype Oleinik, LaTeX Team +%% File: ltcmdhooks.dtx +%% Copyright (C) 2020-2023 +%% Frank Mittelbach, Phelype Oleinik, 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 @@ -13,8 +14,8 @@ % %%% From File: ltcmdhooks.dtx % -\def\ltcmdhooksversion{v1.0f} -\def\ltcmdhooksdate{2021/10/20} +\def\ltcmdhooksversion{v1.0h} +\def\ltcmdhooksdate{2023/05/21} % % % @@ -51,20 +52,32 @@ % % This file implements generic hooks for (arbitrary) commands. % In theory every command \tn[no-index]{\meta{name}} offers now two -% associated hooks to which code can be added using \tn{AddToHook} -% or \tn{AddToHookNext}.\footnote{In practice this is not supported +% associated hooks to which code can be added using +% \tn{AddToHook},\!\footnote{In this documentation, when something is +% being said about \tn{AddToHook}, the same will be valid for +% \tn{AddToHookWithArguments}, unless that particular paragraph is +% highlighting the differences between both. The same is true for +% the other hook-related functions and their +% \texttt{\ldots WithArguments} counterparts.} +% \tn{AddToHookNext}, \tn{AddToHookWithArguments}, and +% \tn{AddToHookNextWithArguments}.\footnote{In practice this is not +% supported % for all types of commands, see section~\ref{sec:look-ahead} for % the restrictions that apply and what happens if one tries to use -% this with commands for which this is not supported.} These are +% this with commands for which this is not supported.} These are: % \begin{description} % \item[\hook{cmd/\meta{name}/before}] % -% This hook is executed at the very start of the command -% execution after its arguments (if any) are parsed. The hook -% \meta{code} is wrapped in the command inside a call to -% \cs{UseHook}|{cmd/|\meta{name}|/before}|, so the arguments -% passed to the command are \emph{not} available in the hook -% \meta{code}. +% This hook is executed at the very start of the command, right +% after its arguments (if any) are parsed. The hook \meta{code} +% runs in the command inside a call to \cs{UseHookWithArguments}. +% Any code added to this hook using \tn{AddToHookWithArguments} +% or \tn{AddToHookNextWithArguments} can access the command's +% arguments using |#1|, |#2|, etc., up to the number of arguments +% of the command. If \tn{AddToHook} or \tn{AddToHookNext} are +% used, the arguments cannot be accessed (see the \pkg{lthooks} +% documentation\footnote{\texttt{texdoc lthooks-doc}} on hooks +% with arguments). % % \item[\hook{cmd/\meta{name}/after}] % @@ -74,9 +87,12 @@ % \end{description} % % The hooks are not physically present before -% \verb=\begin{document}= (i.e., using a command in the preamble -% will never execute them) and if nobody has declared any code for -% them, then they are not added to the command code ever. For +% \verb=\begin{document}=\footnote{More specifically, they are +% inserted in the commands after the \hook{begindocument} hook, so +% they are also not present while \LaTeX{} is reading the +% \texttt{.aux} file.} (i.e., using a command in the preamble +% will never execute the hook) and if nobody has declared any code +% for them, then they are not added to the command code ever. For % example, if we have the following definition %\begin{verbatim} % \newcommand\foo[2]{Code #1 for #2!} @@ -90,23 +106,27 @@ %\end{verbatim} % then, after |\begin{document}| the definition of \cs[no-index]{foo} will be: %\begin{verbatim} -% \renewcommand\foo[2]{\UseHook{cmd/foo/before}Code #1 for #2!} +% \renewcommand\foo[2]{% +% \UseHookWithArguments{cmd/foo/before}{2}{#1}{#2}% +% Code #1 for #2!} %\end{verbatim} % and similarly \verb=\AddToHook{cmd/foo/after}{<after code>}= % alters the definition to %\begin{verbatim} -% \renewcommand\foo[2]{Code #1 for #2!\UseHook{cmd/foo/after}} +% \renewcommand\foo[2]{% +% Code #1 for #2!% +% \UseHookWithArguments{cmd/foo/after}{2}{#1}{#2}} %\end{verbatim} % % In other words, the mechanism is similar to what \pkg{etoolbox} % offers with \tn{pretocmd} and \tn{apptocmd} with the important -% differences +% differences % \begin{itemize} % \item % % that code can be prepended or appended (i.e., added to the % hooks) even if the command itself is not defined, because the -% defining package has not yet been loaded +% defining package has not yet been loaded; % % \item % @@ -197,6 +217,7 @@ % % % \section{Package Author Interface} +% \label{sec:pkg-author} % % The \hook{cmd} hooks are, by default, available for all commands % that can be patched to add the hooks. For some commands, however, @@ -206,9 +227,10 @@ % % If you are a package author and you want to add the hooks to your % own commands in the proper position you can define the command and -% manually add the \cs{UseHook} calls inside the command in the proper -% positions, and manually define the hooks with \cs{NewHook} or -% \cs{NewReversedHook}. When the hooks are explicitly defined, +% manually add the \cs{UseHookWithArguments} calls inside the command in +% the proper positions, and manually define the hooks with +% \cs{NewHookWithArguments} or \cs{NewReversedHookWithArguments}. +% When the hooks are explicitly defined, % patching is not attempted so you can make sure your command works % properly. For example, an (admittedly not really useful) command % that typesets its contents in a framed box with width optionally @@ -230,26 +252,27 @@ % \begin{verbatim} % \newcommand\fancybox{\@ifnextchar({\@fancybox}{\@fancybox(5cm)}} % \def\@fancybox(#1)#2{\fbox{% -% \UseHook{cmd/fancybox/before}% -% \parbox{#1}{#2}% -% \UseHook{cmd/fancybox/after}}} -% \NewHook{cmd/fancybox/before} -% \NewReversedHook{cmd/fancybox/after} +% \UseHookWithArguments{cmd/fancybox/before}{2}{#1}{#2}% +% \parbox{#1}{#2}% +% \UseHookWithArguments{cmd/fancybox/after}{2}{#1}{#2}}} +% \NewHookWithArguments{cmd/fancybox/before}{2} +% \NewReversedHookWithArguments{cmd/fancybox/after}{2} % \end{verbatim} % then the hooks will be executed where they should and no patching % will be attempted. It is important that the hooks are declared with -% \cs{NewHook} or \cs{NewReversedHook}, otherwise the command hook +% \cs{NewHookWithArguments} or \cs{NewReversedHookWithArguments}, +% otherwise the command hook % code will try to patch the command. Note also that the call to -% |\UseHook{cmd/fancybox/before}| does not need to be in the -% definition of \cs[no-index]{fancybox}, but anywhere it makes sense +% |\UseHookWithArguments{cmd/fancybox/before}| does not need to be in +% the definition of \cs[no-index]{fancybox}, but anywhere it makes sense % to insert it (in this case in the internal % \cs[no-index]{@fancybox}). % % Alternatively, if for whatever reason your command does not support % the generic hooks provided here, you can disable a hook with -% \cs{DisableHook}\footnote{Please use \cs{DisableHook} if at all, only -% on hooks that you \enquote{own}, i.e., for commands that your -% package or class defines and not second guess +% \cs{DisableGenericHook}\footnote{Please use \cs{DisableGenericHook} if +% at all, only on hooks that you \enquote{own}, i.e., for commands +% your package or class defines and not second guess % whether or not hooks of other packages should get disabled!}, so % that when someone tries to add code to it they will get an error. % Or if you don't want the error, you can simply declare the hook with @@ -270,6 +293,55 @@ % If you do that then both hooks automatically work and are patched % into the right places. % +% \subsection{Arguments and redefining commands} +% \label{sec:redef-warn} +% +% The code in \pkg{ltcmdhooks} does its best to find out how many +% arguments a given command has, and to insert the appropriate call to +% \cs{UseHookWithArguments}, so that the arguments seen by the hook are +% exactly those grabbed by the command (the hook, after all, is a macro +% call, so the arguments have to be placed in the right order, or they +% won't match). +% +% When using the package writer interface, as discussed in +% section~\ref{sec:pkg-author}, to change the position of the hooks in +% your commands, you are also free to change how the hook code in your +% command sees its arguments. When a \hook{cmd} hook is declared with +% \cs{NewHook} (or \cs{NewHookWithArguments} or other variations of +% that), it loses its \enquote{generic} nature and works as a regular +% hook. This means that you may choose to declare it without +% arguments regardless if the command takes arguments or not, or +% declare it with arguments, even if the command takes none. +% +% However, this flexibility should not be abused. When using a +% nonstandard configuration for the hook arguments, think reasonably: +% a user will expect that the argument \verb|#1| in the hook corresponds +% to the argument's first argument, and so on. Any other configuration +% is likely to cause confusion and, if used, will have to be well +% documented. +% +% This flexibility, however, allows you to \enquote{correct} the +% arguments for the hooks. For example, \LaTeX's \cs{refstepcounter} +% has a single argument, the name of the counter. The \pkg{cleveref} +% package adds an optional argument to \cs{refstepcounter}, making the +% name of the counter argument \verb|#2|. If the author of +% \pkg{cleveref} wanted, for whatever reason, to add hooks to +% \cs{refstepcounter}, to preserve compatibility he could write +% something along the lines of: +% \begin{verbatim} +% \NewHookWithArguments{cmd/refstepcounter/before}{1} +% \renewcommand\refstepcounter[2][<default>]{% +% \UseHookWithArguments{cmd/refstepcounter/before}{1}{#2}% +% <code for \refstepcounter>} +% \end{verbatim} +% so that the mandatory argument, which is arg \verb|#2| in the +% definition, would still be seen as \verb|#1| in the hook code. +% +% Another possibility would be to place the optional argument as the +% second argument for the hook, so that people looking for it would be +% able to use it. In either case, it would have to be well documented +% to cause as little confusion as possible. +% % \MaybeStop{\setlength\IndexMin{200pt} \PrintIndex } % % @@ -366,10 +438,13 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\c_@@_hash_tl} -% A constant token list that contains two parameter tokens. +% \begin{macro}{\c_@@_hash_tl,\c_@@_hashes_tl} +% Two constant token lists that contain one and two parameter tokens. +% \changes{v1.0g}{2023/04/06} +% {Rename to \cs{c_@@_hashes_tl} and add \cs{c_@@_hash_tl} (hook-args).} % \begin{macrocode} -\tl_const:Nn \c_@@_hash_tl { # # } +\tl_const:Nn \c_@@_hash_tl { # } +\tl_const:Nn \c_@@_hashes_tl { # # } % \end{macrocode} % \end{macro} % @@ -702,7 +777,7 @@ % % \changes{v1.0f}{2021/10/20} % {Correct patching by expansion+redefinition when the macro -% contains a parameter tokens (gh/697).} +% contains a parameter token (gh/697).} % Patching with expansion+redefinition is trickier than it looks like % at first glance. Suppose the simple definition: % \begin{verbatim} @@ -756,6 +831,8 @@ % parameter token, so that this case can be handled like the previous % one. % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_patch_expand_redefine:NNnn} +%<latexrelease> {cmd~hooks~with~args} \cs_new_protected:Npn \@@_patch_expand_redefine:NNnn #1 #2 #3 #4 { \@@_patch_debug:x { ++~command~can~be~patched~without~rescanning } @@ -779,14 +856,14 @@ % should be identical to the \meta{parameter text} used when % originally defining that macro. % \item[\cs{l_@@_replace_text_tl}] will contain braced pairs of -% \cs{c_@@_hash_tl}\meta{num} to feed to the macro when expanded. +% \cs{c_@@_hashes_tl}\meta{num} to feed to the macro when expanded. % This token list as well as the previous will have the first item % surrounded by |[|\ldots|]| in the case of an optional argument. % \end{description} % -% The use of \cs{c_@@_hash_tl} here is to differentiate actual +% The use of \cs{c_@@_hashes_tl} here is to differentiate actual % parameters in the macro from parameter tokens in the original -% definition of the macro. Later on, \cs{c_@@_hash_tl} is either +% definition of the macro. Later on, \cs{c_@@_hashes_tl} is either % replaced by actual parameter tokens, or expanded into them. % \begin{macrocode} \int_compare:nNnTF { \l_@@_patch_num_args_int } > { \c_zero_int } @@ -795,7 +872,7 @@ % We'll first check if the command has any parameter token in its % definition (feeding it empty arguments), and set \cs{@@_exp_not:n} % accordingly. \cs{@@_exp_not:n} will be used later to either leave -% \cs{c_@@_hash_tl} or expand it, and also to remember the result of +% \cs{c_@@_hashes_tl} or expand it, and also to remember the result of % \cs{@@_if_has_hash:nTF} to avoid testing twice (the test can be % rather slow). % \begin{macrocode} @@ -814,20 +891,22 @@ % \end{macrocode} % Here we'll conditionally add |[|\ldots|]| around the first % parameter: +% \changes{v1.0g}{2023/04/06} +% {Rename to \cs{c_@@_hashes_tl} (hook-args).} % \begin{macrocode} \bool_if:NTF #1 - { \@@_tmp:w \tl_set:Nx { [ \c_@@_hash_tl 1 ] } } - { \@@_tmp:w \tl_set:Nx { { \c_@@_hash_tl 1 } } } + { \@@_tmp:w \tl_set:Nx { [ \c_@@_hashes_tl 1 ] } } + { \@@_tmp:w \tl_set:Nx { { \c_@@_hashes_tl 1 } } } % \end{macrocode} % Then, for every parameter from the second, just add it normally: % \begin{macrocode} \int_step_inline:nnn { 2 } { \l_@@_patch_num_args_int } - { \@@_tmp:w \tl_put_right:Nx { { \c_@@_hash_tl ##1 } } } + { \@@_tmp:w \tl_put_right:Nx { { \c_@@_hashes_tl ##1 } } } % \end{macrocode} % Now, if the command has any parameter token in its definition % (then \cs{@@_exp_not:n} is \cs{exp_not:n}), call % \cs{@@_double_hashes:n} to double them, and replace every -% \cs{c_@@_hash_tl} by |#|: +% \cs{c_@@_hashes_tl} by |#|: % \begin{macrocode} \tl_set:Nx \l_@@_replace_text_tl { \exp_not:N #2 \exp_not:V \l_@@_replace_text_tl } @@ -875,22 +954,110 @@ { \exp_not:N \@@_make_prefixes:w \cs_prefix_spec:N #2 / / } } % \end{macrocode} -% Finally, call \cs{@@_redefine_with_hooks:Nnnn} with the macro being +% Here we redefine the hook to have the right number of arguments. +% Disabling the hook, undefining the \verb|parameter| token list then +% calling \cs{@@_make_usable:nn} are enough to redefine the hook to +% the extent we want. Code stored in the hook and other metadata +% about it are not lost in the process. +% \changes{v1.0h}{2023/05/21} +% {Changes to allow support arguments in cmd hooks (cmd-args).} +% \begin{macrocode} + \@@_disable:n { cmd / #3 / #4 } + \cs_undefine:c { c_@@_cmd / #3 / #4_parameter_tl } + \@@_make_usable:nn { cmd / #3 / #4 } { \l_@@_patch_num_args_int } +% \end{macrocode} +% Now call \cs{@@_redefine_with_hooks:Nnnn} with the macro being % redefined in |#1|, then \cs{UseHook}|{cmd/<name>/before}| in |#2| or % \cs{UseHook}|{cmd/<name>/after}| in |#3| (one is always empty), and % in |#4| the \meta{replacement text} of the macro. % \begin{macrocode} - \use:x + \use:e { \@@_redefine_with_hooks:Nnnn \exp_not:N #2 \str_if_eq:nnTF {#4} { after } { \use_ii_i:nn } { \use:nn } - { { \@@_exp_not:NN \exp_not:N \UseHook { cmd / #3 / #4 } } } + { { + \@@_exp_not:NN \exp_not:N \UseHookWithArguments + { cmd / #3 / #4 } { \int_use:N \l_@@_patch_num_args_int } + \@@_braced_parameter:n { cmd / #3 / #4 } + } } { { } } { \@@_exp_not:NN \exp_not:V \l_@@_replace_text_tl } } +% \end{macrocode} +% Finally, update the hook code. +% \begin{macrocode} + \@@_update_hook_code:n { cmd / #3 / #4 } } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2021/06/01}{\@@_patch_expand_redefine:NNnn} +%<latexrelease> {cmd~hooks~with~args} +%<latexrelease>\cs_gset_protected:Npn \@@_patch_expand_redefine:NNnn #1 #2 #3 #4 +%<latexrelease> { +%<latexrelease> \@@_patch_debug:x { ++~command~can~be~patched~without~rescanning } +%<latexrelease> \int_set:Nn \l_@@_patch_num_args_int +%<latexrelease> { +%<latexrelease> \exp_args:Nf \str_count:n { \cs_argument_spec:N #2 } / 2 +%<latexrelease> \bool_if:NT #1 { -1 } +%<latexrelease> } +%<latexrelease> \int_compare:nNnTF { \l_@@_patch_num_args_int } > { \c_zero_int } +%<latexrelease> { +%<latexrelease> \tl_set:Nx \l_@@_tmpa_tl { \bool_if:NTF #1 { [ ] } { { } } } +%<latexrelease> \int_step_inline:nnn { 2 } { \l_@@_patch_num_args_int } +%<latexrelease> { \tl_put_right:Nn \l_@@_tmpa_tl { { } } } +%<latexrelease> \exp_args:NNo \exp_args:No \@@_if_has_hash:nTF +%<latexrelease> { \exp_after:wN #2 \l_@@_tmpa_tl } +%<latexrelease> { \cs_set_eq:NN \@@_exp_not:n \exp_not:n } +%<latexrelease> { \cs_set_eq:NN \@@_exp_not:n \use:n } +%<latexrelease> \cs_set_protected:Npn \@@_tmp:w ##1 ##2 +%<latexrelease> { +%<latexrelease> ##1 \l_@@_param_text_tl { \use:n ##2 } +%<latexrelease> ##1 \l_@@_replace_text_tl { \@@_exp_not:n {##2} } +%<latexrelease> } +%<latexrelease> \bool_if:NTF #1 +%<latexrelease> { \@@_tmp:w \tl_set:Nx { [ \c_@@_hash_tl 1 ] } } +%<latexrelease> { \@@_tmp:w \tl_set:Nx { { \c_@@_hash_tl 1 } } } +%<latexrelease> \int_step_inline:nnn { 2 } { \l_@@_patch_num_args_int } +%<latexrelease> { \@@_tmp:w \tl_put_right:Nx { { \c_@@_hash_tl ##1 } } } +%<latexrelease> \tl_set:Nx \l_@@_replace_text_tl +%<latexrelease> { \exp_not:N #2 \exp_not:V \l_@@_replace_text_tl } +%<latexrelease> \tl_set:Nx \l_@@_replace_text_tl +%<latexrelease> { +%<latexrelease> \token_if_eq_meaning:NNTF \@@_exp_not:n \exp_not:n +%<latexrelease> { \exp_args:NNV \exp_args:No \@@_double_hashes:n } +%<latexrelease> { \exp_args:NV \exp_not:o } +%<latexrelease> \l_@@_replace_text_tl +%<latexrelease> } +%<latexrelease> \cs_set_eq:NN \@@_def_cmd:w \tex_gdef:D +%<latexrelease> \cs_set_eq:NN \@@_exp_not:NN \prg_do_nothing: +%<latexrelease> } +%<latexrelease> { +%<latexrelease> \tl_clear:N \l_@@_param_text_tl +%<latexrelease> \tl_set_eq:NN \l_@@_replace_text_tl #2 +%<latexrelease> \cs_set_eq:NN \@@_def_cmd:w \tex_xdef:D +%<latexrelease> \cs_set:Npn \@@_exp_not:NN ##1 { \exp_not:N ##1 \exp_not:N } +%<latexrelease> } +%<latexrelease> \group_begin: +%<latexrelease> \int_set:Nn \tex_escapechar:D { `\/ } +%<latexrelease> \use:x +%<latexrelease> { +%<latexrelease> \group_end: +%<latexrelease> \tl_set:Nx \exp_not:N \l_@@_patch_prefixes_tl +%<latexrelease> { \exp_not:N \@@_make_prefixes:w \cs_prefix_spec:N #2 / / } +%<latexrelease> } +%<latexrelease> \use:x +%<latexrelease> { +%<latexrelease> \@@_redefine_with_hooks:Nnnn \exp_not:N #2 +%<latexrelease> \str_if_eq:nnTF {#4} { after } +%<latexrelease> { \use_ii_i:nn } +%<latexrelease> { \use:nn } +%<latexrelease> { { \@@_exp_not:NN \exp_not:N \UseHook { cmd / #3 / #4 } } } +%<latexrelease> { { } } +%<latexrelease> { \@@_exp_not:NN \exp_not:V \l_@@_replace_text_tl } +%<latexrelease> } +%<latexrelease> } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % % Now that all the needed tools are ready, without further ado we'll @@ -973,7 +1140,7 @@ % } % \cs{@@_double_hashes:n} loops through the token list |#1| and % duplicates any catcode~6 token, and expands tokens \cs{ifx}-equal to -% \cs{c_@@_hash_tl}, and leaves all other tokens \cs{notexpanded} with +% \cs{c_@@_hashes_tl}, and leaves all other tokens \cs{notexpanded} with % \cs{exp_not:N}. Unfortunately pairs of explicit catcode~1 and % catcode~2 character tokens are normalised to |{|$_1$ and |}|$_1$ % because it's not feasible to expandably detect the character code @@ -1000,26 +1167,32 @@ % \end{macrocode} % % \cs{@@_double_hashes_output:N} checks for the end of the token list, -% then checks if the token is \cs{c_@@_hash_tl}, and if so just leaves +% then checks if the token is \cs{c_@@_hashes_tl}, and if so just leaves % it. +% \changes{v1.0g}{2023/04/06} +% {Add case for \cs{c_@@_hashes_tl} (hook-args).} % \begin{macrocode} \cs_new:Npn \@@_double_hashes_output:N #1 { \if_meaning:w \q_@@_recursion_tail #1 \@@_double_hashes_stop:w \fi: - \if_meaning:w \c_@@_hash_tl #1 + \if:w ? + \if_meaning:w \c_@@_hash_tl #1 ! \fi: + \if_meaning:w \c_@@_hashes_tl #1 ! \fi: + ? + \else: % \end{macrocode} % (this \cs{use_i:nnnn} uses \cs{fi:} and consumes \cs{use:n}, the % whole \cs{if_catcode:w} block, and the \cs{exp_not:N}, leaving just -% |#1| which is \cs{c_@@_hash_tl}.) +% |#1| which is \cs{c_@@_hashes_tl}.) % \begin{macrocode} \use_i:nnnn \fi: \use:n { % \end{macrocode} -% If |#1| is not \cs{c_@@_hash_tl}, then check if its catcode is~6, +% If |#1| is not \cs{c_@@_hashes_tl}, then check if its catcode is~6, % and if so, leave it doubled in \cs{exp_not:n} and consume the % following |\exp_not:N #1|. % \begin{macrocode} @@ -1080,10 +1253,10 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_retokenize_patch:Nnn #1 #2 #3 { - \@@_patch_debug:x { ..~command~can~only~be~patched~by~rescanning } \str_if_eq:eeTF { \cs_argument_spec:N #1 } { } { \@@_patch_expand_redefine:NNnn \c_false_bool #1 {#2} {#3} } { + \@@_patch_debug:x { ..~command~can~only~be~patched~by~rescanning } % \end{macrocode} % % Otherwise, we start the actual patching by retokenization job. The @@ -1144,6 +1317,8 @@ % \cs{@@_cmd_if_scanable:NnTF} and \cs{@@_patch_retokenize:Nnnn} if % the former returns \meta{true}, plus some debug messages. % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_try_patch_with_catcodes:Nnnnw} +%<latexrelease> {cmd~hooks~with~args} \cs_new_protected:Npn \@@_try_patch_with_catcodes:Nnnnw #1 #2 #3 #4 { \quark_if_recursion_tail_stop_do:nn {#4} { \use:n } @@ -1152,7 +1327,7 @@ { \@@_patch_debug:x { ++~macro~can~be~retokenized~cleanly } \@@_patch_debug:x { ==~retokenizing~macro~now } - \@@_patch_retokenize:Nnnn #1 {#2} {#3} {#4} + \@@_patch_retokenize:Nnnn #1 { cmd / #2 / #3 } {#3} {#4} \use_i_delimit_by_q_recursion_stop:nw \use_none:n } { @@ -1160,6 +1335,26 @@ \@@_try_patch_with_catcodes:Nnnnw #1 {#2} {#3} } } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2021/06/01}{\@@_try_patch_with_catcodes:Nnnnw} +%<latexrelease> {cmd~hooks~with~args} +%<latexrelease>\cs_gset_protected:Npn \@@_try_patch_with_catcodes:Nnnnw #1 #2 #3 #4 +%<latexrelease> { +%<latexrelease> \quark_if_recursion_tail_stop_do:nn {#4} { \use:n } +%<latexrelease> \@@_patch_debug:x { ++~trying~to~patch~by~retokenization } +%<latexrelease> \@@_cmd_if_scanable:NnTF {#1} {#4} +%<latexrelease> { +%<latexrelease> \@@_patch_debug:x { ++~macro~can~be~retokenized~cleanly } +%<latexrelease> \@@_patch_debug:x { ==~retokenizing~macro~now } +%<latexrelease> \@@_patch_retokenize:Nnnn #1 {#2} {#3} {#4} +%<latexrelease> \use_i_delimit_by_q_recursion_stop:nw \use_none:n +%<latexrelease> } +%<latexrelease> { +%<latexrelease> \@@_patch_debug:x { --~macro~cannot~be~retokenized~cleanly } +%<latexrelease> \@@_try_patch_with_catcodes:Nnnnw #1 {#2} {#3} +%<latexrelease> } +%<latexrelease> } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -1267,15 +1462,86 @@ % \end{macro} % % +% \begin{macro}{\@@_guess_arg_count:NN} +% \begin{macro}{\@@_guess_arg_count:wN} +% \begin{macro}{\@@_guess_arg_count:nw} +% Looks at the parameter text of a macro, and counts the parameters +% by looking at the number after a \verb|#|, and checking if they are +% sequential. This macro assumes that all parameters are marked with +% hashes, and not other characters, and that there is no +% \enquote{trick parameter}. +% \changes{v1.0h}{2023/05/21} +% {Macro added (cmd-args).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_guess_arg_count:NN} +%<latexrelease> {cmd~hooks~with~args} +\cs_new_protected:Npn \@@_guess_arg_count:NN #1 + { + \exp_after:wN \@@_guess_arg_count:wN + \token_to_meaning:N #1 \s_@@_mark + } +\exp_last_unbraced:NNNNo +\cs_new_protected:Npx \@@_guess_arg_count:wN + #1 { \tl_to_str:n { macro: } } #2 \s_@@_mark #3 + { + \int_set:Nn #3 + { + \exp_not:N \@@_guess_arg_count:nw { 0 } #2 + \c_hash_str 0 \s_@@_mark + } + } +\use:e + { \cs_new:Npn \exp_not:N \@@_guess_arg_count:nw #1 #2 \c_hash_str #3 } + { + \int_compare:nNnTF { #1 + 1 } = {#3} + { \@@_guess_arg_count:nw {#3} } + { #1 \@@_use_none_delimit_by_s_mark:w } + } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2021/06/01}{\@@_guess_arg_count:NN} +%<latexrelease> {cmd~hooks~with~args} +%<latexrelease>\cs_undefine:N \@@_guess_arg_count:NN +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% % % \begin{macro}{\@@_patch_retokenize:Nnnn} % Then, if \cs{@@_cmd_if_scanable:NnTF} returned true, we can go on % and patch the command. % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_patch_retokenize:Nnnn} +%<latexrelease> {cmd~hooks~with~args} \cs_new_protected:Npn \@@_patch_retokenize:Nnnn #1 #2 #3 #4 { +% Here, when patching by retokenization, we can only guess the number +% of arguments of the macro. +% \changes{v1.0h}{2023/05/21} +% {Changes to allow support arguments in cmd hooks (cmd-args).} +% \begin{macrocode} + \@@_guess_arg_count:NN #1 \l_@@_patch_num_args_int % \end{macrocode} -% Start off by making some things \tn{relax} to avoid lots of +% +% Then we redefine the hook to have the right number of arguments. +% Disabling the hook, undefining the \verb|parameter| token list then +% calling \cs{@@_make_usable:nn} are enough to redefine the hook to +% the extent we want. Code stored in the hook and other metadata +% about it are not lost in the process. +% \begin{macrocode} + \@@_disable:n {#2} + \cs_undefine:c { c_@@_#2_parameter_tl } + \@@_make_usable:nn {#2} { \l_@@_patch_num_args_int } + \tl_set:Ne \l_@@_tmpa_tl + { \exp_args:Ne \tl_to_str:n { \@@_braced_parameter:n {#2} } } + \use:x + { + \str_replace_all:Nnn \exp_not:N \l_@@_tmpa_tl + { #### } { \c_hash_str } + } +% \end{macrocode} +% Then, make make some things \tn{relax} to avoid lots of % \tn{noexpand} below. % \begin{macrocode} \cs_set_eq:NN \kerneltmpDoNotUse \scan_stop: @@ -1301,10 +1567,18 @@ ####1 \def \kerneltmpDoNotUse ####2 { \str_if_eq:nnT {#3} { before } - { \token_to_str:N \UseHook { cmd / #2 / #3 } } + { + \token_to_str:N \UseHookWithArguments {#2} + { \int_use:N \l_@@_patch_num_args_int } + \l_@@_tmpa_tl + } ####3 \str_if_eq:nnT {#3} { after } - { \token_to_str:N \UseHook { cmd / #2 / #3 } } + { + \token_to_str:N \UseHookWithArguments {#2} + { \int_use:N \l_@@_patch_num_args_int } + \l_@@_tmpa_tl + } } } % \end{macrocode} @@ -1328,7 +1602,39 @@ % {Make patching of commands a global operation (gh/674)} % \begin{macrocode} \cs_gset_eq:NN #1 \kerneltmpDoNotUse +% \end{macrocode} +% Finally, update the hook code. +% \begin{macrocode} + \@@_update_hook_code:n {#2} } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2021/06/01}{\@@_patch_retokenize:Nnnn} +%<latexrelease> {cmd~hooks~with~args} +%<latexrelease>\cs_gset_protected:Npn \@@_patch_retokenize:Nnnn #1 #2 #3 #4 +%<latexrelease> { +%<latexrelease> \cs_set_eq:NN \kerneltmpDoNotUse \scan_stop: +%<latexrelease> \cs_set_eq:NN \@@_tmp:w \scan_stop: +%<latexrelease> \use:x +%<latexrelease> { +%<latexrelease> \cs_set:Npn \@@_tmp:w +%<latexrelease> ####1 \tl_to_str:n { macro: } ####2 -> ####3 \s_@@_mark +%<latexrelease> { +%<latexrelease> ####1 \def \kerneltmpDoNotUse ####2 +%<latexrelease> { +%<latexrelease> \str_if_eq:nnT {#3} { before } +%<latexrelease> { \token_to_str:N \UseHook { cmd / #2 / #3 } } +%<latexrelease> ####3 +%<latexrelease> \str_if_eq:nnT {#3} { after } +%<latexrelease> { \token_to_str:N \UseHook { cmd / #2 / #3 } } +%<latexrelease> } +%<latexrelease> } +%<latexrelease> \tl_set:Nx \exp_not:N \l_@@_tmpa_tl +%<latexrelease> { \exp_not:N \@@_tmp:w \token_to_meaning:N #1 \s_@@_mark } +%<latexrelease> } +%<latexrelease> \tl_rescan:nV { #4 \@@_patch_required_catcodes: } \l_@@_tmpa_tl +%<latexrelease> \cs_gset_eq:NN #1 \kerneltmpDoNotUse +%<latexrelease> } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} % diff --git a/macros/latex/base/ltcntrl.dtx b/macros/latex/base/ltcntrl.dtx index 5ebe256c75..52dcdbf983 100644 --- a/macros/latex/base/ltcntrl.dtx +++ b/macros/latex/base/ltcntrl.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltcounts.dtx b/macros/latex/base/ltcounts.dtx index ffe2265ac3..69025fa479 100644 --- a/macros/latex/base/ltcounts.dtx +++ b/macros/latex/base/ltcounts.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltdefns.dtx b/macros/latex/base/ltdefns.dtx index bd820e7cf2..209c4e0fba 100644 --- a/macros/latex/base/ltdefns.dtx +++ b/macros/latex/base/ltdefns.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltdefns.dtx} - [2022/05/22 v1.5r LaTeX Kernel (definition commands)] + [2022/11/24 v1.5s LaTeX Kernel (definition commands)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltdefns.dtx} @@ -784,7 +784,9 @@ % not take arguments. (but may contain |\par|s) % % Make sure that an attempt to define a `graf' or `group' environment -% fails. +% fails by temporarily letting the undefined \verb=\...= (begin code) to +% the definition of \verb=\end...= and as a result we get an error if that +% has a definition. % \begin{macrocode} \long\def\@newenv#1#2#3#4{% \@ifundefined{#1}% @@ -1641,6 +1643,7 @@ % \end{macrocode} % % \begin{macro}{\declare@commandcopy} +% \begin{macro}{\declare@commandcopy@do} % Start by checking if the command is already defined. The proper action is % taken by each specific command above. If all's good, then % \cs{robust@command@act} is called with the proper arguments as described @@ -1650,11 +1653,14 @@ \long\def\declare@commandcopy#1#2#3#4{% \edef\reserved@a{\@expl@cs@to@str@@N#3}% \@ifundefined\reserved@a{#1}{#2}% - {\robust@command@act - \@declarecommandcopylisthook#4% - \declare@commandcopy@let{#3#4}}} + {\declare@commandcopy@do{#3}{#4}}} +\long\def\declare@commandcopy@do#1#2{% + \robust@command@act + \@declarecommandcopylisthook#2% + \declare@commandcopy@let{#1#2}} % \end{macrocode} % \end{macro} +% \end{macro} % % \begin{macro}{\@declarecommandcopylisthook} % The initial definition of \cs{@declarecommandcopylisthook} contains the @@ -1694,6 +1700,64 @@ % \end{macro} % % +% \begin{macrocode} +%</2ekernel> +%<latexrelease>\IncludeInRelease{2023-06-01}{\DeclareEnvironmentCopy} +%<latexrelease> {Add \NewEnvironmentCopy, \RenewEnvironmentCopy, and \DeclareEnvironmentCopy}% +%<*2ekernel|latexrelease> +% \end{macrocode} +% +% \begin{macro}{\NewEnvironmentCopy} +% \begin{macro}{\RenewEnvironmentCopy} +% \begin{macro}{\DeclareEnvironmentCopy} +% If \verb=\#1= or \verb=\end#1= already exist one gets an error +% message talking about the problematical command (not the +% environment). +% The remainder of the \LaTeX{} run is probably badly +% broken and it is unlikely that continuing it gives +% reasonable results. +% \changes{v1.5s}{2022/11/24}{Add \cs{NewEnvironmentCopy}, +% \cs{RenewEnvironmentCopy}, and \cs{DeclareEnvironmentCopy} (gh/963)} +% \begin{macrocode} +\def\NewEnvironmentCopy{% + \declare@environmentcopy + {\@firstofone}% + {\@firstoftwo\@notdefinable}} +\def\RenewEnvironmentCopy{% + \declare@environmentcopy + {\@latex@error{Environment \reserved@a\space undefined}\@ehc + \@firstofone}% + {\@firstofone}} +\def\DeclareEnvironmentCopy{% + \declare@environmentcopy + {\@firstofone}% + {\@firstofone}} +\long\def\declare@environmentcopy#1#2#3#4{% + \edef\reserved@a{\@ifundefined{#3}{end#3}{#3}}% + \@ifundefined\reserved@a + {\def\reserved@a{#3}#1}% + {\def\reserved@a{#3}#2}% + {\ExpandArgs{cc}\declare@commandcopy@do{#3}{#4}% + \ExpandArgs{cc}\declare@commandcopy@do{end#3}{end#4}}} +% \end{macrocode} +% +% Now the rollback code. +% \begin{macrocode} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000-00-00}{\DeclareEnvironmentCopy} +%<latexrelease> {Undefine \NewEnvironmentCopy, \RenewEnvironmentCopy, and \DeclareEnvironmentCopy}% +%<latexrelease>\let\NewEnvironmentCopy\@undefined +%<latexrelease>\let\RenewEnvironmentCopy\@undefined +%<latexrelease>\let\DeclareEnvironmentCopy\@undefined +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% % \subsubsection{Showing robust commands} % % \begin{macro}{\ShowCommand} @@ -1747,7 +1811,6 @@ % \end{macrocode} % \end{macro} % -% % \begin{macrocode} %</2ekernel> %<latexrelease>\IncludeInRelease{2020-10-01}{\@if@DeclareRobustCommand} @@ -1836,6 +1899,7 @@ % % \begin{macro}{\@show@DeclareRobustCommand} % \begin{macro}{\show@kernel@robust@command} +% \begin{macro}{\@show@macro} % Showing the command is pretty simple. This command prints the top-level % expansion as \TeX's \cs{show} would, but with |robust macro:| rather than % just |macro:|, then a blank line and then \cs{show} the inner command. @@ -1863,12 +1927,14 @@ \robust@command@chk@safe#1% {\@if@newcommand#1% {\@show@newcommand}% - {\show}}% - {\show}% + {\@show@macro}}% + {\@show@macro}% #1} +\let\@show@macro\show % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % % \end{macro} % @@ -1931,7 +1997,7 @@ \typeout{->\@expl@cs@replacement@spec@@N#1.^^J}% \expandafter\@show@newcommand@aux \csname\@backslashchar\@expl@cs@to@str@@N#1\expandafter\endcsname - \expandafter{#1}} + \expandafter{#1}\@show@tokens} % \end{macrocode} % % For a macro defined with, say, |\newcommand\foo[1][opt]{bar}|, it will @@ -1946,20 +2012,28 @@ % \end{verbatim} % If the command was defined with \cs{DeclareRobustCommand}, then another pair % of lines show the top-level expansion \verb*|\protect \foo |. -% -% The extra gymnastics with \cs{showtokens} ensures that \cs{showtokens} -% itself, and the internals of this macro aren't showed in the context lines. % \begin{macrocode} -\long\def\@show@newcommand@aux#1#2{% +\long\def\@show@newcommand@aux#1#2#3{% \typeout{> \string#1=\@expl@cs@prefix@spec@@N#1macro:}% - \edef\reserved@a{% - default \string##1=\expandafter\detokenize\@gobblethree#2.^^J% - \@expl@cs@argument@spec@@N#1->\@expl@cs@replacement@spec@@N#1}% - \showtokens\expandafter\expandafter\expandafter{\expandafter\reserved@a}} + #3{default \string##1=\expandafter\detokenize\@gobblethree#2.^^J% + \@expl@cs@argument@spec@@N#1->\@expl@cs@replacement@spec@@N#1}} % \end{macrocode} % \end{macro} % \end{macro} % +% \begin{macro}{\@show@tokens} +% This macro prints the contents of the token list (macro) |#1| using +% \cs{showtokens}. The \cs{expandafter} gymnastics ensures that +% \cs{showtokens} itself, and the internals of this macro aren't +% showed in the context lines. +% \begin{macrocode} +\long\def\@show@tokens#1{% + \edef\reserved@a{#1}% + \showtokens\expandafter + \expandafter\expandafter{\expandafter\reserved@a}} +% \end{macrocode} +% \end{macro} +% % Now the rollback code. % \begin{macrocode} %</2ekernel|latexrelease> @@ -1985,6 +2059,124 @@ % \end{macro} % % +% \subsubsection{Showing environments} +% +% \begin{macro}{\ShowEnvironment} +% \changes{v1.5s}{2022/11/24}{Added \cs{ShowEnvironment}} +% +% \begin{macrocode} +%</2ekernel> +%<latexrelease>\IncludeInRelease{2023-06-01}{\ShowEnvironment} +%<latexrelease> {Add \ShowEnvironment}% +%<*2ekernel|latexrelease> +% \end{macrocode} +% +% \cs{ShowEnvironment} is quite similar to \cs{ShowCommand}. We will +% pass the environment \meta{env} around as the macro +% \cs[no-index]{env}, because \cs{robust@command@act} expects a single +% token. +% \begin{macrocode} +\def\ShowEnvironment#1{% + \expandafter\@show@environment\csname #1\endcsname} +\long\def\@show@environment#1{% + \robust@command@act + \@showenvironmentlisthook#1% + \@show@normalenv#1} +% \end{macrocode} +% +% \begin{macro}{\@showenvironmentlisthook} +% This is similar to \cs{@showcommandlisthook}, but uses the dedicated +% versions for environments. +% \begin{macrocode} +\def\@showenvironmentlisthook{% + {\@if@DeclareRobustCommand \@show@DeclareRobustCommand@env}% + {\@if@newcommand \@show@newcommand@env}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@show@newcommand@env} +% \begin{macro}{\@show@DeclareRobustCommand@env} +% These are similar to the command versions below, except they say +% \enquote{environment} and call \cs{@show@environment@end} to print +% the \cs{end} part. +% \begin{macrocode} +\long\def\@show@newcommand@env#1{% + \@show@environment@begin#1% + \expandafter\@show@newcommand@aux + \csname\@backslashchar\@expl@cs@to@str@@N#1\expandafter\endcsname + \expandafter{#1}\@show@typeout + \@show@environment@end#1} +\long\def\@show@DeclareRobustCommand@env#1{% + \@show@environment@begin#1% + \begingroup + \let\@show@tokens\@show@typeout + \let\@show@macro\@show@nonstop + \expandafter\show@kernel@robust@command + \csname\@expl@cs@to@str@@N#1 \endcsname + \endgroup + \@show@environment@end#1} +\long\def\@show@environment@begin#1{% + \typeout{> \string\begin{\@expl@cs@to@str@@N#1}=environment:}% + \typeout{\@expl@cs@argument@spec@@N#1->% + \@expl@cs@replacement@spec@@N#1.^^J}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@show@normalenv} +% \begin{macro}{\@show@environment@end} +% A \enquote{normal} environment is straightforward. +% \cs{@show@environment@end} needs to check if the \cs{end} part is +% defined and show it accordingly, otherwise the output would show +% gibberish. +% \begin{macrocode} +\long\def\@show@normalenv#1{% + \@show@environment@begin#1% + \@show@environment@end#1} +\long\def\@show@environment@end#1{% + \expandafter\@show@environment@end@aux + \csname end\@expl@cs@to@str@@N#1\endcsname#1} +\long\def\@show@environment@end@aux#1#2{% + \@show@tokens{\string\end{\@expl@cs@to@str@@N#2}% + \ifx\relax#1=undefined% + \else:^^J\@expl@cs@argument@spec@@N#1->% + \@expl@cs@replacement@spec@@N#1% + \fi}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@show@nonstop} +% \begin{macro}{\@show@typeout} +% And here some auxiliaries: +% \begin{description} +% \item[\cs{@show@nonstop}] same output as \cs{show}, but doesn't +% stop for interaction; +% \item[\cs{@show@typeout}] same output as \cs{showtokens}, but +% doesn't stop for interaction. +% \end{description} +% \begin{macrocode} +\def\@show@nonstop#1{% + \typeout{> \string#1=\@expl@cs@prefix@spec@@N#1macro:^^J% + \@expl@cs@argument@spec@@N#1->\@expl@cs@replacement@spec@@N#1.}} +\def\@show@typeout#1{\typeout{> #1.^^J}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% Now the rollback code. +% \begin{macrocode} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000-00-00}{\ShowEnvironment} +%<latexrelease> {Undefine \ShowEnvironment}% +%<latexrelease>\let\ShowEnvironment\@undefined +%<latexrelease>\EndIncludeInRelease +%<*2ekernel> +% \end{macrocode} +% \end{macro} +% +% % \subsection{Internal defining commands} % % These commands are used internally to define other \LaTeX{} diff --git a/macros/latex/base/ltdirchk.dtx b/macros/latex/base/ltdirchk.dtx index 16a2ed9e68..6e02929754 100644 --- a/macros/latex/base/ltdirchk.dtx +++ b/macros/latex/base/ltdirchk.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/lterror.dtx b/macros/latex/base/lterror.dtx index b302a9a74c..77672168ce 100644 --- a/macros/latex/base/lterror.dtx +++ b/macros/latex/base/lterror.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltexpl.dtx b/macros/latex/base/ltexpl.dtx index aab189bec2..92e6de52cb 100644 --- a/macros/latex/base/ltexpl.dtx +++ b/macros/latex/base/ltexpl.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2019-2022 +% Copyright (C) 2019-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltfilehook-code.pdf b/macros/latex/base/ltfilehook-code.pdf index fbaf7f0502..e52041c425 100644 Binary files a/macros/latex/base/ltfilehook-code.pdf and b/macros/latex/base/ltfilehook-code.pdf differ diff --git a/macros/latex/base/ltfilehook-doc.pdf b/macros/latex/base/ltfilehook-doc.pdf index bb38e6a544..392b3c05af 100644 Binary files a/macros/latex/base/ltfilehook-doc.pdf and b/macros/latex/base/ltfilehook-doc.pdf differ diff --git a/macros/latex/base/ltfilehook.dtx b/macros/latex/base/ltfilehook.dtx index c8503de891..e10a5416e5 100644 --- a/macros/latex/base/ltfilehook.dtx +++ b/macros/latex/base/ltfilehook.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 2020-2022 -% Frank Mittelbach, Phelype Oleinik & LaTeX Team +% Copyright (C) 2020-2023 +% Frank Mittelbach, Phelype Oleinik and The LaTeX Project % % This file is part of the LaTeX base system. % ------------------------------------------- @@ -31,8 +31,8 @@ %%% From File: ltfilehook.dtx % % \begin{macrocode} -\providecommand\ltfilehookversion{v1.0n} -\providecommand\ltfilehookdate{2022/08/18} +\providecommand\ltfilehookversion{v1.0o} +\providecommand\ltfilehookdate{2023/04/02} % \end{macrocode} % %<*driver> @@ -1229,8 +1229,10 @@ % This auxiliary compares \cs{\meta{filename}} with % \cs{csname\cs{endcsname}} to check if the empty |.tex| file was % requested. +% \changes{v1.0o}{2023/04/02} +% {Make \cs{@set@curr@file@aux} \cs{long} gh/942} % \begin{macrocode} -\def\@set@curr@file@aux#1{% +\long\def\@set@curr@file@aux#1{% \expandafter\ifx\csname\endcsname#1% .tex\else\string#1\fi} % \end{macrocode} diff --git a/macros/latex/base/ltfiles.dtx b/macros/latex/base/ltfiles.dtx index d99dfdcd48..3bac7ea0b2 100644 --- a/macros/latex/base/ltfiles.dtx +++ b/macros/latex/base/ltfiles.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltfiles.dtx} - [2022/05/27 v1.2r LaTeX Kernel (File Handling)] + [2023/05/17 v1.2t LaTeX Kernel (File Handling)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltfiles.dtx} @@ -417,6 +417,16 @@ \ignorespaces} % \end{macrocode} % +% Provide a global definition for \cs{do} as well, so that it is +% already defined in the preamble and not late as +% \verb=\begin{document}= overwriting some definition given by the +% unsuspecting user in the preamble. +% \changes{v1.2s}{2023/01/05}{\cs{do} now with default definition in +% the kernel (gh/975)} +% \begin{macrocode} +\let\do\noexpand +% \end{macrocode} +% % The \hook{begindocument} hook already existed in the kernel since % 1994 under the name \cs{atbegindocumenthook} the % additional ones are originally from the \pkg{etoolbox} @@ -1192,6 +1202,9 @@ % \changes{v1.0t}{1995/05/25}{(CAR) added \cs{long}} % \changes{v1.2d}{2019/10/26}{quote on openin} % \changes{v1.2k}{2021/03/12}{Allow unbalanced conditionals (gh/530)} +% \changes{v1.2t}{2023/05/15}{Use \pkg{expl3} file existence test} +% \begin{macro}{\IfFileExists@} +% \changes{v1.2t}{2023/05/15}{Macro added} % Argument |#1| is |\@curr@file| so catcode 12 string with no quotes. % % The original definition picked up arguments |#2| and |#3| in a @@ -1201,23 +1214,35 @@ % \cs{secondoftwo}. However, that changes how |#| is interpreted % and so we can't do that nowaways without invalidating a lot of % code. Therefore the somewhat curious construction near the end. +% +% Earlier versions used |\openin| here, but this led to two +% code paths, one in \pkg{expl3} and one here. To avoid that, +% and as the \pkg{expl3} approach works by expansion, we use +% that here. As we need the file name to include the path, +% the actual \pkg{expl3} function used is not the file existence +% test! % \begin{macrocode} %</2ekernel> %<*2ekernel|latexrelease> -%<latexrelease>\IncludeInRelease{2021/06/01}% -%<latexrelease> {\IfFileExists@}{manage unbalanced conditionals} +%<latexrelease>\IncludeInRelease{2023/05/01}% +%<latexrelease> {\IfFileExists@}{IfFileExists} \long\def \IfFileExists@#1#2#3{% - \openin\@inputcheck"#1" % - \ifeof\@inputcheck - \ifx\input@path\@undefined - \let\reserved@a\@secondoftwo + \edef\@filef@und{\IfFileExists@@{#1}}% +% \end{macrocode} +% The \pkg{expl3} function regards an empty argument as nothing at all, +% but the \LaTeXe{} convention is that this is equal to the special +% \texttt{.tex} file. +% \begin{macrocode} + \ifx\@filef@und\@empty + \if\relax\detokenize{#1}\relax + \let\reserved@a\@firstoftwo + \def\@filef@und{".tex" }% \else - \def\reserved@a{\@iffileonpath{#1}}% + \let\reserved@a\@secondoftwo \fi \else - \closein\@inputcheck - \edef\@filef@und{"#1" }% \let\reserved@a\@firstoftwo + \edef\@filef@und{"\@filef@und" }% \fi % \end{macrocode} % This is just there so that any |#| inside |#2| or |#3| needs @@ -1226,10 +1251,35 @@ \expandafter\def\expandafter\reserved@a \expandafter{\reserved@a{#2}{#3}}% \reserved@a} +\ExplSyntaxOn +\cs_new_eq:NN \IfFileExists@@ \file_full_name:n +\ExplSyntaxOff %</2ekernel|latexrelease> %<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2021/06/01}% +%<latexrelease> {\IfFileExists@}{IfFileExists} +%<latexrelease> +%<latexrelease>\long\def \IfFileExists@#1#2#3{% +%<latexrelease> \openin\@inputcheck"#1" % +%<latexrelease> \ifeof\@inputcheck +%<latexrelease> \ifx\input@path\@undefined +%<latexrelease> \let\reserved@a\@secondoftwo +%<latexrelease> \else +%<latexrelease> \def\reserved@a{\@iffileonpath{#1}}% +%<latexrelease> \fi +%<latexrelease> \else +%<latexrelease> \closein\@inputcheck +%<latexrelease> \edef\@filef@und{"#1" }% +%<latexrelease> \let\reserved@a\@firstoftwo +%<latexrelease> \fi +%<latexrelease> \expandafter\def\expandafter\reserved@a +%<latexrelease> \expandafter{\reserved@a{#2}{#3}}% +%<latexrelease>\reserved@a} +%<latexrelease>\let\IfFileExists@@\@undefined +%<latexrelease>\EndIncludeInRelease +%<latexrelease> %<latexrelease>\IncludeInRelease{2019/10/01}% -%<latexrelease> {\IfFileExists@}{manage unbalanced conditionals} +%<latexrelease> {\IfFileExists@}{IfFileExists} %<latexrelease> %<latexrelease>\long\def \IfFileExists@#1#2#3{% %<latexrelease> \openin\@inputcheck"#1" % @@ -1247,7 +1297,7 @@ %<latexrelease> \reserved@a} %<latexrelease>\EndIncludeInRelease %<latexrelease>\IncludeInRelease{0000/00/00}% -%<latexrelease> {\IfFileExists@}{manage unbalanced conditionals} +%<latexrelease> {\IfFileExists@}{IfFileExists} %<latexrelease> %<latexrelease>\let\IfFileExists@\@undefined %<latexrelease> @@ -1256,7 +1306,7 @@ %<*2ekernel> % \end{macrocode} % \end{macro} -% +% \end{macro} % % % diff --git a/macros/latex/base/ltfinal.dtx b/macros/latex/base/ltfinal.dtx index a19ffa8305..2652f6ce44 100644 --- a/macros/latex/base/ltfinal.dtx +++ b/macros/latex/base/ltfinal.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltfinal.dtx} - [2022/11/30 v2.2y LaTeX Kernel (Final Settings)] + [2023/05/30 v2.3c LaTeX Kernel (Final Settings)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltfinal.dtx} @@ -1062,6 +1062,24 @@ \fi % End of reset block for 8-bit engines % \end{macrocode} % +% \begin{macro}{\BCPdata} +% \changes{v2.3a}{2023/04/16}{Command added} +% A stub for use by \pkg{babel}, \pkg{polyglossia}, etc. +% \begin{macrocode} +\ExplSyntaxOn +\newcommand*\BCPdata[1]{ + \str_case:nn {#1} + { + { language } { en } + { region } { US } + { script } { Latn } + { tag } { en-US } + } +} +\ExplSyntaxOff +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\MakeUppercase} % \begin{macro}{\MakeLowercase} % \begin{macro}{\MakeTitlecase} @@ -1069,6 +1087,9 @@ % \begin{macro}{\AddToNoCaseChangeList} % \begin{macro}{\CaseSwitch} % \begin{macro}{\DeclareCaseChangeEquivalent} +% \begin{macro}{\DeclareLowercaseMapping} +% \begin{macro}{\DeclareTitlecaseMapping} +% \begin{macro}{\DeclareUppercaseMapping} % \begin{macro}{\@uclclist} % % @@ -1088,6 +1109,7 @@ % \changes{v2.2x}{2022/10/26}{Introduce optional argument for case-changing commands} % \changes{v2.2x}{2022/10/26}{Make case changing commands language-aware} % \changes{v2.2x}{2022/10/26}{Auto-detect \pkg{babel} locale} +% \changes{v2.3a}{2023/04/11}{Use new generic mechanism to detect locale} % Wrappers around the L3 case changing functions. % |\protected| to make them mostly safe as replacements for |uppercase| % and |\lowercase|. @@ -1121,33 +1143,24 @@ { \cs_set_nopar:Npn \reserved@a { } \tl_if_blank:nTF {#2} - { \@@text@case@aux@ } - { \keys_set:nn { __kernel } {#2} } - \use:c { text_ #1 case:Vn } \reserved@a {#3} - } -\cs_new_protected:Npn \@@text@case@aux@ { } -\tl_gput_right:Nn \@kernel@after@begindocument - { - \@ifpackageloaded { babel } { - \@ifpackagelater { babel } { 2020-01-15 } + \str_set:Nx \reserved@a + { \BCPdata { casing } } + \str_if_empty:NT \reserved@a { - \cs_gset_protected:Npn \@@text@case@aux@ - { - \str_set:Nx \reserved@a - { \localeinfo* { tag.bcp47 } } - } + \str_set:Nx \reserved@a + { \BCPdata { language } } } - { } } - { } + { \keys_set:nn { __kernel } {#2} } + \use:c { text_ #1 case:Vn } \reserved@a {#3} } -\exp_args_generate:n { cnx } % \end{macrocode} % The odd use of \emph{three} spaces here is needed as \pkg{ltcmd} uses the % name with one and two spaces to give a `friendly' error message for a runaway % argument: that means we can't use it here. % \begin{macrocode} +\exp_args_generate:n { cnx } \cs_set_protected:Npn \reserved@a #1 { \cs_generate_variant:cn { text_ \str_lowercase:n {#1} case:nn } { V } @@ -1161,36 +1174,35 @@ \reserved@a { Title } % \end{macrocode} % \changes{v2.2y}{2022/11/30}{Set \cs{oe}/\cs{OE} equal to act as a marker for \pkg{babel}} +% \changes{v2.2z}{2023/03/28}{Use groups for gh/1021} % Currently, \pkg{babel} uses the equivalence of \cs{oe} and \cs{OE} to force casing of % some material, most notably in \cs{today}. To enable that to work, we have to set those % commands equal even though the current case changing code does not work using this % approach. % \begin{macrocode} \cs_new_protected:cpn { MakeLowercase \c_space_tl \c_space_tl \c_space_tl } [#1] #2 - { - \let \kernel@saved@OE \OE + {{ \let \OE \oe \@@text@case@aux { lower } {#1} {#2} - \let \OE \kernel@saved@OE - } + }} \cs_new_protected:cpn { MakeUppercase \c_space_tl \c_space_tl \c_space_tl } [#1] #2 - { - \let \kernel@saved@oe \oe + {{ \let \oe \OE \@@text@case@aux { upper } {#1} {#2} - \let \oe \kernel@saved@oe - } + }} \cs_new_protected:cpn { MakeTitlecase \c_space_tl \c_space_tl \c_space_tl } [#1] #2 - { - \let \kernel@saved@oe \oe + {{ \let \oe \OE \@@text@case@aux { title } {#1} {#2} - \let \oe \kernel@saved@oe - } + }} % \end{macrocode} % % \changes{v2.2u}{2022/06/02}{Add \cs{NoCaseChange}} % \changes{v2.2u}{2022/06/30}{Add \cs{AddToNoCaseChangeList}} +% \changes{v2.3b}{2023/04/19}{Add \cs{DeclareLowercaseMapping}, +% \cs{DeclareTitlecaseMapping} and \cs{DeclareUppercaseMapping}} +% \changes{v2.3c}{2023/05/30}{Fix a typo in implementation of +% \cs{DeclareLowercaseMapping}, etc.} % |\NoCaseChange| protects its argument from the case change functions. % % |\AddToNoCaseChangeList| Allows new commands to protect their arguments, eg @@ -1204,6 +1216,27 @@ \cs_new_eq:NN \CaseSwitch \text_case_switch:nnnn \cs_new_eq:NN \DeclareCaseChangeEquivalent \text_declare_case_equivalent:Nn +\NewDocumentCommand \DeclareLowercaseMapping { o m m } + { + \IfNoValueTF {#1} + { \text_declare_lowercase_mapping:nn } + { \text_declare_lowercase_mapping:nnn {#1} } + {#2} {#3} + } +\NewDocumentCommand \DeclareTitlecaseMapping { o m m } + { + \IfNoValueTF {#1} + { \text_declare_titlecase_mapping:nn } + { \text_declare_titlecase_mapping:nnn {#1} } + {#2} {#3} + } +\NewDocumentCommand \DeclareUppercaseMapping { o m m } + { + \IfNoValueTF {#1} + { \text_declare_uppercase_mapping:nn } + { \text_declare_uppercase_mapping:nnn {#1} } + {#2} {#3} + } \ExplSyntaxOff % \end{macrocode} % @@ -1222,6 +1255,9 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % \changes{v1.0h}{1994/05/13}{Added output enc stuff} % \changes{v1.0i}{1994/05/16}{moved output enc stuff to lfonts} diff --git a/macros/latex/base/ltfloat.dtx b/macros/latex/base/ltfloat.dtx index 8b5b92759a..7247824548 100644 --- a/macros/latex/base/ltfloat.dtx +++ b/macros/latex/base/ltfloat.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltfntcmd.dtx b/macros/latex/base/ltfntcmd.dtx index 64064abcb5..bb6dbfe75c 100644 --- a/macros/latex/base/ltfntcmd.dtx +++ b/macros/latex/base/ltfntcmd.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltfssaxes.dtx b/macros/latex/base/ltfssaxes.dtx index 843e8b544c..9e68b38654 100644 --- a/macros/latex/base/ltfssaxes.dtx +++ b/macros/latex/base/ltfssaxes.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2019-2022 +% Copyright (C) 2019-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltfssbas.dtx b/macros/latex/base/ltfssbas.dtx index cc43622a4b..fda3d1ca4b 100644 --- a/macros/latex/base/ltfssbas.dtx +++ b/macros/latex/base/ltfssbas.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -35,7 +35,7 @@ % % \ProvidesFile{ltfssbas.dtx} - [2022/07/04 v3.2k LaTeX Kernel (NFSS Basic Macros)] + [2023/04/01 v3.2l LaTeX Kernel (NFSS Basic Macros)] % \iffalse \documentclass{ltxdoc} \begin{document} @@ -1050,11 +1050,22 @@ % {\cs{def} $\to$ \cs{edef} for \cs{math@version}.} % \changes{v1.2g}{1990/02/16}{\cs{@nomath} added.} % \changes{v2.1a}{1994/01/17}{New math font setup} +% \changes{v3.2l}{2023/04/01}{Reset frozen mathversion gh/1028} % \begin{macrocode} \DeclareRobustCommand\mathversion[1] {\@nomath\mathversion \expandafter\ifx\csname mv@#1\endcsname\relax \@latex@error{Math version `#1' is not defined}\@eha\else +% \end{macrocode} +% If there has been a frozen math version reset locally. See GH 1028. +% \begin{macrocode} + \ifcsname mv@\math@version @frozen\endcsname + \expandafter\let + \csname mv@\math@version @frozen\expandafter\endcsname + \csname mv@\math@version\endcsname + \fi +% \end{macrocode} +% \begin{macrocode} \edef\math@version{#1}% % \end{macrocode} % We need to force a math font setup both now and at the point diff --git a/macros/latex/base/ltfsscmp.dtx b/macros/latex/base/ltfsscmp.dtx index 09f43a0d94..7bdfe2fd3e 100644 --- a/macros/latex/base/ltfsscmp.dtx +++ b/macros/latex/base/ltfsscmp.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltfssdcl.dtx b/macros/latex/base/ltfssdcl.dtx index 49041605e9..c3a743d249 100644 --- a/macros/latex/base/ltfssdcl.dtx +++ b/macros/latex/base/ltfssdcl.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltfssini.dtx b/macros/latex/base/ltfssini.dtx index 12e3b6289b..7b43f0228b 100644 --- a/macros/latex/base/ltfssini.dtx +++ b/macros/latex/base/ltfssini.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltfsstrc.dtx b/macros/latex/base/ltfsstrc.dtx index 699fd2c594..be0e6c68cf 100644 --- a/macros/latex/base/ltfsstrc.dtx +++ b/macros/latex/base/ltfsstrc.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/lthooks-code.pdf b/macros/latex/base/lthooks-code.pdf index eac5817e79..88b163641f 100644 Binary files a/macros/latex/base/lthooks-code.pdf and b/macros/latex/base/lthooks-code.pdf differ diff --git a/macros/latex/base/lthooks-doc.pdf b/macros/latex/base/lthooks-doc.pdf index 69ab35fb5a..d47c52c4ad 100644 Binary files a/macros/latex/base/lthooks-doc.pdf and b/macros/latex/base/lthooks-doc.pdf differ diff --git a/macros/latex/base/lthooks.dtx b/macros/latex/base/lthooks.dtx index cfa1454775..3807d25c44 100644 --- a/macros/latex/base/lthooks.dtx +++ b/macros/latex/base/lthooks.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment % -% Copyright (C) 2020-2022 -% Frank Mittelbach, Phelype Oleinik & LaTeX Team +% Copyright (C) 2020-2023 +% Frank Mittelbach, Phelype Oleinik, The LaTeX Project % % This file is part of the LaTeX base system. % ------------------------------------------- @@ -31,8 +31,8 @@ %%% From File: lthooks.dtx % % \begin{macrocode} -\def\lthooksversion{v1.0v} -\def\lthooksdate{2022/06/15} +\def\lthooksversion{v1.1e} +\def\lthooksdate{2023/06/06} % \end{macrocode} % %<*driver> @@ -148,7 +148,6 @@ % the current package name. See section~\ref{sec:default-label}. % \end{function} % -% % \begin{function}{\NewMirroredHookPair} % \begin{syntax} % \cs{NewMirroredHookPair} \Arg{hook-1} \Arg{hook-2} @@ -156,7 +155,45 @@ % A shorthand for % \cs{NewHook}\Arg{hook-1}\cs{NewReversedHook}\Arg{hook-2}. % -% The \meta{hooks} can be specified using the dot-syntax to denote +% The \meta{hook} can be specified using the dot-syntax to denote +% the current package name. See section~\ref{sec:default-label}. +% \end{function} +% +% +% \begin{function}{\NewHookWithArguments} +% \begin{syntax} +% \cs{NewHookWithArguments} \Arg{hook} \Arg{number} +% \end{syntax} +% Creates a new \meta{hook} whose code takes \meta{number} arguments, +% and otherwise works exactly like \cs{NewHook}. +% Section~\ref{sec:hook-args} explains hooks with arguments. +% +% The \meta{hook} can be specified using the dot-syntax to denote +% the current package name. See section~\ref{sec:default-label}. +% \end{function} +% +% \begin{function}{\NewReversedHookWithArguments} +% \begin{syntax} +% \cs{NewReversedHookWithArguments} \Arg{hook} \Arg{number} +% \end{syntax} +% Like \cs{NewReversedHook}, but creates a hook whose code takes +% \meta{number} arguments. +% Section~\ref{sec:hook-args} explains hooks with arguments. +% +% The \meta{hook} can be specified using the dot-syntax to denote +% the current package name. See section~\ref{sec:default-label}. +% \end{function} +% +% \begin{function}{\NewMirroredHookPairWithArguments} +% \begin{syntax} +% \cs{NewMirroredHookPairWithArguments} \Arg{hook-1} \Arg{hook-2} \Arg{number} +% \end{syntax} +% A shorthand for +% \cs{NewHookWithArguments}\Arg{hook-1}\Arg{number}\\ +% \cs{NewReversedHookWithArguments}\Arg{hook-2}\Arg{number}. +% Section~\ref{sec:hook-args} explains hooks with arguments. +% +% The \meta{hook} can be specified using the dot-syntax to denote % the current package name. See section~\ref{sec:default-label}. % \end{function} % @@ -173,9 +210,9 @@ % \begin{syntax} % \cs{DisableGenericHook} \Arg{hook} % \end{syntax} -% After this declaration\footnotemark{} the \meta{hook} is no longer usable: Any -% attempt to add further code to it will result in an error and any -% use, e.g., via \cs{UseHook}, will simply do nothing. +% After this declaration\footnotemark{} the \meta{hook} is no longer +% usable: Any further attempt to add code to it will result in an +% error and any use, e.g., via \cs{UseHook}, will simply do nothing. % % This is intended to be used with generic command hooks (see % \texttt{ltcmdhooks-doc}) as depending on the definition of the @@ -215,7 +252,7 @@ % \begin{syntax} % \cs{UseHook} \Arg{hook} % \end{syntax} -% Execute the hook code inside a command or environment. +% Execute the code stored in the \meta{hook}. % % Before \verb=\begin{document}= the fast execution code for a hook % is not set up, so in order to use a hook there it is explicitly @@ -227,14 +264,30 @@ % A leading |.| is treated literally. % \end{function} % +% \begin{function}{\UseHookWithArguments} +% \begin{syntax} +% \cs{UseHookWithArguments} \Arg{hook} \Arg{number} \Arg{arg_1} \ldots \Arg{arg_n} +% \end{syntax} +% Execute the code stored in the \meta{hook} and pass the arguments +% \Arg{arg_1} through \Arg{arg_n} to the \meta{hook}. Otherwise, it +% works exactly like \cs{UseHook}. +% The \meta{number} should be the number of arguments declared for +% the hook. If the hook is not declared, this command does nothing +% and it will remove \meta{number} items from the input. +% Section~\ref{sec:hook-args} explains hooks with arguments. +% +% The \meta{hook} \emph{cannot} be specified using the dot-syntax. +% A leading |.| is treated literally. +% \end{function} +% % \begin{function}{\UseOneTimeHook} % \begin{syntax} % \cs{UseOneTimeHook} \Arg{hook} % \end{syntax} % Some hooks are only used (and can be only used) in one place, for % example, those in \verb=\begin{document}= or -% \verb=\end{document}=. Once we have passed that point adding to -% the hook through a defined \cs[no-index]{\meta{addto-cmd}} command (e.g., +% \verb=\end{document}=. From that point onwards, adding to the hook +% through a defined \cs[no-index]{\meta{addto-cmd}} command (e.g., % \cs{AddToHook} or \cs{AtBeginDocument}, etc.\@) would have no % effect (as would the use of such a command inside the hook code % itself). It is therefore customary to redefine @@ -250,15 +303,30 @@ % section~\ref{sec:default-label} for details. % % Using \cs{UseOneTimeHook} several times with the same -% \Arg{hook} means that it only executes the first time it is used. +% \Arg{hook} means that it only executes the first time it is used. % For example, if it is used in a command that can be called several times -% then the hook executes during only the \emph{first} invocation of that +% then the hook executes during only the \emph{first} invocation of that % command; this allows its use as an \enquote{initialization hook}. % % Mixing \cs{UseHook} and \cs{UseOneTimeHook} for the same % \Arg{hook} should be avoided, but if this is done then neither will execute % after the first \cs{UseOneTimeHook}. +% \end{function} % +% \begin{function}{\UseOneTimeHookWithArguments} +% \begin{syntax} +% \cs{UseOneTimeHookWithArguments} \Arg{hook} \Arg{number} \Arg{arg_1} \ldots \Arg{arg_n} +% \end{syntax} +% Works exactly like \cs{UseOneTimeHook}, but passes arguments +% \Arg{arg_1} through \Arg{arg_n} to the \meta{hook}. +% The \meta{number} should be the number of arguments declared for +% the hook. If the hook is not declared, this command does nothing +% and it will remove \meta{number} items from the input. +% +% It should be noted that after a one-time hook is used, it is no +% longer possible to use \cs{AddToHookWithArguments} or similar with +% that hook. \cs{AddToHook} continues to work as normal. +% Section~\ref{sec:hook-args} explains hooks with arguments. % \end{function} % % @@ -294,6 +362,34 @@ % See section~\ref{sec:default-label}. % \end{function} % +% \begin{function}{\AddToHookWithArguments} +% \begin{syntax} +% \cs{AddToHookWithArguments} \Arg{hook}\oarg{label}\Arg{code} +% \end{syntax} +% Works exactly like \cs{AddToHook}, except that the \meta{code} can +% access the arguments passed to the hook using \verb|#1|, \verb|#2|, +% \ldots, \verb|#n| (up to the number of arguments declared for the +% hook). If the \meta{code} should contain \emph{parameter tokens} +% (\verb|#|) that are not supposed to be understood as the arguments +% of the hook, such tokens should be doubled. For example, with +% \cs{AddToHook} one can write: +%\begin{verbatim} +% \AddToHook{myhook}{\def\foo#1{Hello, #1!}} +%\end{verbatim} +% but to achieve the same with \cs{AddToHookWithArguments}, one should +% write: +%\begin{verbatim} +% \AddToHookWithArguments{myhook}{\def\foo##1{Hello, ##1!}} +%\end{verbatim} +% because in the latter case, \verb|#1| refers to the first argument +% of the hook \hook{myhook}. +% Section~\ref{sec:hook-args} explains hooks with arguments. +% +% The \meta{hook} and \meta{label} can be specified using the +% dot-syntax to denote the current package name. +% See section~\ref{sec:default-label}. +% \end{function} +% % \begin{function}{\RemoveFromHook} % \begin{syntax} % \cs{RemoveFromHook} \Arg{hook}\oarg{label} @@ -403,6 +499,19 @@ % \end{function}\footnotetext{There is % no mechanism to reorder such code chunks (or delete them).} % +% \begin{function}{\AddToHookNextWithArguments} +% \begin{syntax} +% \cs{AddToHookNextWithArguments} \Arg{hook}\Arg{code} +% \end{syntax} +% Works exactly like \cs{AddToHookNext}, but the \meta{code} can +% contain references to the arguments of the \meta{hook} as described +% for \cs{AddToHookWithArguments} above. +% Section~\ref{sec:hook-args} explains hooks with arguments. +% +% The \meta{hook} can be specified using the dot-syntax to denote +% the current package name. See section~\ref{sec:default-label}. +% \end{function} +% % % % \begin{function}{\ClearHookNext} @@ -511,10 +620,10 @@ % package's hooks, so the dot-syntax doesn't make much sense. % % In some cases, for example in large packages, one may want to separate -% it in logical parts, but still use the main package name as +% the code in logical parts, but still use the main package name as the % \meta{label}, then the \meta{default label} can be set using -% \cs{SetDefaultHookLabel} or -% \cs{PushDefaultHookLabel}\verb={..}=\,\ldots\cs{PopDefaultHookLabel}. +% \cs{PushDefaultHookLabel}\verb={...}=\,\ldots\cs{PopDefaultHookLabel} +% or \cs{SetDefaultHookLabel}\verb={...}=. % % \begin{function}{\PushDefaultHookLabel,\PopDefaultHookLabel} % \begin{syntax} @@ -906,8 +1015,11 @@ % section even in \texttt{expl3} packages, but the choice is yours. % % -% \begin{function} -% {\hook_new:n,\hook_new_reversed:n,\hook_new_pair:nn} +% \begin{function}{ +% \hook_new:n, +% \hook_new_reversed:n, +% \hook_new_pair:nn +% } % \begin{syntax} % \cs{hook_new:n} \Arg{hook} % \cs{hook_new_reversed:n} \Arg{hook} @@ -923,6 +1035,27 @@ % the current package name. See section~\ref{sec:default-label}. % \end{function} % +% \begin{function}{ +% \hook_new_with_args:nn, +% \hook_new_reversed_with_args:nn, +% \hook_new_pair_with_args:nnn +% } +% \begin{syntax} +% \cs{hook_new_with_args:nn} \Arg{hook} \Arg{number} +% \cs{hook_new_reversed_with_args:nn} \Arg{hook} \Arg{number} +% \cs{hook_new_pair_with_args:nnn} \Arg{hook-1} \Arg{hook-2} \Arg{number} +% \end{syntax} +% Creates a new \meta{hook} with normal or reverse ordering of code +% chunks, that takes \meta{number} arguments from the input stream +% when it is used. \cs{hook_new_pair_with_args:nn} creates a pair of +% such hooks with \Arg{hook-2} being a reversed hook. +% If a hook name is already taken, an error is raised and the hook +% is not created. +% +% The \meta{hook} can be specified using the dot-syntax to denote +% the current package name. See section~\ref{sec:default-label}. +% \end{function} +% % % % \begin{function}{\hook_disable_generic:n} @@ -958,37 +1091,62 @@ % % % -% \begin{function}{\hook_use:n} +% \begin{function}{\hook_use:n,\hook_use:nnw} % \begin{syntax} % \cs{hook_use:n} \Arg{hook} +% \cs{hook_use:nnw} \Arg{hook} \Arg{number} \Arg{arg_1} \ldots \Arg{arg_n} % \end{syntax} % Executes the \Arg{hook} code followed (if set up) by the code for next % invocation only, then empties that next invocation code. +% \cs{hook_use:nnw} should be used for hooks declared with arguments, +% and should be followed by as many brace groups as the declared +% number of arguments. +% The \meta{number} should be the number of arguments declared for +% the hook. If the hook is not declared, this command does nothing +% and it will remove \meta{number} items from the input. % % The \meta{hook} \emph{cannot} be specified using the dot-syntax. % A leading |.| is treated literally. % \end{function} % -% \begin{function}{\hook_use_once:n} +% \begin{function}{\hook_use_once:n,\hook_use_once:nnw} % \begin{syntax} % \cs{hook_use_once:n} \Arg{hook} +% \cs{hook_use_once:nnw} \Arg{hook} \Arg{number} \Arg{arg_1} \ldots \Arg{arg_n} % \end{syntax} % Changes the \Arg{hook} status so that from now on any addition to % the hook code is executed immediately. Then execute any % \Arg{hook} code already set up. +% \cs{hook_use_once:nnw} should be used for hooks declared with arguments, +% and should be followed by as many brace groups as the declared +% number of arguments. +% The \meta{number} should be the number of arguments declared for +% the hook. If the hook is not declared, this command does nothing +% and it will remove \meta{number} items from the input. % % The \meta{hook} \emph{cannot} be specified using the dot-syntax. % A leading |.| is treated literally. % \end{function} % -% \begin{function}{\hook_gput_code:nnn} +% \begin{function}{ +% \hook_gput_code:nnn, +% \hook_gput_code_with_args:nnn +% } % \begin{syntax} % \cs{hook_gput_code:nnn} \Arg{hook} \Arg{label} \Arg{code} +% \cs{hook_gput_code_with_args:nnn} \Arg{hook} \Arg{label} \Arg{code} % \end{syntax} % Adds a chunk of \meta{code} to the \meta{hook} labeled % \meta{label}. If the label already exists the \meta{code} is % appended to the already existing code. % +% If \cs{hook_gput_code_with_args:nnn} is used, the \meta{code} +% can access the arguments passed to \cs{hook_use:nnw} +% (or~\cs{hook_use_once:nnw}) with \verb|#1|, \verb|#2|, \ldots, +% \verb|#n| (up to the number of arguments declared for the hook). +% In that case, if an actual parameter token should be added to the +% code, it should be doubled. +% % If code is added to an external \meta{hook} (of the kernel or % another package) then the convention is to use the package name % as the \meta{label} not some internal module name or some other @@ -999,18 +1157,26 @@ % See section~\ref{sec:default-label}. % \end{function} % -% \begin{function} -% {\hook_gput_next_code:nn} +% \begin{function}{ +% \hook_gput_next_code:nn, +% \hook_gput_next_code_with_args:nn, +% } % \begin{syntax} % \cs{hook_gput_next_code:nn} \Arg{hook} \Arg{code} % \end{syntax} % Adds a chunk of \meta{code} for use only in the next invocation of the % \meta{hook}. Once used it is gone. % +% If \cs{hook_gput_next_code_with_args:nn} is used, the \meta{code} +% can access the arguments passed to \cs{hook_use:nnw} +% (or~\cs{hook_use_once:nnw}) with \verb|#1|, \verb|#2|, \ldots, +% \verb|#n| (up to the number of arguments declared for the hook). +% In that case, if an actual parameter token should be added to the +% code, it should be doubled. +% % This is simpler than \cs{hook_gput_code:nnn}, the code is simply % appended to the hook in the order of declaration at the very end, % i.e., after all standard code for the hook got executed. -% % Thus if one needs to undo what the standard does one has to do % that as part of \meta{code}. % @@ -1019,8 +1185,7 @@ % \end{function} % % -% \begin{function} -% {\hook_gclear_next_code:n} +% \begin{function}{\hook_gclear_next_code:n} % \begin{syntax} % \cs{hook_gclear_next_code:n} \Arg{hook} % \end{syntax} @@ -1240,7 +1405,7 @@ % \begin{itshape}\begin{color}{blue} ... % \end{itshape}\end{color} %\end{verbatim} -% and an error message that \verb=\begin{color}= ended by +% and an error message saying that \verb=\begin{color}= was ended by % \verb=\end{itshape}=. % With \hook{env/quote/after} declared as a reversed hook the % execution order is reversed and so all environments are closed in @@ -1377,9 +1542,9 @@ % you typically do not know what kind of variable parts may come up % in real documents. % -% For example, \pkg{babel} may want to provide hooks such as -% \hook{babel/\meta{language}/afterextras}. Language support in -% \pkg{babel} is often done through external language +% For example, \pkg{babel} provides hooks such as +% \hook{babel/\meta{language}/afterextras}. However, language +% support in \pkg{babel} is often done through external language % packages. Thus doing the activation for all languages inside the % core \pkg{babel} code is not a viable approach. Instead it needs % to be done by each language package (or by the user who wants to @@ -1396,6 +1561,125 @@ % conciderably. % % +% \subsection{Hooks with arguments} +% \label{sec:hook-args} +% +% Sometimes it is necessary to pass contextual information to a hook, +% and, for one reason or another, it is not feasible to store such +% information in macros. To serve this purpose, hooks can be +% declared with arguments, so that the programmer can pass along the +% data necessary for the code in the hook to function properly. +% +% A hook with arguments works mostly like a regular hook, and most +% commands that work for regular hooks, also work for hooks that take +% arguments. The differences are when the hook is declared +% (\cs{NewHookWithArguments} is used instead of \cs{NewHook}), then +% code can be added with both \cs{AddToHook} and +% \cs{AddToHookWithArguments}, and when the hook is used +% (\cs{UseHookWithArguments} instead of \cs{UseHook}). +% +% \medskip +% +% A hook with arguments must be declared as such (before it is first +% used, as all regular hooks) using +% \cs{NewHookWithArguments}\Arg{hook}\Arg{number}. All code added to +% that hook can then use \verb|#1| to access the first argument, +% \verb|#2| to access the second, and so forth up to the number of +% arguments declared. However, it is still possible to add code with +% references to the arguments of a hook that was not yet declared +% (we will discuss that later). At their core, hooks are macros, so +% \TeX's limit of 9~arguments applies, and a low-level \TeX{} error +% is raised if you try to reference an argument number that doesn't +% exist. +% +% \medskip +% +% To use a hook with arguments, just write +% \cs{UseHookWithArguments}\Arg{hook}\Arg{number} followed by a +% braced list of the arguments. For example, if the hook \hook{test} +% takes three arguments, write: +%\begin{verbatim} +% \UseHookWithArguments{test}{3}{arg-1}{arg-2}{arg-3} +%\end{verbatim} +% then, in the \meta{code} of the hook, all instances of \verb|#1| +% will be replaced by \verb|arg-1|, \verb|#2| by \verb|arg-2| and so +% on. If, at the point of usage, the programmer provides more +% arguments than the hook is declared to take, the excess arguments +% are simply ignored by the hook. Behaviour is +% unpredictable\footnote +% {The hook \emph{will} take the declared number of arguments, and +% what will happen depends on what was grabbed, and what the hook +% code does with its arguments.} +% if too few arguments are provided. If the hook isn't declared, +% \meta{number} arguments are removed from the input stream. +% +% \medskip +% +% Adding code to a hook with arguments can be done with +% \cs{AddToHookWithArguments} as well as with the regular +% \cs{AddToHook}, to achieve different outcomes. The main difference +% when it comes to adding code to a hook, in this case, is firstly +% the possibility of accessing a hook's arguments, of course, and +% second, how parameter tokens (\verb|#|$_6$) are treated. +% +% Using \cs{AddToHook} in a hook that takes arguments will work as it +% does for all other hooks. This allows a package developer to add +% arguments to a hook that otherwise had none without having to worry +% about compatibility. This means that, for example: +%\begin{verbatim} +% \AddToHook{test}{\def\foo#1{Hello, #1!}} +%\end{verbatim} +% will define the same macro \cs[no-index]{foo} regardless if the +% hook \hook{test} takes arguments or not. +% +% Using \cs{AddToHookWithArguments} allows the \meta{code} added to +% access the arguments of the hook with \verb|#1|, \verb|#2|, and so +% forth, up to the number of the arguments declared in the hook. +% This means that if one wants to add a \verb|#|$_6$ to the +% \meta{code} that token must be doubled in the input. The same +% definition from above, using \cs{AddToHookWithArguments}, needs to +% be rewritten: +%\begin{verbatim} +% \AddToHookWithArguments{test}{\def\foo##1{Hello, ##1!}} +%\end{verbatim} +% +% Extending the above example to use the hook arguments, we could +% rewrite something like (now from declaration to usage, to get the +% whole picture): +%\begin{verbatim} +% \NewHookWithArguments{test}{1} +% \AddToHookWithArguments{test}{% +% \typeout{Defining foo with "#1"} +% \def\foo##1{Hello, ##1! Some text after: #1}% +% } +% \UseHook{test}{Howdy!} +% \ShowCommand\foo +%\end{verbatim} +% Running the code above prints in the terminal: +%\begin{verbatim} +% Defining foo with "Howdy!" +% > \foo=macro: +% #1->Hello, #1! Some text after: Howdy!. +%\end{verbatim} +% Note how \verb|##1| in the call to \cs{AddToHookWithArguments} +% became \verb|#1|, and the \verb|#1| was replaced by the argument +% passed to the hook. Should the hook be used again, with a +% different argument, the definition would naturally change. +% +% \bigskip +% +% It is possible to add code referencing a hook's arguments before +% such hook is declared and the number of hooks is fixed. However, +% if some code is added to the hook, that references more arguments +% than will be declared for the hook, there will be a low-level +% \TeX{} error about an \enquote{Illegal parameter number} at the +% time the hook is declared, which will be hard to track down because +% at that point \TeX{} can't know whence the offending code came +% from. Thus it is important that package writers explicitly +% document how many arguments (if any) each hook can take, so users +% of those packages know how many arguments can be referenced, and +% equally important, what each argument means. +% % \subsection{Private \LaTeX{} kernel hooks} % % There are a few places where it is absolutely essential for @@ -1461,7 +1745,7 @@ % package/class name if called inside such a file % (see section~\ref{sec:default-label}). % -% This way one can add further code to the hook using +% This way one can add code to the hook using % \cs{AddToHook} or \cs{AtBeginDocument} using a different label % and explicitly order the code chunks as necessary, e.g., run some % code before or after another package's code. When using the @@ -1746,10 +2030,10 @@ % % \subsection{Hooks provided by \cs{end}\texttt{\{document\}}} % -% \LaTeXe{} always provided \cs{AtEndDocument} to add code to the -% execution of \verb=\end{document}= just in front of the code that +% \LaTeXe{} has always provided \cs{AtEndDocument} to add code to the +% \verb=\end{document}=, just in front of the code that % is normally executed there. While this was a big improvement over -% the situation in \LaTeX\,2.09 it was not flexible enough for a +% the situation in \LaTeX\,2.09, it was not flexible enough for a % number of use cases and so packages, such as \pkg{etoolbox}, % \pkg{atveryend} and others patched \cs{enddocument} to add % additional points where code could be hooked into. @@ -2095,13 +2379,37 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[int]{\tl_gremove_once:Nx,\tl_show:x,\tl_log:x} +% \begin{macro}{\c_@@_empty_tl} +% \begin{macro}{\c_@@_nine_parameters_tl} +% An empty token list, and one containing nine parameters. +% \changes{v1.1a}{2023/04/06} +% {Add auxiliary token lists (hook-args).} +% \begin{macrocode} +\tl_const:Nn \c_@@_empty_tl { } +\tl_const:Nn \c_@@_nine_parameters_tl { #1#2#3#4#5#6#7#8#9 } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[int]{ +% \tl_gremove_once:Nx, +% \tl_show:x, +% \tl_log:x, +% \tl_set:Ne, +% \cs_replacement_spec:c, +% \prop_put:Nne, +% \str_count:e +% } % Some variants of \pkg{expl3} functions. % \fmiinline{should probably be moved to expl3} % \begin{macrocode} \cs_generate_variant:Nn \tl_gremove_once:Nn { Nx } \cs_generate_variant:Nn \tl_show:n { x } \cs_generate_variant:Nn \tl_log:n { x } +\cs_generate_variant:Nn \tl_set:Nn { Ne } +\cs_generate_variant:Nn \cs_replacement_spec:N { c } +\cs_generate_variant:Nn \prop_put:Nnn { Nne } +\cs_generate_variant:Nn \str_count:n { e } % \end{macrocode} % \end{macro} % @@ -2112,15 +2420,20 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_clean_to_scan:w} +% \begin{macro}{ +% \@@_use_none_delimit_by_s_mark:w, +% \@@_use_i_delimit_by_s_mark:nw +% } % Removes tokens until the next \cs{s_@@_mark}. +% \changes{v1.1a}{2023/04/06} +% {Use standard naming scheme (hook-args).} % \begin{macrocode} -\cs_new:Npn \@@_clean_to_scan:w #1 \s_@@_mark { } +\cs_new:Npn \@@_use_none_delimit_by_s_mark:w #1 \s_@@_mark { } +\cs_new:Npn \@@_use_i_delimit_by_s_mark:nw #1 #2 \s_@@_mark {#1} % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_tl_set:Nn,\@@_tl_set:Nx, -% \@@_tl_set:cn,\@@_tl_set:cx} +% \begin{macro}{\@@_tl_set:cn} % Private copies of a few \pkg{expl3} functions. \pkg{l3debug} will % only add debugging to the public names, not to these copies, so we % don't have to use \cs{debug_suspend:} and \cs{debug_resume:} @@ -2130,44 +2443,43 @@ % copied because in \pkg{expl3} they use % \cs[no-index]{__kernel_tl_(g)set:Nx}, which is also patched by % \pkg{l3debug}. -% \changes{v1.0h}{2021/01/07}{Manually define some \pkg{l3tl} commands +% \changes{v1.0h}{2021/01/07}{Manually define some \pkg{l3tl} commands % to work around \pkg{expl3} changes} +% \changes{v1.1a}{2023/04/06} +% {Clean-up unused variants (hook-args).} % \begin{macrocode} -\cs_new_protected:Npn \@@_tl_set:Nn #1#2 - { \cs_set_nopar:Npx #1 { \__kernel_exp_not:w {#2} } } -\cs_new_protected:Npn \@@_tl_set:Nx #1#2 - { \cs_set_nopar:Npx #1 {#2} } -\cs_generate_variant:Nn \@@_tl_set:Nn { c } -\cs_generate_variant:Nn \@@_tl_set:Nx { c } +\cs_new_protected:Npn \@@_tl_set:cn #1#2 + { \cs_set_nopar:cpx {#1} { \__kernel_exp_not:w {#2} } } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_tl_gset:Nn,\@@_tl_gset:No,\@@_tl_gset:Nx, +% \begin{macro}{\@@_tl_gset:Nn,\@@_tl_gset:Nx, % \@@_tl_gset:cn,\@@_tl_gset:co,\@@_tl_gset:cx} % Same as above. % \begin{macrocode} \cs_new_protected:Npn \@@_tl_gset:Nn #1#2 { \cs_gset_nopar:Npx #1 { \__kernel_exp_not:w {#2} } } -\cs_new_protected:Npn \@@_tl_gset:No #1#2 - { \cs_gset_nopar:Npx #1 { \__kernel_exp_not:w \exp_after:wN {#2} } } \cs_new_protected:Npn \@@_tl_gset:Nx #1#2 { \cs_gset_nopar:Npx #1 {#2} } -\cs_generate_variant:Nn \@@_tl_gset:Nn { c } -\cs_generate_variant:Nn \@@_tl_gset:No { c } +\cs_generate_variant:Nn \@@_tl_gset:Nn { c, co } \cs_generate_variant:Nn \@@_tl_gset:Nx { c } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_tl_gput_right:Nn,\@@_tl_gput_right:No,\@@_tl_gput_right:cn} +% \begin{macro}{ +% \@@_tl_gput_right:Nn, +% \@@_tl_gput_right:Ne, +% \@@_tl_gput_right:cn, +% } % Same as above. % \begin{macrocode} \cs_new_protected:Npn \@@_tl_gput_right:Nn #1#2 { \@@_tl_gset:Nx #1 { \__kernel_exp_not:w \exp_after:wN { #1 #2 } } } -\cs_generate_variant:Nn \@@_tl_gput_right:Nn { No, cn } +\cs_generate_variant:Nn \@@_tl_gput_right:Nn { Ne, cn } % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_tl_gput_left:Nn,\@@_tl_gput_left:No} +% \begin{macro}{\@@_tl_gput_left:Nn} % Same as above. % \begin{macrocode} \cs_new_protected:Npn \@@_tl_gput_left:Nn #1#2 @@ -2175,7 +2487,6 @@ \@@_tl_gset:Nx #1 { \__kernel_exp_not:w {#2} \__kernel_exp_not:w \exp_after:wN {#1} } } -\cs_generate_variant:Nn \@@_tl_gput_left:Nn { No } % \end{macrocode} % \end{macro} % @@ -2202,7 +2513,11 @@ % % \DescribeMacro{\g_@@_\meta{hook}_code_prop} % \DescribeMacro{\@@\textvisiblespace\meta{hook}} +% \DescribeMacro{\g_@@_\meta{hook}_reversed_tl} +% \DescribeMacro{\g_@@_\meta{hook}_declared_tl} +% \DescribeMacro{\g_@@_\meta{hook}_parameter_tl} % \DescribeMacro{\@@_next\textvisiblespace\meta{hook}} +% \DescribeMacro{\@@_toplevel\textvisiblespace\meta{hook}} % Hooks have a name (called \meta{hook} in the description below) % and for each hook we have to % provide a number of data structures. These are @@ -2232,12 +2547,17 @@ % so that it can be identified. The |-| character is used because % $\meta{reversed}1$ is $+1$ for normal hooks and $-1$ for reversed % ones. - +% % \item[{\cs[no-index]{g_@@_\meta{hook}_declared_tl}}] This token -% list serves as marker for the hook being officially declared. Its +% list serves as a marker for the hook being officially declared. Its % existence is tested to raise an error in case another declaration % is attempted. % +% \item[{\cs[no-index]{c_@@_\meta{hook}_parameter_tl}}] This token +% list stores the parameter text for a declared hook (its existence +% almost completely intersects the token list above), which is used +% for managing hooks with arguments. +% % \item[\cs{@@_toplevel\textvisiblespace\meta{hook}}] This token list stores the code % inserted in the hook from the user's document, in the |top-level| % label. This label is special, and doesn't participate in sorting. @@ -2367,45 +2687,92 @@ % \subsubsection{Setting hooks up} % % -% \begin{macro}{\hook_new:n,\@@_new:n} +% \begin{macro}{ +% \hook_new:n, +% \hook_new_with_args:nn +% } +% \begin{macro}{@@_new:nn} % The \cs{hook_new:n} declaration declares a new hook and expects % the hook \meta{name} as its argument, e.g., % \hook{begindocument}. +% \changes{v1.1a}{2023/04/06} +% {Add \cs{hook_new_with_args:nn} (hook-args).} % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\hook_new_with_args:nn} +%<latexrelease> {Hooks~with~args} \cs_new_protected:Npn \hook_new:n #1 - { \@@_normalize_hook_args:Nn \@@_new:n {#1} } + { \@@_normalize_hook_args:Nn \@@_new:nn {#1} { 0 } } +\cs_new_protected:Npn \hook_new_with_args:nn #1 #2 + { \@@_normalize_hook_args:Nn \@@_new:nn {#1} {#2} } % \end{macrocode} % % \begin{macrocode} -\cs_new_protected:Npn \@@_new:n #1 +\cs_new_protected:Npn \@@_new:nn #1 #2 { % \end{macrocode} % We check if the hook was already \emph{explicitly} declared with % \cs{hook_new:n}, and if it already exists we complain, otherwise set % the \enquote{created} flag for the hook so that it errors next time % \cs{hook_new:n} is used. +% \changes{v1.1d}{2023/05/21} +% {Changes to allow support arguments in cmd hooks (cmd-args).} % \begin{macrocode} \@@_if_declared:nTF {#1} { \msg_error:nnn { hooks } { exists } {#1} } { \tl_new:c { g_@@_#1_declared_tl } - \@@_make_usable:n {#1} + \cs_undefine:c { @@~#1 } + \cs_undefine:c { c_@@_#1_parameter_tl } + \@@_make_usable:nn {#1} {#2} +% \end{macrocode} +% In case there is already code in a hook, but it's undeclared, run +% \cs{@@_update_hook_code:n} to make it ready to be executed (see test +% \texttt{lthooks-034}). +% \changes{v1.1a}{2023/04/06} +% {Update hook code after declaring.} +% \begin{macrocode} + \@@_update_hook_code:n {#1} } } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{\hook_new_with_args:nn} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_gset_protected:Npn \hook_new:n #1 +%<latexrelease> { \@@_normalize_hook_args:Nn \@@_new:n {#1} } +%<latexrelease>\cs_undefine:N \@@_new:nn +%<latexrelease>\cs_gset_protected:Npn \@@_new:n #1 +%<latexrelease> { +%<latexrelease> \@@_if_declared:nTF {#1} +%<latexrelease> { \msg_error:nnn { hooks } { exists } {#1} } +%<latexrelease> { +%<latexrelease> \tl_new:c { g_@@_#1_declared_tl } +%<latexrelease> \@@_make_usable:n {#1} +%<latexrelease> } +%<latexrelease> } +%<latexrelease>\cs_gset_protected:Npn \hook_new_with_args:nn #1 { } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} % % % -% \begin{macro}{\@@_make_usable:n} +% \begin{macro}{\@@_make_usable:nn} % % This initializes all hook data structures for the hook but if % used on its own doesn't mark the hook as declared (as % \cs{hook_new:n} does, so a later \cs{hook_new:n} on that hook will % not result in an error. This command is internally used by -% \cs{hook_gput_code:n} when adding code to a generic hook. +% \cs{hook_gput_code:nnn} when adding code to a generic hook. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} -\cs_new_protected:Npn \@@_make_usable:n #1 +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_make_usable:nn} +%<latexrelease> {Hooks~with~args} +\cs_new_protected:Npn \@@_make_usable:nn #1 #2 { % \end{macrocode} % Now we check if the hook's data structure can be safely created @@ -2414,29 +2781,70 @@ % allocate the necessary data structures for the new hook, % otherwise just do nothing. % \begin{macrocode} - \tl_if_exist:cF { @@~#1 } + \@@_if_usable:nF {#1} { \seq_gput_right:Nn \g_@@_all_seq {#1} % \end{macrocode} +% Here we'll define the \cs[no-index]{c_@@_\meta{hook}_parameter_tl} +% to hold a run of parameters up to the number of arguments of the +% hook (\verb|#2|). +% \begin{macrocode} + \__kernel_cs_parm_from_arg_count:nnF + { \tl_const:cn { c_@@_#1_parameter_tl } } {#2} + { + \msg_error:nnnn { hooks } { too-many-args } {#1} {#2} + \tl_const:cx { c_@@_#1_parameter_tl } + { \exp_not:V \c_@@_nine_parameters_tl } + } +% \end{macrocode} +% After that, use \cs{@@_normalise_cs_args:nn} to correct the number +% of parameters of the macros +% \cs[no-index]{@@_toplevel\textvisiblespace\meta{hook}} and +% \cs[no-index]{@@_next\textvisiblespace\meta{hook}}. We need to be +% able to add +% code with arguments to a hook without prior knowledge of the number +% of arguments of that hook, so \pkg{lthooks} assumes~9 until the +% hook is properly declared and the number of arguments is known. +% \cs{@@_normalise_cs_args:nn} does the normalisation by using the +% \cs[no-index]{c_@@_\meta{hook}_parameter_tl} defined just above. +% \begin{macrocode} + \@@_normalise_cs_args:nn { _toplevel } {#1} + \@@_normalise_cs_args:nn { _next } {#1} +% \end{macrocode} % This is only used by the actual code of the current hook, so % declare it normally: % \begin{macrocode} - \tl_new:c { @@~#1 } + \@@_code_gset:nn {#1} { } % \end{macrocode} % Now ensure that the base data structure for the hook exists: % \begin{macrocode} \@@_init_structure:n {#1} % \end{macrocode} +% The call to \cs{@@_normalise_code_pool:n} will correct any improper +% reference to arguments that don't exist in the hook, raising a +% low-level \TeX{} error and doubling the offending parameter tokens. +% It has to be done after \cs{@@_init_structure:n} because it +% operates on \cs[no-index]{g_@@_\meta{hook}_code_prop}. +% \begin{macrocode} + \@@_normalise_code_pool:n {#1} +% \end{macrocode} % The \cs{g_@@_\meta{hook}_labels_clist} holds the sorted list of % labels (once it got sorted). This is used only for debugging. +% These are defined conditionally, in case \cs{@@_make_usable:nn} +% is being used to redefine a hook. +% \changes{v1.1d}{2023/05/21} +% {Changes to allow support arguments in cmd hooks (cmd-args).} % \begin{macrocode} - \clist_new:c { g_@@_#1_labels_clist } + \clist_if_exist:cF { g_@@_#1_labels_clist } + { + \clist_new:c { g_@@_#1_labels_clist } % \end{macrocode} % Some hooks should reverse the default order of code chunks. To % signal this we have a token list which is empty for normal hooks % and contains a \verb=-= for reversed hooks. % \begin{macrocode} - \tl_new:c { g_@@_#1_reversed_tl } + \tl_new:c { g_@@_#1_reversed_tl } + } % \end{macrocode} % The above is all in L3 convention, but we also provide an % interface to legacy \LaTeXe{} hooks of the form \cs{@...hook}, @@ -2454,9 +2862,28 @@ \@@_include_legacy_code_chunk:n {#1} } } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} -% \end{macro} % +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_make_usable:nn} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_undefine:N \@@_make_usable:nn +%<latexrelease>\cs_gset_protected:Npn \@@_make_usable:n #1 +%<latexrelease> { +%<latexrelease> \tl_if_exist:cF { @@~#1 } +%<latexrelease> { +%<latexrelease> \seq_gput_right:Nn \g_@@_all_seq {#1} +%<latexrelease> \tl_new:c { @@~#1 } +%<latexrelease> \@@_init_structure:n {#1} +%<latexrelease> \clist_new:c { g_@@_#1_labels_clist } +%<latexrelease> \tl_new:c { g_@@_#1_reversed_tl } +%<latexrelease> \@@_include_legacy_code_chunk:n {#1} +%<latexrelease> } +%<latexrelease> } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} % % % \begin{macro}{\@@_init_structure:n} @@ -2472,49 +2899,124 @@ % \cs{@@_init_structure:n} the first time anything is added to it. % Initializing a hook just with \cs{@@_init_structure:n} will not % make it usable with \cs{hook_use:n}. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_init_structure:n} +%<latexrelease> {Hooks~with~args} \cs_new_protected:Npn \@@_init_structure:n #1 { \@@_if_structure_exist:nF {#1} { \prop_new:c { g_@@_#1_code_prop } - \tl_new:c { @@_toplevel~#1 } - \tl_new:c { @@_next~#1 } + \@@_toplevel_gset:nn {#1} { } + \@@_next_gset:nn {#1} { } } } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} -% \end{macro} -% % +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_init_structure:n} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_gset_protected:Npn \@@_init_structure:n #1 +%<latexrelease> { +%<latexrelease> \@@_if_structure_exist:nF {#1} +%<latexrelease> { +%<latexrelease> \prop_new:c { g_@@_#1_code_prop } +%<latexrelease> \tl_new:c { @@_toplevel~#1 } +%<latexrelease> \tl_new:c { @@_next~#1 } +%<latexrelease> } +%<latexrelease> } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} % -% \begin{macro}{\hook_new_reversed:n,\@@_new_reversed:n} +% \begin{macro}{ +% \hook_new_reversed:n, +% \hook_new_reversed_with_args:nn +% } +% \begin{macro}{\@@_new_reversed:nn} % % Declare a new hook. The default ordering of code chunks is % reversed, signaled by setting the token list to a minus sign. +% \changes{v1.1a}{2023/04/06} +% {Add \cs{hook_new_reversed_with_args:nn} (hook-args).} % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\hook_new_reversed_with_args:nn} +%<latexrelease> {Hooks~with~args} \cs_new_protected:Npn \hook_new_reversed:n #1 - { \@@_normalize_hook_args:Nn \@@_new_reversed:n {#1} } -\cs_new_protected:Npn \@@_new_reversed:n #1 + { \@@_normalize_hook_args:Nn \@@_new_reversed:nn {#1} { 0 } } +\cs_new_protected:Npn \hook_new_reversed_with_args:nn #1 #2 + { \@@_normalize_hook_args:Nn \@@_new_reversed:nn {#1} {#2} } +\cs_new_protected:Npn \@@_new_reversed:nn #1 #2 { - \@@_new:n {#1} + \@@_if_declared:nTF {#1} + { \msg_error:nnn { hooks } { exists } {#1} } + { + \@@_new:nn {#1} {#2} + \tl_gset:cn { g_@@_#1_reversed_tl } { - } + } + } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} -% If the hook already exists the above will generate an error -% message, so the next line should be executed (but it is --- too -% bad). +% % \begin{macrocode} - \tl_gset:cn { g_@@_#1_reversed_tl } { - } - } +%<latexrelease>\IncludeInRelease{2020/10/01}{\hook_new_reversed_with_args:nn} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_gset_protected:Npn \hook_new_reversed:n #1 +%<latexrelease> { \@@_normalize_hook_args:Nn \@@_new_reversed:n {#1} } +%<latexrelease>\cs_undefine:N \@@_new_reversed:nn +%<latexrelease>\cs_gset_protected:Npn \@@_new_reversed:n #1 +%<latexrelease> { +%<latexrelease> \@@_new:n {#1} +%<latexrelease> \tl_gset:cn { g_@@_#1_reversed_tl } { - } +%<latexrelease> } +%<latexrelease>\cs_undefine:N \@@_new_reversed:nn +%<latexrelease>\cs_gset_protected:Npn \hook_new_reversed_with_args:nn #1 #2 { } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} +% \end{macro} % -% -% -% -% \begin{macro}{\hook_new_pair:nn} +% \begin{macro}{\hook_new_pair:nn,\hook_new_pair_with_args:nnn} % A shorthand for declaring a normal and a (matching) reversed hook in one go. +% \changes{v1.1a}{2023/04/06} +% {Add \cs{hook_new_pair_with_args:nnn} (hook-args).} % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\hook_new_pair_with_args:nnn} +%<latexrelease> {Hooks~with~args} \cs_new_protected:Npn \hook_new_pair:nn #1#2 - { \hook_new:n {#1} \hook_new_reversed:n {#2} } + { \@@_normalize_hook_args:Nnn \@@_new_pair:nnn {#1} {#2} { 0 } } +\cs_new_protected:Npn \hook_new_pair_with_args:nnn #1#2#3 + { \@@_normalize_hook_args:Nnn \@@_new_pair:nnn {#1} {#2} {#3} } +\cs_new_protected:Npn \@@_new_pair:nnn #1 #2 #3 + { + \@@_if_declared:nTF {#1} + { \msg_error:nnn { hooks } { exists } {#1} } + { + \@@_if_declared:nTF {#2} + { \msg_error:nnn { hooks } { exists } {#2} } + { + \@@_new:nn {#1} {#3} + \@@_new_reversed:nn {#2} {#3} + } + } + } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{\hook_new_pair_with_args:nnn} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_gset_protected:Npn \hook_new_pair:nn #1#2 +%<latexrelease> { +%<latexrelease> \hook_new:n {#1} +%<latexrelease> \hook_new_reversed:n {#2} +%<latexrelease> } +%<latexrelease>\cs_gset_protected:Npn \hook_new_pair_with_args:nnn #1#2#3 +%<latexrelease> { } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -2531,6 +3033,8 @@ % \textbf{Warning: this support will vanish in future releases!} % \end{quote} % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_include_legacy_code_chunk:n} +%<latexrelease> {Hooks~with~args} \cs_new_protected:Npn \@@_include_legacy_code_chunk:n #1 { % \end{macrocode} @@ -2538,15 +3042,27 @@ % needs to be done. % \begin{macrocode} \tl_if_exist:cT { @#1hook } + { % \end{macrocode} % Of course if the legacy hook exists but is empty, there is no need % to add anything under \texttt{legacy} the legacy label. % \begin{macrocode} - { \tl_if_empty:cF { @#1hook } { - \exp_args:Nnnv \@@_hook_gput_code_do:nnn {#1} - { legacy } { @#1hook } +% \end{macrocode} +% Here we set \cs{@@_replacing_args_false:} because no legacy code +% will reference hook arguments. +% \changes{v1.1b}{2023/04/16} +% {\cs{@@_replacing_args_false:} in +% \cs{@@_include_legacy_code_chunk:n}.} +% \begin{macrocode} + \@@_replacing_args_false: + \use:e + { + \@@_hook_gput_code_do:nnn {#1} { legacy } + { \exp_not:v { @#1hook } } + } + \@@_replacing_args_reset: % \end{macrocode} % Once added to the hook, we need to clear it otherwise it might % get added again later if the hook data gets updated. @@ -2555,6 +3071,22 @@ } } } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_include_legacy_code_chunk:n} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_gset_protected:Npn \@@_include_legacy_code_chunk:n #1 +%<latexrelease> { +%<latexrelease> \tl_if_exist:cT { @#1hook } +%<latexrelease> { +%<latexrelease> \tl_if_empty:cF { @#1hook } +%<latexrelease> { +%<latexrelease> \exp_args:Nnnv \@@_hook_gput_code_do:nnn +%<latexrelease> {#1} { legacy } { @#1hook } +%<latexrelease> \@@_tl_gclear:c { @#1hook } +%<latexrelease> } +%<latexrelease> } +%<latexrelease> } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -2579,8 +3111,8 @@ % if the hook is disabled. % % \begin{macrocode} -%<latexrelease>\IncludeInRelease{2021/06/01}% -%<latexrelease> {\hook_disable_generic:n}{Disable~hooks} +%<latexrelease>\IncludeInRelease{2021/06/01}{\hook_disable_generic:n} +%<latexrelease> {Disable~hooks} % \end{macrocode} % % \begin{macrocode} @@ -2595,7 +3127,7 @@ { \bool_lazy_and:nnTF { \tl_if_exist_p:c { g_@@_#1_declared_tl } } - { ! \tl_if_exist_p:c { @@~#1 } } + { ! \cs_if_exist_p:c { @@~#1 } } { \prg_return_true: } { \prg_return_false: } } @@ -2603,8 +3135,8 @@ % \end{macrocode} % % \begin{macrocode} -%<latexrelease>\IncludeInRelease{2020/10/01} -%<latexrelease> {\hook_disable_generic:n}{Disable~hooks} +%<latexrelease>\IncludeInRelease{2020/10/01}{\hook_disable_generic:n} +%<latexrelease> {Disable~hooks} %<latexrelease> %<latexrelease>\cs_new_protected:Npn \hook_disable_generic:n #1 {} %<latexrelease> @@ -2619,9 +3151,11 @@ % The \cs{hook_activate_generic:n} declaration declares a new hook if it % wasn't declared already, in which case it only checks that the % already existing hook is not a reversed hook. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} -%<latexrelease>\IncludeInRelease{2021/06/01}% -%<latexrelease> {\hook_activate_generic:n}{Providing~hooks} +%<latexrelease>\IncludeInRelease{2023/06/01}{\hook_activate_generic:n} +%<latexrelease> {Providing~hooks} % \end{macrocode} % % \begin{macrocode} @@ -2646,7 +3180,7 @@ \@@_if_declared:nF {#1} { \tl_new:c { g_@@_#1_declared_tl } - \@@_make_usable:n {#1} + \@@_make_usable:nn {#1} { 0 } \tl_gset:cx { g_@@_#1_reversed_tl } { \@@_if_generic_reversed:nT {#1} { - } } % \end{macrocode} @@ -2660,21 +3194,40 @@ } } % \end{macrocode} -% \end{macro} -% \end{macro} % % \begin{macrocode} %<latexrelease>\EndIncludeInRelease % \end{macrocode} % % \begin{macrocode} -%<latexrelease>\IncludeInRelease{2020/10/01} -%<latexrelease> {\hook_activate_generic:n}{Providing~hooks} -%<latexrelease> -%<latexrelease>\cs_new_protected:Npn \hook_activate_generic:n #1 {} -%<latexrelease> +%<latexrelease>\IncludeInRelease{2021/06/01}{\hook_activate_generic:n} +%<latexrelease> {Providing~hooks} +%<latexrelease>\cs_gset_protected:Npn \@@_activate_generic:nn #1 #2 +%<latexrelease> { +%<latexrelease> \@@_if_disabled:nTF {#1} +%<latexrelease> { \msg_warning:nnn { hooks } { activate-disabled } {#1} } +%<latexrelease> { +%<latexrelease> \@@_if_declared:nF {#1} +%<latexrelease> { +%<latexrelease> \tl_new:c { g_@@_#1_declared_tl } +%<latexrelease> \@@_make_usable:n {#1} +%<latexrelease> \tl_gset:cx { g_@@_#1_reversed_tl } +%<latexrelease> { \@@_if_generic_reversed:nT {#1} { - } } +%<latexrelease> \@@_update_hook_code:n {#1} +%<latexrelease> } +%<latexrelease> } +%<latexrelease> } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{\hook_activate_generic:n} +%<latexrelease> {Providing~hooks} +%<latexrelease>\cs_gset_protected:Npn \hook_activate_generic:n #1 { } %<latexrelease>\EndIncludeInRelease % \end{macrocode} +% \end{macro} +% \end{macro} % % % \subsection{Parsing a label} @@ -2965,63 +3518,109 @@ % % \subsection{Adding or removing hook code} % -% \begin{macro}{\hook_gput_code:nnn} -% \begin{macro}{\@@_gput_code:nnn,\@@_hook_gput_code_do:nnn} +% \begin{macro}{\hook_gput_code:nnn,\hook_gput_code_with_args:nnn} +% \begin{macro}{ +% \@@_gput_code:nnn, +% \@@_gput_code_store:nnn, +% \@@_hook_gput_code_do:nnn, +% \@@_prop_gput_labeled_cleanup:nnn, +% \@@_prop_gput_labeled_do:Nnnn +% } % % With \cs{hook_gput_code:nnn}\Arg{hook}\Arg{label}\Arg{code} a % chunk of \meta{code} is added to an existing \meta{hook} labeled % with \meta{label}. % \changes{v1.0o}{2021/07/22}{Do not queue removals (gh/625)} +% \changes{v1.1a}{2023/04/06} +% {Add \cs{hook_gput_code_with_args:nnn} (hook-args).} % \begin{macrocode} -\cs_new_protected:Npn \hook_gput_code:nnn #1 #2 - { \@@_normalize_hook_args:Nnn \@@_gput_code:nnn {#1} {#2} } +%<latexrelease>\IncludeInRelease{2023/06/01}{\hook_gput_code_with_args:nnn} +%<latexrelease> {Hooks~with~args} +\cs_new_protected:Npn \hook_gput_code:nnn #1 #2 #3 + { + \@@_replacing_args_false: + \@@_normalize_hook_args:Nnn \@@_gput_code:nnn {#1} {#2} {#3} + \@@_replacing_args_reset: + } +\cs_new_protected:Npn \hook_gput_code_with_args:nnn #1 #2 #3 + { + \@@_replacing_args_true: + \@@_normalize_hook_args:Nnn \@@_gput_code:nnn {#1} {#2} {#3} + \@@_replacing_args_reset: + } % \end{macrocode} % +% If \cs{AddToHookWithArguments} was used, do some sanity checking, +% and if it's not possible to use arguments at this point, fall back +% to regular \cs{AddToHook} by using \cs{@@_replacing_args_false:}. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} \cs_new_protected:Npn \@@_gput_code:nnn #1 #2 #3 { + \@@_chk_args_allowed:nn {#1} { AddToHook } % \end{macrocode} -% First check if the code should be executed immediately, rather than +% Then check if the code should be executed immediately, rather than % stored: % \changes{v1.0r}{2021/09/06}{Use dedicated conditional (gh/606)} % \begin{macrocode} \@@_if_execute_immediately:nTF {#1} - {#3} { % \end{macrocode} +% \cs{AddToHookWithArguments} can't be used on one-time hooks (that +% were already used). +% \begin{macrocode} + \@@_if_replacing_args:TF + { + \msg_error:nnnn { hooks } { one-time-args } + {#1} { AddToHook } + } + { } + \use:n + } + { \@@_gput_code_store:nnn {#1} {#2} } + {#3} + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_gput_code_store:nnn #1 #2 #3 + { +% \end{macrocode} % Then check if the hook is usable. % \begin{macrocode} - \@@_if_usable:nTF {#1} + \@@_if_usable:nTF {#1} % \end{macrocode} % If so we simply add (or append) the new code to the property list % holding different chunks for the hook. At \verb=\begin{document}= % this is then sorted into a token list for fast execution. % \begin{macrocode} - { - \@@_hook_gput_code_do:nnn {#1} {#2} {#3} + { + \@@_hook_gput_code_do:nnn {#1} {#2} {#3} % \end{macrocode} % However, if there is an update within the document we need to alter % this execution code which is done by % \cs{@@_update_hook_code:n}. In the preamble this does nothing. % \begin{macrocode} - \@@_update_hook_code:n {#1} - } + \@@_update_hook_code:n {#1} + } % \end{macrocode} % % If the hook is not usable, before giving up, check if it's not % disabled and otherwise try to declare it as a generic hook, if its % name matches one of the valid patterns. % \begin{macrocode} - { - \@@_if_disabled:nTF {#1} - { \msg_error:nnn { hooks } { hook-disabled } {#1} } - { \@@_try_declaring_generic_hook:nnn {#1} {#2} {#3} } - } + { + \@@_if_disabled:nTF {#1} + { \msg_error:nnn { hooks } { hook-disabled } {#1} } + { \@@_try_declaring_generic_hook:nnn {#1} {#2} {#3} } } } % \end{macrocode} % % This macro will unconditionally add a chunk of code to the given hook. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} \cs_new_protected:Npn \@@_hook_gput_code_do:nnn #1 #2 #3 { @@ -3046,42 +3645,172 @@ \str_if_eq:eeTF { top-level } { \@@_currname_or_default: } { % \end{macrocode} -% If the hook's basic structure does not exist, we need to declare it -% with \cs{@@_init_structure:n}. +% If the hook's basic structure does not exist, we need to declare it +% with \cs{@@_init_structure:n}. % \begin{macrocode} \@@_init_structure:n {#1} - \@@_tl_gput_right:cn { @@_toplevel~#1 } {#3} +% \end{macrocode} +% Then append to the \verb|_toplevel| container for the hook. +% \begin{macrocode} + \@@_cs_gput_right:nnn { _toplevel } {#1} {#3} } { \msg_error:nnn { hooks } { misused-top-level } {#1} } } { - \prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl +% \end{macrocode} +% When adding to the code pool, we have to double hashes if +% \cs{AddToHook} was used (\verb|replacing_args| is false), so that +% later it is turned into a single parameter token, rather than a +% parameter to the hook macro. +% \begin{macrocode} + \exp_args:Nx \@@_prop_gput_labeled_cleanup:nnn { - \prop_gput:cno { g_@@_#1_code_prop } {#2} - { \l_@@_return_tl #3 } + \@@_if_replacing_args:TF + { \exp_not:n } + { \@@_double_hashes:n } + {#3} } - { \prop_gput:cnn { g_@@_#1_code_prop } {#2} {#3} } + {#1} {#2} } } % \end{macrocode} -% \end{macro} -% \end{macro} % -% \begin{macro}{\@@_gput_undeclared_hook:nnn} -% Often it may happen that a package $A$ defines a hook \verb=foo=, -% but package $B$, that adds code to that hook, is loaded before $A$. -% In such case we need to add code to the hook before its declared. +% Adds code to a hook's code pool. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} % \begin{macrocode} -\cs_new_protected:Npn \@@_gput_undeclared_hook:nnn #1 #2 #3 +\cs_new_protected:Npn \@@_prop_gput_labeled_cleanup:nnn #1 #2 #3 { - \@@_init_structure:n {#1} - \@@_hook_gput_code_do:nnn {#1} {#2} {#3} + \tl_set:Nn \l_@@_return_tl {#1} + \@@_if_replacing_args:TF + { + \@@_if_usable:nT {#2} + { + \@@_set_normalise_fn:nn {#2} + { Invalid~code~added~\msg_line_context: } + \@@_normalise_fn:nn {#3} {#1} + \prop_get:NnN \l_@@_work_prop {#3} \l_@@_return_tl + } + } + { } + \exp_args:NcV \@@_prop_gput_labeled_do:Nnn + { g_@@_#2_code_prop } \l_@@_return_tl {#3} + } +\cs_new_protected:Npn \@@_prop_gput_labeled_do:Nnn #1 #2 #3 + { + \prop_get:NnNTF #1 {#3} \l_@@_return_tl + { \prop_gput:Nno #1 {#3} { \l_@@_return_tl #2 } } + { \prop_gput:Nnn #1 {#3} {#2} } } % \end{macrocode} -% \end{macro} -% -% \begin{macro}{\@@_try_declaring_generic_hook:nnn, -% \@@_try_declaring_generic_next_hook:nn} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{\hook_gput_code:nnn} +%<latexrelease> {Providing~hooks} +%<latexrelease>\cs_gset_protected:Npn \hook_gput_code:nnn #1 #2 +%<latexrelease> { \@@_normalize_hook_args:Nnn \@@_gput_code:nnn {#1} {#2} } +%<latexrelease>\cs_gset_protected:Npn \@@_gput_code:nnn #1 #2 #3 +%<latexrelease> { +%<latexrelease> \@@_if_execute_immediately:nTF {#1} +%<latexrelease> {#3} +%<latexrelease> { +%<latexrelease> \@@_if_usable:nTF {#1} +%<latexrelease> { +%<latexrelease> \@@_hook_gput_code_do:nnn {#1} {#2} {#3} +%<latexrelease> \@@_update_hook_code:n {#1} +%<latexrelease> } +%<latexrelease> { +%<latexrelease> \@@_if_disabled:nTF {#1} +%<latexrelease> { \msg_error:nnn { hooks } { hook-disabled } {#1} } +%<latexrelease> { \@@_try_declaring_generic_hook:nnn {#1} {#2} {#3} } +%<latexrelease> } +%<latexrelease> } +%<latexrelease> } +%<latexrelease>\cs_gset_protected:Npn \@@_hook_gput_code_do:nnn #1 #2 #3 +%<latexrelease> { +%<latexrelease> \@@_debug:n{\iow_term:x{****~ Add~ to~ +%<latexrelease> \@@_if_usable:nF {#1} { undeclared~ } +%<latexrelease> hook~ #1~ (#2) +%<latexrelease> \on@line\space <-~ \tl_to_str:n{#3}} } +%<latexrelease> \str_if_eq:nnTF {#2} { top-level } +%<latexrelease> { +%<latexrelease> \str_if_eq:eeTF { top-level } { \@@_currname_or_default: } +%<latexrelease> { +%<latexrelease> \@@_init_structure:n {#1} +%<latexrelease> \@@_tl_gput_right:cn { @@_toplevel~#1 } {#3} +%<latexrelease> } +%<latexrelease> { \msg_error:nnn { hooks } { misused-top-level } {#1} } +%<latexrelease> } +%<latexrelease> { +%<latexrelease> \prop_get:cnNTF { g_@@_#1_code_prop } {#2} \l_@@_return_tl +%<latexrelease> { +%<latexrelease> \prop_gput:cno { g_@@_#1_code_prop } {#2} +%<latexrelease> { \l_@@_return_tl #3 } +%<latexrelease> } +%<latexrelease> { \prop_gput:cnn { g_@@_#1_code_prop } {#2} {#3} } +%<latexrelease> } +%<latexrelease> } +%<latexrelease>\cs_gset_protected:Npn \hook_gput_code_with_args:nnn #1#2#3 { } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_chk_args_allowed:nn} +% This macro checks if it is possible to add code with references to +% a hook's arguments for hook \verb|#1|. It only does something if +% the function being run is \verb|replacing_args|. This macro will +% error if the hook is declared and takes no arguments, then it will +% set \cs{@@_replacing_args_false:} so that the macro which called it +% will add the code normally. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_chk_args_allowed:nn} +%<latexrelease> {Hooks~with~args} +\cs_new_protected:Npn \@@_chk_args_allowed:nn #1 #2 + { + \@@_if_replacing_args:TF + { + \@@_if_declared:nT {#1} + { \tl_if_empty:cT { c_@@_#1_parameter_tl } { \use_ii:nn } } + \use_none:n + { + \msg_error:nnnn { hooks } { without-args } {#1} {#2} + \@@_replacing_args_false: + } + } + { } + } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_chk_args_allowed:nn} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_undefine:N \@@_chk_args_allowed:nn +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_gput_undeclared_hook:nnn} +% Often it may happen that a package $A$ defines a hook \verb=foo=, +% but package $B$, that adds code to that hook, is loaded before $A$. +% In such case we need to add code to the hook before its declared. +% An implicitly declared hook doesn't have arguments (in principle), +% so use \cs{c_false_bool} here. +% \begin{macrocode} +\cs_new_protected:Npn \@@_gput_undeclared_hook:nnn #1 #2 #3 + { + \@@_init_structure:n {#1} + \@@_hook_gput_code_do:nnn {#1} {#2} {#3} + } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_try_declaring_generic_hook:nnn, +% \@@_try_declaring_generic_next_hook:nn} % % These entry-level macros just pass the arguments along to the % common \cs{@@_try_declaring_generic_hook:nNNnn} with the right @@ -3098,24 +3827,43 @@ % \cs{hook_gput_next_code:nn} if the generic hook was declared, or % to \cs{@@_gput_next_do:nn} otherwise. % \changes{v1.0p}{2021/08/25}{Standardise generic hook names (gh/648)} +% \changes{v1.1d}{2023/05/21} +% {Changes to allow support arguments in cmd hooks (cmd-args).} % \begin{macrocode} -%<latexrelease>\IncludeInRelease{2021/11/15}{\@@_try_declaring_generic_hook:nnn} -%<latexrelease> {Standardise~generic~hook~names} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_try_declaring_generic_hook:nnn} +%<latexrelease> {Hooks~with~args} \cs_new_protected:Npn \@@_try_declaring_generic_hook:nnn #1 { \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1} - \hook_gput_code:nnn + \@@_gput_code:nnn \@@_gput_undeclared_hook:nnn {#1} } \cs_new_protected:Npn \@@_try_declaring_generic_next_hook:nn #1 { \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1} - \hook_gput_next_code:nn + \@@_gput_next_code:nn \@@_gput_next_do:nn {#1} } %<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2021/11/15}{\@@_try_declaring_generic_hook:nnn} +%<latexrelease> {Standardise~generic~hook~names} +%<latexrelease>\cs_gset_protected:Npn \@@_try_declaring_generic_hook:nnn #1 +%<latexrelease> { +%<latexrelease> \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1} +%<latexrelease> \hook_gput_code:nnn +%<latexrelease> \@@_gput_undeclared_hook:nnn +%<latexrelease> {#1} +%<latexrelease> } +%<latexrelease>\cs_gset_protected:Npn \@@_try_declaring_generic_next_hook:nn #1 +%<latexrelease> { +%<latexrelease> \@@_try_declaring_generic_hook:wnTF #1 / / / \scan_stop: {#1} +%<latexrelease> \hook_gput_next_code:nn +%<latexrelease> \@@_gput_next_do:nn +%<latexrelease> {#1} +%<latexrelease> } +%<latexrelease>\EndIncludeInRelease %<latexrelease>\IncludeInRelease{2020/10/01}{\@@_try_declaring_generic_hook:nnn} %<latexrelease> {Standardise~generic~hook~names} %<latexrelease>\cs_new_protected:Npn \@@_try_declaring_generic_hook:nnn #1 @@ -3170,9 +3918,11 @@ % \end{macro} % % \begin{macro}[TF]{\@@_try_declaring_generic_hook:wn} +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} -%<latexrelease>\IncludeInRelease{2021/11/15}{\@@_try_declaring_generic_hook:wn}% -%<latexrelease> {Standardise~generic~hook~names} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_try_declaring_generic_hook:wn} +%<latexrelease> {Hooks~with~args} \prg_new_protected_conditional:Npnn \@@_try_declaring_generic_hook:wn #1 / #2 / #3 / #4 \scan_stop: #5 { TF } { @@ -3188,18 +3938,25 @@ % For some commands this will not be possible, in which case % \cs{@@_patch_cmd_or_delay:Nnn} (defined in \texttt{ltcmdhooks}) % will generate an appropriate error message. +% \changes{v1.1d}{2023/05/21} +% {Changes to allow support arguments in cmd hooks (cmd-args).} % \begin{macrocode} \str_if_eq:nnT {#1} { cmd } - { \@@_try_put_cmd_hook:n {#5} } + { + \@@_try_put_cmd_hook:n {#5} + \@@_make_usable:nn {#5} { 9 } + \use_none:nnn + } % \end{macrocode} % % Declare the hook always even if it can't really be used (error % message generated elsewhere). % -% Here we use \cs{@@_make_usable:n}, so that a \cs{hook_new:n} is still -% possible later. +% Here we use \cs{@@_make_usable:nn}, so that a \cs{hook_new:n} is +% still possible later. Generic hooks (except \hook{cmd} hooks) take +% no arguments, so use zero as the second argument. % \begin{macrocode} - \@@_make_usable:n {#5} + \@@_make_usable:nn {#5} { 0 } } \@@_if_generic_reversed:nT {#5} { \tl_gset:cn { g_@@_#5_reversed_tl } { - } } @@ -3285,6 +4042,37 @@ % \end{macro} % % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2021/11/15}{\@@_try_declaring_generic_hook:wn} +%<latexrelease> {Standardise~generic~hook~names} +%<latexrelease>\prg_new_protected_conditional:Npnn \@@_try_declaring_generic_hook:wn +%<latexrelease> #1 / #2 / #3 / #4 \scan_stop: #5 { TF } +%<latexrelease> { +%<latexrelease> \@@_if_generic:nTF {#5} +%<latexrelease> { +%<latexrelease> \@@_if_usable:nF {#5} +%<latexrelease> { +%<latexrelease> \str_if_eq:nnT {#1} { cmd } +%<latexrelease> { \@@_try_put_cmd_hook:n {#5} } +%<latexrelease> \@@_make_usable:n {#5} +%<latexrelease> } +%<latexrelease> \@@_if_generic_reversed:nT {#5} +%<latexrelease> { \tl_gset:cn { g_@@_#5_reversed_tl } { - } } +%<latexrelease> \prg_return_true: +%<latexrelease> } +%<latexrelease> { +%<latexrelease> \@@_if_deprecated_generic:nTF {#5} +%<latexrelease> { +%<latexrelease> \@@_deprecated_generic_warn:n {#5} +%<latexrelease> \exp_after:wN \@@_declare_deprecated_generic:NNn +%<latexrelease> \exp:w % \exp_end: +%<latexrelease> } +%<latexrelease> { \prg_return_false: } +%<latexrelease> } +%<latexrelease> } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} %<latexrelease>\IncludeInRelease{2021/06/01}{\@@_try_declaring_generic_hook:wn} %<latexrelease> {Support~cmd~hooks} %<latexrelease>\prg_new_protected_conditional:Npnn \@@_try_declaring_generic_hook:wn @@ -3316,7 +4104,7 @@ % \end{macrocode} % % \begin{macrocode} -%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_try_declaring_generic_hook:wn}% +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_try_declaring_generic_hook:wn} %<latexrelease> {Support~cmd~hooks} %<latexrelease>\prg_new_protected_conditional:Npnn \@@_try_declaring_generic_hook:wn %<latexrelease> #1 / #2 / #3 / #4 \scan_stop: #5 { TF } @@ -3338,7 +4126,6 @@ %<latexrelease> { \prg_return_false: } %<latexrelease> } %<latexrelease> } -%<latexrelease> %<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} @@ -3350,24 +4137,10 @@ % |file/foo.tex/before|). If it is a file-specific hook, then it % executes the \meta{true} branch, otherwise \meta{false}. % \begin{macrocode} -%<latexrelease>\IncludeInRelease{2021/11/15}{\@@_if_file_hook:w}% +%<latexrelease>\IncludeInRelease{2021/11/15}{\@@_if_file_hook:w} %<latexrelease> {Standardise~generic~hook~names} -\prg_new_conditional:Npnn \@@_if_file_hook:w - #1 / #2 \s_@@_mark #3 { TF } - { - \@@_if_generic:nTF {#3} - { - \str_if_eq:nnTF {#1} { file } - { \prg_return_true: } - { \prg_return_false: } - } - { \prg_return_false: } - } %<latexrelease>\EndIncludeInRelease -% \end{macrocode} -% -% \begin{macrocode} -%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_if_file_hook:w}% +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_if_file_hook:w} %<latexrelease> {Standardise~generic~hook~names} %<latexrelease>\prg_new_conditional:Npnn \@@_if_file_hook:w %<latexrelease> #1 / #2 / #3 \s_@@_mark { TF } @@ -3394,7 +4167,7 @@ % \begin{macro}[EXP]{\@@_strip_double_slash:n,\@@_strip_double_slash:w} % % \begin{macrocode} -%<latexrelease>\IncludeInRelease{2021/11/15}{\@@_file_hook_normalize:n}% +%<latexrelease>\IncludeInRelease{2021/11/15}{\@@_file_hook_normalize:n} %<latexrelease> {Standardise~generic~hook~names} %<latexrelease>\EndIncludeInRelease % \end{macrocode} @@ -3406,7 +4179,7 @@ % like \verb|\def\input@path{{./mypath/}}|, in which case a hook would % have to be \verb|\AddToHook{file/./mypath//file.tex/after}|. % \begin{macrocode} -%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_file_hook_normalize:n}% +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_file_hook_normalize:n} %<latexrelease> {Standardise~generic~hook~names} %<latexrelease>\cs_new:Npn \@@_file_hook_normalize:n #1 %<latexrelease> { \@@_strip_double_slash:n {#1} } @@ -3453,7 +4226,7 @@ % The generic hooks used when loading a file % \end{description} % \begin{macrocode} -%<latexrelease>\IncludeInRelease{2021/11/15}{\c_@@_generics_prop}% +%<latexrelease>\IncludeInRelease{2021/11/15}{\c_@@_generics_prop} %<latexrelease> {Standardise~generic~hook~names} \clist_map_inline:nn { cmd , env , file , package , class , include } { @@ -3482,7 +4255,7 @@ % \end{macrocode} % % \begin{macrocode} -%<latexrelease>\IncludeInRelease{2020/10/01}{\c_@@_generics_prop}% +%<latexrelease>\IncludeInRelease{2020/10/01}{\c_@@_generics_prop} %<latexrelease> {Standardise~generic~hook~names} %<latexrelease>\prop_const_from_keyval:Nn \c_@@_generics_prop %<latexrelease> {cmd=,env=,file=,package=,class=,include=} @@ -3496,13 +4269,13 @@ % The following generic hooks are supposed to use reverse ordering % (the |ii| and |iii| names are kept for the deprecation cycle): % \begin{macrocode} -%<latexrelease>\IncludeInRelease{2021/11/15}{\c_@@_generics_reversed_ii_prop}% +%<latexrelease>\IncludeInRelease{2021/11/15}{\c_@@_generics_reversed_ii_prop} %<latexrelease> {Standardise~generic~hook~names} %<latexrelease>\EndIncludeInRelease % \end{macrocode} % % \begin{macrocode} -%<latexrelease>\IncludeInRelease{2020/10/01}{\c_@@_generics_reversed_ii_prop}% +%<latexrelease>\IncludeInRelease{2020/10/01}{\c_@@_generics_reversed_ii_prop} %<latexrelease> {Standardise~generic~hook~names} %<latexrelease>\prop_const_from_keyval:Nn \c_@@_generics_reversed_ii_prop {after=,end=} %<latexrelease>\prop_const_from_keyval:Nn \c_@@_generics_reversed_iii_prop {after=} @@ -3511,13 +4284,46 @@ % \end{macrocode} % \end{macro} % +% +% \begin{macro}{ +% \c_@@_parameter_cmd/./before_tl,\c_@@_parameter_cmd/./after_tl, +% } +% Token lists defining the number of arguments for a given type of +% generic hook. +% \changes{v1.1d}{2023/05/21} +% {Token lists added (cmd-args).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\c_@@_parameter_cmd/./before_tl} +%<latexrelease> {Hooks~with~args} +% \end{macrocode} +% +% \hook{cmd} hooks are declared with 9 arguments because they have a +% variable number of arguments (depending on the command they are +% attached to), so we use the maximum here. +% \begin{macrocode} +\tl_const:cn { c_@@_parameter_cmd/./before_tl } { #1#2#3#4#5#6#7#8#9 } +\tl_const:cn { c_@@_parameter_cmd/./after_tl } { #1#2#3#4#5#6#7#8#9 } +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\c_@@_parameter_cmd/./before_tl} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\hook_gremove_code:nn} % \begin{macro}{\@@_gremove_code:nn} % % With \cs{hook_gremove_code:nn}\Arg{hook}\Arg{label} any code % for \meta{hook} stored under \meta{label} is removed. % \changes{v1.0o}{2021/07/22}{Do not queue removals (gh/625)} +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\hook_gremove_code:nn} +%<latexrelease> {Hooks~with~args} \cs_new_protected:Npn \hook_gremove_code:nn #1 #2 { \@@_normalize_hook_args:Nnn \@@_gremove_code:nn {#1} {#2} } \cs_new_protected:Npn \@@_gremove_code:nn #1 #2 @@ -3542,8 +4348,8 @@ \str_if_eq:nnTF {#2} {*} { \prop_gclear:c { g_@@_#1_code_prop } - \@@_tl_gclear:c { @@_toplevel~#1 } - \@@_tl_gclear:c { @@_next~#1 } + \@@_toplevel_gset:nn {#1} { } + \@@_next_gset:nn {#1} { } } { % \end{macrocode} @@ -3551,7 +4357,7 @@ % there is under the same label. % \begin{macrocode} \str_if_eq:nnTF {#2} { top-level } - { \@@_tl_gclear:c { @@_toplevel~#1 } } + { \@@_toplevel_gset:nn {#1} { } } { \prop_gpop:cnNF { g_@@_#1_code_prop } {#2} \l_@@_return_tl { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} } @@ -3576,14 +4382,568 @@ { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} } } } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\hook_gremove_code:nn} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_new_protected:Npn \@@_gremove_code:nn #1 #2 +%<latexrelease> { +%<latexrelease> \@@_if_structure_exist:nTF {#1} +%<latexrelease> { +%<latexrelease> \str_if_eq:nnTF {#2} {*} +%<latexrelease> { +%<latexrelease> \prop_gclear:c { g_@@_#1_code_prop } +%<latexrelease> \@@_tl_gclear:c { @@_toplevel~#1 } +%<latexrelease> \@@_tl_gclear:c { @@_next~#1 } +%<latexrelease> } +%<latexrelease> { +%<latexrelease> \str_if_eq:nnTF {#2} { top-level } +%<latexrelease> { \@@_tl_gclear:c { @@_toplevel~#1 } } +%<latexrelease> { +%<latexrelease> \prop_gpop:cnNF { g_@@_#1_code_prop } {#2} \l_@@_return_tl +%<latexrelease> { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} } +%<latexrelease> } +%<latexrelease> } +%<latexrelease> \@@_if_usable:nT {#1} +%<latexrelease> { \@@_update_hook_code:n {#1} } +%<latexrelease> } +%<latexrelease> { +%<latexrelease> \@@_if_deprecated_generic:nTF {#1} +%<latexrelease> { +%<latexrelease> \@@_deprecated_generic_warn:n {#1} +%<latexrelease> \@@_do_deprecated_generic:Nn \@@_gremove_code:nn {#1} {#2} +%<latexrelease> } +%<latexrelease> { \msg_warning:nnnn { hooks } { cannot-remove } {#1} {#2} } +%<latexrelease> } +%<latexrelease> } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_cs_gput_right:nnn} +% \begin{macro}{\@@_cs_gput_right_fast:nnn,\@@_cs_gput_right_slow:nnn} +% \begin{macro}{\@@_code_gset_auxi:nnnn,\@@_code_gset_auxi:eeen} +% This macro is used to append code to the \verb|toplevel| and +% \verb|next| token lists, trating them correctly depending on their +% number of arguments, and depending if the code being added should +% have parameter tokens understood as parameters, or doubled to be +% stored as parameter tokens. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \changes{v1.1e}{2023/06/06} +% {Short-circuit when the hook is declared without args (gh1078).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_cs_gput_right:nnn} +%<latexrelease> {Hooks~with~args} +% \end{macrocode} +% +% Check if the current hook is declared and takes no arguments. In +% this case, we short-circuit and use the simpler and much faster +% approach that doesn't require hash-doubling. +% \begin{macrocode} +\cs_new_protected:Npn \@@_cs_gput_right:nnn #1 #2 + { + \if:w T + \@@_if_declared:nF {#2} { F } + \tl_if_empty:cF { c_@@_#2_parameter_tl } { F } + T + \exp_after:wN \@@_cs_gput_right_fast:nnn + \else: + \exp_after:wN \@@_cs_gput_right_slow:nnn + \fi: + {#1} {#2} + } +\cs_new_protected:Npn \@@_cs_gput_right_fast:nnn #1 #2 #3 + { \cs_gset:cpx { @@#1~#2 } { \exp_not:v { @@#1~#2 } \exp_not:n {#3} } } +\cs_new_protected:Npn \@@_cs_gput_right_slow:nnn #1 #2 #3 + { +% \end{macrocode} +% The auxiliary \cs{@@_code_gset_auxi:eeen} just does the assignment +% at the end. Its first argument is the parameter text of the macro, +% which is chosen here depending if +% \cs[no-index]{c_@@_\meta{hook}_parameter_tl} exists, if the hook is +% declared, and if it's a generic hook. +% \begin{macrocode} + \cs_if_exist:cF { @@#1~#2 } + { \@@_code_gset_aux:nnn {#1} {#2} { } } + \@@_code_gset_auxi:eeen + { + \@@_if_declared:nTF {#2} + { \tl_use:c { c_@@_#2_parameter_tl } } + { + \@@_if_generic:nTF {#2} + { \@@_generic_parameter:n {#2} } + { \c_@@_nine_parameters_tl } + } + } +% \end{macrocode} +% Here we take the existing code in the macro, expand it with as many +% arguments as it takes, then double the hashes so the code can be +% reused. \pho{Maybe can be improved. The case of adding to an empty +% cs can be optimised by quickly checking \cs{cs_replacement_spec}.} +% \begin{macrocode} + { + \exp_args:NNo \exp_args:No \@@_double_hashes:n + { + \cs:w @@#1~#2 \exp_last_unbraced:Ne \cs_end: + { \@@_braced_cs_parameter:n { @@#1~#2 } } + } + } +% \end{macrocode} +% Now the new code: if we are replacing arguments, then hashes are +% left untouched, otherwise they are doubled. +% \begin{macrocode} + { + \@@_if_replacing_args:TF + { \exp_not:n } + { \@@_double_hashes:n } + {#3} + } +% \end{macrocode} +% And finally, the csname which we'll define with all the above. +% \begin{macrocode} + { @@#1~#2 } + } +% \end{macrocode} +% +% And as promised, the auxiliary that does the definition. +% \begin{macrocode} +\cs_new_protected:Npn \@@_code_gset_auxi:nnnn #1 #2 #3 #4 + { \cs_gset:cpn {#4} #1 { #2 #3 } } +\cs_generate_variant:Nn \@@_code_gset_auxi:nnnn { eeen } % \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_cs_gput_right:nnn} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_undefine:N \@@_cs_gput_right:nnn +%<latexrelease>\cs_undefine:N \@@_cs_gput_right_fast:nnn +%<latexrelease>\cs_undefine:N \@@_cs_gput_right_slow:nnn +%<latexrelease>\cs_undefine:N \@@_code_gset_auxi:nnnn +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} % \end{macro} % \end{macro} % % \begin{macro}{ +% \@@_code_gset:nn,\@@_code_gset:ne, +% \@@_toplevel_gset:nn, +% \@@_next_gset:nn, +% \@@_code_gset_aux:nnn +% } +% These macros define +% \cs[no-index]{@@\meta{type}\textvisiblespace\meta{hook}} (with +% \meta{type} being \verb|_next|, \verb|_toplevel|, or empty) with the +% given code and the parameters stored in +% \cs[no-index]{c_@@_\meta{hook}_parameter_tl} (or none, if that +% doesn't exist). +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_code_gset:nn} +%<latexrelease> {Hooks~with~args} +\cs_new_protected:Npn \@@_code_gset:nn + { \@@_code_gset_aux:nnn { } } +\cs_new_protected:Npn \@@_toplevel_gset:nn + { \@@_code_gset_aux:nnn { _toplevel } } +\cs_new_protected:Npn \@@_next_gset:nn + { \@@_code_gset_aux:nnn { _next } } +\cs_new_protected:Npn \@@_code_gset_aux:nnn #1 #2 #3 + { + \cs_gset:cpn { @@#1~#2 \exp_last_unbraced:Ne } + { \@@_parameter:n {#2} } + {#3} + } +\cs_generate_variant:Nn \@@_code_gset:nn { ne } +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_code_gset:nn} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_undefine:N \@@_code_gset:nn +%<latexrelease>\cs_undefine:N \@@_toplevel_gset:nn +%<latexrelease>\cs_undefine:N \@@_next_gset:nn +%<latexrelease>\cs_undefine:N \@@_code_gset_aux:nnn +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_normalise_cs_args:nn} +% This macro normalises the parameters of the macros +% \cs[no-index]{@@\meta{type}\textvisiblespace\meta{hook}} to take the +% right number of arguments after a hook is declared. At this point +% we know \cs[no-index]{c_@@_\meta{hook}_parameter_tl} exists, so use +% that to count the arguments and use that as \meta{parameter text} +% for the newly (re)defined macro. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_normalise_cs_args:nn} +%<latexrelease> {Hooks~with~args} +\cs_new_protected:Npn \@@_normalise_cs_args:nn #1 #2 + { + \cs_if_exist:cT { @@#1~#2 } + { + \@@_code_gset_auxi:eeen + { \tl_use:c { c_@@_#2_parameter_tl } } + { + \exp_args:NNo \exp_args:No \@@_double_hashes:n + { + \cs:w @@#1~#2 \exp_last_unbraced:Ne \cs_end: + { \@@_braced_cs_parameter:n { @@#1~#2 } } + } + } + { } + { @@#1~#2 } + } + } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_normalise_cs_args:nn} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_undefine:N \@@_normalise_cs_args:nn +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_normalise_code_pool:n} +% \begin{macro}{\@@_set_normalise_fn:nn} +% This one's a bit of a hack. It takes a hook, and iterates over its +% code pool (\cs[no-index]{g_@@_\meta{hook}_code_prop}), redefining +% each code label to use only valid arguments. This is used when, for +% example, a code is added referencing arguments \verb|#1| and +% \verb|#2|, but the hook has only \verb|#1|. In this example, every +% reference to \verb|#2| is changed to \verb|##2|. This is done +% because otherwise \TeX{} will throw a low-level error every time +% some change happens to the hook (code is added, a rule is set, etc), +% which can get quite repetitive for no good reason. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_normalise_code_pool:n} +%<latexrelease> {Hooks~with~args} +\cs_new_protected:Npn \@@_normalise_code_pool:n #1 + { +% \end{macrocode} +% First, call \cs{@@_set_normalise_fn:nn} with the hook name to set +% everything up, then we'll loop over the +% hook's code pool applying the normalisation above. After that's +% done, copy the temporary property list back to the hook's. +% \begin{macrocode} + \@@_set_normalise_fn:nn {#1} { Offending~label:~'##1' } + \prop_clear:N \l_@@_work_prop + \prop_map_function:cN { g_@@_#1_code_prop } \@@_normalise_fn:nn + \prop_gset_eq:cN { g_@@_#1_code_prop } \l_@@_work_prop + } +% \end{macrocode} +% +% The sole purpose of this function is to define +% \cs{@@_normalise_fn:nn}, which will then do the correcting of the +% code being added to the hook. +% \begin{macrocode} +\cs_new_protected:Npn \@@_set_normalise_fn:nn #1 #2 + { +% \end{macrocode} +% To start, we define two auxiliary token lists. +% \cs[no-index]{l_@@_tmpb_tl} contains: +%\begin{verbatim} +% {\c__hook_hashes_tl 1} +% {\c__hook_hashes_tl 2} +% ... +% {\c__hook_hashes_tl 9} +%\end{verbatim} +% \begin{macrocode} + \cs_set:Npn \@@_tmp:w ##1##2##3##4##5##6##7##8##9 { } + \tl_set:Ne \l_@@_tmpb_tl + { \@@_braced_cs_parameter:n { @@_tmp:w } } + \group_begin: + \@@_tl_set:cn { c_@@_hash_tl } { \exp_not:N \c_@@_hashes_tl } + \use:e + { + \group_end: + \tl_set:Nn \exp_not:N \l_@@_tmpb_tl { \l_@@_tmpb_tl } + } +% \end{macrocode} +% And \cs[no-index]{l_@@_tmpa_tl} contains: +%\begin{verbatim} +% {\c__hook_hash_tl 1} +% {\c__hook_hash_tl 2} +% ... +% {\c__hook_hash_tl <n>} +%\end{verbatim} +% with \meta{n} being the number of arguments declared for the hook. +% \begin{macrocode} + \exp_last_unbraced:NNf + \cs_set:Npn \@@_tmp:w { \@@_parameter:n {#1} } { } + \tl_set:Ne \l_@@_tmpa_tl { \@@_braced_cs_parameter:n { @@_tmp:w } } +% \end{macrocode} +% Now this function does the fun part. It is meant to be used with +% \cs{prop_map_function:NN}, taking a label name in \verb|##1| and the +% code stored in that label in \verb|##2|. +% \begin{macrocode} + \cs_gset_protected:Npx \@@_normalise_fn:nn ##1 ##2 + { +% \end{macrocode} +% Here we'll define two auxiliary macros: the first one throws an +% error when it detects an invalid argument reference. It piggybacks +% on \TeX's low-level \enquote{Illegal parameter number} error, but it +% defines a weirdly-named control sequence so that the error comes out +% nicely formatted. For example, if the label \enquote{badpkg} adds +% some code that references argument \verb|#3| in the hook +% \enquote{foo}, which takes only two arguments, the error will be: +%\begin{verbatim} +% ! Illegal parameter number in definition of hook 'foo'. +% (hooks) Offending label: 'badpkg'. +% <to be read again> +% 3 +%\end{verbatim} +% At the point of this definition, the error is raised if the code +% happens to reference an invalid argument. If it was possible to +% detect that this definition raised no error, the next step would be +% unnecessary. We'll do all this in a group so this weird definition +% doesn't leak out, and set \cs{tex_escapechar:D} to $-1$ so this hack +% shows up extra nice in the case of an error. +% \begin{macrocode} + \group_begin: + \int_set:Nn \tex_escapechar:D { -1 } + \cs_set:cpn + { + hook~'#1'. ^^J + (hooks) \prg_replicate:nn { 13 } { ~ } + #2 % more message text + } + \exp_not:v { c_@@_#1_parameter_tl } + {##2} + \group_end: +% \end{macrocode} +% This next macro, with a much less fabulous name, takes always nine +% arguments, and it just transfers the code \verb|##2| under the label +% \verb|##1| to the temporary property list. The first \meta{n} +% arguments are taken from \cs[no-index]{l_@@_tmpa_tl}, and the other +% $9-\meta{n}$ taken from \cs[no-index]{l_@@_tmpb_tl} (which contains +% twice as many \verb|#| tokens as the former). Then, +% \cs{@@_double_hashes:n} is used to double non-argument hashes, and +% expand the \cs{c_@@_hash_tl} and \cs{c_@@_hashes_tl} to the actual +% parameter tokens. +% \begin{macrocode} + \cs_set:Npn \exp_not:N \@@_tmp:w + \exp_not:V \c_@@_nine_parameters_tl + { + \prop_put:Nne \exp_not:N \l_@@_work_prop + {##1} { \exp_not:N \@@_double_hashes:n {##2} } + } +% \end{macrocode} +% This next macro, with a much less fabulous name, takes always nine +% arguments, and it just transfers the code \verb|##2| under the label +% \verb|##1| to the temporary property list. The first \meta{n} +% arguments are taken from \cs[no-index]{l_@@_tmpa_tl}, and the other +% $9-\meta{n}$ taken from \cs[no-index]{l_@@_tmpb_tl} (which contains +% twice as many \verb|#| tokens as the former). Then, +% \cs{@@_double_hashes:n} is used to double non-argument hashes, and +% expand the \cs{c_@@_hash_tl} and \cs{c_@@_hashes_tl} to the actual +% parameter tokens. +% \begin{macrocode} + \exp_not:N \@@_tmp:w + \exp_not:V \l_@@_tmpa_tl + \exp_args:No \exp_not:o + { \exp_after:wN \@@_tmp:w \l_@@_tmpb_tl } + } + } +\cs_new_eq:NN \@@_normalise_fn:nn ? +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_normalise_code_pool:n} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_undefine:N \@@_normalise_code_pool:n +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[pTF]{\@@_cs_if_empty:c} +% Check if the expansion of a control sequence is empty by looking at +% its replacement text. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_cs_if_empty:c} +%<latexrelease> {Hooks~with~args} +\prg_new_conditional:Npnn \@@_cs_if_empty:c #1 { p, T, F, TF } + { + \if:w \scan_stop: \@@_replacement_spec:c {#1} \scan_stop: + \prg_return_true: + \else: + \prg_return_false: + \fi: + } +\cs_new:Npn \@@_replacement_spec:c #1 + { + \exp_args:Nc \token_if_macro:NT {#1} + { \cs_replacement_spec:c {#1} } + } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_cs_if_empty:c} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_undefine:N \@@_cs_if_empty:c +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_braced_cs_parameter:n} +% \begin{macro}{\@@_braced_hidden_loop:w} +% \begin{macro}{\@@_cs_parameter_count:N} +% \begin{macro}{\@@_cs_parameter_count:w,\@@_cs_end:w} +% Looks at the \meta{parameter text} of a control sequence, and +% returns a run of \enquote{hidden} braced parameters for that macro. +% This works as long as the macros take a simple run of zero to nine +% arguments. The parameters are \enquote{hidden} because the +% parameter tokens are returned inside \cs{c_@@_hash_tl} instead of +% explicitly, so that \cs{@@_double_hashes:n} won't touch these. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_braced_cs_parameter:n} +%<latexrelease> {Hooks~with~args} +\cs_new:Npn \@@_braced_cs_parameter:n #1 + { + \exp_last_unbraced:Ne \@@_braced_hidden_loop:w + { \exp_args:Nc \@@_cs_parameter_count:N {#1} } ? \s_@@_mark + } +\cs_new:Npn \@@_braced_hidden_loop:w #1 + { + \if:w ? #1 + \@@_use_i_delimit_by_s_mark:nw + \fi: + { \exp_not:N \c_@@_hash_tl #1 } + \@@_braced_hidden_loop:w + } +\cs_new:Npn \@@_cs_parameter_count:N #1 + { + \exp_last_unbraced:Nf \@@_cs_parameter_count:w + { \token_if_macro:NT #1 { \cs_parameter_spec:N #1 } } + ? \@@_cs_end:w ? \@@_cs_end:w ? \@@_cs_end:w + ? \@@_cs_end:w ? \@@_cs_end:w ? \@@_cs_end:w + ? \@@_cs_end:w ? \@@_cs_end:w ? \@@_cs_end:w + \s_@@_mark + } +\cs_new:Npn \@@_cs_parameter_count:w #1#2 #3#4 #5#6 #7#8 + { #2 #4 #6 #8 \@@_cs_parameter_count:w } +\cs_new:Npn \@@_cs_end:w #1 \s_@@_mark { } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% This function can't be undefined when rolling back because it's used +% at the end of this module to adequate the hook data structures to +% previous versions. +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_braced_cs_parameter:n} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_braced_parameter:n} +% \begin{macro}{\@@_braced_real_loop:w} +% This one is used in simpler cases, where no special handling of +% hashes is required. This is used only inside +% \cs{@@_initialize_hook_code:n}, so it assumes +% \cs[no-index]{c_@@_\meta{hook}_parameter_tl} is defined, but should +% work otherwise. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_braced_parameter:n} +%<latexrelease> {Hooks~with~args} +\cs_new:Npn \@@_braced_parameter:n #1 + { + \if_case:w + \int_eval:n + { \exp_args:Nv \str_count:n { c_@@_#1_parameter_tl } / 3 } + \exp_stop_f: + \or: {##1} + \or: {##1} {##2} + \or: {##1} {##2} {##3} + \or: {##1} {##2} {##3} {##4} + \or: {##1} {##2} {##3} {##4} {##5} + \or: {##1} {##2} {##3} {##4} {##5} {##6} + \or: {##1} {##2} {##3} {##4} {##5} {##6} {##7} + \or: {##1} {##2} {##3} {##4} {##5} {##6} {##7} {##8} + \or: {##1} {##2} {##3} {##4} {##5} {##6} {##7} {##8} {##9} + \else: + \msg_expandable_error:nnn { latex2e } { should-not-happen } + { Invalid~parameter~spec. } + \fi: + } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_braced_parameter:n} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_undefine:N \@@_braced_parameter:n +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\@@_parameter:n} +% This is just a shortcut to \verb|e|- or \verb|f|-expand to the +% \meta{parameter text} of the hook. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_parameter:n} +%<latexrelease> {Hooks~with~args} +\cs_new:Npn \@@_parameter:n #1 + { + \cs:w c_@@_ + \tl_if_exist:cTF { c_@@_#1_parameter_tl } + { #1_parameter } { empty } + _tl \cs_end: + } +\cs_new:Npn \@@_generic_parameter:n #1 + { \@@_generic_parameter:w #1 / / / \s_@@_mark } +\cs_new:Npn \@@_generic_parameter:w #1 / #2 / #3 / #4 \s_@@_mark + { + \cs_if_exist_use:cF { c_@@_parameter_#1/./#3_tl } + { \c_@@_empty_tl } + } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_parameter:n} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_undefine:N \@@_parameter:n +%<latexrelease>\cs_undefine:N \@@_generic_parameter:n +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% +% +% \subsection{Setting rules for hooks code} +% +% \begin{macro}{ % \g_@@_??_code_prop, % \@@~??, % \g_@@_??_reversed_tl, +% \c_@@_??_parameter_tl, % } % % Initially these variables simply used an empty ``label'' name (not @@ -3597,11 +4957,11 @@ % lot, the code should be fast, so this is not done with \texttt{c} % expansion in the code later on. % -% \cs{@@\textvisiblespace??} isn't used, but it has to be defined to trick -% the code into thinking that \texttt{??} is actually a hook. +% \cs{@@\textvisiblespace??} isn't used, but it has to be defined to +% trick the code into thinking that \texttt{??} is actually a hook. % \begin{macrocode} -\prop_new:c {g_@@_??_code_prop} -\prop_new:c {@@~??} +\prop_new:c { g_@@_??_code_prop } +\prop_new:c { @@~?? } % \end{macrocode} % % Default rules are always given in normal ordering (never in @@ -3610,11 +4970,23 @@ % \texttt{after} becomes \texttt{before}) % because those rules are applied first and then the order is reversed. % \begin{macrocode} -\tl_new:c {g_@@_??_reversed_tl} +\tl_new:c { g_@@_??_reversed_tl } % \end{macrocode} -% \end{macro} % -% \subsection{Setting rules for hooks code} +% The parameter text for the \enquote{default} hook is empty. +% \changes{v1.1a}{2023/04/06} +% {Token list added (hook-args).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\c_@@_??_parameter_tl} +%<latexrelease> {Hooks~with~args} +\tl_const:cn { c_@@_??_parameter_tl } { } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\c_@@_??_parameter_tl} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_undefine:c { c_@@_??_parameter_tl } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} % % \begin{macro}{\hook_gset_rule:nnnn} % \begin{macro}{\@@_gset_rule:nnnn} @@ -3645,13 +5017,13 @@ \@@_deprecated_generic_warn:n {#1} \@@_do_deprecated_generic:Nn \@@_gset_rule:nnnn {#1} {#2} {#3} {#4} - \@@_clean_to_scan:w + \@@_use_none_delimit_by_s_mark:w } \@@_if_execute_immediately:nT {#1} { \msg_error:nnnnnn { hooks } { rule-too-late } {#1} {#2} {#3} {#4} - \@@_clean_to_scan:w + \@@_use_none_delimit_by_s_mark:w } % \end{macrocode} % First we ensure the basic data structure of the hook exists: @@ -3840,44 +5212,82 @@ % \begin{macro}{\@@_initialize_all:} % Initialize all known hooks (at \verb=\begin{document}=), i.e., % update the fast execution token lists to hold the necessary code -% in the right order. +% in the right order. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} -\cs_new_protected:Npn \@@_initialize_all: { +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_initialize_all:} +%<latexrelease> {Hooks~with~args} +\cs_new_protected:Npn \@@_initialize_all: + { % \end{macrocode} % First we change \cs{@@_update_hook_code:n} which so far was a % no-op to now initialize one hook. This way any later updates to % the hook will run that code and also update the execution token % list. % \begin{macrocode} - \cs_gset_eq:NN \@@_update_hook_code:n \@@_initialize_hook_code:n + \cs_gset_eq:NN \@@_update_hook_code:n \@@_initialize_hook_code:n % \end{macrocode} % Now we loop over all hooks that have been defined and update each -% of them. +% of them. Here we have to determine if the hook has arguments so +% that auxiliaries know what to do with hashes. We look at +% \cs[no-index]{c_@@_\meta{hook}_parameter_tl}, if it has any +% parameters, and set \verb|replacing_args| accordingly. % \begin{macrocode} - \@@_debug:n { \prop_gclear:N \g_@@_used_prop } - \seq_map_inline:Nn \g_@@_all_seq + \@@_debug:n { \prop_gclear:N \g_@@_used_prop } + \seq_map_inline:Nn \g_@@_all_seq { + \tl_if_empty:cTF { c_@@_##1_parameter_tl } + { \@@_replacing_args_false: } + { \@@_replacing_args_true: } \@@_update_hook_code:n {##1} + \@@_replacing_args_reset: } % \end{macrocode} % If we are debugging we show results hook by hook for all hooks % that have data. % \begin{macrocode} - \@@_debug:n - { \iow_term:x{^^JAll~ initialized~ (non-empty)~ hooks:} - \prop_map_inline:Nn \g_@@_used_prop - { \iow_term:x{^^J~ ##1~ ->~ - \exp_not:v {@@~##1}~ } - } - } + \@@_debug:n + { + \iow_term:x { ^^J All~initialized~(non-empty)~hooks: } + \prop_map_inline:Nn \g_@@_used_prop + { + \iow_term:x + { ^^J ~ ##1 ~ -> ~ \cs_replacement_spec:c { @@~##1 } ~ } + } + } % \end{macrocode} % After all hooks are initialized we change the ``use'' to just % call the hook code and not initialize it (as it was done in the % preamble. % \begin{macrocode} - \cs_gset_eq:NN \hook_use:n \@@_use_initialized:n - \cs_gset_eq:NN \@@_preamble_hook:n \use_none:n -} + \@@_post_initialization_defs: + } +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_initialize_all:} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_gset_protected:Npn \@@_initialize_all: +%<latexrelease> { +%<latexrelease> \cs_gset_eq:NN \@@_update_hook_code:n \@@_initialize_hook_code:n +%<latexrelease> \@@_debug:n { \prop_gclear:N \g_@@_used_prop } +%<latexrelease> \seq_map_inline:Nn \g_@@_all_seq +%<latexrelease> { \@@_update_hook_code:n {##1} } +%<latexrelease> \@@_debug:n +%<latexrelease> { +%<latexrelease> \iow_term:x{^^JAll~ initialized~ (non-empty)~ hooks:} +%<latexrelease> \prop_map_inline:Nn \g_@@_used_prop +%<latexrelease> { +%<latexrelease> \iow_term:x +%<latexrelease> { ^^J ~ ##1 ~ -> ~ \cs_replacement_spec:c { @@~##1 } ~ } +%<latexrelease> } +%<latexrelease> } +%<latexrelease> \cs_gset_eq:NN \hook_use:n \@@_use_initialized:n +%<latexrelease> \cs_gset_eq:NN \@@_preamble_hook:n \use_none:n +%<latexrelease> } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -3887,7 +5297,11 @@ % the preamble this is selectively done in case a hook gets used % and at \verb=\begin{document}= this is done for all hooks and % afterwards only if the hook code changes. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_initialize_hook_code:n} +%<latexrelease> {Hooks~with~args} \cs_new_protected:Npn \@@_initialize_hook_code:n #1 { \@@_debug:n @@ -3915,10 +5329,15 @@ { \prop_if_empty:cTF { g_@@_#1_code_prop } { - \@@_tl_gset:co { @@~#1 } + \@@_code_gset:ne {#1} { - \cs:w @@_toplevel~#1 \exp_after:wN \cs_end: - \cs:w @@_next~#1 \cs_end: +% \end{macrocode} +% The hook may take arguments, so we add a run of braced parameters +% after the \verb|_next| and \verb|_toplevel| macros, so that the +% arguments passed to the hook are forwarded to them. +% \begin{macrocode} + \exp_not:c { @@_toplevel~#1 } \@@_braced_parameter:n {#1} + \exp_not:c { @@_next~#1 } \@@_braced_parameter:n {#1} } } { @@ -3958,6 +5377,42 @@ } } } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_initialize_hook_code:n} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_gset_protected:Npn \@@_initialize_hook_code:n #1 +%<latexrelease> { +%<latexrelease> \@@_debug:n +%<latexrelease> { \iow_term:x { ^^J Update~code~for~hook~'#1' \on@line :^^J } } +%<latexrelease> \@@_include_legacy_code_chunk:n {#1} +%<latexrelease> \@@_if_usable:nT {#1} +%<latexrelease> { +%<latexrelease> \prop_if_empty:cTF { g_@@_#1_code_prop } +%<latexrelease> { +%<latexrelease> \@@_tl_gset:co { @@~#1 } +%<latexrelease> { +%<latexrelease> \cs:w @@_toplevel~#1 \exp_after:wN \cs_end: +%<latexrelease> \cs:w @@_next~#1 \cs_end: +%<latexrelease> } +%<latexrelease> } +%<latexrelease> { +%<latexrelease> \@@_if_reversed:nTF {#1} +%<latexrelease> { \cs_set_eq:NN \@@_tl_gput:Nn \@@_tl_gput_left:Nn +%<latexrelease> \cs_set_eq:NN \@@_clist_gput:NV \clist_gput_left:NV } +%<latexrelease> { \cs_set_eq:NN \@@_tl_gput:Nn \@@_tl_gput_right:Nn +%<latexrelease> \cs_set_eq:NN \@@_clist_gput:NV \clist_gput_right:NV } +%<latexrelease> \prop_set_eq:Nc \l_@@_work_prop { g_@@_#1_code_prop } +%<latexrelease> \@@_initialize_single:ccn +%<latexrelease> { @@~#1 } { g_@@_#1_labels_clist } {#1} +%<latexrelease> \@@_debug:n +%<latexrelease> { \exp_args:NNx \prop_gput:Nnn \g_@@_used_prop {#1} { } } +%<latexrelease> } +%<latexrelease> } +%<latexrelease> } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -4034,7 +5489,12 @@ % ^^A #1 <- \@@~#1 % ^^A #2 <- \g_@@_#1_labels_clist % ^^A #3 <- #1 +% +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_initialize_single:NNn} +%<latexrelease> {Hooks~with~args} \cs_new_protected:Npn \@@_initialize_single:NNn #1#2#3 { % \end{macrocode} @@ -4181,15 +5641,103 @@ % time execution (\verb=#3=). These should normally be empty. The % |top-level| code is added with \cs{@@_tl_gput:Nn} as that might % change for a reversed hook (then |top-level| is the very first code -% chunk added). The |next| code is always added last. -% \begin{macrocode} - \exp_args:NNo \@@_tl_gput:Nn #1 { \cs:w @@_toplevel~#3 \cs_end: } - \@@_tl_gput_right:No #1 { \cs:w @@_next~#3 \cs_end: } +% chunk added). The |next| code is always added last (to the right). +% The hook may take arguments, so we add a run of braced parameters +% after the \verb|_next| and \verb|_toplevel| macros, so that the +% arguments passed to the hook are forwarded to them. +% \begin{macrocode} + \exp_args:NNe \@@_tl_gput:Nn #1 + { \exp_not:c { @@_toplevel~#3 } \@@_braced_parameter:n {#3} } + \@@_tl_gput_right:Ne #1 + { \exp_not:c { @@_next~#3 } \@@_braced_parameter:n {#3} } + \use:e + { + \cs_gset:cpn { @@~#3 } \use:c { c_@@_#3_parameter_tl } + { \exp_not:V #1 } + } } % \end{macrocode} % % \begin{macrocode} \cs_generate_variant:Nn \@@_initialize_single:NNn { cc } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_initialize_single:NNn} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_new_protected:Npn \@@_initialize_single:NNn #1#2#3 +%<latexrelease> { +%<latexrelease> \seq_clear:N \l_@@_labels_seq +%<latexrelease> \int_zero:N \l_@@_labels_int +%<latexrelease> \tl_set:Nn \l_@@_cur_hook_tl {#3} +%<latexrelease> \prop_map_inline:Nn \l_@@_work_prop +%<latexrelease> { +%<latexrelease> \int_incr:N \l_@@_labels_int +%<latexrelease> \seq_put_right:Nn \l_@@_labels_seq {##1} +%<latexrelease> \@@_tl_set:cn { \@@_tl_csname:n {##1} } { 0 } +%<latexrelease> \seq_clear_new:c { \@@_seq_csname:n {##1} } +%<latexrelease> } +%<latexrelease> \prop_map_inline:Nn \l_@@_work_prop +%<latexrelease> { +%<latexrelease> \prop_map_inline:Nn \l_@@_work_prop +%<latexrelease> { +%<latexrelease> \@@_if_label_case:nnnnn {##1} {####1} +%<latexrelease> { \prop_map_break: } +%<latexrelease> { \@@_apply_label_pair:nnn {##1} {####1} } +%<latexrelease> { \@@_apply_label_pair:nnn {####1} {##1} } +%<latexrelease> {#3} +%<latexrelease> } +%<latexrelease> } +%<latexrelease> \@@_debug:n { \@@_debug_label_data:N \l_@@_work_prop } +%<latexrelease> \tl_set:Nn \l_@@_rear_tl { 0 } +%<latexrelease> \tl_set:cn { \@@_tl_csname:n { 0 } } { 0 } +%<latexrelease> \seq_map_inline:Nn \l_@@_labels_seq +%<latexrelease> { +%<latexrelease> \int_compare:nNnT { \cs:w \@@_tl_csname:n {##1} \cs_end: } = 0 +%<latexrelease> { +%<latexrelease> \tl_set:cn { \@@_tl_csname:n { \l_@@_rear_tl } }{##1} +%<latexrelease> \tl_set:Nn \l_@@_rear_tl {##1} +%<latexrelease> } +%<latexrelease> } +%<latexrelease> \tl_set_eq:Nc \l_@@_front_tl { \@@_tl_csname:n { 0 } } +%<latexrelease> \@@_tl_gclear:N #1 +%<latexrelease> \clist_gclear:N #2 +%<latexrelease> \bool_while_do:nn { ! \str_if_eq_p:Vn \l_@@_front_tl { 0 } } +%<latexrelease> { +%<latexrelease> \int_decr:N \l_@@_labels_int +%<latexrelease> \prop_get:NVN \l_@@_work_prop \l_@@_front_tl \l_@@_return_tl +%<latexrelease> \exp_args:NNV \@@_tl_gput:Nn #1 \l_@@_return_tl +%<latexrelease> \@@_clist_gput:NV #2 \l_@@_front_tl +%<latexrelease> \@@_debug:n{ \iow_term:x{Handled~ code~ for~ \l_@@_front_tl} } +%<latexrelease> \seq_map_inline:cn { \@@_seq_csname:n { \l_@@_front_tl } } +%<latexrelease> { +%<latexrelease> \tl_set:cx { \@@_tl_csname:n {##1} } +%<latexrelease> { \int_eval:n +%<latexrelease> { \cs:w \@@_tl_csname:n {##1} \cs_end: - 1 } +%<latexrelease> } +%<latexrelease> \int_compare:nNnT +%<latexrelease> { \cs:w \@@_tl_csname:n {##1} \cs_end: } = 0 +%<latexrelease> { +%<latexrelease> \tl_set:cn { \@@_tl_csname:n { \l_@@_rear_tl } } {##1} +%<latexrelease> \tl_set:Nn \l_@@_rear_tl {##1} +%<latexrelease> } +%<latexrelease> } +%<latexrelease> \tl_set_eq:Nc \l_@@_front_tl +%<latexrelease> { \@@_tl_csname:n { \l_@@_front_tl } } +%<latexrelease> } +%<latexrelease> \int_compare:nNnF \l_@@_labels_int = 0 +%<latexrelease> { +%<latexrelease> \iow_term:x{====================} +%<latexrelease> \iow_term:x{Error:~ label~ rules~ are~ incompatible:} +%<latexrelease> \@@_debug_label_data:N \l_@@_work_prop +%<latexrelease> \iow_term:x{====================} +%<latexrelease> } +%<latexrelease> \exp_args:NNo \@@_tl_gput:Nn #1 { \cs:w @@_toplevel~#3 \cs_end: } +%<latexrelease> \@@_tl_gput_right:No #1 { \cs:w @@_next~#3 \cs_end: } +%<latexrelease> } +%<latexrelease>\cs_generate_variant:Nn \@@_tl_gput_right:Nn { No } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -4444,7 +5992,11 @@ { \@@_log_cmd:x { >~\@spaces #1 } } % \end{macrocode} % +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_log:nN} +%<latexrelease> {Hooks~with~args} \cs_new_protected:Npn \@@_log:nN #1 #2 { \@@_if_deprecated_generic:nT {#1} @@ -4455,7 +6007,20 @@ } \@@_preamble_hook:n {#1} \@@_log_cmd:x - { ^^J ->~The~ \@@_if_generic:nT {#1} { generic~ } hook~'#1': } + { + ^^J ->~The~ + \@@_if_generic:nT {#1} { generic~ } + hook~'#1' + \@@_if_disabled:nF {#1} + { + \exp_args:Nf \@@_print_args:nn {#1} + { + \int_eval:n + { \str_count:e { \@@_parameter:n {#1} } / 3 } + } + } + : + } % \end{macrocode} % % \begin{macrocode} @@ -4471,7 +6036,12 @@ { \@@_log_line_indent:x { --- } } { \prop_map_inline:cn { g_@@_#1_code_prop } - { \@@_log_line_indent:x { ##1~->~\tl_to_str:n {##2} } } + { + \exp_after:wN \cs_set:Npn \exp_after:wN \@@_tmp:w + \c_@@_nine_parameters_tl {##2} + \@@_log_line_indent:x + { ##1~->~\cs_replacement_spec:N \@@_tmp:w } + } } % \end{macrocode} % @@ -4485,9 +6055,9 @@ } \@@_log_line_indent:x { - \tl_if_empty:cTF { @@_toplevel~#1 } + \@@_cs_if_empty:cTF { @@_toplevel~#1 } { --- } - { -> ~ \exp_args:Nv \tl_to_str:n { @@_toplevel~#1 } } + { -> ~ \cs_replacement_spec:c { @@_toplevel~#1 } } } % \end{macrocode} % @@ -4495,7 +6065,7 @@ \@@_log_line:x { Extra~code~for~next~invocation: } \@@_log_line_indent:x { - \tl_if_empty:cTF { @@_next~#1 } + \@@_cs_if_empty:cTF { @@_next~#1 } { --- } % \end{macrocode} % @@ -4503,7 +6073,10 @@ % the first tokens (the code to clear itself) so we call a helper % command to get rid of them. % \begin{macrocode} - { ->~ \exp_args:Nv \@@_log_next_code:n { @@_next~#1 } } + { + -> ~ \exp_last_unbraced:Nf \@@_log_next_code:w + { \cs_replacement_spec:c { @@_next~#1 } } + } } % \end{macrocode} % @@ -4549,7 +6122,7 @@ \@spaces \clist_if_empty:cTF { g_@@_#1_labels_clist } { --- } - { \clist_use:cn {g_@@_#1_labels_clist} { ,~ } } + { \clist_use:cn { g_@@_#1_labels_clist } { ,~ } } } } { @@ -4563,15 +6136,139 @@ } } } +%<latexrelease>\EndIncludeInRelease +% +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_log:nN} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_new_protected:Npn \@@_log:nN #1 #2 +%<latexrelease> { +%<latexrelease> \@@_if_deprecated_generic:nT {#1} +%<latexrelease> { +%<latexrelease> \@@_deprecated_generic_warn:n {#1} +%<latexrelease> \@@_do_deprecated_generic:Nn \@@_log:nN {#1} #2 +%<latexrelease> \exp_after:wN \use_none:nnnnnnnnn \use_none:nnnnn +%<latexrelease> } +%<latexrelease> \@@_preamble_hook:n {#1} +%<latexrelease> \@@_log_cmd:x +%<latexrelease> { ^^J ->~The~ \@@_if_generic:nT {#1} { generic~ } hook~'#1': } +%<latexrelease> \@@_if_usable:nF {#1} +%<latexrelease> { \@@_log_line:x { The~hook~is~not~declared. } } +%<latexrelease> \@@_if_disabled:nT {#1} +%<latexrelease> { \@@_log_line:x { The~hook~is~disabled. } } +%<latexrelease> \hook_if_empty:nTF {#1} +%<latexrelease> { #2 { The~hook~is~empty } } +%<latexrelease> { +%<latexrelease> \@@_log_line:x { Code~chunks: } +%<latexrelease> \prop_if_empty:cTF { g_@@_#1_code_prop } +%<latexrelease> { \@@_log_line_indent:x { --- } } +%<latexrelease> { +%<latexrelease> \prop_map_inline:cn { g_@@_#1_code_prop } +%<latexrelease> { \@@_log_line_indent:x { ##1~->~\tl_to_str:n {##2} } } +%<latexrelease> } +%<latexrelease> \@@_log_line:x +%<latexrelease> { +%<latexrelease> Document-level~(top-level)~code +%<latexrelease> \@@_if_usable:nT {#1} +%<latexrelease> { ~(executed~\@@_if_reversed:nTF {#1} {first} {last} ) } : +%<latexrelease> } +%<latexrelease> \@@_log_line_indent:x +%<latexrelease> { +%<latexrelease> \tl_if_empty:cTF { @@_toplevel~#1 } +%<latexrelease> { --- } +%<latexrelease> { -> ~ \exp_args:Nv \tl_to_str:n { @@_toplevel~#1 } } +%<latexrelease> } +%<latexrelease> \@@_log_line:x { Extra~code~for~next~invocation: } +%<latexrelease> \@@_log_line_indent:x +%<latexrelease> { +%<latexrelease> \tl_if_empty:cTF { @@_next~#1 } +%<latexrelease> { --- } +%<latexrelease> { ->~ \exp_args:Nv \@@_log_next_code:n { @@_next~#1 } } +%<latexrelease> } +%<latexrelease> \@@_log_line:x { Rules: } +%<latexrelease> \bool_set_true:N \l_@@_tmpa_bool +%<latexrelease> \@@_list_rules:nn {#1} +%<latexrelease> { +%<latexrelease> \bool_set_false:N \l_@@_tmpa_bool +%<latexrelease> \@@_log_line_indent:x +%<latexrelease> { +%<latexrelease> ##2~ with~ +%<latexrelease> \str_if_eq:nnT {##3} {??} { default~ } +%<latexrelease> relation~ ##1 +%<latexrelease> } +%<latexrelease> } +%<latexrelease> \bool_if:NT \l_@@_tmpa_bool +%<latexrelease> { \@@_log_line_indent:x { --- } } +%<latexrelease> \bool_lazy_and:nnTF +%<latexrelease> { \@@_if_usable_p:n {#1} } +%<latexrelease> { ! \hook_if_empty_p:n {#1} } +%<latexrelease> { +%<latexrelease> \@@_log_line:x +%<latexrelease> { +%<latexrelease> Execution~order +%<latexrelease> \bool_if:NTF \l_@@_tmpa_bool +%<latexrelease> { \@@_if_reversed:nT {#1} { ~(after~reversal) } } +%<latexrelease> { ~(after~ +%<latexrelease> \@@_if_reversed:nT {#1} { reversal~and~ } +%<latexrelease> applying~rules) +%<latexrelease> } : +%<latexrelease> } +%<latexrelease> #2 % \tl_show:n +%<latexrelease> { +%<latexrelease> \@spaces +%<latexrelease> \clist_if_empty:cTF { g_@@_#1_labels_clist } +%<latexrelease> { --- } +%<latexrelease> { \clist_use:cn { g_@@_#1_labels_clist } { ,~ } } +%<latexrelease> } +%<latexrelease> } +%<latexrelease> { +%<latexrelease> \@@_log_line:x { Execution~order: } +%<latexrelease> #2 +%<latexrelease> { +%<latexrelease> \@spaces Not~set~because~the~hook~ \@@_if_usable:nTF {#1} +%<latexrelease> { code~pool~is~empty } +%<latexrelease> { is~\@@_if_disabled:nTF {#1} {disabled} {undeclared} } +%<latexrelease> } +%<latexrelease> } +%<latexrelease> } +%<latexrelease> } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % % \begin{macro}{\@@_log_next_code:n} % To display the code for next invocation only (i.e., from -% \cs{AddToHookNext} we have to remove the first two tokens at the -% front which are \cs{tl_gclear:N} and the token list to clear. +% \cs{AddToHookNext} we have to remove the string +% \cs{@@_clear_next:n}\Arg{hook}, so the simplest is to use a macro +% delimited by a \verb|}|$_12$. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_log_next_code:n} +%<latexrelease> {Hooks~with~args} +\exp_last_unbraced:NNNNo +\cs_new:Npn \@@_log_next_code:w #1 \c_right_brace_str { } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_log_next_code:n} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_gset:Npn \@@_log_next_code:n #1 +%<latexrelease> { \exp_args:No \tl_to_str:n { \use_none:nn #1 } } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\@@_print_args:n} +% Pretty-prints the number of arguments of a hook. % \begin{macrocode} -\cs_new:Npn \@@_log_next_code:n #1 - { \exp_args:No \tl_to_str:n { \use_none:nn #1 } } +\cs_new:Npn \@@_print_args:nn #1 #2 + { + \int_compare:nNnT {#2} > { 0 } + { + \@@_if_declared:nT {#1} { \use_none:nnn } + \@@_if_cmd_hook:nT {#1} + { \use_i:nnn { ~ (unknown ~ } } + \use:n { ~ (#2 ~ } + argument \int_compare:nNnT {#2} > { 1 } { s } ) + } + } % \end{macrocode} % \end{macro} % @@ -4656,15 +6353,34 @@ % \subsection{Specifying code for next invocation} % % \begin{macro}{\hook_gput_next_code:nn} +% \changes{v1.1a}{2023/04/06} +% {Add \cs{hook_gput_next_code_with_args:nn} (hook-args).} % \begin{macrocode} -\cs_new_protected:Npn \hook_gput_next_code:nn #1 - { \@@_normalize_hook_args:Nn \@@_gput_next_code:nn {#1} } +%<latexrelease>\IncludeInRelease{2023/06/01}{\hook_gput_next_code:nn} +%<latexrelease> {Hooks~with~args} +\cs_new_protected:Npn \hook_gput_next_code:nn #1 #2 + { + \@@_replacing_args_false: + \@@_normalize_hook_args:Nn \@@_gput_next_code:nn {#1} {#2} + \@@_replacing_args_reset: + } +\cs_new_protected:Npn \hook_gput_next_code_with_args:nn #1 #2 + { + \@@_replacing_args_true: + \@@_normalize_hook_args:Nn \@@_gput_next_code:nn {#1} {#2} + \@@_replacing_args_reset: + } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\hook_gput_next_code:nn} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_gset_protected:Npn \hook_gput_next_code:nn #1 +%<latexrelease> { \@@_normalize_hook_args:Nn \@@_gput_next_code:nn {#1} } +%<latexrelease>\cs_gset_protected:Npn \hook_gput_next_code_with_args:nn #1 #2 { } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} % -% \begin{macro}{\@@_gput_next_code:nn, -% \@@_gput_next_do:nn, -% \@@_gput_next_do:Nnn} +% \begin{macro}{\@@_gput_next_code:nn} % \begin{macrocode} \cs_new_protected:Npn \@@_gput_next_code:nn #1 #2 { @@ -4672,20 +6388,17 @@ { \msg_error:nnn { hooks } { hook-disabled } {#1} } { \@@_if_structure_exist:nTF {#1} - { \@@_gput_next_do:nn {#1} {#2} } - { \@@_try_declaring_generic_next_hook:nn {#1} {#2} } + { \@@_gput_next_do:nn } + { \@@_try_declaring_generic_next_hook:nn } + {#1} {#2} } } % \end{macrocode} +% \end{macro} % -% \begin{macrocode} -\cs_new_protected:Npn \@@_gput_next_do:nn #1 - { - \exp_args:Nc \@@_gput_next_do:Nnn - { @@_next~#1 } {#1} - } -% \end{macrocode} -% First check if the ``next code'' token list is empty: if so we need +% \begin{macro}{\@@_gput_next_do:nn} +% Start by sanity-checking with \cs{@@_chk_args_allowed:nn}. +% Then check if the ``next code'' token list is empty: if so we need % to add a \cs{tl_gclear:c} to clear it, so the code lasts for one % usage only. The token list is cleared early so that nested usages % don't get lost. \cs{tl_gclear:c} is used instead of @@ -4694,38 +6407,74 @@ % that would make an infinite loop. Also in case the main code token % list is empty, the hook code has to be updated to add the next % execution token list. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} +% \changes{v1.1c}{2023/04/19} +% {Initialise hook structure when adding 'next' code (gh/1052).} % \begin{macrocode} -\cs_new_protected:Npn \@@_gput_next_do:Nnn #1 #2 +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_gput_next_do:nn} +%<latexrelease> {Hooks~with~args} +\cs_new_protected:Npn \@@_gput_next_do:nn #1 { - \tl_if_empty:cT { @@~#2 } - { \@@_update_hook_code:n {#2} } - \tl_if_empty:NT #1 - { \@@_tl_gset:Nn #1 { \@@_clear_next:n {#2} } } - \@@_tl_gput_right:Nn #1 + \@@_init_structure:n {#1} + \@@_chk_args_allowed:nn {#1} { AddToHookNext } + \@@_cs_if_empty:cT { @@~#1 } + { \@@_update_hook_code:n {#1} } + \@@_cs_if_empty:cT { @@_next~#1 } + { \@@_next_gset:nn {#1} { \@@_clear_next:n {#1} } } + \@@_cs_gput_right:nnn { _next } {#1} } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_gput_next_do:nn} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_gset_protected:Npn \@@_gput_next_do:nn #1 +%<latexrelease> { +%<latexrelease> \exp_args:Nc \@@_gput_next_do:Nnn +%<latexrelease> { @@_next~#1 } {#1} +%<latexrelease> } +%<latexrelease>\cs_gset_protected:Npn \@@_gput_next_do:Nnn #1 #2 +%<latexrelease> { +%<latexrelease> \tl_if_empty:cT { @@~#2 } +%<latexrelease> { \@@_update_hook_code:n {#2} } +%<latexrelease> \tl_if_empty:NT #1 +%<latexrelease> { \@@_tl_gset:Nn #1 { \@@_clear_next:n {#2} } } +%<latexrelease> \@@_tl_gput_right:Nn #1 +%<latexrelease> } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} % -% -% -% \begin{macro}{\hook_gclear_next_code:n,\@@_clear_next:n} +% \begin{macro}{\hook_gclear_next_code:n} % Discard anything set up for next invocation of the hook. % \changes{v1.0o}{2021/07/27}{Macro made public} % \begin{macrocode} \cs_new_protected:Npn \hook_gclear_next_code:n #1 { \@@_normalize_hook_args:Nn \@@_clear_next:n {#1} } -\cs_new_protected:Npn \@@_clear_next:n #1 - { \cs_gset_eq:cN { @@_next~#1 } \c_empty_tl } % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_clear_next:n} +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_clear_next:n} +%<latexrelease> {Hooks~with~args} +\cs_new_protected:Npn \@@_clear_next:n #1 + { \@@_next_gset:nn {#1} { } } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_clear_next:n} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_gset_protected:Npn \@@_clear_next:n #1 +%<latexrelease> { \cs_gset_eq:cN { @@_next~#1 } \c_empty_tl } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} % % % \subsection{Using the hook} % % \begin{macro}{\hook_use:n} % \begin{macro}[EXP]{\@@_use_initialized:n} -% \begin{macro}{\@@_use_undefined:w,\@@_use_end:} % \begin{macro}{\@@_preamble_hook:n} % \cs{hook_use:n} as defined here is used in the preamble, where % hooks aren't initialized by default. \cs{@@_use_initialized:n} is @@ -4750,24 +6499,50 @@ % \verb=\csname ...\endcsname= construct \cs{tl_if_exist:c} is % careful to avoid this. % \begin{macrocode} -%<latexrelease>\IncludeInRelease{2021/11/15}{\hook_use:n} -%<latexrelease> {Standardise~generic~hook~names} +%<latexrelease>\IncludeInRelease{2023/06/01}{\hook_use:n} +%<latexrelease> {Hooks~with~args} \cs_new_protected:Npn \hook_use:n #1 { - \tl_if_exist:cT { @@~#1 } - { - \@@_preamble_hook:n {#1} - \cs:w @@~#1 \cs_end: - } + \@@_preamble_hook:n {#1} + \@@_use_initialized:n {#1} } \cs_new:Npn \@@_use_initialized:n #1 { \if_cs_exist:w @@~#1 \cs_end: - \cs:w @@~#1 \exp_after:wN \cs_end: + \cs:w @@~#1 \use_i:nn \fi: + \use_none:n + \cs_end: } \cs_new_protected:Npn \@@_preamble_hook:n #1 - { \@@_initialize_hook_code:n {#1} } + { + \if_cs_exist:w @@~#1 \cs_end: + \@@_initialize_hook_code:n {#1} + \fi: + } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2021/11/15}{\hook_use:n} +%<latexrelease> {Standardise~generic~hook~names} +%<latexrelease>\cs_new_protected:Npn \hook_use:n #1 +%<latexrelease> { +%<latexrelease> \tl_if_exist:cT { @@~#1 } +%<latexrelease> { +%<latexrelease> \@@_preamble_hook:n {#1} +%<latexrelease> \cs:w @@~#1 \cs_end: +%<latexrelease> } +%<latexrelease> } +%<latexrelease>\cs_new:Npn \@@_use_initialized:n #1 +%<latexrelease> { +%<latexrelease> \if_cs_exist:w @@~#1 \cs_end: +%<latexrelease> \cs:w @@~#1 \exp_after:wN \cs_end: +%<latexrelease> \fi: +%<latexrelease> } +%<latexrelease>\cs_new_protected:Npn \@@_preamble_hook:n #1 +%<latexrelease> { \@@_initialize_hook_code:n {#1} } +%<latexrelease>\cs_new:Npn \hook_use:nnw #1 { } %<latexrelease>\EndIncludeInRelease % \end{macrocode} % @@ -4799,13 +6574,69 @@ %<latexrelease>\cs_new_protected:Npn \@@_preamble_hook:n #1 %<latexrelease> { \@@_initialize_hook_code:n {#1} } %<latexrelease>\cs_new_eq:NN \@@_use_end: \cs_end: +%<latexrelease>\cs_new:Npn \hook_use:nnw #1 { } %<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% +% +% \begin{macro}{\hook_use:nnw} +% \begin{macro}[EXP]{\@@_use_initialized:nnw} +% \changes{v1.1a}{2023/04/06} +% {Add \cs{hook_use:nnw} (hook-args).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\hook_use:nnw} +%<latexrelease> {Hooks~with~args} +\cs_new_protected:Npn \hook_use:nnw #1 + { + \@@_preamble_hook:n {#1} + \@@_use_initialized:nnw {#1} + } +\cs_new:Npn \@@_use_initialized:nnw #1 #2 + { + \cs:w + \if_cs_exist:w @@~#1 \cs_end: + @@~#1 + \else: + use_none: \prg_replicate:nn {#2} { n } + \fi: + \cs_end: + } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\hook_use:nnw} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_gset:Npn \hook_use:nnw #1 #2 +%<latexrelease> { \use:c { use_none: \prg_replicate:nn {#2} { n } } } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\@@_post_initialization_defs:} +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_post_initialization_defs:} +%<latexrelease> {Hooks~with~args} +\cs_new_protected:Npn \@@_post_initialization_defs: + { + \cs_gset_eq:NN \hook_use:n \@@_use_initialized:n + \cs_gset_eq:NN \hook_use:nnw \@@_use_initialized:nnw + \cs_gset_eq:NN \@@_preamble_hook:n \use_none:n + \cs_gset_eq:NN \@@_post_initialization_defs: \prg_do_nothing: + } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_post_initialization_defs:} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_undefine:N \@@_post_initialization_defs: +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} % \end{macro} % +% % \begin{macro}[EXP]{\@@_use:wn} % \begin{macro}{\@@_try_file_hook:n,\@@_if_usable_use:n} % \cs{@@_use:wn} does a quick check to test if the current hook is a @@ -4861,8 +6692,7 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\hook_use_once:n} -% \begin{macro}{\@@_use_once:n} +% \begin{macro}{\hook_use_once:n,\hook_use_once:nnw} % For hooks that can and should be used only once we have a special % use command that further inhibits the hook from getting more code % added to it. This has the effect that any @@ -4874,20 +6704,80 @@ % documented to not trim spaces. % % \changes{v1.0r}{2021/09/06}{Clean up after \cs{UseOneTimeHook} (gh/606)} +% \changes{v1.1a}{2023/04/06} +% {Add \cs{hook_use_once:nnw} (hook-args).} % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\hook_use_once:nnw} +%<latexrelease> {Hooks~with~args} \cs_new_protected:Npn \hook_use_once:n #1 { \@@_if_execute_immediately:nF {#1} - { \@@_normalize_hook_args:Nn \@@_use_once:n { \use:n {#1} } } + { \@@_normalize_hook_args:Nn \@@_use_once:nn { \use:n {#1} } { 0 } } } -\cs_new_protected:Npn \@@_use_once:n #1 +\cs_new_protected:Npn \hook_use_once:nnw #1 #2 + { + \@@_if_execute_immediately:nF {#1} + { \@@_normalize_hook_args:Nn \@@_use_once:nn { \use:n {#1} } {#2} } + } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{\hook_use_once:nnw} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_gset_protected:Npn \hook_use_once:n #1 +%<latexrelease> { +%<latexrelease> \@@_if_execute_immediately:nF {#1} +%<latexrelease> { \@@_normalize_hook_args:Nn \@@_use_once:n { \use:n {#1} } } +%<latexrelease> } +%<latexrelease>\cs_gset:Npn \hook_use_once:nnw #1 #2 +%<latexrelease> { \use:c { use_none: \prg_replicate:nn {#2} { n } } } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macro}{\@@_use_once:nn} +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_use_once:nn} +%<latexrelease> {Hooks~with~args} +\cs_new_protected:Npn \@@_use_once:nn #1 #2 { \@@_preamble_hook:n {#1} \@@_use_once_set:n {#1} - \@@_use_initialized:n {#1} - \@@_use_once_clear:n {#1} +% \end{macrocode} +% When a hook has arguments, the call to \cs{@@_use_initialized:n}, +% should be the very last thing to happen, otherwise the arguments +% grabbed will be wrong. So, to clean up after the hook we need to +% cheat a bit and sneak the cleanup code at the end of the hook, +% along with the next execution code. +% \begin{macrocode} + \@@_replacing_args_false: + \@@_cs_gput_right:nnn { _next } {#1} { \@@_use_once_clear:n {#1} } + \@@_replacing_args_reset: + \@@_if_usable:nTF {#1} + { \@@_use_initialized:n {#1} } + { + \int_compare:nNnT {#2} > { 0 } + { \use:c { use_none: \prg_replicate:nn {#2} { n } } } + } } +%<latexrelease>\EndIncludeInRelease +% +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_use_once:nn} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_gset_protected:Npn \@@_use_once:n #1 +%<latexrelease> { +%<latexrelease> \@@_preamble_hook:n {#1} +%<latexrelease> \@@_use_once_set:n {#1} +%<latexrelease> \@@_use_initialized:n {#1} +%<latexrelease> \@@_use_once_clear:n {#1} +%<latexrelease> } +%<latexrelease>\cs_undefine:N \@@_use_once:nn +%<latexrelease>\EndIncludeInRelease % \end{macrocode} +% \end{macro} % % \begin{macro}{\@@_use_once_set:n} % \begin{macro}{\@@_use_once_clear:n} @@ -4900,43 +6790,60 @@ % \cs{hook_use_once:n} will expand to nothing. % \changes{v1.0r}{2021/09/06}{Clean up after \cs{UseOneTimeHook} (gh/606)} % \changes{v1.0u}{2022/05/13}{Check if prop exists to avoid l3debug error} +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_use_once_clear:n} +%<latexrelease> {Hooks~with~args} \cs_new_protected:Npn \@@_use_once_set:n #1 { \@@_tl_gset:cn { g_@@_#1_reversed_tl } { I } } \cs_new_protected:Npn \@@_use_once_clear:n #1 { - \@@_tl_gclear:c { @@~#1 } - \@@_tl_gclear:c { @@_next~#1 } - \@@_tl_gclear:c { @@_toplevel~#1 } + \@@_code_gset:nn {#1} { } + \@@_next_gset:nn {#1} { } + \@@_toplevel_gset:nn {#1} { } \prop_gclear_new:c { g_@@_#1_code_prop } } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_use_once_clear:n} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_new_protected:Npn \@@_use_once_clear:n #1 +%<latexrelease> { +%<latexrelease> \@@_tl_gclear:c { @@~#1 } +%<latexrelease> \@@_tl_gclear:c { @@_next~#1 } +%<latexrelease> \@@_tl_gclear:c { @@_toplevel~#1 } +%<latexrelease> \prop_gclear_new:c { g_@@_#1_code_prop } +%<latexrelease> } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} -% \end{macro} -% \end{macro} % \end{macro} % \end{macro} % % \begin{macro}[pTF]{\@@_if_execute_immediately:n} -% To check whether the code being added should be executed immediately (that -% is, if the hook is a one-time hook), we check if it's usable (it -% can't be one-time if it was not already usable), then we check that +% To check whether the code being added should be executed immediately +% (that is, if the hook is a one-time hook), we check if % \cs[no-index]{g_@@_\meta{hook}_reversed_tl} is |I|. The gymnastics % around \cs{if:w} is there to allow the |reversed| token list to be % empty. % \changes{v1.0r}{2021/09/06}{Macro added (gh/606)} +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} % \begin{macrocode} \prg_new_conditional:Npnn \@@_if_execute_immediately:n #1 { T, F, TF } { - \@@_if_usable:nTF {#1} - { - \exp_after:wN \@@_clean_to_scan:w - \if:w I \cs:w g_@@_#1_reversed_tl \cs_end: - \s_@@_mark \prg_return_true: - \else: - \s_@@_mark \prg_return_false: + \exp_after:wN \@@_use_none_delimit_by_s_mark:w + \if:w I + \if_cs_exist:w g_@@_#1_reversed_tl \cs_end: + \cs:w g_@@_#1_reversed_tl \exp_after:wN \cs_end: \fi: - } - { \prg_return_false: } + X + \s_@@_mark \prg_return_true: + \else: + \s_@@_mark \prg_return_false: + \fi: } % \end{macrocode} % \end{macro} @@ -4963,30 +6870,57 @@ % % All other states can only be queried with internal tests as the % different states are irrelevant for package code. - +% % \begin{macro}[pTF]{\hook_if_empty:n} % Test if a hook is empty (that is, no code was added to that hook). % A \meta{hook} being empty means that all three of its % \cs{g_@@_\meta{hook}_code_prop}, its % \cs{@@_toplevel\textvisiblespace\meta{hook}} and its % \cs{@@_next\textvisiblespace\meta{hook}} are empty. +% \changes{v1.1a}{2023/04/06} +% {Changes to add hook arguments (hook-args).} +% \changes{v1.1c}{2023/04/19} +% {Simpler and faster version (gh/1052).} % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\hook_if_empty:n} +%<latexrelease> {Hooks~with~args} \prg_new_conditional:Npnn \hook_if_empty:n #1 { p , T , F , TF } { - \@@_if_structure_exist:nTF {#1} - { - \bool_lazy_and:nnTF - { \prop_if_empty_p:c { g_@@_#1_code_prop } } - { - \bool_lazy_and_p:nn - { \tl_if_empty_p:c { @@_toplevel~#1 } } - { \tl_if_empty_p:c { @@_next~#1 } } - } - { \prg_return_true: } - { \prg_return_false: } - } - { \prg_return_true: } + \if:w + T + \prop_if_exist:cT { g_@@_#1_code_prop } + { \prop_if_empty:cF { g_@@_#1_code_prop } { F } } + \@@_cs_if_empty:cF { @@_toplevel~#1 } { F } + \@@_cs_if_empty:cF { @@_next~#1 } { F } + T + \prg_return_true: + \else: + \prg_return_false: + \fi: } +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{\hook_if_empty:n} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\prg_new_conditional:Npnn \hook_if_empty:n #1 { p , T , F , TF } +%<latexrelease> { +%<latexrelease> \@@_if_structure_exist:nTF {#1} +%<latexrelease> { +%<latexrelease> \bool_lazy_and:nnTF +%<latexrelease> { \prop_if_empty_p:c { g_@@_#1_code_prop } } +%<latexrelease> { +%<latexrelease> \bool_lazy_and_p:nn +%<latexrelease> { \tl_if_empty_p:c { @@_toplevel~#1 } } +%<latexrelease> { \tl_if_empty_p:c { @@_next~#1 } } +%<latexrelease> } +%<latexrelease> { \prg_return_true: } +%<latexrelease> { \prg_return_false: } +%<latexrelease> } +%<latexrelease> { \prg_return_true: } +%<latexrelease> } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -4994,15 +6928,15 @@ % \begin{macro}[pTF]{\@@_if_usable:n} % A hook is usable if the % token list that stores the sorted code for that hook, -% \cs[no-index]{@@~\meta{hook}}, exists. The property list -% \cs[no-index]{g_@@_\meta{hook}_code_prop} cannot be used here +% \cs[no-index]{@@\textvisiblespace\meta{hook}}, exists. The property +% list \cs[no-index]{g_@@_\meta{hook}_code_prop} cannot be used here % because often it is necessary to add code to a hook without knowing % if such hook was already declared, or even if it will ever be % (for example, in case the package that defines it isn't loaded). % \begin{macrocode} \prg_new_conditional:Npnn \@@_if_usable:n #1 { p , T , F , TF } { - \tl_if_exist:cTF { @@~#1 } + \cs_if_exist:cTF { @@~#1 } { \prg_return_true: } { \prg_return_false: } } @@ -5046,7 +6980,7 @@ % \begin{macrocode} \prg_new_conditional:Npnn \@@_if_reversed:n #1 { p , T , F , TF } { - \exp_after:wN \@@_clean_to_scan:w + \exp_after:wN \@@_use_none_delimit_by_s_mark:w \if:w - \cs:w g_@@_#1_reversed_tl \cs_end: \s_@@_mark \prg_return_true: \else: @@ -5086,6 +7020,37 @@ % \end{macro} % \end{macro} % +% \begin{macro}[pTF]{\@@_if_cmd_hook:n} +% \begin{macro}[pTF]{\@@_if_cmd_hook:w} +% An internal conditional that checks if a given hook is a valid +% generic \hook{cmd} hook. +% \changes{v1.1d}{2023/05/21} +% {Changes to allow support arguments in cmd hooks (cmd-args).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\@@_if_cmd_hook:n} +%<latexrelease> {Hooks~with~args} +\prg_new_conditional:Npnn \@@_if_cmd_hook:n #1 { T } + { \@@_if_cmd_hook:w #1 / / / \s_@@_mark } +\cs_new:Npn \@@_if_cmd_hook:w #1 / #2 / #3 / #4 \s_@@_mark + { + \if:w Y + \str_if_eq:nnF {#1} { cmd } { N } + \tl_if_exist:cF { c_@@_generic_#1/./#3_tl } { N } + Y + \prg_return_true: + \else: + \prg_return_false: + \fi: + } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\@@_if_cmd_hook:n} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_undefine:N \@@_if_cmd_hook:nT +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macro}[pTF]{\@@_if_generic_reversed:n} % An internal conditional that checks if a name belongs to a generic % reversed hook. @@ -5103,6 +7068,50 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}[EXP]{\@@_if_replacing_args:TF} +% \begin{macro}[EXP]{\@@_misused_if_replacing_args:nn} +% \begin{macro}{\@@_replacing_args_true:} +% \begin{macro}{\@@_replacing_args_false:} +% \begin{macro}{\@@_replacing_args_reset:} +% \begin{macro}{\g_@@_replacing_stack_seq} +% An internal conditional that checks if the code being added to the +% hook contains arguments. +% \changes{v1.1a}{2023/04/06} +% {Macro added (hook-args).} +% \begin{macrocode} +\seq_new:N \g_@@_replacing_stack_seq +\cs_new:Npn \@@_misused_if_replacing_args:nn #1 #2 + { + \msg_expandable_error:nnn { latex2e } { should-not-happen } + { Misused~\@@_if_replacing_args:. } + } +\cs_new:Npn \@@_if_replacing_args:TF + { \@@_misused_if_replacing_args:nn } +\cs_new_protected:Npn \@@_replacing_args_true: + { + \seq_gpush:No \g_@@_replacing_stack_seq + { \@@_if_replacing_args:TF } + \cs_set:Npn \@@_if_replacing_args:TF { \use_i:nn } + } +\cs_new_protected:Npn \@@_replacing_args_false: + { + \seq_gpush:No \g_@@_replacing_stack_seq + { \@@_if_replacing_args:TF } + \cs_set:Npn \@@_if_replacing_args:TF { \use_ii:nn } + } +\cs_new_protected:Npn \@@_replacing_args_reset: + { + \seq_gpop:NN \g_@@_replacing_stack_seq \l_@@_return_tl + \cs_gset_eq:NN \@@_if_replacing_args:TF \l_@@_return_tl + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% % \subsection{Messages} % % Hook errors are LaTeX kernel errors: @@ -5137,6 +7146,55 @@ Please~ use~ a~ different~ name~ for~ your~ hook.} % \end{macrocode} % +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{too-many-args} +%<latexrelease> {Hooks~with~args} +% \end{macrocode} +% +% \changes{v1.1a}{2023/04/06} +% {Messages 'too-many-args', 'without-args' and 'one-time-args' added (hook-args).} +% \begin{macrocode} +\msg_new:nnnn { hooks } { too-many-args } + { Too~many~arguments~for~hook~'#1'. } + { + You~tried~to~declare~a~hook~with~#2~arguments,~but~a~ + hook~can~only~have~up~to~nine.~LaTeX~will~define~this~ + hook~with~nine~arguments. + } +% \end{macrocode} +% +% \begin{macrocode} +\msg_new:nnnn { hooks } { without-args } + { Hook~'#1'~has~no~arguments. } + { + You~tried~to~use~\iow_char:N\\#2WithArguments~ + on~a~hook~that~takes~no~arguments.\\ + Check~the~usage~of~the~hook~or~use~\iow_char:N\\#2~instead.\\ + \\ + LaTeX~will~use~\iow_char:N\\#2. + } +% \end{macrocode} +% +% \begin{macrocode} +\msg_new:nnnn { hooks } { one-time-args } + { You~can't~have~arguments~in~used~one-time~hook~'#1'. } + { + You~tried~to~use~\iow_char:N\\#2WithArguments~ + on~a~one-time~hook~that~has~already~been~used.~ + You~have~to~add~the~code~before~the~hook~is~used,~ + or~add~the~code~without~arguments~using~\iow_char:N\\#2~instead.\\ + \\ + LaTeX~will~use~\iow_char:N\\#2. + } +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{too-many-args} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\EndIncludeInRelease +% \end{macrocode} +% % % \begin{macrocode} \msg_new:nnnn { hooks } { hook-disabled } @@ -5278,17 +7336,49 @@ % \begin{macro}{\NewHook,\NewReversedHook,\NewMirroredHookPair} % Declaring new hooks \ldots % \begin{macrocode} -\NewDocumentCommand \NewHook { m }{ \hook_new:n {#1} } -\NewDocumentCommand \NewReversedHook { m }{ \hook_new_reversed:n {#1} } -\NewDocumentCommand \NewMirroredHookPair { mm }{ \hook_new_pair:nn {#1}{#2} } +\NewDocumentCommand \NewHook { m } + { \hook_new:n {#1} } +\NewDocumentCommand \NewReversedHook { m } + { \hook_new_reversed:n {#1} } +\NewDocumentCommand \NewMirroredHookPair { mm } + { \hook_new_pair:nn {#1}{#2} } +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{ +% \NewHookWithArguments, +% \NewReversedHookWithArguments, +% \NewMirroredHookPairWithArguments +% } +% Declaring new hooks with arguments\ldots +% \changes{v1.1a}{2023/04/06} +% {Add \cs{NewHookWithArguments} (hook-args).} +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\NewHookWithArguments} +%<latexrelease> {Hooks~with~args} +\NewDocumentCommand \NewHookWithArguments { mm } + { \hook_new_with_args:nn {#1} {#2} } +\NewDocumentCommand \NewReversedHookWithArguments { mm } + { \hook_new_reversed_with_args:nn {#1} {#2} } +\NewDocumentCommand \NewMirroredHookPairWithArguments { mmm } + { \hook_new_pair_with_args:nnn {#1} {#2} {#3} } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2023/06/01}{\NewHookWithArguments} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_new_protected:Npn \NewHookWithArguments #1 #2 { } +%<latexrelease>\cs_new_protected:Npn \NewReversedHookWithArguments #1 #2 { } +%<latexrelease>\cs_new_protected:Npn \NewMirroredHookPairWithArguments #1 #2 #3 { } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} % % % % \begin{macrocode} -%<latexrelease>\IncludeInRelease{2021/06/01}% -%<latexrelease> {\hook_activate_generic:n}{Providing~hooks} +%<latexrelease>\IncludeInRelease{2021/06/01}{\ActivateGenericHook} +%<latexrelease> {Providing~hooks} % \end{macrocode} % % \begin{macro}{\ActivateGenericHook} @@ -5296,7 +7386,8 @@ % \changes{v1.0m}{2021/04/29}{Add \cs{ProvideHook} etc.} % \changes{v1.0o}{2021/08/02}{Change name} % \begin{macrocode} -\NewDocumentCommand \ActivateGenericHook { m }{ \hook_activate_generic:n {#1} } +\NewDocumentCommand \ActivateGenericHook { m } + { \hook_activate_generic:n {#1} } % \end{macrocode} % \end{macro} % @@ -5304,32 +7395,57 @@ % Disabling a generic hook. % \changes{v1.0o}{2021/08/02}{Change name} % \begin{macrocode} -\NewDocumentCommand \DisableGenericHook { m }{ \hook_disable_generic:n {#1} } +\NewDocumentCommand \DisableGenericHook { m } + { \hook_disable_generic:n {#1} } % \end{macrocode} % \end{macro} % % \begin{macrocode} %<latexrelease>\EndIncludeInRelease -%<latexrelease>\IncludeInRelease{2020/10/01} -%<latexrelease> {\hook_activate_generic:n}{Providing~hooks} -%<latexrelease> -%<latexrelease>\def \ActivateGenericHook#1{} -%<latexrelease> +% \end{macrocode} +% +% \begin{macrocode} +%<latexrelease>\IncludeInRelease{2020/10/01}{\ActivateGenericHook} +%<latexrelease> {Providing~hooks} +%<latexrelease>\def \ActivateGenericHook #1 { } +%<latexrelease>\def \DisableGenericHook #1 { } %<latexrelease>\EndIncludeInRelease % \end{macrocode} % % -% \begin{macro}{\AddToHook} +% \begin{macro}{\AddToHook,\AddToHookWithArguments} +% \changes{v1.1a}{2023/04/06} +% {Add \cs{AddToHookWithArguments} (hook-args).} % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\AddToHookWithArguments} +%<latexrelease> {Hooks~with~args} \NewDocumentCommand \AddToHook { m o +m } { \hook_gput_code:nnn {#1} {#2} {#3} } +\NewDocumentCommand \AddToHookWithArguments { m o +m } + { \hook_gput_code_with_args:nnn {#1} {#2} {#3} } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\AddToHookWithArguments} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_new_protected:Npn \AddToHookWithArguments #1 #2 #3 { } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} % -% \begin{macro}{\AddToHookNext} +% \begin{macro}{\AddToHookNext,\AddToHookNextWithArguments} +% \changes{v1.1a}{2023/04/06} +% {Add \cs{AddToHookNextWithArguments} (hook-args).} % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\AddToHookNextWithArguments} +%<latexrelease> {Hooks~with~args} \NewDocumentCommand \AddToHookNext { m +m } { \hook_gput_next_code:nn {#1} {#2} } +\NewDocumentCommand \AddToHookNextWithArguments { m +m } + { \hook_gput_next_code_with_args:nn {#1} {#2} } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\AddToHookNextWithArguments} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_new_protected:Npn \AddToHookNextWithArguments #1 #2 { } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -5396,12 +7512,29 @@ % % % -% \begin{macro}{\UseHook,\UseOneTimeHook} +% \begin{macro}{ +% \UseHook, +% \UseOneTimeHook, +% \UseHookWithArguments, +% \UseOneTimeHookWithArguments, +% } % Avoid the overhead of \pkg{xparse} and its protection that we % don't want here (since the hook should vanish without trace if empty)! +% \changes{v1.1a}{2023/04/06} +% {Add \cs{UseHookWithArguments} (hook-args).} % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01}{\UseHookWithArguments} +%<latexrelease> {Hooks~with~args} \cs_new:Npn \UseHook { \hook_use:n } \cs_new:Npn \UseOneTimeHook { \hook_use_once:n } +\cs_new:Npn \UseHookWithArguments { \hook_use:nnw } +\cs_new:Npn \UseOneTimeHookWithArguments { \hook_use_once:nnw } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2020/10/01}{\UseHookWithArguments} +%<latexrelease> {Hooks~with~args} +%<latexrelease>\cs_new:Npn \UseHookWithArguments #1 #2 { } +%<latexrelease>\cs_new:Npn \UseOneTimeHookWithArguments #1 #2 { } +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} % @@ -5462,7 +7595,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}[EXP]{\IfHookExistsTF} +% \begin{macro}[EXP,int]{\IfHookExistsTF} % Marked for removal and no longer documented in the doc section! % \phoinline{\cs{IfHookExistsTF} is used in \texttt{jlreq.cls}, % \texttt{pxatbegshi.sty}, \texttt{pxeverysel.sty}, @@ -5484,7 +7617,7 @@ % \changes{v1.0p}{2021/08/20}{Added deprecation warnings for % old generic hook commands (gh/638)} % -% \begin{macro}{ +% \begin{macro}[int]{ % \hook_disable:n, % \hook_provide:n, % \hook_provide_reversed:n, @@ -5529,7 +7662,7 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{ +% \begin{macro}[int]{ % \DisableHook, % \ProvideHook, % \ProvideReversedHook, @@ -5596,8 +7729,10 @@ %<@@=> % \end{macrocode} % -% \begin{macro}{\@expl@@@initialize@all@@, -% \@expl@@@hook@curr@name@pop@@} +% \begin{macro}[int]{ +% \@expl@@@initialize@all@@, +% \@expl@@@hook@curr@name@pop@@ +% } % % \InternalDetectionOff % \begin{macrocode} @@ -5620,8 +7755,8 @@ % to be for \cs{AddToHook} vice versa (gh/401)} % \begin{macrocode} % -%<latexrelease>\IncludeInRelease{0000/00/00}% -%<latexrelease> {lthooks}{The~hook~management}% +%<latexrelease>\IncludeInRelease{0000/00/00}{lthooks} +%<latexrelease> {The~hook~management}% %<latexrelease> %<latexrelease>\def \NewHook#1{} %<latexrelease>\def \NewReversedHook#1{} @@ -5656,10 +7791,56 @@ %<latexrelease>\long\def \IfHookEmptyTF #1#2#3{#2} %<latexrelease> %<latexrelease>\EndModuleRelease +% \end{macrocode} +% +% \begin{macrocode} +%<@@=hook> +% \end{macrocode} +% +% \changes{v1.1a}{2023/04/06} +% {Add dedicated rollback code to revert data structures (hook-args).} +% \begin{macrocode} +%<latexrelease>\cs:w @@_rollback_tidying: \cs_end: +%<latexrelease>\bool_lazy_and:nnT +%<latexrelease> { \int_compare_p:nNn { \sourceLaTeXdate } > { 20230600 } } +%<latexrelease> { \int_compare_p:nNn { \requestedLaTeXdate } < { 20230601 } } +%<latexrelease> { +%<latexrelease> \cs_gset_protected:Npn \@@_rollback_tidying: +%<latexrelease> { +%<latexrelease> \@latex@error { Rollback~code~executed~twice } +%<latexrelease> { +%<latexrelease> Something~went~wrong~(unless~this~was~ +%<latexrelease> done~on~purpose~in~a~testing~environment). +%<latexrelease> } +%<latexrelease> \use_none:nnnn +%<latexrelease> } +%<latexrelease> \cs_set:Npn \@@_tmp:w #1 #2 +%<latexrelease> { +%<latexrelease> \@@_tl_gset:cx { @@#1~#2 } +%<latexrelease> { +%<latexrelease> \exp_args:No \exp_not:o +%<latexrelease> { +%<latexrelease> \cs:w @@#1~#2 \exp_last_unbraced:Ne \cs_end: +%<latexrelease> { \@@_braced_cs_parameter:n { @@#1~#2 } } +%<latexrelease> } +%<latexrelease> } +%<latexrelease> } +%<latexrelease> \seq_map_inline:Nn \g_@@_all_seq +%<latexrelease> { +%<latexrelease> \exp_after:wN \cs_gset_nopar:Npn +%<latexrelease> \cs:w g_@@_#1_code_prop \exp_args:NNo \exp_args:No +%<latexrelease> \cs_end: { \cs:w g_@@_#1_code_prop \cs_end: } +%<latexrelease> \@@_tmp:w { _toplevel } {#1} +%<latexrelease> \@@_tmp:w { _next } {#1} +%<latexrelease> } +%<latexrelease> } \ExplSyntaxOff %</2ekernel|latexrelease> % \end{macrocode} % +% \begin{macrocode} +%<@@=> +% \end{macrocode} % % \Finale % diff --git a/macros/latex/base/lthyphen.dtx b/macros/latex/base/lthyphen.dtx index b7cede1175..88d30c9cca 100644 --- a/macros/latex/base/lthyphen.dtx +++ b/macros/latex/base/lthyphen.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltidxglo.dtx b/macros/latex/base/ltidxglo.dtx index 395fe83975..a2dc6b873e 100644 --- a/macros/latex/base/ltidxglo.dtx +++ b/macros/latex/base/ltidxglo.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltkeys.dtx b/macros/latex/base/ltkeys.dtx index edf12f7cb2..80c36d5cd9 100644 --- a/macros/latex/base/ltkeys.dtx +++ b/macros/latex/base/ltkeys.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2021-2022 +% Copyright (C) 2021-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltlength.dtx b/macros/latex/base/ltlength.dtx index f979dd4e23..10e4b671c8 100644 --- a/macros/latex/base/ltlength.dtx +++ b/macros/latex/base/ltlength.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltlists.dtx b/macros/latex/base/ltlists.dtx index d0413dad08..d43df93a54 100644 --- a/macros/latex/base/ltlists.dtx +++ b/macros/latex/base/ltlists.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -31,7 +31,7 @@ %<*driver> % \fi \ProvidesFile{ltlists.dtx} - [2020/12/05 v1.0t LaTeX Kernel (List Environments)] + [2023/05/17 v1.0t LaTeX Kernel (List Environments)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltlists.dtx} @@ -68,7 +68,6 @@ % \begin{quote} % |\list|\marg{LABEL}\marg{COMMANDS} ... |\endlist| % \end{quote} -% % which can be invoked by the user as the list environment. The LABEL % argument specifies item labeling. COMMANDS contains commands for % changing the horizontal and vertical spacing parameters. @@ -187,7 +186,7 @@ % |\hsize|. % % Here are the parameters of a list that can be set by commands in -% the |\list|'s COMMANDS argument. These parameters are all TeX +% the |\list|'s COMMANDS argument. These parameters are all \TeX{} % skips or dimensions (defined by |\newskip| or |\newdimen|), so the % usual \TeX\ or \LaTeX\ commands can be used to set them. The % commands will be executed in vmode if and only if the |\list| was @@ -228,7 +227,7 @@ % label. % \item[\cs{labelwidth}:] nominal width of box that contains the label. % If the natural width of the -% label $< =$ \cs{labelwidth}, +% label $\leq$ \cs{labelwidth}, % then the label is flushed right inside a box % of width \cs{labelwidth} (with an \cs{hfil}). % Otherwise, diff --git a/macros/latex/base/ltlogos.dtx b/macros/latex/base/ltlogos.dtx index 56453f73db..7589cf36e1 100644 --- a/macros/latex/base/ltlogos.dtx +++ b/macros/latex/base/ltlogos.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltluatex.dtx b/macros/latex/base/ltluatex.dtx index 6c66a96be0..135cb63009 100644 --- a/macros/latex/base/ltluatex.dtx +++ b/macros/latex/base/ltluatex.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2015-2022 +% Copyright (C) 2015-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -28,7 +28,7 @@ \ProvidesFile{ltluatex.dtx} %</driver> %<*tex> -[2022/10/03 v1.2a +[2023/01/19 v1.2b %</tex> %<plain> LuaTeX support for plain TeX (core) %<*tex> @@ -968,10 +968,10 @@ local luatexbase = luatexbase % % Some Lua best practice: use local versions of functions where possible. % \changes{v1.1u}{2021/08/11}{Define missing local function} +% \changes{v1.2b}{2023/01/19}{Remove unused local variable tex_setattribute} % \begin{macrocode} local string_gsub = string.gsub local tex_count = tex.count -local tex_setattribute = tex.setattribute local tex_setcount = tex.setcount local texio_write_nl = texio.write_nl local flush_list = node.flush_list diff --git a/macros/latex/base/ltluatex.pdf b/macros/latex/base/ltluatex.pdf index f53e9a5b13..8b854be87e 100644 Binary files a/macros/latex/base/ltluatex.pdf and b/macros/latex/base/ltluatex.pdf differ diff --git a/macros/latex/base/ltmarks-code.pdf b/macros/latex/base/ltmarks-code.pdf index 7c88582032..9fc96a45bd 100644 Binary files a/macros/latex/base/ltmarks-code.pdf and b/macros/latex/base/ltmarks-code.pdf differ diff --git a/macros/latex/base/ltmarks-doc.pdf b/macros/latex/base/ltmarks-doc.pdf index 0aad6985bc..86c684dc7a 100644 Binary files a/macros/latex/base/ltmarks-doc.pdf and b/macros/latex/base/ltmarks-doc.pdf differ diff --git a/macros/latex/base/ltmarks.dtx b/macros/latex/base/ltmarks.dtx index 3dc4b493ac..677534dd27 100644 --- a/macros/latex/base/ltmarks.dtx +++ b/macros/latex/base/ltmarks.dtx @@ -1,7 +1,8 @@ % \iffalse meta-comment % -%% File: ltmarks.dtx (C) Copyright 2022 -% Frank Mittelbach, LaTeX Team +%% File: ltmarks.dtx +%% Copyright (C) 2022-2023 +%% Frank Mittelbach, 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 diff --git a/macros/latex/base/ltmath.dtx b/macros/latex/base/ltmath.dtx index 60394460f5..3b1518dd2e 100644 --- a/macros/latex/base/ltmath.dtx +++ b/macros/latex/base/ltmath.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -38,7 +38,7 @@ %<*driver> % \fi \ProvidesFile{ltmath.dtx} - [2022/09/07 v1.2m LaTeX Kernel (Math Setup)] + [2023/05/13 v1.2n LaTeX Kernel (Math Setup)] % \iffalse %</driver> % @@ -1132,9 +1132,29 @@ \fi % \end{macrocode} % +% \begin{macro}{\eqno} +% \begin{macro}{\leqno} +% \changes{v1.2n}{2023/05/13}{add \cs{ignorespaces} gh/1059} +% Ensure the (deprecated) \verb|$$..\eqno 1 $$| ignores spaces. % \begin{macrocode} %</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2023/06/01}% +%<latexrelease> {\eqno}{add ignorespaces to eqno}% +\let\@kernel@eqno\eqno +\let\@kernel@leqno\leqno +\protected\def\eqno{\@kernel@eqno\aftergroup\ignorespaces} +\protected\def\leqno{\@kernel@leqno\aftergroup\ignorespaces} +%</2ekernel|latexrelease> +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\eqno}{add ignorespaces to eqno}% +%<latexrelease>\let\eqno\@kernel@eqno +%<latexrelease>\let\leqno\@kernel@leqno +%<latexrelease>\EndIncludeInRelease % \end{macrocode} +% \end{macro} +% \end{macro} % % % @@ -1322,6 +1342,5 @@ % \end{environment} % % -% % \Finale % diff --git a/macros/latex/base/ltmeta.dtx b/macros/latex/base/ltmeta.dtx index 31c5d8dbee..daaa71626b 100644 --- a/macros/latex/base/ltmeta.dtx +++ b/macros/latex/base/ltmeta.dtx @@ -1,7 +1,8 @@ % \iffalse meta-comment % -%% File: ltmeta.dtx (C) Copyright 2021, 2022 -% Frank Mittelbach, LaTeX Team +%% File: ltmeta.dtx +%% Copyright (C) 2021-2023 +%% Frank Mittelbach, 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 diff --git a/macros/latex/base/ltmiscen.dtx b/macros/latex/base/ltmiscen.dtx index b7b2bf5e31..801d1e6862 100644 --- a/macros/latex/base/ltmiscen.dtx +++ b/macros/latex/base/ltmiscen.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltmiscen.dtx} - [2021/06/05 v1.1z LaTeX Kernel (Misc. Environments)] + [2022/11/06 v1.2a LaTeX Kernel (Misc. Environments)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltmiscen.dtx} @@ -270,9 +270,17 @@ % This is one of the few places where we already add data and rules % to a hook already in the kernel. % \changes{v1.0w}{1994/11/30}{(DPC) Use \cs{@dofilelist}} +% \changes{v1.2a}{2022/11/06}{Repeat release info at the end (gh/944)} % \begin{macrocode} \AddToHook{enddocument/info}[kernel/filelist]{\@dofilelist} \AddToHook{enddocument/info}[kernel/warnings]{\@enddocument@kernel@warnings} +\AddToHook{enddocument/info}[kernel/release]{% + \let\show@release@info\wlog + \show@release@info{ ***********}% + \the\LaTeXReleaseInfo + \show@release@info{ ***********}} + +\DeclareHookRule{enddocument/info}{kernel/release}{before}{kernel/filelist} \DeclareHookRule{enddocument/info}{kernel/filelist}{before}{kernel/warnings} % \end{macrocode} % \end{macro} diff --git a/macros/latex/base/ltnews.cls b/macros/latex/base/ltnews.cls index 9271b56f1c..45ee3664d1 100644 --- a/macros/latex/base/ltnews.cls +++ b/macros/latex/base/ltnews.cls @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 1993-2020 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -41,7 +41,7 @@ \NeedsTeXFormat{LaTeX2e} -\ProvidesClass{ltnews}[2017/12/13 v1.06 Standard LaTeX class] +\ProvidesClass{ltnews}[2023/05/28 v1.08 Standard LaTeX class] % The configuration file, used for passing options. @@ -429,6 +429,30 @@ \newcommand{\@year}{\ClassError{ltnews} {No \protect\publicationyear~given}\@eha} +\newcommand{\publicationday}{\renewcommand{\@day}} +\newcommand{\@day}{01} % most releases happen on 1st of a month + +\newcommand{\publicationdate}{% + % support draft ltnews, \publicationyear{2023 --- DRAFT ...} + \expandafter\@gobblenonyear\@year\@nil + -\@julianmonthtonum\@month-\two@digits\@day} + +\newcommand{\@julianmonthtonum}[1]{\@nameuse{@juliantonum#1}} +\def\@juliantonumJanuary {01} +\def\@juliantonumFebruary {02} +\def\@juliantonumMarch {03} +\def\@juliantonumApril {04} +\def\@juliantonumMay {05} +\def\@juliantonumJune {06} +\def\@juliantonumJuly {07} +\def\@juliantonumAugust {08} +\def\@juliantonumSeptember{09} +\def\@juliantonumOctober {10} +\def\@juliantonumNovember {11} +\def\@juliantonumDecember {12} + +\long\def\@gobblenonyear#1#2#3#4#5\@nil{#1#2#3#4} + \newcommand{\publicationissue}{\renewcommand{\@issue}} \newcommand{\@issue}{\ClassError{ltnews} {No \protect\publicationissue~given}\@eha} @@ -449,7 +473,8 @@ \twocolumn[{% \parbox[t][7\baselineskip]{\textwidth}{% \@titlefont\@title\\[\medskipamount] - \normalfont\normalsize\issuename~\@issue, \@month~\@year + \normalfont\normalsize\issuename~\@issue, + \@month~\@year~(\LaTeX\ release \publicationdate)% }% }]% \thispagestyle{titlepage} @@ -494,6 +519,17 @@ {1sp}{\@subheadingfont}% } + +% suggestion by Karl Berry (not integrated (yet)) + +\newcommand{\ltnewssectformat}{% + \@headingfont + \frenchspacing + \raggedright + \hyphenpenalty=10000 + \exhyphenpenalty=10000 +} + % No section numbers. \setcounter{secnumdepth}{0} diff --git a/macros/latex/base/ltnews.pdf b/macros/latex/base/ltnews.pdf index 5a52a33471..5ecb14ad3e 100644 Binary files a/macros/latex/base/ltnews.pdf and b/macros/latex/base/ltnews.pdf differ diff --git a/macros/latex/base/ltnews.tex b/macros/latex/base/ltnews.tex index 8d45f77cda..d239fc274f 100644 --- a/macros/latex/base/ltnews.tex +++ b/macros/latex/base/ltnews.tex @@ -1,7 +1,7 @@ % \iffalse meta-comment % % Copyright (C) 2006, 2009, 2011, 2014 Heiko Oberdiek -% Copyright (C) 2014-2022 +% Copyright (C) 2014-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -40,7 +40,7 @@ \ProvidesFile{ltnews.tex}% [2022/06/10 v1.4e Master file for ltnews*.tex (LaTeX Project)] -\providecommand*{\lastissue}{36} +\providecommand*{\lastissue}{37} \InputIfFileExists{ltnews-lastissue.cfg}{}{} @@ -113,22 +113,11 @@ \renewcommand{\@evenfoot}{\@indiciafont\@indicia\hfill --\thepage}% } -\newcommand*{\MonthJanuary}{01} -\newcommand*{\MonthFebruary}{02} -\newcommand*{\MonthMarch}{03} -\newcommand*{\MonthApril}{04} -\newcommand*{\MonthMay}{05} -\newcommand*{\MonthJune}{06} -\newcommand*{\MonthJuly}{07} -\newcommand*{\MonthAugust}{08} -\newcommand*{\MonthSeptember}{09} -\newcommand*{\MonthOctober}{10} -\newcommand*{\MonthNovember}{11} -\newcommand*{\MonthDecember}{12} \newcommand*{\printissue}{% Issue % \texorpdfstring{\number\value{issue}}{\theissue}, % - \texorpdfstring{\@month\space\@year}{\@year/\@nameuse{Month\@month}}% + \texorpdfstring{\@month\space\@year\space(\publicationdate)} + {\@year/\@julianmonthtonum{\@month}}% } \let\l@part\l@section \let\l@section\l@subsection @@ -303,6 +292,7 @@ \loop \ifnum\value{issue}<\lastissue \stepcounter{issue}% + \publicationday{01}% \input{ltnews\theissue}% \repeat \stepcounter{issue}% diff --git a/macros/latex/base/ltnews01.pdf b/macros/latex/base/ltnews01.pdf index 46f89cea3b..670facd8c6 100644 Binary files a/macros/latex/base/ltnews01.pdf and b/macros/latex/base/ltnews01.pdf differ diff --git a/macros/latex/base/ltnews01.tex b/macros/latex/base/ltnews01.tex index 08ac57d27d..55c6b20dd6 100644 --- a/macros/latex/base/ltnews01.tex +++ b/macros/latex/base/ltnews01.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews02.pdf b/macros/latex/base/ltnews02.pdf index bbe1c4ebd1..458c10709a 100644 Binary files a/macros/latex/base/ltnews02.pdf and b/macros/latex/base/ltnews02.pdf differ diff --git a/macros/latex/base/ltnews02.tex b/macros/latex/base/ltnews02.tex index 1d875dcd03..58856fe97b 100644 --- a/macros/latex/base/ltnews02.tex +++ b/macros/latex/base/ltnews02.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews03.pdf b/macros/latex/base/ltnews03.pdf index 58a9a40d0b..54deb688dd 100644 Binary files a/macros/latex/base/ltnews03.pdf and b/macros/latex/base/ltnews03.pdf differ diff --git a/macros/latex/base/ltnews03.tex b/macros/latex/base/ltnews03.tex index 93f0963426..96a5bec428 100644 --- a/macros/latex/base/ltnews03.tex +++ b/macros/latex/base/ltnews03.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews04.pdf b/macros/latex/base/ltnews04.pdf index 5236b48dd8..37a344bc9d 100644 Binary files a/macros/latex/base/ltnews04.pdf and b/macros/latex/base/ltnews04.pdf differ diff --git a/macros/latex/base/ltnews04.tex b/macros/latex/base/ltnews04.tex index 527024fa18..ab49d7ade3 100644 --- a/macros/latex/base/ltnews04.tex +++ b/macros/latex/base/ltnews04.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews05.pdf b/macros/latex/base/ltnews05.pdf index 82c03a4c12..f84999681e 100644 Binary files a/macros/latex/base/ltnews05.pdf and b/macros/latex/base/ltnews05.pdf differ diff --git a/macros/latex/base/ltnews05.tex b/macros/latex/base/ltnews05.tex index d13f469dd6..cdfe8bc072 100644 --- a/macros/latex/base/ltnews05.tex +++ b/macros/latex/base/ltnews05.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews06.pdf b/macros/latex/base/ltnews06.pdf index 0b8753998e..d5b2c509a7 100644 Binary files a/macros/latex/base/ltnews06.pdf and b/macros/latex/base/ltnews06.pdf differ diff --git a/macros/latex/base/ltnews06.tex b/macros/latex/base/ltnews06.tex index ac32eab8d1..3d5cadb745 100644 --- a/macros/latex/base/ltnews06.tex +++ b/macros/latex/base/ltnews06.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews07.pdf b/macros/latex/base/ltnews07.pdf index b8aad35370..bca35e9904 100644 Binary files a/macros/latex/base/ltnews07.pdf and b/macros/latex/base/ltnews07.pdf differ diff --git a/macros/latex/base/ltnews07.tex b/macros/latex/base/ltnews07.tex index 56cfd76661..43cf204fed 100644 --- a/macros/latex/base/ltnews07.tex +++ b/macros/latex/base/ltnews07.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews08.pdf b/macros/latex/base/ltnews08.pdf index c3d9b6b848..157e8f2c3d 100644 Binary files a/macros/latex/base/ltnews08.pdf and b/macros/latex/base/ltnews08.pdf differ diff --git a/macros/latex/base/ltnews08.tex b/macros/latex/base/ltnews08.tex index 68cd1247e6..f1386a5332 100644 --- a/macros/latex/base/ltnews08.tex +++ b/macros/latex/base/ltnews08.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews09.pdf b/macros/latex/base/ltnews09.pdf index 92fb1771a0..543a2c8795 100644 Binary files a/macros/latex/base/ltnews09.pdf and b/macros/latex/base/ltnews09.pdf differ diff --git a/macros/latex/base/ltnews09.tex b/macros/latex/base/ltnews09.tex index af14a53e34..26eccedd1e 100644 --- a/macros/latex/base/ltnews09.tex +++ b/macros/latex/base/ltnews09.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews10.pdf b/macros/latex/base/ltnews10.pdf index f87a2bd4e2..7dc732ba41 100644 Binary files a/macros/latex/base/ltnews10.pdf and b/macros/latex/base/ltnews10.pdf differ diff --git a/macros/latex/base/ltnews10.tex b/macros/latex/base/ltnews10.tex index c6a77e6e36..b011eacf7e 100644 --- a/macros/latex/base/ltnews10.tex +++ b/macros/latex/base/ltnews10.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews11.pdf b/macros/latex/base/ltnews11.pdf index 8a9605348b..c07bf4681b 100644 Binary files a/macros/latex/base/ltnews11.pdf and b/macros/latex/base/ltnews11.pdf differ diff --git a/macros/latex/base/ltnews11.tex b/macros/latex/base/ltnews11.tex index b4f6d19910..07dbd64240 100644 --- a/macros/latex/base/ltnews11.tex +++ b/macros/latex/base/ltnews11.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews12.pdf b/macros/latex/base/ltnews12.pdf index b74dc492f6..f848096ed0 100644 Binary files a/macros/latex/base/ltnews12.pdf and b/macros/latex/base/ltnews12.pdf differ diff --git a/macros/latex/base/ltnews12.tex b/macros/latex/base/ltnews12.tex index b7a01bc208..38ea9122a0 100644 --- a/macros/latex/base/ltnews12.tex +++ b/macros/latex/base/ltnews12.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews13.pdf b/macros/latex/base/ltnews13.pdf index 014faa5e5f..d511573394 100644 Binary files a/macros/latex/base/ltnews13.pdf and b/macros/latex/base/ltnews13.pdf differ diff --git a/macros/latex/base/ltnews13.tex b/macros/latex/base/ltnews13.tex index 0cbbe49a5d..e489b4ff27 100644 --- a/macros/latex/base/ltnews13.tex +++ b/macros/latex/base/ltnews13.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews14.pdf b/macros/latex/base/ltnews14.pdf index 40972a5a43..debb104763 100644 Binary files a/macros/latex/base/ltnews14.pdf and b/macros/latex/base/ltnews14.pdf differ diff --git a/macros/latex/base/ltnews14.tex b/macros/latex/base/ltnews14.tex index b5fa7cb019..44cc44647e 100644 --- a/macros/latex/base/ltnews14.tex +++ b/macros/latex/base/ltnews14.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews15.pdf b/macros/latex/base/ltnews15.pdf index 3fd5dce4aa..9e2432ea99 100644 Binary files a/macros/latex/base/ltnews15.pdf and b/macros/latex/base/ltnews15.pdf differ diff --git a/macros/latex/base/ltnews15.tex b/macros/latex/base/ltnews15.tex index 3b1ea3f89c..b95801dd6e 100644 --- a/macros/latex/base/ltnews15.tex +++ b/macros/latex/base/ltnews15.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews16.pdf b/macros/latex/base/ltnews16.pdf index 5fc21f98ee..612c1bd5f2 100644 Binary files a/macros/latex/base/ltnews16.pdf and b/macros/latex/base/ltnews16.pdf differ diff --git a/macros/latex/base/ltnews16.tex b/macros/latex/base/ltnews16.tex index 7f7183ac0e..7edf8a7f53 100644 --- a/macros/latex/base/ltnews16.tex +++ b/macros/latex/base/ltnews16.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews17.pdf b/macros/latex/base/ltnews17.pdf index 9806abea05..e8325346a0 100644 Binary files a/macros/latex/base/ltnews17.pdf and b/macros/latex/base/ltnews17.pdf differ diff --git a/macros/latex/base/ltnews17.tex b/macros/latex/base/ltnews17.tex index 4dab20f53f..e18e4660eb 100644 --- a/macros/latex/base/ltnews17.tex +++ b/macros/latex/base/ltnews17.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews18.pdf b/macros/latex/base/ltnews18.pdf index b3628bab08..641dc18d2e 100644 Binary files a/macros/latex/base/ltnews18.pdf and b/macros/latex/base/ltnews18.pdf differ diff --git a/macros/latex/base/ltnews18.tex b/macros/latex/base/ltnews18.tex index 04491760b2..8c70621534 100644 --- a/macros/latex/base/ltnews18.tex +++ b/macros/latex/base/ltnews18.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews19.pdf b/macros/latex/base/ltnews19.pdf index d6ac262c05..2bf99f3954 100644 Binary files a/macros/latex/base/ltnews19.pdf and b/macros/latex/base/ltnews19.pdf differ diff --git a/macros/latex/base/ltnews19.tex b/macros/latex/base/ltnews19.tex index 43d388b29b..7e9492a8f2 100644 --- a/macros/latex/base/ltnews19.tex +++ b/macros/latex/base/ltnews19.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -36,6 +36,7 @@ \usepackage{lmodern,url} +\publicationday{24} \publicationmonth{September} \publicationyear{2009} diff --git a/macros/latex/base/ltnews20.pdf b/macros/latex/base/ltnews20.pdf index 54544a702f..6382f7b26f 100644 Binary files a/macros/latex/base/ltnews20.pdf and b/macros/latex/base/ltnews20.pdf differ diff --git a/macros/latex/base/ltnews20.tex b/macros/latex/base/ltnews20.tex index 89d166b49c..b233f92dc4 100644 --- a/macros/latex/base/ltnews20.tex +++ b/macros/latex/base/ltnews20.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 1993--2019 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -36,6 +36,7 @@ \usepackage{lmodern,url} +\publicationday{27} \publicationmonth{June} \publicationyear{2011} diff --git a/macros/latex/base/ltnews21.pdf b/macros/latex/base/ltnews21.pdf index 69332e0e04..c6b0913181 100644 Binary files a/macros/latex/base/ltnews21.pdf and b/macros/latex/base/ltnews21.pdf differ diff --git a/macros/latex/base/ltnews21.tex b/macros/latex/base/ltnews21.tex index 7b363447d9..a48cd0b199 100644 --- a/macros/latex/base/ltnews21.tex +++ b/macros/latex/base/ltnews21.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 2019 +% Copyright (C) 2019-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews22.pdf b/macros/latex/base/ltnews22.pdf index 429820ea50..4ca923a557 100644 Binary files a/macros/latex/base/ltnews22.pdf and b/macros/latex/base/ltnews22.pdf differ diff --git a/macros/latex/base/ltnews22.tex b/macros/latex/base/ltnews22.tex index 8d1c91acfa..dfc2e2326a 100644 --- a/macros/latex/base/ltnews22.tex +++ b/macros/latex/base/ltnews22.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2015-2022 +% Copyright (C) 2015-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews23.pdf b/macros/latex/base/ltnews23.pdf index 86bcb55ada..b3b97d9071 100644 Binary files a/macros/latex/base/ltnews23.pdf and b/macros/latex/base/ltnews23.pdf differ diff --git a/macros/latex/base/ltnews23.tex b/macros/latex/base/ltnews23.tex index 29241766ca..ee75a6463e 100644 --- a/macros/latex/base/ltnews23.tex +++ b/macros/latex/base/ltnews23.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2015-2022 +% Copyright (C) 2015-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews24.pdf b/macros/latex/base/ltnews24.pdf index 30ddd82eba..0555a29b8c 100644 Binary files a/macros/latex/base/ltnews24.pdf and b/macros/latex/base/ltnews24.pdf differ diff --git a/macros/latex/base/ltnews24.tex b/macros/latex/base/ltnews24.tex index 13d2fc8519..6a50ef902c 100644 --- a/macros/latex/base/ltnews24.tex +++ b/macros/latex/base/ltnews24.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2015-2022 +% Copyright (C) 2015-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews25.pdf b/macros/latex/base/ltnews25.pdf index 0e2c3fa717..17c09e30d9 100644 Binary files a/macros/latex/base/ltnews25.pdf and b/macros/latex/base/ltnews25.pdf differ diff --git a/macros/latex/base/ltnews25.tex b/macros/latex/base/ltnews25.tex index 5a9f480718..0676220a2e 100644 --- a/macros/latex/base/ltnews25.tex +++ b/macros/latex/base/ltnews25.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2016-2022 +% Copyright (C) 2016-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews26.pdf b/macros/latex/base/ltnews26.pdf index 0e31e2c482..64a5a94b8a 100644 Binary files a/macros/latex/base/ltnews26.pdf and b/macros/latex/base/ltnews26.pdf differ diff --git a/macros/latex/base/ltnews26.tex b/macros/latex/base/ltnews26.tex index 94b4c4818b..9fbb6716b1 100644 --- a/macros/latex/base/ltnews26.tex +++ b/macros/latex/base/ltnews26.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2017-2022 +% Copyright (C) 2017-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews27.pdf b/macros/latex/base/ltnews27.pdf index 260f2b6ebd..0db3aec237 100644 Binary files a/macros/latex/base/ltnews27.pdf and b/macros/latex/base/ltnews27.pdf differ diff --git a/macros/latex/base/ltnews27.tex b/macros/latex/base/ltnews27.tex index 03c8c04205..917bf1cc10 100644 --- a/macros/latex/base/ltnews27.tex +++ b/macros/latex/base/ltnews27.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2017-2022 +% Copyright (C) 2017-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -35,6 +35,7 @@ \usepackage{lmodern,url,hologo} +\publicationday{15} \publicationmonth{April} \publicationyear{2017} diff --git a/macros/latex/base/ltnews28.pdf b/macros/latex/base/ltnews28.pdf index a20223db92..e1bdb5e1b5 100644 Binary files a/macros/latex/base/ltnews28.pdf and b/macros/latex/base/ltnews28.pdf differ diff --git a/macros/latex/base/ltnews28.tex b/macros/latex/base/ltnews28.tex index 28bfe0577c..3c3b92da97 100644 --- a/macros/latex/base/ltnews28.tex +++ b/macros/latex/base/ltnews28.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2017-2022 +% Copyright (C) 2017-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews29.pdf b/macros/latex/base/ltnews29.pdf index 95619ddaff..609c139590 100644 Binary files a/macros/latex/base/ltnews29.pdf and b/macros/latex/base/ltnews29.pdf differ diff --git a/macros/latex/base/ltnews29.tex b/macros/latex/base/ltnews29.tex index c06d4de347..999836b01d 100644 --- a/macros/latex/base/ltnews29.tex +++ b/macros/latex/base/ltnews29.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2018-2022 +% Copyright (C) 2018-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews30.pdf b/macros/latex/base/ltnews30.pdf index d45d527caa..fbd9a3af3d 100644 Binary files a/macros/latex/base/ltnews30.pdf and b/macros/latex/base/ltnews30.pdf differ diff --git a/macros/latex/base/ltnews30.tex b/macros/latex/base/ltnews30.tex index 74d7659512..8183f7eabb 100644 --- a/macros/latex/base/ltnews30.tex +++ b/macros/latex/base/ltnews30.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 2019 +% Copyright (C) 2019-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews31.pdf b/macros/latex/base/ltnews31.pdf index f88b776066..bb9c2e3e45 100644 Binary files a/macros/latex/base/ltnews31.pdf and b/macros/latex/base/ltnews31.pdf differ diff --git a/macros/latex/base/ltnews31.tex b/macros/latex/base/ltnews31.tex index 8bb6e638b5..44bf494142 100644 --- a/macros/latex/base/ltnews31.tex +++ b/macros/latex/base/ltnews31.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 2019-2020 +% Copyright (C) 2019-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -119,6 +119,7 @@ \fi %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\publicationday{02} \publicationmonth{February} \publicationyear{2020} diff --git a/macros/latex/base/ltnews32.pdf b/macros/latex/base/ltnews32.pdf index f6298a7cfb..6c99b2cf6d 100644 Binary files a/macros/latex/base/ltnews32.pdf and b/macros/latex/base/ltnews32.pdf differ diff --git a/macros/latex/base/ltnews32.tex b/macros/latex/base/ltnews32.tex index 28f3bf88b4..c64cd97958 100644 --- a/macros/latex/base/ltnews32.tex +++ b/macros/latex/base/ltnews32.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 2019-2020 +% Copyright (C) 2019-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews33.pdf b/macros/latex/base/ltnews33.pdf index b5132f035e..9372bf0ec1 100644 Binary files a/macros/latex/base/ltnews33.pdf and b/macros/latex/base/ltnews33.pdf differ diff --git a/macros/latex/base/ltnews33.tex b/macros/latex/base/ltnews33.tex index 39af4f1b72..0b98a707ba 100644 --- a/macros/latex/base/ltnews33.tex +++ b/macros/latex/base/ltnews33.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 2019-2021 +% Copyright (C) 2019-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltnews34.pdf b/macros/latex/base/ltnews34.pdf index 8962193f72..481e449690 100644 Binary files a/macros/latex/base/ltnews34.pdf and b/macros/latex/base/ltnews34.pdf differ diff --git a/macros/latex/base/ltnews34.tex b/macros/latex/base/ltnews34.tex index 04d1c25bc7..d3a9202b56 100644 --- a/macros/latex/base/ltnews34.tex +++ b/macros/latex/base/ltnews34.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 2019-2021 +% Copyright (C) 2019-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -116,6 +116,7 @@ \providecommand\tubcommand[1]{} \tubcommand{\input{tubltmac}} +\publicationday{15} \publicationmonth{November} \publicationyear{2021} diff --git a/macros/latex/base/ltnews35.pdf b/macros/latex/base/ltnews35.pdf index e044273d06..1eda06fb70 100644 Binary files a/macros/latex/base/ltnews35.pdf and b/macros/latex/base/ltnews35.pdf differ diff --git a/macros/latex/base/ltnews35.tex b/macros/latex/base/ltnews35.tex index 0230ef6e58..8d49bf1984 100644 --- a/macros/latex/base/ltnews35.tex +++ b/macros/latex/base/ltnews35.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 2021-2022 +% Copyright (C) 2021-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -322,7 +322,6 @@ has been refined, such that \ProcessKeyOptions \end{verbatim} will now automatically pick up the package name as the key \emph{family}, -%unless explicitly given as an optional argument. unless explicitly given as an optional argument: \begin{verbatim} \ProcessKeyOptions[family] @@ -378,9 +377,7 @@ syntax are described in \file{usrguide3.pdf}. The command \cs{fpeval} offers a rich syntax allowing for extensive calculations, whereas the other three commands are essentially thin wrappers for \cs{numexpr}, \cs{dimexpr}, and \cs{glueexpr} \Dash therefore inheriting some syntax -%peculiars and limitations in expressiveness. peculiarities and limitations in expressiveness. -% \newcommand\calulateheight[1]{% \begin{verbatim} \newcommand\calculateheight[1]{% \setlength\textheight{\dimeval{\topskip @@ -698,7 +695,7 @@ Source files containing \textlangle\ or \textrangle\ directly written as Unicode codepoints U+2329 and U+232A no longer break when the source file gets normalized under Unicode normalization rules. % -\githubissue{gh/714} +\githubissue{714} @@ -907,7 +904,6 @@ For details and further examples, see \file{mathcolor.pdf}. \subsection{Fix locating files with \cs{graphicspath}} -% If a call to \cs{includegraphics} asked for a file (say, \file{image}) without extension, and if both \file{A/image.pdf} and \file{B/image.tex} @@ -953,22 +949,10 @@ internal syntax errors due to premature expansion. \emph{\LaTeX{} Tagged PDF \Dash A blueprint for a large project}.\\ \url{https://latex-project.org/publications/indexbyyear/2020/} -%\bibitem{35:source2e} -% \emph{\LaTeX{} documentation on the \LaTeX{} Project Website}.\\ -% \url{https://latex-project.org/help/documentation/} - -%\bibitem{35:ltnews31} \LaTeX{} Project Team: -% \emph{\LaTeXe{} news 31}.\\ -% \url{https://latex-project.org/news/latex2e-news/ltnews31.pdf} - \bibitem{35:ltnews32} \LaTeX{} Project Team: \emph{\LaTeXe{} news 32}.\\ \url{https://latex-project.org/news/latex2e-news/ltnews32.pdf} -%\bibitem{35:ltnews33} \LaTeX{} Project Team: -% \emph{\LaTeXe{} news 33}.\\ -% \url{https://latex-project.org/news/latex2e-news/ltnews33.pdf} - \bibitem{35:ltnews34} \LaTeX{} Project Team: \emph{\LaTeXe{} news 34}.\\ \url{https://latex-project.org/news/latex2e-news/ltnews34.pdf} diff --git a/macros/latex/base/ltnews36.pdf b/macros/latex/base/ltnews36.pdf index fbbd2036d0..7113dbcce4 100644 Binary files a/macros/latex/base/ltnews36.pdf and b/macros/latex/base/ltnews36.pdf differ diff --git a/macros/latex/base/ltnews36.tex b/macros/latex/base/ltnews36.tex index d6df801db2..5dee958747 100644 --- a/macros/latex/base/ltnews36.tex +++ b/macros/latex/base/ltnews36.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 2021-2022 +% Copyright (C) 2021-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -262,10 +262,11 @@ will give the expected result: {\fontfamily{cmr} \bfseries \textsc{\textsl{Bold Slanted Small Caps}}; \textsc{\textit{Bold Italic Small Caps}}}. -Given that the Computer Modern fonts in \texttt{T1} do not have real italic small caps but only -slanted small caps, the latter is substituted for the former, which is -why above both work but you see no difference between the two (and in the log you get a -substitution warning for the \cs{textit}\cs{textsc} shape combination). +Given that the Computer Modern fonts in \texttt{T1} do not have real +italic small caps but only slanted small caps, the latter is +substituted for the former. This is why both work in the above, but +there is no difference between the two (and you get a substitution +warning for the \cs{textit}\cs{textsc} shape combination). % \githubissue{782} diff --git a/macros/latex/base/ltnews37.pdf b/macros/latex/base/ltnews37.pdf new file mode 100644 index 0000000000..b0f6947d8d Binary files /dev/null and b/macros/latex/base/ltnews37.pdf differ diff --git a/macros/latex/base/ltnews37.tex b/macros/latex/base/ltnews37.tex new file mode 100644 index 0000000000..5527975c54 --- /dev/null +++ b/macros/latex/base/ltnews37.tex @@ -0,0 +1,848 @@ +% \iffalse meta-comment +% +% Copyright (C) 2021-2023 +% The LaTeX Project and any individual authors listed elsewhere +% in this file. +% +% This file is part of the LaTeX base system. +% -—————————————— +% +% It may be distributed and/or modified under the +% conditions of the LaTeX Project Public License, either version 1.3c +% of this license or (at your option) any later version. +% The latest version of this license is in +% https://www.latex-project.org/lppl.txt +% and version 1.3c or later is part of all distributions of LaTeX +% version 2008 or later. +% +% This file has the LPPL maintenance status "maintained". +% +% The list of all files belonging to the LaTeX base distribution is +% given in the file `manifest.txt'. See also `legal.txt' for additional +% information. +% +% The list of derived (unpacked) files belonging to the distribution +% and covered by LPPL is defined by the unpacking scripts (with +% extension .ins) which are part of the distribution. +% +% \fi +% Filename: ltnews37.tex +% +% This is issue 37 of LaTeX News. + +\NeedsTeXFormat{LaTeX2e}[2020-02-02] + +\documentclass{ltnews} + +%% Maybe needed only for Chris' inadequate system: +\providecommand\Dash {\unskip \textemdash} + +%% NOTE: Chris' preferred hyphens! +%%\showhyphens{parameters} +%% \hyphenation{because parameters parameter} + +\usepackage[T1]{fontenc} + +\usepackage{lmodern,url,hologo} + +\usepackage{csquotes} +\usepackage{multicol} +\usepackage{color} + +\providecommand\hook[1]{\texttt{#1}} + +\providecommand\meta[1]{$\langle$\textrm{\itshape#1}$\rangle$} +\providecommand\option[1]{\texttt{#1}} +\providecommand\env[1]{\texttt{#1}} +\providecommand\Arg[1]{\texttt\{\meta{#1}\texttt\}} + + +\providecommand\eTeX{\hologo{eTeX}} +\providecommand\XeTeX{\hologo{XeTeX}} +\providecommand\LuaTeX{\hologo{LuaTeX}} +\providecommand\pdfTeX{\hologo{pdfTeX}} +\providecommand\MiKTeX{\hologo{MiKTeX}} +\providecommand\CTAN{\textsc{ctan}} +\providecommand\TL{\TeX\,Live} +\providecommand\githubissue[2][]{\ifhmode\unskip\fi + \quad\penalty500\strut\nobreak\hfill + \mbox{\small\slshape(% + \href{https://github.com/latex3/latex2e/issues/\getfirstgithubissue#2 \relax}% + {github issue#1 #2}% + )}% + \par\smallskip} +%% But Chris has to mostly disable \href for his TEXPAD app: +%% \def\href #1{} % Only For Chris' deficient TeX engine + +% simple solution right now (just link to the first issue if there are more) +\def\getfirstgithubissue#1 #2\relax{#1} + +\providecommand\sxissue[1]{\ifhmode\unskip + \else + % githubissue preceding + \vskip-\smallskipamount + \vskip-\parskip + \fi + \quad\penalty500\strut\nobreak\hfill + \mbox{\small\slshape(\url{https://tex.stackexchange.com/#1})}\par} + +\providecommand\gnatsissue[2]{\ifhmode\unskip\fi + \quad\penalty500\strut\nobreak\hfill + \mbox{\small\slshape(% + \href{https://www.latex-project.org/cgi-bin/ltxbugs2html?pr=#1\%2F\getfirstgithubissue#2 \relax}% + {gnats issue #1/#2}% + )}% + \par} + +\let\cls\pkg +\providecommand\env[1]{\texttt{#1}} +\providecommand\acro[1]{\textsc{#1}} + +\vbadness=1400 % accept slightly empty columns + + +\makeatletter +% maybe not the greatest design but normally we wouldn't have subsubsections +\renewcommand{\subsubsection}{% + \@startsection {subsubsection}{2}{0pt}{1.5ex \@plus 1ex \@minus .2ex}% + {-1em}{\@subheadingfont\colonize}% +} +\providecommand\colonize[1]{#1:} +\makeatother + +\let\finalvspace\vspace % for document layout fixes + +% Undo ltnews's \verbatim@font with active < and > +% (we have meta variables in verbatim, so keep it.) +%\makeatletter +%\def\verbatim@font{% +% \normalsize\ttfamily} +%\makeatother + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +\providecommand\tubcommand[1]{} +\tubcommand{\input{tubltmac}} + +% \publicationday{01} % change this if it's not released on 1st of a month +\publicationmonth{June} +%\publicationyear{2023 --- DRAFT version for upcoming release} +\publicationyear{2023} + +\publicationissue{37} + +\begin{document} + +\tubcommand{\addtolength\textheight{4.1pc}} % only for TUB + +\maketitle +{\hyphenpenalty=10000 \exhyphenpenalty=10000 \spaceskip=3.33pt \hbadness=10000 +\tableofcontents} + +\setlength\rightskip{0pt plus 3em} + +% for ltnews37, squeeze to five pages. +\tubcommand{\fontsize{9.6}{12}\selectfont} + + +\medskip + + +%\section{Introduction} + + +\section{New functionality offered as part of the + \enquote{\LaTeX{} Tagged PDF} project} + +We have now enabled new automatic tagging functionality for additional +\LaTeX{} elements, among them most display environments, standard +sectioning commands, content, figure and table listings, floats and graphics and +bibliographies. This can +be activated through +\begin{verbatim} +\DocumentMetadata{testphase=phase-III} +\end{verbatim} +At this point in time tagging support is only available for a +restricted set of documents, i.e., those that use one of the basic +document classes (\texttt{article}, \texttt{report}, and +\texttt{book}) and only use commands and environments described in +Lamport's \LaTeX{} manual. + +Using other document classes or adding additional packages in the +preamble may work (or may partially work) but at this stage it is not +very likely, at least not for packages or classes that excessively +alter internals of \LaTeX{}. + +Also note that there are still several environments and commands +described in the \LaTeX{} manual that do not have tagging support yet, +notably tabulars, \texttt{tabbing}, the various math environment and a +few others. They will get this support as part of \texttt{phase-III}, +but some of them will be delayed until after the June release. + +A prototype for math tagging (including support for the \pkg{amsmath} +environments) is already available, but it is mainly intended for +experimentation and feedback and the resulting tagging is by no means +the way we envision it to be eventually. If you would like to try it out use +the following line: +\begin{verbatim} +\DocumentMetadata{testphase={phase-III,math}} +\end{verbatim} +Note that the math tagging code at this point in time will clash with +packages that redefine the \texttt{\$} character (which then may lead to strange +errors) and that packages that use math mode for non-mathematical +constructs may result in surprising output as far as tagging is +concerned. Feedback on which packages fail with the code in one or +another way would be appreciated. + +The \texttt{latex-lab} bundle contains various +(still untagged) documentation files about the new code that can +be accessed with \verb|texdoc -l latex-lab|. + +Feedback is welcome! +Please use \url{https://github.com/latex3/latex2e/discussions/1010}. + + + +\section{New or improved commands} + +\subsection{Extending hooks to take arguments} + +Hooks have always been containers for code whose outcome was entirely +dependent on the contents of the hook alone. If any type of contextual +information had to be passed to the hook, it had to be done by setting +some variable before the hook so that the code in the hook could use +that. But this is somewhat hard to keep track of, clumsy to implement, +and it required the programmer to have some kind of \enquote{hook before +the hook} to do that setup. + +To make things a bit easier, \pkg{lthooks} was enhanced to support hooks +with arguments. Hooks can now be declared and used with arguments, then +the code added to these hooks can reference the hook's arguments using +\verb|#1|, \verb|#2|, etc., so now hooks can behave more like macros +than like \emph{token lists} (using \pkg{expl3} terminology). Regular +argument-less hooks continue to work exactly like they did before: this +extension is completely compatible with older documents and packages. + +\AddToHook{cmd/verbatim@font/after}[hack]{\small} +To declare a hook with arguments, use +\begin{verbatim} +\NewHookWithArguments {<hook>} {<num-args>} +\end{verbatim} +then, similarly, to use the code in the hook, supposing a hook declared +with 2 arguments, write +\begin{verbatim} +\UseHookWithArguments {<hook>} {2} {<arg1>} {<arg2>} +\end{verbatim} + +Or, if you want to add some code to a hook that takes arguments, write +\begin{verbatim} +\AddToHookWithArguments {<hook>} [<label>] {<code>} +\end{verbatim} +exactly like you would for regular hooks, except that the \meta{code} +can use the arguments by referencing \verb|#1|, \verb|#2|, etc. In this +case, if you want to add an actual parameter token (\verb|#|) to the +\meta{code}, you have to double it, as usual. +\RemoveFromHook{cmd/verbatim@font/after}[hack] + +Additionally, if you want to add \enquote{regular} code to a hook with +arguments, you can still use \cs{AddToHook} --- in that case \verb|#| +tokens are \emph{not} doubled. This means that a package author can +decide to add arguments to an existing hook without worrying about +compatibility: \cs{AddToHook} will do the right thing and will not +mistakenly reference the newly added arguments. + +The commands \cs{NewReversedHookWithArguments}, \cs +{NewMirroredHookPairWithArguments}, \cs +{AddToHookNextWithArguments}, \cs{UseOneTimeHookWithArguments}, and +the \pkg{expl3} counterparts of the commands discussed in this section +were also added. The complete documentation can be found in the +\pkg{lthooks} documentation \cite{37:lthooks-doc}. + +\subsubsection{Generic \texttt{cmd} hooks with arguments} + +Along with the possibility of passing arguments to a regular hook as +discussed above, generic \hook{cmd} hooks can now access the arguments +of the command they are patched into, using the interface described in +the previous section. + +For example, if you were to add some code to the \cs{title} command +using hooks, you could access the actual title given in the argument. +Thus, to write the title of the document in the terminal you +could use: +\begin{verbatim} + \AddToHookWithArguments{cmd/title/before} + {\typeout{Document title: #1}} +\end{verbatim} + +As with regular hooks, code added to a \hook{cmd} hook using +\cs{AddToHook} will not be able to access the command's arguments. This +means that, as with regular hooks, this change is completely backwards +compatible, so previous usages of \hook{cmd} hooks will work exactly as +they did before. + +\subsection{Providing copy and show functions for environments} + +To copy a command definition we introduced \cs{NewCommandCopy} in +2022. This even allows you to copy commands that consist of several internal +components, such as robust commands or those with a complex signature. +To do the same with environments, e.g., to define the environment +\env{myitemize} to be equivalent to \env{itemize}, you can now write +\begin{verbatim} + \NewEnvironmentCopy{myitemize}{itemize} +\end{verbatim} +There are also \cs{Renew...}\ and \cs{Declare...}, which may be useful +depending on the circumstances. + +In addition, we offer a \cs{ShowEnvironment} command, which displays the +\cs{begin} and \cs{end} code of the environment passed as an +argument. E.g., \verb=\ShowEnvironment{center}= results in the +following output: +\begin{verbatim} + >> \begin{center}=environment: + >> ->>\trivlist \centering \item \relax . + <<recently read>> } + l. ...\ShowEnvironment{center} + >> \end{center}: + >> ->>\endtrivlist . + <<recently read>> } + l. ...\ShowEnvironment{center} +\end{verbatim} +% +\githubissue{963} + +\subsection{\cs{IfFileAtLeastTF}} + +The 2020-10-01 \LaTeX{} release introduced the CamelCase tests +\cs{IfClassAtLeastTF} and \cs{IfPackageAtLeastTF} for checking class +and package dates. We have now added \cs{IfFileAtLeastTF} to allow the +same to happen for generic files which contain a \cs{ProvidesFile} +line. +% +\githubissue{1015} + +\subsection{\cs{DeclareLowercaseMapping}, \cs{DeclareTitlecaseMapping} + and \cs{DeclareUppercaseMapping}\texorpdfstring{\raggedright}{}} + +The move from a case-changing approach using \cs{lccode} and \cs{uccode} data +to one where information is stored by a kernel-managed structure left a gap in +the ability of the user to \emph{tune} the case changing outcomes. This has now +been addressed by the addition of three commands +\begin{itemize}\tubcommand{\setlength{\parskip}{0pt}}% + \item \cs{DeclareLowercaseMapping} + \item \cs{DeclareTitlecaseMapping} + \item \cs{DeclareUppercaseMapping} +\end{itemize} +which can be used to customise the outcome for codepoints. This can be applied +generally or to a specific locale (see also the next section). A small number +of pre-defined customisations have been set up in the kernel where the outcomes +for \pdfTeX{} should be different for those from Unicode engines. For +example +\begin{verbatim} + \DeclareUppercaseMapping{"01F0}{\v{J}} +\end{verbatim} +allows \v{J} to be produced in 8-bit engines: without this customisation, +an error would occur as there is no pre-composed \v{J} in Unicode. More detail +is given in \texttt{usrguide}. +% +\githubissue{1033} + +\subsection{\cs{BCPdata}} + +Improvements in the Unicode handling for case changing have highlighted that +the kernel has not to-date been locale-aware. The packages \pkg{babel} and +\pkg{polyglossia} provide comprehensive locale support, but did not have +an agreed unified interface to pass that information back to other code. +Following discussion with the maintainers of those two bundles, the kernel +now defines \cs{BCPdata} as a stub (so it is always defined), and \pkg{babel} +and \pkg{polyglossia} will redefine it to provide the locale data. An agreed +set of keywords mean that \cs{BCPdata} can be queried in a structured way +by both the kernel and any other \enquote{consumer} packages. +% +\githubissue{1035} + +\subsection{Improve \cs{samepage}} + +The \cs{samepage} declaration sets various parameters to +\texttt{10000} to prevent undesired page breaks. The +\cs{predisplaypenalty} parameter has already by default a value of +\texttt{10000}, and to save space in the past it was therefore not +explicitly set. However, there are a few classes that change the +parameter and as result the user might experience a page break in +front of a display formula within the scope of \cs{samepage} when +using such classes. This has now been corrected and +\cs{predisplaypenalty} is also explicitly set to \texttt{10000}. +% +\githubissue{1022} + +\subsection{Groups in \cs{MakeUppercase}} +% +Prior to 2022, \cs{MakeUppercase} and \cs{MakeLowercase} used a brace +group around their argument so providing a scope for any declarations +within the argument. This grouping has been restored (also +for \cs{MakeTitlecase}), although the underlying L3 text case commands do +not use grouping. +% +\githubissue{1021} + +\subsection{Extension of the \cs{label} command} + +Previously, in standard \LaTeX{}, the \cs{label} command wrote a \cs{newlabel} declaration into +the \texttt{.aux} file and stored two values in +the second argument of this \cs{newlabel} command: +\cs{@currentlabel}, which normally contains the state of the current +counter and \cs{thepage} for the current page number. + +The packages \pkg{hyperref} and +\pkg{nameref} then patched the \cs{label} command to store five values instead. +In addition to the above they saved \cs{@currentlabelname}, which normally contains the +current title text and can be retrieved with \cs{nameref}, and +\cs{@currentHref}, which is the name of the destination needed to create an +active link. The fifth argument was only used if external +references were loaded with the \pkg{xr-hyper} package. + +Starting with this release, the number of values stored in \cs{newlabel} has been unified. +\cs{label} now writes a +\cs{newlabel} command that always contains five values in the second argument (each in a brace group): +\cs{@currentlabel}, \cs{thepage}, \cs{@currentlabelname}, +\cs{@currentHref}, and \cs{@kernel@reserved@label@data} (which is reserved for the kernel). + +Additionally, a hook with the name \texttt{label} has been +added. It takes one argument: the label string. +Code added to the hook can refer to this argument with~\verb+#1+. +The hook is executed directly before the \cs{label} command writes to the \texttt{.aux} file +but \emph{after} the \cs{@bsphack} command has done its spacing magic, and it is located \emph{inside} a group; thus, its code only affects the write operation. + +\section{Code improvements} + +\subsection{Performance in checking file existence} + +The addition of hooks, etc., to file operations had a side effect of making +multiple checks that the file existed. In larger documents using +many files, these file system operations caused non-trivial performance +impact. We now cache the existence of files, such that these repeated filesystem +calls are avoided. + +\subsection{\pkg{doc}: Handle \texttt{\textbackslash\textvisiblespace} correctly in the index} + +Due to some problems in the code it wasn't possible to prevent +\verb*=\ = from showing up in the index\Dash \verb=\DoNotIndex{\ }=, etc.\ had no effect. This has now been corrected. +% +\githubissue{943} + + +\subsection{\pkg{doc}: Support the \pkg{upquote} package} + +The default quote and backquote characters in typewriter fonts are +typographical quotes, e.g., the input +\begin{verbatim} + \verb/`prog 'my input'`/ +\end{verbatim} + is rendered as \verb/`prog 'my input'`/ and not as +% +\begingroup % code to mimic upquote.sty +\catcode`'=\active +\catcode``=\active +\makeatletter +\g@addto@macro\@noligs + {\let'\textquotesingle + \let`\textasciigrave + \ifx\encodingdefault\upquote@OTone + \ifx\ttdefault\upquote@cmtt + \def'{\char13 }% + \def`{\char18 }% + \fi\fi} +\endgroup +% +\verb/`prog 'my input'`/ as preferred by many programmers. + +This can be adjusted, for example, with the \pkg{upquote} package, +which results in the second output. However, for historical reasons +\pkg{doc} had its own definition of \cs{verb} and \env{verbatim} and +as a consequence the two packages did not cooperate. This has now +been fixed and loading \pkg{upquote} together with \pkg{doc} has the +desired effect. +% +\githubissue{953} + + +\subsection{Default definition for \cs{do}} + +The command \cs{do} with its nice public name is in reality an +internal command inherited from plain \TeX{} for list +processing. However, it only got a definition when +\verb=\begin{document}= was executed, with a result that a user +definition in the preamble was unconditionally overwritten at this +point. To properly alert the user that this command is not freely +available we now make a definition in the format, so that +\cs{newcommand} and friends produce a proper error message instead of +allowing a definition that doesn't last. +% +\githubissue{975} + + + + +\subsection{New key for \env{filecontents}} + +The \env{filecontents} environment warns on the terminal if a file +gets overwritten even if that is intentional, +e.g., when you write a temporary file over and over again. To make +the warning less noisy in this case we added a new \texttt{nowarn} key +that redirects the overwriting warning to the transcript file. We +think that some record of the action is still required to help with +debugging, thus it is not completely silenced. The warning that +nothing gets written, because the file already exists (and the +\texttt{force} key was not used), is not altered and still shows up on +the terminal. +% +\githubissue{958} + + +\subsection{A further hook for shipping out pages} + +Since October 2020 the shipout process offers a number of hooks to +adjust what is happening before, during, and after the +\cs{shipout}. For example, with the \hook{shipout/before} hook, packages +can reset code they have altered (e.g., \cs{catcode}s during +verbatim-like processing) and with \hook{shipout/background} and +\hook{shipout/foreground} material can be added to the pages. +Details are given in \cite{37:ltshipout-doc}. + +However, still +missing was a hook that allows a package writer to manipulate the +completed page (with foreground and background attached) just before +the actual shipout happens. +For this we now provide the additional hook \hook{shipout}. One +use case (sometimes needed in print production) is to mirror the +whole page via \cs{reflectbox} including all the extra data that may +have been added into the fore- or background. +% +\githubissue{920} + + + +\subsection{Displaying release information in the \texttt{.log}} + +\LaTeX{} displays its release information at the very beginning of the +\LaTeX{} run on the terminal, and also writes it to the transcript file +if that is already opened at this point. While this is normally true, +it is not the case if the \LaTeX{} run was started passing additional +\TeX{} code on the command line, e.g., +\begin{verbatim} +pdflatex '\PassOptionsToClass{11pt}{article} + \input{myarticle}' +\end{verbatim} +In this case the release information is displayed when +\cs{PassOptionsToClass} is processed but the transcript file is only +opened when the output file name is known, i.e., after \cs{input} has +been seen, and as a result the release information is only shown on +the terminal. + +To account for this scenario, we now repeat the release information +also at the very end of the transcript file where we can be sure that +it is open and ready to receive material. +% +\githubissue{944} + + + + + +\section{Bug fixes} + +\subsection{Incompatibility between \pkg{doc} and \pkg{unicode-math}} + +The \pkg{unicode-math} package alters the catcode of \verb=|= but does +not adjust its value for use in \pkg{doc}, with the result that +\enquote{or} modules, i.e., $\langle A | B \rangle$ are displayed in a +strange way. This is now fixed with some firstaid code that will +eventually be moved into \pkg{unicode-math}. +% +\githubissue{820} + + +\subsection{A fix for \cs{hspace}} + +The change to \cs{hspace}, done in 2020 to make it \pkg{calc}-aware, +had the unfortunate side effect that starting a paragraph with +\cs{hspace} would result in the execution of \cs{everypar} inside a +group (i.e., any local changes would immediately be revoked, breaking, +for example, \pkg{wrapfig} in that special situation). +% +This got fixed with the 2022-11 PL1 hotfix, so was already corrected in +the previous release, but is only now documented in the newsletter. +% +\githubissue{967} + +\subsection{Ensure that \cs{cs} is defined in \cls{ltxdoc}} + +The class \cls{ltxdoc} defined the command \cs{cs} to typeset a +command name with a backslash in front. This definition was moved to +the \pkg{doc} package itself. This meant that it was suddenly missing +when reverting to the old \pkg{doc} package implementation via the +class option \texttt{doc2}. This has now been corrected. +% +\githubissue{981} + + + +\subsection{Improve spacing at top of \env{minipages}} + +A list and several other document elements add some vertical space in +front of them. However this should not happen at the beginning of a +box (such as a \env{minipage}) and normally it doesn't, because +\TeX{} automatically drops such space at the start of a vertical +list. However, if there is some invisible material, such as a +\cs{color} command, a \pkg{hyperref} anchor, a \cs{write} or +other such items, then the list is no longer empty and \TeX{} no longer +drops the vertical space. + +With the new paragraph handling introduced in 2021 it is now finally +possible to detect and avoid this problem and apply appropriate +counter measures so that from now on the spacing will always be +correct. +% +\githubissue{989} + + +\subsection{A fix for \cs{NewCommandCopy} and \cs{ShowCommand}} + +When copying and showing definitions of (non-expandable) document commands +(a.k.a.\ commands defined by \cs{NewDocumentCommand} and friends) containing empty +or only \texttt{m}-type arguments, these commands were wrongly recognized as +expandable ones. +This is fixed in the present \LaTeX{} release. +% +\githubissue{1009} + +\subsection{Corrections for switching math version} +Some internal code improvements improve support for switching math version +when nested within an outer math expression. +This will improve \cs{boldsymbol} and \cs{bm} and similar commands. +% +\githubissue{1028} + +\subsection{Allow par as a filename} +\verb|\input{par}| or \verb|\includegraphics{par}| could give spurious +errors. This has been fixed by making an internal command \cs{long}. +% +\githubissue{942} + +\subsection{Correct setting of \cs{endlinechar} in \texttt{+v} arguments} +In the particular case of a document command with a \texttt{+v}-type +argument used inside \cs{ExplSyntaxOn}\texttt{/Off}, newlines would be +misinterpreted as spaces because the value of \cs{endlinechar} was +set too late. This has been fixed, and now newlines are correctly +translated to ``\verb|the character ^^M|''. +% +\githubissue{876} + +\subsection{Correct handling of hooks with only `next' code} +When \cs{AddToHookNext} was used on a not-yet-declared hook, that hook +would be incorrectly identified as empty by \cs{ShowHook}. Also, if +that hook was later declared, that `next' code would not be executed. +This has been fixed by correctly initializing the hook structure when +\cs{AddToHookNext} is used. +% +\githubissue{1052} + +\subsection{Ignoring space after \texttt{\$\$}} +Space is normally ignored after a closing \texttt{\$\$}, +but internal \LaTeX{} font handling code could interfere if +\cs{eqno} was used. \cs{eqno} and \cs{leqno} have been redefined +to add \cs{ignorespaces} after the math group. +% +\githubissue{1059} + +\section{Documentation improvements} + +\subsection{Updates to the guides} + +When \LaTeXe{} was released, the team provided documentation for both document +authors and package/class developers in the two files \texttt{usrguide} and +\texttt{clsguide}. Over time, the team have augmented these documents as new +methods have been added to the kernel. However, they retained their structure +as assuming familiarity with \LaTeX{}~2.09. This meant that for new users, +there was material which is no longer relevant, and less clarity than desirable +regarding the approaches that are recommended today. + +The two files have now been (partially) re-written, with the versions available +previously now frozen as \texttt{usrguide-historic} and \texttt{clsguide-historic}. +More material has been carried forward in the class/package guide than in the +user guide, but both are worth a re-read by experienced \LaTeX{} users. + + + +\subsection{Displaying the exact release dates for \LaTeX{}} + +In some situations it is necessary to find out the exact release dates +for older versions of the \LaTeX{} format, for example, when you need +to use different code in a package depending on the availability of a +certain feature and you therefore want to use +\cs{IfFormatAtLeastTF}\texttt\{\meta{date}\texttt\} or the +rather horrible construction \verb/\@ifl@t@r\fmtversion{/\meta{date}\texttt\}, +if you +want to cater for formats that are older than 2020. + +Or you know that your package is definitely not going to work with a +format before a certain \meta{date}, in which case you could use +\verb/\NeedsTeXFormat{LaTeX2e}[/\meta{date}\texttt] to ensure that +users are alerted if their format is too old. + +The big problem is knowing the exact \meta{date} to put into such +commands; in the past, that was not that easy to find. You could have +looked in the file \file{changes.txt}, but that is hidden somewhere +in your installation and if you try +\verb/texdoc -l changes.txt/ you get more than thirty results and the %* +right file is by no means the first. + +Yukai Chou (\textsf{@muzimuzhi}) kindly provided a patch for this, so that we now have +the exact dates for each \LaTeX{} format listed in an easy to remember +place: in \file{ltnews.pdf} and that file conveniently also contains all major +features and changes to \LaTeX{} over the years\Dash one of which is +most likely the reason you need the \meta{date} in the first +place. + +The date is now given in parentheses in the newsletter title, thus this +newsletter tells you that on +% +\makeatletter +\mbox{\expandafter\@gobblenonyear\@year\@nil + -\@julianmonthtonum\@month-\two@digits\@day} +\makeatother +% +the command +\cs{NewEnvironmentCopy}, a new \texttt{shipout} hook, etc.\ was made +available. And looking into \file{ltnews.pdf} you can now easily find +out that the \LaTeX3 programming layer was added on 2020-02-02 +(because the date was so nice) and not on the first of the month. +% +\githubissue{982} + +\subsection{Fresh from the press:\ \enquote{The \LaTeX{} Companion, third~edition} is now in print} + +The third edition of \emph{The \LaTeX{} Companion} is now +available. This is the result of five years of careful work and we hope +that it will provide our readers with all the information they need to +successfully navigate the \LaTeX{} ecosystem and efficiently produce +beautiful documents. + +Since the publication of the last edition (2004), a lot has happened in +the \LaTeX{} world and thus a complete rewrite was necessary. All +chapters have been thoroughly revised, and in many cases significantly +extended, to describe new important functionality and features. More +than 5,000 add-on packages have been analyzed in detail, out of which +roughly 10\% have been chosen for inclusion in \emph{The \LaTeX{} +Companion}. All important aspects of these packages are described to +provide the user once again with a satisfying one-stop–shop experience +for the decade to come. + +To cover what we thought worth describing today, the book nearly +doubled in size. The print edition is therefore produced as a +two-volume set and sold as a bundle. Both volumes come as hardcover +with ribbons to easily mark pages in the book. + +To give you an idea of what is covered in the third edition you can +find some excerpts at +\begin{quote} +\url{https://www.latex-project.org/news/2023/03/17/TLC3} +\end{quote} + +The edition is also available as an eBook (Parts~I and~II combined) +consisting of PDF and ePub format, without DRM\@. Finally, the publisher +offers the combination of the printed books and the digital versions at +a very attractive price not available anywhere else. + +%% bb -- add reference to TUGboat review here + + +%\section{Changes to packages in the \pkg{amsmath} category} + +%\section{Changes to packages in the \pkg{graphics} category} + +\section{Changes to packages in the \pkg{tools} category} + + +\subsection{\pkg{multicol}: Better support for CJK languages} + +The default minimum depth of each column in a \env{multicols} +corresponds to the depth of a \enquote{p} in the current font. This +helps to get some uniformity if rules are used between the columns and +makes sense for Latin-based languages. Until now it was hard-wired, +but for CJK (Chinese/Japanese/Korean) languages it is better to use a zero depth, because there +all characters have the same height and depth. And even with +Latin-based languages one might want to use the depth of a \cs{strut} +or that of a parenthesis. So we now offer a way to adjust this while +maintaining backward compatibility: redefine +\cs{multicolmindepthstring} to hold whatever you want to get measured +for its depth (the width is not relevant). +% +\githubissue{698} + + +\subsection{\pkg{multicol}: Fix handling of nested environments} + +If \env{multicols} environments have been nested into each other (the +inner one boxed) it could fail if the boxed environment appeared near a +page break. The problem was that the output routine was called while +the \cs{hsize} was still altered to fit the column width of the inner +\env{multicols} --- thereby messing up the placement of columns of the +page. This has now been fixed. +% +\githubissue{1002} + + + +%\medskip + +\begin{thebibliography}{9} + +%\fontsize{9.3}{11.3}\selectfont + +\bibitem{37:ltshipout-doc} Frank Mittelbach, \LaTeX{}~Project~Team: + \emph{The~\texttt{\upshape ltshipout} documentation}.\\ + Run \texttt{texdoc} \texttt{ltshipout-doc} to view. + +\bibitem{37:lthooks-doc} Frank Mittelbach, Phelype Oleinik, \LaTeX{}~Project~Team: + \emph{\LaTeX's hook management}.\\ + Run \texttt{texdoc} \texttt{lthooks-doc} to view. + +%\bibitem{37:blueprint} Frank Mittelbach and Chris Rowley: +% \emph{\LaTeX{} Tagged PDF \Dash A blueprint for a large project}.\\ +% \url{https://latex-project.org/publications/indexbyyear/2020/} + +%\bibitem{37:source2e} +% \emph{\LaTeX{} documentation on the \LaTeX{} Project Website}.\\ +% \url{https://latex-project.org/help/documentation/} + +%\bibitem{37:Lamport} +%Leslie Lamport. +%\newblock {\LaTeX}: {A} Document Preparation System: User's Guide and Reference +% Manual. +%\newblock \mbox{Addison}-Wesley, Reading, MA, USA, 2nd edition, 1994. +%\newblock ISBN 0-201-52983-1. +%\newblock Reprinted with corrections in 1996. +% +%\bibitem{37:ltnews32} \LaTeX{} Project Team: +% \emph{\LaTeXe{} news 32}.\\ +% \url{https://latex-project.org/news/latex2e-news/ltnews32.pdf} +% +%\bibitem{37:ltnews34} \LaTeX{} Project Team: +% \emph{\LaTeXe{} news 34}.\\ +% \url{https://latex-project.org/news/latex2e-news/ltnews34.pdf} +% +%\bibitem{37:ltnews35} \LaTeX{} Project Team: +% \emph{\LaTeXe{} news 35}.\\ +% \url{https://latex-project.org/news/latex2e-news/ltnews35.pdf} +% +%\bibitem{37:fntguide} \LaTeX{} Project Team: +% \emph{\LaTeXe{} font selection}.\\ +% \url{https://latex-project.org/help/documentation/} +% +%\bibitem{37:ltfilehook-doc} Frank Mittelbach, Phelype Oleinik, \LaTeX{}~Project~Team: +% \emph{The \texttt{\upshape ltfilehook} documentation}.\\ +% Run \texttt{texdoc} \texttt{ltfilehook-doc} to view. +\end{thebibliography} + + + +\end{document} diff --git a/macros/latex/base/ltoutenc.dtx b/macros/latex/base/ltoutenc.dtx index 4dac4e1548..1d257805a4 100644 --- a/macros/latex/base/ltoutenc.dtx +++ b/macros/latex/base/ltoutenc.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltoutenc.ins b/macros/latex/base/ltoutenc.ins index 8ff0f02608..2f0c39517f 100644 --- a/macros/latex/base/ltoutenc.ins +++ b/macros/latex/base/ltoutenc.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/ltoutput.dtx b/macros/latex/base/ltoutput.dtx index 1cbc7ab0b1..18388b1cc6 100644 --- a/macros/latex/base/ltoutput.dtx +++ b/macros/latex/base/ltoutput.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -37,7 +37,7 @@ %<*driver> % \fi \ProvidesFile{ltoutput.dtx} - [2022/08/20 v1.4j LaTeX Kernel (Output Routine)] + [2023/05/26 v1.4j LaTeX Kernel (Output Routine)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltoutput.dtx} @@ -3005,9 +3005,6 @@ % % There is also an |\addpenalty\interlinepenalty| above. % -% Since in 2e |\samepage| is no longer supported, these could be -% removed. -% % Although it is best to use |\addvspace| in case two h floats come % together, this makes other spacing more difficult to adjust; whereas % if a user specifies two h floats together then they can more easily @@ -3227,9 +3224,6 @@ % % There is also an |\addpenalty\interlinepenalty| above. % -% Since in 2e |\samepage| is no longer supported, these could be -% removed. -% % Although it is best to use |\addvspace| in case two h floats come % together, this makes other spacing more difficult to adjust; whereas % if a user specifies two h floats together then they can more easily diff --git a/macros/latex/base/ltpage.dtx b/macros/latex/base/ltpage.dtx index 1d514fc7c7..1a6586d067 100644 --- a/macros/latex/base/ltpage.dtx +++ b/macros/latex/base/ltpage.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltpageno.dtx b/macros/latex/base/ltpageno.dtx index 8142639633..6c02d0fa7f 100644 --- a/macros/latex/base/ltpageno.dtx +++ b/macros/latex/base/ltpageno.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltpar.dtx b/macros/latex/base/ltpar.dtx index 50ff57183c..31d863610b 100644 --- a/macros/latex/base/ltpar.dtx +++ b/macros/latex/base/ltpar.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltpara-code.pdf b/macros/latex/base/ltpara-code.pdf index 2ad8d90eab..4ca5193aa2 100644 Binary files a/macros/latex/base/ltpara-code.pdf and b/macros/latex/base/ltpara-code.pdf differ diff --git a/macros/latex/base/ltpara-doc.pdf b/macros/latex/base/ltpara-doc.pdf index 31ac4d0714..1f47fc92db 100644 Binary files a/macros/latex/base/ltpara-doc.pdf and b/macros/latex/base/ltpara-doc.pdf differ diff --git a/macros/latex/base/ltpara.dtx b/macros/latex/base/ltpara.dtx index 9296f2b2cd..9c1a95ee61 100644 --- a/macros/latex/base/ltpara.dtx +++ b/macros/latex/base/ltpara.dtx @@ -1,7 +1,8 @@ % \iffalse meta-comment % -%% File: ltpara.dtx (C) Copyright 2020-2021 -% Frank Mittelbach, LaTeX Team +%% File: ltpara.dtx +%% Copyright (C) 2020-2023 +%% Frank Mittelbach, 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 @@ -14,8 +15,8 @@ %%% From File: ltpara.dtx % % \begin{macrocode} -\def\ltparaversion{v1.0k} -\def\ltparadate{2022/05/13} +\def\ltparaversion{v1.0l} +\def\ltparadate{2023/01/30} % \end{macrocode} %<*driver> \documentclass{l3doc} @@ -729,6 +730,8 @@ % for error recovery and so altering \cs{tex_everypar:D} all the % time should be a tiny bit faster. % \begin{macrocode} +%<latexrelease>\IncludeInRelease{2023/06/01} +%<latexrelease> {\g_@@_standard_everypar_tl}{minipage~ fix} \tl_new:N \g_@@_standard_everypar_tl % \end{macrocode} % Here is now its definition: @@ -769,7 +772,28 @@ % \begin{macrocode} \group_begin: \tex_everypar:D {} - \skip_zero:N \tex_parskip:D +% \end{macrocode} +% There has been a long-standing problem with \LaTeX's minipages in +% that invisible material at the beginning of a minipage (such as a +% \cs{color} setting) would result in \cs{parskip} being added in +% front of the first paragraph---something that is not done by +% \TeX{} if a vertical list is completely empty. As this is +% happening on a very low-level in the engine it wasn't really +% possible to find out if this \cs{parskip} was added or if a space +% we see in front of the current point is legitimate. However, with +% the new paragraph handling we are in a better position: while we +% still don't know if there is such a space or not, we do know +% if we have just created an empty paragraph. Thus, if we now set +% \cs{parskip} to \texttt{-}\cs{parskip} the two will cancel each other +% if present and if the first was ignored because the vertical list +% was empty, then the second will be ignored too because it is +% still empty. Of course, we don't want to cancel always but only +% at the start of a minipage and that is signaled with the +% \texttt{@minipage} switch. +% \changes{v1.0l}{2023/01/30}{Backout \cs{parskip} at top of minipage (gh/989)} +% \begin{macrocode} + \skip_set:Nn \tex_parskip:D + { \if@minipage -\tex_parskip:D \else: \c_zero_skip \fi: } \tex_noindent:D \group_end: % \end{macrocode} @@ -800,6 +824,43 @@ \@@_handle_indent: % \the \everypar % <--- done differently below } +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2021/06/01} +%<latexrelease> {\g_@@_standard_everypar_tl}{minipage~ fix} +%<latexrelease> +%<latexrelease>\tl_gset:Nn \g_@@_standard_everypar_tl { +%<latexrelease> \box_gset_to_last:N \g_para_indent_box +%<latexrelease> \group_begin: +%<latexrelease> \tex_par:D +%<latexrelease> \group_end: +%<latexrelease> \tex_everypar:D { \msg_error:nnnn { hooks }{ para-mode }{before}{vertical} } +%<latexrelease> \@kernel@before@para@before +%<latexrelease> \hook_use:n {para/before} +%<latexrelease> \group_begin: +%<latexrelease> \tex_everypar:D {} +%<latexrelease> \skip_zero:N \tex_parskip:D +%<latexrelease> \tex_noindent:D +%<latexrelease> \group_end: +%<latexrelease> \tex_everypar:D{\g_@@_standard_everypar_tl} +%<latexrelease> \@kernel@before@para@begin +%<latexrelease> \hook_use:n {para/begin} +%<latexrelease> \if_mode_horizontal: \else: +%<latexrelease> \msg_error:nnnn { hooks }{ para-mode }{begin}{vertical} \fi: +%<latexrelease> \@@_handle_indent: +%<latexrelease>} +% \end{macrocode} +% We also have to add the \cs{everypar} toks register at the +% end. In case of rollback this is already allocated and we have to +% find out the correct number (hope this is correctly done) +% \begin{macrocode} +%<latexrelease>\cs_set:Npn \@@_tmp:w #1#2#3#4#5 { } +%<latexrelease>\tl_gput_right:Nx \g_@@_standard_everypar_tl { +%<latexrelease> \exp_not:N \the +%<latexrelease> \exp_not:N \toks +%<latexrelease> \exp_after:wN \@@_tmp:w \token_to_meaning:N \everypar +%<latexrelease> \c_space_tl +%<latexrelease>} +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} % diff --git a/macros/latex/base/ltpictur.dtx b/macros/latex/base/ltpictur.dtx index 453ec6149e..926fd5c692 100644 --- a/macros/latex/base/ltpictur.dtx +++ b/macros/latex/base/ltpictur.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltplain.dtx b/macros/latex/base/ltplain.dtx index ee1cf0a161..89e5017300 100644 --- a/macros/latex/base/ltplain.dtx +++ b/macros/latex/base/ltplain.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltplain.dtx} - [2022/01/25 v2.3h LaTeX Kernel (Plain TeX)] + [2023/04/15 v2.3i LaTeX Kernel (Plain TeX)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltplain.dtx} @@ -660,6 +660,10 @@ \def\extrafloats#1{% \ifnum#1>\z@ \count@\numexpr\float@count-1\relax +% \end{macrocode} +% \changes{v2.3i}{2023/04/15}{Protect box 255 in lualatex gh/1041} +% \begin{macrocode} + \ifnum\count@<266 \ch@ck0\m@ne\insert\fi \ch@ck0\count@\count \ch@ck1\count@\dimen \ch@ck2\count@\skip @@ -668,8 +672,12 @@ \global\expandafter\e@alloc@chardef \csname bx@\the\float@count\endcsname\float@count \@cons\@freelist{\csname bx@\the\float@count\endcsname}% -\expandafter -\extrafloats\expandafter{\numexpr#1-1\relax}% +% \end{macrocode} +% \changes{v2.3i}{2023/04/15}{unwind numexpr and ifnum nesting} +% \begin{macrocode} +\expandafter\extrafloats\expandafter{\the\numexpr#1-1\expandafter}% +% \end{macrocode} +% \begin{macrocode} \fi}% % \end{macrocode} % @@ -880,7 +888,6 @@ % but the code is commented out if no special value needs to be set. % INITEX makes all parameters zero except where noted. % -% \begin{oldcomments} % \begin{macrocode} \pretolerance=100 \tolerance=200 % INITEX sets this to 10000 @@ -897,10 +904,14 @@ \brokenpenalty=100 \predisplaypenalty=10000 % \end{macrocode} +% +% \begin{macrocode} % \postdisplaypenalty=0 % \interlinepenalty=0 % \floatingpenalty=0, set during \insert % \outputpenalty=0, set before TeX enters \output +% \end{macrocode} +% % \begin{macrocode} \doublehyphendemerits=10000 \finalhyphendemerits=5000 @@ -971,6 +982,8 @@ % \begin{macrocode} \uchyph=1 % \end{macrocode} +% +% \begin{macrocode} % \lefthyphenmin=2 \righthyphenmin=3 set below % \globaldefs=0 % \maxdeadcycles=25 % INITEX does this @@ -978,21 +991,29 @@ % \fam=0 % \mag=1000 % INITEX does this % \escapechar=`\\ % INITEX does this +% \end{macrocode} +% % \begin{macrocode} \defaulthyphenchar=`\- \defaultskewchar=-1 % \end{macrocode} +% +% \begin{macrocode} % \endlinechar=`\^^M % INITEX does this % \newlinechar=-1 \LaTeX\ sets this in ltdefns.dtx. +% \end{macrocode} +% % \begin{macrocode} \delimiterfactor=901 % \end{macrocode} +% +% \begin{macrocode} % \time=now % TeX does this at beginning of job % \day=now % TeX does this at beginning of job % \month=now % TeX does this at beginning of job % \year=now % TeX does this at beginning of job +% \end{macrocode} % -% \end{oldcomments} % In \LaTeX{} we don't want box information in the transcript % unless we do a full tracing. % \changes{v1.0g}{1994/04/28}{Turn off overfull box tracing in log} @@ -1012,26 +1033,36 @@ \boxmaxdepth=\maxdimen % \end{macrocode} % -% \begin{oldcomments} +% \begin{macrocode} % \lineskiplimit=0pt, changed by \normalbaselines +% \end{macrocode} +% % \begin{macrocode} \delimitershortfall=5pt \nulldelimiterspace=1.2pt \scriptspace=0.5pt % \end{macrocode} +% +% \begin{macrocode} % \mathsurround=0pt % \predisplaysize=0pt, set before TeX enters $$ % \displaywidth=0pt, set before TeX enters $$ % \displayindent=0pt, set before TeX enters $$ +% \end{macrocode} +% % \begin{macrocode} \parindent=20pt % \end{macrocode} +% +% \begin{macrocode} % \hangindent=0pt, zeroed by TeX after each paragraph % \hoffset=0pt % \voffset=0pt % % \baselineskip=0pt, changed by \normalbaselines % \lineskip=0pt, changed by \normalbaselines +% \end{macrocode} +% % \begin{macrocode} \parskip=0pt plus 1pt \abovedisplayskip=12pt plus 3pt minus 9pt @@ -1039,19 +1070,26 @@ \belowdisplayskip=12pt plus 3pt minus 9pt \belowdisplayshortskip=7pt plus 3pt minus 4pt % \end{macrocode} +% +% \begin{macrocode} % \leftskip=0pt % \rightskip=0pt +% \end{macrocode} +% % \begin{macrocode} \topskip=10pt \splittopskip=10pt % \end{macrocode} +% +% \begin{macrocode} % \tabskip=0pt % \spaceskip=0pt % \xspaceskip=0pt +% \end{macrocode} +% % \begin{macrocode} \parfillskip=0pt plus 1fil % \end{macrocode} -% \end{oldcomments} % % % \begin{macro}{\normalbaselineskip} @@ -1215,7 +1253,7 @@ \gdef\obeylines{\catcode`\^^M\active% \let^^M\obeyedline% % \end{macrocode} -% +% % The next line ending the definition is rather curious and it took % me awhile to understand why rollback fails. The problem is the % following: if \texttt{latexrelease} is used, then blocks of diff --git a/macros/latex/base/ltsect.dtx b/macros/latex/base/ltsect.dtx index 71ab1ee89d..5a03fd4977 100644 --- a/macros/latex/base/ltsect.dtx +++ b/macros/latex/base/ltsect.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltshipout-code.pdf b/macros/latex/base/ltshipout-code.pdf index efc6444c48..6209463f89 100644 Binary files a/macros/latex/base/ltshipout-code.pdf and b/macros/latex/base/ltshipout-code.pdf differ diff --git a/macros/latex/base/ltshipout-doc.pdf b/macros/latex/base/ltshipout-doc.pdf index a2d210dda0..86bd577603 100644 Binary files a/macros/latex/base/ltshipout-doc.pdf and b/macros/latex/base/ltshipout-doc.pdf differ diff --git a/macros/latex/base/ltshipout.dtx b/macros/latex/base/ltshipout.dtx index ae29c1acad..b19814a6fd 100644 --- a/macros/latex/base/ltshipout.dtx +++ b/macros/latex/base/ltshipout.dtx @@ -1,7 +1,7 @@ % \iffalse meta-comment %% -%% Copyright (C) 2020-2022 -%% Frank Mittelbach, LaTeX Team +%% Copyright (C) 2020-2023 +%% Frank Mittelbach, The LaTeX Project %% % % This file is part of the LaTeX base system. @@ -32,8 +32,8 @@ %%% From File: ltshipout.dtx % % \begin{macrocode} -\providecommand\ltshipoutversion{v1.0m} -\providecommand\ltshipoutdate{2022/08/26} +\providecommand\ltshipoutversion{v1.0n} +\providecommand\ltshipoutdate{2022/11/08} % \end{macrocode} % %<*driver> @@ -75,7 +75,7 @@ % \providecommand\pkg[1]{\texttt{#1}} % % -% \title{The \texttt{ltshipout} package\thanks{This package has version +% \title{The \texttt{ltshipout} documentation\thanks{This file has version % \ltshipoutversion\ dated \ltshipoutdate, \copyright\ \LaTeX\ % Project.}} % @@ -241,6 +241,18 @@ % But being placed after the main box content it will be typeset % later and thus overprints it (i.e., is in the foreground). % +% \item[\hook{shipout}] +% This hook is executed after foreground and/or background +% material has been added, i.e., just in front of the actual +% shipout operation. Its purpose is to allow manipulation of the +% finalized box (stored in \cs{ShipoutBox}) with the extra +% material also in place (which is not yet the case in +% \hook{shipout/before}). +% +% It cannot be used to cancel the shipout operation via +% \cs{DiscardShipoutBox} (that has +% to happen in \hook{shipout/before}, if desired! +% % % \item[\hook{shipout/firstpage}] % @@ -296,7 +308,7 @@ % actual shipout. It is even run if there was a % \cs{DiscardShipoutBox} request in the document. % -% The other hooks (except \hook{shipout/after}) are added inside +% The other hooks (except \hook{shipout} and \hook{shipout/after}) are added inside % hboxes to the box being shipped out in the following order: % \begin{center} % \begin{tabular}{ll} @@ -307,9 +319,13 @@ % \hook{shipout/lastpage} & only on the last page \\ % \end{tabular} % \end{center} -% If any of the hooks has no code then that particular no box is +% If any of the hooks has no code then the corresponding box is % added at that point. % +% Once the (page) box has got the above extra content it can +% again be manipulated using the \hook{shipout} hook and then +% is shipped out for real. +% % Once the (page) box has been shipped out the \hook{shipout/after} % hook is called (while you are still inside the output routine). It % is not called if the shipout box was discarded. @@ -381,13 +397,16 @@ % % \fmi{Once we have a new mark mechanism available we can improve % on that and make sure that the declaration applies to the page -% that contains it.} +% that contains it --- not done (yet)} +% +% \cs{DiscardShipoutBox} cannot be used in any of the \hook{shipout/...} +% hooks other than \hook{shipout/before}. % \end{function} % % In the \pkg{atbegshi} package there are a number of additional % commands for use inside the \hook{shipout/before} hook. They % should normally not be needed any more as one can instead simply -% add code to the hooks \hook{shipout/before}, +% add code to the hooks \hook{shipout/before}, \hook{shipout}, % \hook{shipout/background} or % \hook{shipout/foreground}.\footnote{If that assumption turns out to % be wrong it would be trivial to change them to public functions @@ -401,7 +420,9 @@ % % \begin{variable}{pre_shipout_filter} % Under Lua\TeX{} the \texttt{pre\_shipout\_filter} Lua callback is -% provided which gets called immediately before the shipout primitive gets invoked. +% provided which gets called directly after the +% \hook{shipout} hook, immediately before the shipout +% primitive gets invoked. % The signature is % \begin{verbatim} % function(<node> head) @@ -1014,15 +1035,20 @@ \_@@_add_foreground_box:n { \UseHook{shipout/lastpage} \@kernel@after@shipout@lastpage } - \bool_gset_true:N \g_@@_lastpage_handled_bool % \end{macrocode} % We record that we have handled the \hook{shipout/lastpage} hook % but only if we really did. % \changes{v1.0m}{2022/05/08}{Handle case where shipout/lastpage is % run too early (gh/813)} % \begin{macrocode} + \bool_gset_true:N \g_@@_lastpage_handled_bool } } +% \end{macrocode} +% +% \changes{v1.0n}{2022/11/08}{Add shipout hook (gh/920)} +% \begin{macrocode} + \hook_use:n {shipout} \@@_finalize_box: % \end{macrocode} % Finally we run the actual \TeX{} primitive for shipout. As that will @@ -1116,13 +1142,14 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{shipout/before,shipout/after, +% \begin{macro}{shipout/before,shipout,shipout/after, % shipout/foreground,shipout/background, -% shipout/firstpage, -% shipout/lastpage} +% shipout/firstpage,shipout/lastpage} % Declaring all hooks for the shipout code. +% \changes{v1.0n}{2022/11/08}{Add shipout hook (gh/920)} % \begin{macrocode} \hook_new:n{shipout/before} +\hook_new:n{shipout} \hook_new:n{shipout/after} \hook_new:n{shipout/foreground} \hook_new:n{shipout/background} diff --git a/macros/latex/base/ltspace.dtx b/macros/latex/base/ltspace.dtx index 30bda278fb..a77314b1bd 100644 --- a/macros/latex/base/ltspace.dtx +++ b/macros/latex/base/ltspace.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{ltspace.dtx} - [2022/11/28 v1.3o LaTeX Kernel (spacing)] + [2023/05/26 v1.3p LaTeX Kernel (spacing)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltspace.dtx} @@ -94,6 +94,7 @@ % inhibits page breaking most places by setting the % following penalties to 10000:\\ % |\interlinepenalty|\\ +% |\predisplaypenalty|\\ % |\postdisplaypenalty|\\ % |\interdisplaylinepenalty|\\ % |\@beginparpenalty|\\ @@ -308,8 +309,10 @@ % \end{macro} % % \begin{macro}{\samepage} +% \changes{v1.3p}{2023/03/22}{Add \cs{predisplaypenalty} setting (gh/1022)} % \begin{macrocode} \DeclareRobustCommand\samepage{\interlinepenalty\@M + \predisplaypenalty\@M \postdisplaypenalty\@M \interdisplaylinepenalty\@M \@beginparpenalty\@M diff --git a/macros/latex/base/lttab.dtx b/macros/latex/base/lttab.dtx index e32153f31c..e76325d82b 100644 --- a/macros/latex/base/lttab.dtx +++ b/macros/latex/base/lttab.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/lttextcomp.dtx b/macros/latex/base/lttextcomp.dtx index 8f5ec0d200..3602e0a6b0 100644 --- a/macros/latex/base/lttextcomp.dtx +++ b/macros/latex/base/lttextcomp.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2019-2022 +% Copyright (C) 2019-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltthm.dtx b/macros/latex/base/ltthm.dtx index d0d04d9669..b321c7ac2b 100644 --- a/macros/latex/base/ltthm.dtx +++ b/macros/latex/base/ltthm.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltvers.dtx b/macros/latex/base/ltvers.dtx index 24308589f1..de3c022755 100644 --- a/macros/latex/base/ltvers.dtx +++ b/macros/latex/base/ltvers.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltvers.dtx} - [2022/02/28 v1.1i LaTeX Kernel (Version Info)] + [2022/11/06 v1.1j LaTeX Kernel (Version Info)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltvers.dtx} @@ -112,10 +112,10 @@ %</2ekernel> %<latexrelease>\edef\latexreleaseversion %<*2ekernel|latexrelease> - {2022-11-01} + {2023-06-01} %</2ekernel|latexrelease> %<*2ekernel> -\def\patch@level{1} +\def\patch@level{0} % \end{macrocode} % % \begin{macro}{\development@branch@name} @@ -178,20 +178,33 @@ % by a loader (\texttt{.ini} file)} % \changes{v1.0v}{2015/08/23}{Allow negative patchlevel for pre-release} % \changes{v1.1e}{2020/01/31}{Allow for upcoming format as pre-release 0} +% \changes{v1.1j}{2022/11/06}{Repeat release info at the end (gh/944)} +% +% We store release info in the toks \cs{LaTeXReleaseInfo} to be +% used in \cs{everyjob} but also when \verb=\end{document}= is +% executed. +% Instead of using \cs{typeout} we use \cs{show@release@info} so +% that we can write to the log only by changing that to \cs{wlog}. +% \begin{macrocode} +\newtoks\LaTeXReleaseInfo +\everyjob\expandafter{\the\everyjob\the\LaTeXReleaseInfo} +\let\show@release@info\typeout +% \end{macrocode} +% % \begin{macrocode} \ifnum0\ifnum\patch@level=0 \ifx\development@branch@name\@empty 1\fi\fi>0 % - \everyjob\expandafter{\the\everyjob - \typeout{\fmtname\space <\fmtversion>}} + \LaTeXReleaseInfo\expandafter{\the\LaTeXReleaseInfo + \show@release@info{\fmtname\space <\fmtversion>}} \immediate \write16{\fmtname \space<\fmtversion>} \else\ifnum\patch@level>0 - \everyjob\expandafter{\the\everyjob - \typeout{\fmtname\space <\fmtversion> patch level \patch@level}} + \LaTeXReleaseInfo\expandafter{\the\LaTeXReleaseInfo + \show@release@info{\fmtname\space <\fmtversion> patch level \patch@level}} \immediate \write16{\fmtname\space <\fmtversion> patch level \patch@level} \else - \everyjob\expandafter{\the\everyjob - \typeout{\fmtname\space <\fmtversion> + \LaTeXReleaseInfo\expandafter{\the\LaTeXReleaseInfo + \show@release@info{\fmtname\space <\fmtversion> pre-release-\number-\patch@level\space \ifx\development@branch@name\@undefined \else \ifx\development@branch@name\@empty \else diff --git a/macros/latex/base/ltx3info.pdf b/macros/latex/base/ltx3info.pdf index 368f3162ad..1756ab795e 100644 Binary files a/macros/latex/base/ltx3info.pdf and b/macros/latex/base/ltx3info.pdf differ diff --git a/macros/latex/base/ltx3info.tex b/macros/latex/base/ltx3info.tex index 13231da818..096fa2db9a 100644 --- a/macros/latex/base/ltx3info.tex +++ b/macros/latex/base/ltx3info.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltxcheck.tex b/macros/latex/base/ltxcheck.tex index 7f4b925b79..d219d2ebc2 100644 --- a/macros/latex/base/ltxcheck.tex +++ b/macros/latex/base/ltxcheck.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltxdoc.dtx b/macros/latex/base/ltxdoc.dtx index 6863349be3..e147c9d22f 100644 --- a/macros/latex/base/ltxdoc.dtx +++ b/macros/latex/base/ltxdoc.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -30,7 +30,7 @@ % %<class>\NeedsTeXFormat{LaTeX2e} %<class>\ProvidesClass{ltxdoc} -%<class> [2022/06/22 v2.1i Standard LaTeX documentation class] +%<class> [2023/03/28 v2.1j Standard LaTeX documentation class] % %<*driver> \documentclass{ltxdoc} @@ -182,9 +182,13 @@ % % Support rolling back \pkg{doc} to version 2: % \changes{v2.1e}{2022/05/27}{Support rolling back doc to version 2} +% \changes{v2.1j}{2023/03/28}{Define \cs{cs} if doc is rolled back to v2 (gh/981)} % \begin{macrocode} \let\ltxdoc@doc@version\@empty % use current version by default -\DeclareOption{doc2}{\def\ltxdoc@doc@version{=v2}} +\DeclareOption{doc2}{% + \def\ltxdoc@doc@version{=v2}% + \DeclareRobustCommand\cs[1]{\texttt{\bslash #1}}% +} % \end{macrocode} % % \begin{macrocode} @@ -670,8 +674,10 @@ Bug reports can be opened (category \texttt{#1}) at\\% % kernel sources. % % -% Copyright 2006, 2007, 2011 Heiko Oberdiek -% Copyright 2014-2021 The LaTeX Project +% Copyright 2006, 2007, 2011 +% Heiko Oberdiek +% Copyright (C) 2014-2023 +% The LaTeX Project % \ProvidesFile{ltxdoc.cfg}% diff --git a/macros/latex/base/ltxdoc.pdf b/macros/latex/base/ltxdoc.pdf index aae8871c68..e3c23c97ec 100644 Binary files a/macros/latex/base/ltxdoc.pdf and b/macros/latex/base/ltxdoc.pdf differ diff --git a/macros/latex/base/ltxguide.cls b/macros/latex/base/ltxguide.cls index b743fd9cda..778f7e993e 100644 --- a/macros/latex/base/ltxguide.cls +++ b/macros/latex/base/ltxguide.cls @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 1993-2019 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/ltxref.dtx b/macros/latex/base/ltxref.dtx index 596eb2fd74..0f842e4312 100644 --- a/macros/latex/base/ltxref.dtx +++ b/macros/latex/base/ltxref.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -33,7 +33,7 @@ %<*driver> % \fi \ProvidesFile{ltxref.dtx} - [2022/04/12 v1.1p LaTeX Kernel (Cross Referencing)] + [2023/05/16 v1.1q LaTeX Kernel (Cross Referencing)] % \iffalse \documentclass{ltxdoc} \GetFileInfo{ltxref.dtx} @@ -93,6 +93,15 @@ % to align with the use of \pkg{hyperref}. Without \pkg{hyperref} (or some % other package using the starred form) the star is simply ignored. % +% Note: starting with 2023-06-01 |\label| stores also the current value +% of |\@currentlabelname| which should typically contain a (sanitized) title. +% (A reference command |\nameref| is provided by the \pkg{nameref} package.) +% |\label| also stores |\@currentHref| which if set should refer to a target name +% for links. This value is set and used by \pkg{hyperref}. Unlike the other values +% |\@currentHref| should be set globally. A fifth value |\@kernel@reserved@label@data| +% is reserved for the kernel to allow future extensions of the cross-reference +% system. +% % % \MaybeStop{} % @@ -108,7 +117,8 @@ % incremented by the command \refstepcounter{CNT} , which sets % \@currentlabel == {CNT}{eval(\p@cnt\theCNT)}. The command % \label{FOO} then writes the following on file \@auxout : -% \newlabel{FOO}{{eval(\@currentlabel)}{eval(\thepage)}} +% \newlabel{FOO}{{eval(\@currentlabel)}{eval(\thepage)}% +% {eval(\@currentlabelname)}{eval(\@currentHref)}{eval(\@kernel@reserved@label@data)}} % % \ref{FOO} == % BEGIN @@ -228,6 +238,10 @@ % % RmS 93/09/08: Added setting of refundefined switch. % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2023/06/01}% +%<latexrelease> {\@kernel@sref}{store five arguments}% \def\@setref#1#2#3{% \ifx#1\relax \protect\G@refundefinedtrue @@ -235,19 +249,53 @@ \@latex@warning{Reference `#3' on page \thepage \space undefined}% \else - \expandafter#2#1\null + \expandafter#2#1\@empty\@empty\@empty\null \fi} % \end{macrocode} % \begin{macrocode} -%</2ekernel> -%<*2ekernel|latexrelease> +\long\def\@firstoffive#1#2#3#4#5{#1} +\long\def\@secondoffive#1#2#3#4#5{#2} +\def\@kernel@sref#1{\expandafter\@setref\csname r@#1\endcsname\@firstoffive{#1}} +\def\@kernel@spageref#1{\expandafter\@setref\csname r@#1\endcsname + \@secondoffive{#1}} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{2022/06/01}% +%<latexrelease> {\@kernel@sref}{store five arguments}% +%<latexrelease>\def\@setref#1#2#3{% +%<latexrelease> \ifx#1\relax +%<latexrelease> \protect\G@refundefinedtrue +%<latexrelease> \nfss@text{\reset@font\bfseries ??}% +%<latexrelease> \@latex@warning{Reference `#3' on page \thepage \space +%<latexrelease> undefined}% +%<latexrelease> \else +%<latexrelease> \expandafter#2#1\null +%<latexrelease> \fi} +%<latexrelease>\let\@firstoffive\undefined +%<latexrelease>\let\@secondoffive\undefined +%<latexrelease>\def\@kernel@sref#1{\expandafter\@setref\csname r@#1\endcsname\@firstoftwo{#1}} +%<latexrelease>\def\@kernel@spageref#1{\expandafter\@setref\csname r@#1\endcsname +%<latexrelease> \@secondoftwo{#1}} +%<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\@kernel@sref}{store five arguments}% +%<latexrelease>\def\@setref#1#2#3{% +%<latexrelease> \ifx#1\relax +%<latexrelease> \protect\G@refundefinedtrue +%<latexrelease> \nfss@text{\reset@font\bfseries ??}% +%<latexrelease> \@latex@warning{Reference `#3' on page \thepage \space +%<latexrelease> undefined}% +%<latexrelease> \else +%<latexrelease> \expandafter#2#1\null +%<latexrelease> \fi} +%<latexrelease>\let\@firstoffive\undefined +%<latexrelease>\let\@secondoffive\undefined +%<latexrelease>\let\@kernel@sref\undefined +%<latexrelease>\let\@kernel@spageref\undefined +%<latexrelease>\EndIncludeInRelease %<latexrelease>\IncludeInRelease{2022/06/01}% %<latexrelease> {\ref}{Add starred reference commands}% % \end{macrocode} % \begin{macrocode} -\def\@kernel@sref#1{\expandafter\@setref\csname r@#1\endcsname\@firstoftwo{#1}} -\def\@kernel@spageref#1{\expandafter\@setref\csname r@#1\endcsname - \@secondoftwo{#1}} \let\@kernel@ref\@kernel@sref \let\@kernel@pageref\@kernel@spageref \NewDocumentCommand\ref{s} @@ -334,6 +382,8 @@ % \begin{macro}{\label} % \changes{v1.1d}{1994/11/04}{(ASAJ)Added \cs{protected@write}} % \changes{v1.1d}{1994/11/04}{(ASAJ)Added \cs{protected@edef}} +% \changes{v1.1q}{2023/05/12}{(UFi)extended to store five arguments} +% \changes{v1.1q}{2023/05/12}{(UFi)added a hook with argument} % The commands |\label| and |\refstepcounter| have been changed to % allow |\protect|'ed commands to work properly. For example, %\begin{verbatim} @@ -343,16 +393,27 @@ % to something like |\foo{4.d}|. Change made 20 Jul 88. % % \begin{macrocode} +%</2ekernel> +%<*2ekernel|latexrelease> +%<latexrelease>\IncludeInRelease{2023/06/01}% +%<latexrelease> {\label}{store five label arguments}% +\providecommand\@currentlabelname{} +\providecommand\@currentHref{} +\providecommand\@kernel@reserved@label@data{} +\NewHookWithArguments{label}{1} \def\label#1{\@bsphack + \begingroup + \UseHookWithArguments{label}{1}{#1}% \protected@write\@auxout{}% - {\string\newlabel{#1}{{\@currentlabel}{\thepage}}}% + {\string\newlabel{#1}{{\@currentlabel}{\thepage}% + {\@currentlabelname}{\@currentHref}{\@kernel@reserved@label@data}}}% + \endgroup \@esphack} +%<latexrelease>\EndIncludeInRelease % \end{macrocode} % \end{macro} % % \begin{macrocode} -%</2ekernel> -%<*2ekernel|latexrelease> %<latexrelease>\IncludeInRelease{2022/06/01}% %<latexrelease> {\Ref}{Add starred version}% % \end{macrocode} @@ -432,6 +493,16 @@ % \begin{macrocode} %</2ekernel|latexrelease> %<latexrelease>\EndIncludeInRelease +%<latexrelease>\IncludeInRelease{0000/00/00}% +%<latexrelease> {\label}{store five label arguments}% +%<latexrelease>\let\@currenttitle\@undefined +%<latexrelease>\let\@currenttarget\@undefined +%<latexrelease>\let\@kernel@currentdata\@undefined +%<latexrelease>\def\label#1{\@bsphack +%<latexrelease> \protected@write\@auxout{}% +%<latexrelease> {\string\newlabel{#1}{{\@currentlabel}{\thepage}}}% +%<latexrelease> \@esphack} +%<latexrelease>\EndIncludeInRelease %<latexrelease>\IncludeInRelease{2020/10/01}% %<latexrelease> {\Ref}{Add starred version}% %<latexrelease>\def\@currentcounter{} diff --git a/macros/latex/base/makeindx.dtx b/macros/latex/base/makeindx.dtx index fb6c474659..b91d3a6c44 100644 --- a/macros/latex/base/makeindx.dtx +++ b/macros/latex/base/makeindx.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/makeindx.ins b/macros/latex/base/makeindx.ins index 0fe55ed039..1c5f6edcb9 100644 --- a/macros/latex/base/makeindx.ins +++ b/macros/latex/base/makeindx.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/makeindx.pdf b/macros/latex/base/makeindx.pdf index 139accd18f..677cf80b00 100644 Binary files a/macros/latex/base/makeindx.pdf and b/macros/latex/base/makeindx.pdf differ diff --git a/macros/latex/base/manifest.txt b/macros/latex/base/manifest.txt index d63945fa0e..22791a2494 100644 --- a/macros/latex/base/manifest.txt +++ b/macros/latex/base/manifest.txt @@ -27,7 +27,8 @@ % sample2e.tex -- Sample LaTeX input file. % small2e.tex -- Small sample LaTeX input file. % -% clsguide.tex -- How to write class files. +% clsguide.tex -- How to write class files. +% clsguide-historic.tex -- How to write class files with a focus on moving from 2.09. % cfgguide.tex -- Guide to using `.cfg' files to configure LaTeX. % cyrguide.tex -- Guide to using cyrillic languages in LaTeX. % encguide.tex -- Guide to font encodings. @@ -71,12 +72,15 @@ % ltnews33.tex -- What was new in the release dated 2021/06. % ltnews34.tex -- What was new in the release dated 2021/11. % ltnews35.tex -- What was new in the release dated 2022/06. +% ltnews36.tex -- What was new in the release dated 2022/11. +% ltnews37.tex -- What was new in the release dated 2023/06. % % ltx3info.tex -- Information about the LaTeX3 project. % % lamport-manual.err -- Errata for the LaTeX Manual book, second edition. % tlc2.err -- Errata for the LaTeX Companion, second edition. +% tlc3.err -- Errata for the LaTeX Companion, third edition. % lb2.err -- Errata for the LaTeX-Begleiter, 2te erw. Auflage (German). % lgc2.err -- Errata for the LaTeX Graphics Companion, second edition. % webcomp.err -- Errata for the LaTeX Web Companion. diff --git a/macros/latex/base/minimal.cls b/macros/latex/base/minimal.cls index 9024a23bca..89c233c30f 100644 --- a/macros/latex/base/minimal.cls +++ b/macros/latex/base/minimal.cls @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 1993-2019 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/modguide.pdf b/macros/latex/base/modguide.pdf index f74e0c15f7..92c662c2f3 100644 Binary files a/macros/latex/base/modguide.pdf and b/macros/latex/base/modguide.pdf differ diff --git a/macros/latex/base/modguide.tex b/macros/latex/base/modguide.tex index 3474d8a5fc..332b609ab3 100644 --- a/macros/latex/base/modguide.tex +++ b/macros/latex/base/modguide.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -42,7 +42,7 @@ \author{\copyright~Copyright 1995, \LaTeX\ Project Team.\\ All rights reserved.% - \footnote{This file may distributed and/or modified under the + \footnote{This file may be distributed and/or modified under the conditions of the \LaTeX{} Project Public License, either version 1.3c of this license or (at your option) any later version. See the source texttt{modguide.tex} for full details.}% diff --git a/macros/latex/base/newdc.ins b/macros/latex/base/newdc.ins index eeec6479eb..277e8ea21f 100644 --- a/macros/latex/base/newdc.ins +++ b/macros/latex/base/newdc.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/newlfont.dtx b/macros/latex/base/newlfont.dtx index 86c0d47ab6..0b35eddd80 100644 --- a/macros/latex/base/newlfont.dtx +++ b/macros/latex/base/newlfont.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/nfssfont.dtx b/macros/latex/base/nfssfont.dtx index 51d7834aa3..556ce5f76d 100644 --- a/macros/latex/base/nfssfont.dtx +++ b/macros/latex/base/nfssfont.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/nfssfont.ins b/macros/latex/base/nfssfont.ins index a181c61972..21a13f70a8 100644 --- a/macros/latex/base/nfssfont.ins +++ b/macros/latex/base/nfssfont.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/nfssfont.pdf b/macros/latex/base/nfssfont.pdf index 4b657e0f39..d08548d0eb 100644 Binary files a/macros/latex/base/nfssfont.pdf and b/macros/latex/base/nfssfont.pdf differ diff --git a/macros/latex/base/olddc.ins b/macros/latex/base/olddc.ins index 707fb207e6..320b3a4b0e 100644 --- a/macros/latex/base/olddc.ins +++ b/macros/latex/base/olddc.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/oldlfont.dtx b/macros/latex/base/oldlfont.dtx index b7c9abc3eb..33ae5e6fd9 100644 --- a/macros/latex/base/oldlfont.dtx +++ b/macros/latex/base/oldlfont.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/preload.dtx b/macros/latex/base/preload.dtx index 3b75df38fd..d26bdaa9ed 100644 --- a/macros/latex/base/preload.dtx +++ b/macros/latex/base/preload.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/proc.dtx b/macros/latex/base/proc.dtx index 135c67bc0b..bbbf71162f 100644 --- a/macros/latex/base/proc.dtx +++ b/macros/latex/base/proc.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/proc.ins b/macros/latex/base/proc.ins index 16f60195e5..056816e99e 100644 --- a/macros/latex/base/proc.ins +++ b/macros/latex/base/proc.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/proc.pdf b/macros/latex/base/proc.pdf index c99e5989d7..8f28a58bdc 100644 Binary files a/macros/latex/base/proc.pdf and b/macros/latex/base/proc.pdf differ diff --git a/macros/latex/base/slides.dtx b/macros/latex/base/slides.dtx index 5ea9e58d9c..a918c337dd 100644 --- a/macros/latex/base/slides.dtx +++ b/macros/latex/base/slides.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/slides.ins b/macros/latex/base/slides.ins index 8c9862c2d5..3acb556b96 100644 --- a/macros/latex/base/slides.ins +++ b/macros/latex/base/slides.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. @@ -96,7 +96,7 @@ extension .ins) which are part of the distribution. This is a generated file. -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. @@ -138,7 +138,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/slides.pdf b/macros/latex/base/slides.pdf index cf5f4f9794..f294fcc6a6 100644 Binary files a/macros/latex/base/slides.pdf and b/macros/latex/base/slides.pdf differ diff --git a/macros/latex/base/slifonts.fdd b/macros/latex/base/slifonts.fdd index ec8b802596..5b66975095 100644 --- a/macros/latex/base/slifonts.fdd +++ b/macros/latex/base/slifonts.fdd @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 1993-2019 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/slifonts.pdf b/macros/latex/base/slifonts.pdf index 49fcdd0ada..4598e87180 100644 Binary files a/macros/latex/base/slifonts.pdf and b/macros/latex/base/slifonts.pdf differ diff --git a/macros/latex/base/source2e.pdf b/macros/latex/base/source2e.pdf index b837332107..2aa83c3624 100644 Binary files a/macros/latex/base/source2e.pdf and b/macros/latex/base/source2e.pdf differ diff --git a/macros/latex/base/source2e.tex b/macros/latex/base/source2e.tex index 797304e8d6..873daebb4d 100644 --- a/macros/latex/base/source2e.tex +++ b/macros/latex/base/source2e.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/syntonly.dtx b/macros/latex/base/syntonly.dtx index ae4d4cd1f8..2b0049b696 100644 --- a/macros/latex/base/syntonly.dtx +++ b/macros/latex/base/syntonly.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/syntonly.ins b/macros/latex/base/syntonly.ins index 5812ef2fd6..8ccaf254d1 100644 --- a/macros/latex/base/syntonly.ins +++ b/macros/latex/base/syntonly.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 1993-2022 +Copyright (C) 1993-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/syntonly.pdf b/macros/latex/base/syntonly.pdf index 6c9ca64273..9d15389b26 100644 Binary files a/macros/latex/base/syntonly.pdf and b/macros/latex/base/syntonly.pdf differ diff --git a/macros/latex/base/testpage.tex b/macros/latex/base/testpage.tex index e199a2bb71..7eae6c142c 100644 --- a/macros/latex/base/testpage.tex +++ b/macros/latex/base/testpage.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/tlc2.err b/macros/latex/base/tlc2.err index 8925a8bee1..5b01ff0513 100644 --- a/macros/latex/base/tlc2.err +++ b/macros/latex/base/tlc2.err @@ -1,4 +1,4 @@ -\newcommand\erratafiledate{2022-01-03} +\newcommand\erratafiledate{2023-01-08} \def\comando#1{\texttt{\string#1}} @@ -359,7 +359,7 @@ you own by changing the configuration in the file \texttt{\jobname.cfg}. \end{center} Any mistake found and reported is a gain for all readers of our book. -For this reason Addison-Wesley and the authors offer a prize (for 6 +For this reason Addison-Wesley and the authors offer a prize (for 5 periods) to the eligible person who finds the largest number of bugs during that period (in case of a draw a random choice will be made between all those with the largest number of findings). @@ -385,7 +385,7 @@ Contest period ends & Winner \\[4pt] 2005/10 & Daniel Alonso i Alemany & 13 suggestions\\ 2006/04 & Michael Schutte & 2 suggestions\\ 2008/05 & Brooks Moses & 1 suggestion \\ -\ldots & -- final draw eventually -- + & -- final draw was 2008/05 -- \end{tabular} \end{center} \end{list} @@ -2185,6 +2185,8 @@ Change: ``The unaccented ASCII Latin letters and Arabic |\dag| and |\ddag| are |\mathord|s not |\mathbin| as claimed in table 8.13. + Frank: This is actually correct nowadays (maybe it wasn't in 2008) + \seriouserroronpage{529}{table 8.12, l.3}{JGr}{2004/06/10}{2} \verb=\mathring{x}= is missing its accent. @@ -2202,6 +2204,9 @@ Change: ``The unaccented ASCII Latin letters and Arabic aren't (as claimed in legend) synonyms of |\dagger| and |\ddagger| respectively. + Frank: This is actually correct nowadays (maybe it wasn't in 2008) + + \erroronpage{531}{table 8.15}{BMo/FMi}{2004/05/21}{2} The commands starting with |\var...| are only partially in blue to indicate their relationship with those commands missing the ``var'' in their @@ -2236,10 +2241,6 @@ Change: ``The unaccented ASCII Latin letters and Arabic Various deviations from alphabetical sort order of the table entries. -\erroronpage{553}{para 3, l.1}{EOl}{2022/01/02}{} - Missing letter: ``sup\u{p}ressing'' - - \iffalse % more blue align stuff \erroronpage{534}{page}{FMi}{2004/04/23}{} Printing problem: blue color not properly aligned (horizontally). @@ -2332,6 +2333,10 @@ Plural: ``Clearly, 8 bits \u{are} not sufficient\ldots'' respectively %(ref: TB 14-3-252-259) +\erroronpage{553}{para 3, l.1}{EOl}{2022/01/02}{} + Missing letter: ``sup\u{p}ressing'' + + \seriouserroronpage{553}{para 4}{UFi}{2004/06/03}{2} Replace with: ``Another popular shorthand is |"-|, which indicates a diff --git a/macros/latex/base/tlc2.pdf b/macros/latex/base/tlc2.pdf index e82f587b19..3d93429fbc 100644 Binary files a/macros/latex/base/tlc2.pdf and b/macros/latex/base/tlc2.pdf differ diff --git a/macros/latex/base/tlc3.err b/macros/latex/base/tlc3.err new file mode 100644 index 0000000000..b7e2c1c0fd --- /dev/null +++ b/macros/latex/base/tlc3.err @@ -0,0 +1,848 @@ +\newcommand\erratafiledate{2023-05-30} + +\def\comando#1{\texttt{\string#1}} + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +% To produce a printed version of this errata file run this file through +% LaTeX. It will unpack a small class file (if not already present) and +% a configuration file with the extension .cfg. You might want to modify +% the setting in this configuration file to print only a partial errata +% suitable for your printed revision of this book, see details in the +% .cfg file. +% +% The current version of this file can be found at: +% +% https://www.latex-project.org/help/books/ +% +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + + +\begin{filecontents}{ttcterrata.cls} +%% +%% Copyright (C) 1997-2021 Frank Mittelbach +%% This class file is licensed under LPPL latest version; +%% see https://www.latex-project.org/lppl +% +% +% It sets up a few commands used to format the errata entries for books in the +% Addison-Wesley Series: +% +% Tools and Techniques for Computer Typesetting +% +% hence the name. However, anybody who likes to use it is free to apply it for +% errata files of other books. +% +% Changes: +% +% v1.0a - changed name from errata.cls to ttcterrata.cls +% v1.0b - added \arraybackslash +% v1.0c - and took it out again and used \tabularnewline instead + +\ProvidesClass{ttcterrata} + [2021/08/03 v1.0c Mini class for errata files; subject to change (FMi)] + +\LoadClass{article} + +\setcounter{secnumdepth}{-1} +\addtolength\textwidth{5cm} +\addtolength\oddsidemargin{-3cm} + +\addtolength\textheight{36pt} + +\RequirePackage{shortvrb} +\MakeShortVerb{\|} + +\RequirePackage{array,longtable} +\RequirePackage{multicol} + + +\newcommand\erratagetnumber{} +\def\erratagetnumber#1/#2/#3\erratagetnumber{#1#2#3} + + +\newcommand\gobbleerrata{% + \setbox\@tempboxa\vbox\bgroup + \let\endgobble\egroup + \let\hideamp\relax + \let\\\relax + \let\tabularnewline\relax + \let\par\@@par} + +\newcommand*\hideamp{&} + +\let\endgobble\relax + + +\newcommand\erratastartdate{} +\newcommand\myprinting{1} + + +\newcommand\doweprint[2]{% + \ifnum \myprinting < \if!#2!1000 \else \ifx s#2 1000\else#2 \fi\fi + \ifnum \expandafter\erratagetnumber\erratastartdate\erratagetnumber < + \erratagetnumber#1\erratagetnumber \relax + \@tempswatrue + \else + \@tempswafalse + \fi + \else + \@tempswafalse + \fi +} + + + +\newcommand\includedentries{entries after = \erratastartdate} +\newcommand\printedentries{between \erratastartdate\space and} + +\newcommand\showallerrors{% + \renewcommand\includedentries{all errata entries}% + \renewcommand\printedentries{up to} + \renewcommand\doweprint[2]{\@tempswatrue}} + + +\newcommand\displayrevisionfix[2]{% + \if!#2!\textbf{#1}\else\textit{#1}\rlap{\textsuperscript{#2}}\fi} + +\newcommand\norevisionnumbers{% + \renewcommand\displayrevisionfix[2]{\textbf{##1}}} + +\IfFileExists{\jobname.cfg} + { + \input{\jobname.cfg} + \typeout{***************************************************} + \typeout{*} + \typeout{* Configuration file for \jobname.err found } + \typeout{*} + \typeout{***************************************************} + \AtEndDocument{ + \typeout{***************************************************} + \typeout{*} + \typeout{* If you wish to generate an errata listing} + \typeout{* containing only errors found after a certain revision} + \typeout{* and/or only errors found after a certain date} + \typeout{* modify the information stored in \jobname.cfg} + \typeout{*} + \typeout{* Current settings are:} + \typeout{*} + \typeout{* \@spaces printing of your book = \myprinting} + \typeout{* \@spaces include \includedentries} + \typeout{*} + \typeout{***************************************************} + }} + {} + +%% \erroronpage <page> <line info> <contributor> <date> <fixed in revision> + +\newcommand\erroronpage[5]{% + \endgobble + \doweprint{#4}{#5}% + \if@tempswa + \typeout{Typesetting entry #1 #2 #3 #4}% + \else + \typeout{Ignoring entry #1 #2 #3 #4}% + \expandafter\gobbleerrata + \fi + \hideamp \tabularnewline + \displayrevisionfix{#1}{#5} + \hideamp #2 \hideamp (\textsf{#3}) \hideamp +} + +\newcommand\seriouserroronpage[5]{% + \endgobble + \doweprint{#4}{#5}% + \if@tempswa + \typeout{Typesetting entry #1 #2 #3 #4}% + \else + \typeout{Ignoring entry #1 #2 #3 #4}% + \expandafter\gobbleerrata + \fi + \hideamp \tabularnewline + \fbox{\bfseries !!}\hfill + \displayrevisionfix{#1}{#5} + \hideamp #2 \hideamp (\textsf{#3}) \hideamp +} + +\newcommand\CHAPTER[1]{\endgobble + &\tabularnewline[4pt]% + \multicolumn{4}{l}{\framebox[10cm][l]{\textbf{\normalsize\strut#1}}} \tabularnewline} + +\newenvironment{erratalist} + {\begin{longtable}{r>{\raggedright}p{2cm}l>{\raggedright}p{10cm}l}} + {\endgobble\end{longtable}} + +\newcommand\erratatitle[2] + {\begin{center}\LARGE\bfseries + Errata list for #1\\[5pt](\myprinting.\ printing)\\[10pt] + \small Includes all entries found \printedentries\space #2\\ + (For other periods/print runs reprocess this document + with different config settings) + \end{center}% + \markright{Errata for #1 (\printedentries\space #2)}% + \thispagestyle{plain}% + \vspace{20pt}} + +\pagestyle{myheadings} + +\AtBeginDocument{\small} + +\setlength\parindent{0pt} +\setlength\parskip{2pt} + +\newcommand\contributor[2]{\makebox[1cm][l]{\sffamily#1} #2\par} + +% some special shortcuts overwriting existing commands: + +\let\u\underline +\renewcommand\>{$\to$} + +%%% some code suggested by Thorsten Hansen to count the number of +%%% contributions by individuals (will work only if we do not get +%%% too many :-) + +\def\count@contributors#1/#2/#3\@nil{ + \@ifundefined{c@#1}{\newcounter{#1}}{}\stepcounter{#1}% +%%% also count secondary: +%%% \@ifundefined{c@#2}{\newcounter{#2}}{}\stepcounter{#2}% +} + +\renewcommand\erroronpage[5]{% + \count@contributors#3/secondary/\@nil + \endgobble + \doweprint{#4}{#5}% + \if@tempswa + \typeout{Typesetting entry #1 #2 #3 #4}% + \else + \typeout{Ignoring entry #1 #2 #3 #4}% + \expandafter\gobbleerrata + \fi + \hideamp \tabularnewline + \displayrevisionfix{#1}{#5} + \hideamp #2 \hideamp (\textsf{#3}) \hideamp +} + +\renewcommand\seriouserroronpage[5]{% + \count@contributors#3/secondary/\@nil + \endgobble + \doweprint{#4}{#5}% + \if@tempswa + \typeout{Typesetting entry #1 #2 #3 #4}% + \else + \typeout{Ignoring entry #1 #2 #3 #4}% + \expandafter\gobbleerrata + \fi + \hideamp \tabularnewline + \fbox{\bfseries !!}\hfill + \displayrevisionfix{#1}{#5} + \hideamp #2 \hideamp (\textsf{#3}) \hideamp +} + +\renewcommand\contributor[2]{\makebox[1cm][l]{% + \sffamily#1} #2\@ifundefined{c@#1}{}{ (\arabic{#1})}\par} + +\end{filecontents} + + +\begin{filecontents}{\jobname.cfg} +% +% +% Configuration file for the errata listing of +% +% The LaTeX Companion, Third Edition, Parts I & II +% +% +% \erratastartdate +% +% Specifies the date from which on errata entries should be listed. +% +% The format is YYYY/MM/DD. +% +% The default below ensures that all entries for a particular +% printing are typeset. +% + +\renewcommand\erratastartdate{2023/04/01} + + +% +% \myprinting +% +% Specifies which (revised) printing you own. For example, if you +% have the second printing set this to 2 so that errors already +% corrected in that printing will not appear in your errata +% listing. +% +% The default below ensures that all entries relevant to the x-th +% printing are typeset. +% +% + +\renewcommand\myprinting{1} + +% +% \norevisionnumbers +% +% Specifies that all page numbers in the errata are shown in the same +% format (bold face) irregardless of whether or not they are fixed +% in some revision. The default is to print corrected errors in +% italic and add the revision number as a superscript. + +% +% \showallerrors +% +% With this command you tell the program that all errata entries are +% supposed to be generated. This makes \myprinting and +% \erratastartdate basically obsolete so this isn't turned on by +% default. +% +% +\endinput +\end{filecontents} + + +\documentclass{ttcterrata}[2005/11/10] % we want new class + +\usepackage[T1]{fontenc} +\let\u\underline % shortcut for this file +\newcommand\meta[1]{$\langle$\textit{#1\/}$\rangle$} + +\usepackage{textcomp} + +\usepackage{url} + +\begin{document} + +\erratatitle{The \LaTeX{} Companion, Third Edition, Parts I \& II}{\erratafiledate} + + +\begin{verbatim} +@book(A-W:MF:2023, + author = {Frank Mittelbach and Ulrike Fischer}, + title = {The {\LaTeX} Companion}, + edition = 3, + note = {With contributions by Javier Bezos, Johannes Braams, and Joseph Wright}, + series = {Tools and Techniques for Computer Typesetting}, + publisher = {Addison-Wesley}, + address = {Boston, Massachusetts}, + year = 2023, + pagenums = {976 (Part I) and 1008 (Part II)}, + bibliography = {yes}, + index = {yes}, + isbn = {978-0-13-816648-9}, +) +\end{verbatim} + + +\begin{list}{}{\setlength\leftmargin{0cm}\setlength\rightmargin{3cm}} +\item[] + +This file (\texttt{\jobname.err}) can be found as part of the \LaTeX{} +distribution and its latest version is maintained on the \LaTeX{} +project site at \texttt{https://www.latex-project.org/help/books/\jobname.err} +where you will also find extracts of the book. + +The first column in the table shows the page number of the errata +entry. Superscript numbers in the first column refer to the printed +revision in which this entry was corrected (\textit{s} indicates a +correction in the sources only). The second +column gives the precise location (negative line or paragraph numbers +are counted from the bottom of the page). The third column shows the +first finder of the problem. + +You can customize this list to only show errata related to the printing +you own by changing the configuration in the file \texttt{\jobname.cfg}. + +\begin{center} + \Large \bfseries To Err is Human --- Bug Contest +\end{center} + +Any mistake found and reported is a gain for all readers of our book. +For this reason Addison-Wesley and the authors offer a prize (for 5 +periods) to the eligible person who finds the largest +number of bugs during that period (in case of a draw a random choice +will be made between all those with the largest number of findings). +A person can receive at most one prize, ever; errors found by any of +the authors do not count. + +Each prize is a free choice of any single computing book found on the +Addison-Wesley/Pearson web site: +\texttt{https://www.informit.com} (that +is, no boxed sets or multiple volume offers). + + +As usual, the authors and publisher reserve the right to make various +decisions such as whether a reported feature is an error for +competitive purposes or whether similar features count as a single or +multiple errors. --- +Good luck! + +\begin{center} +\begin{tabular}{clr} +Contest period ends & Winner \\[4pt] +2023/?? & & ??? suggestions\\ +\end{tabular} +\end{center} + + +Due to its size the third edition of \textit{The \LaTeX{} Companion} is printed +as a two-volume set. The digital version, however, is provided as a +single PDF or ePub. This means that a small fraction of the digital +content differs from that of the printed version: there is only a +single font matter, a single bibliography, and a single index, whereas +in the printed books these are separated out. However, all versions share the main +matter (down to the page numbering) so most of the errata applies to +all versions, but a few only to the digital and some only to the +printed version. Thus, we end up with three separate lists. + + +\end{list} + +%\newpage + + +%<-------------------------- + +\newcommand\BibTeX{\textsc{Bib}\TeX} +\newcommand\cs[1]{\texttt{\textbackslash #1}} +\newcommand\env[1]{\texttt{#1}} +\newcommand\pkg[1]{\textsf{#1}} + +\section*{Errata for the print version (not applicable to the digital version)} + +The printed books differ from the digital version in that the +bibliography is split across both volumes (with a few repeats) and that +the font matter of each volume has its own table of contents and list +of figures and tables. Therefore these parts have different page +numbers and you will see similar errata entries for both print and +digital differing only in that respect. + +\begin{erratalist} + +\CHAPTER{Front matter (Part I)} + +\erroronpage{I-ix\ldots I-xvi}{}{FMi}{2023/04/04}{s} +Dot leaders have been changed on all sections. + +\erroronpage{I-xvii}{chapter head}{FMi}{2023/04/04}{s} +formulas \> \u{F}ormulas + +\erroronpage{I-xvii}{chapter head}{FMi}{2023/04/04}{s} +documents \> \u{D}ocuments + +\erroronpage{I-xvii}{chapter head}{FMi}{2023/04/04}{s} +beyond \> \u{B}eyond + +\erroronpage{I-xx\ldots I-xxi}{}{FMi}{2023/04/04}{s} +Dot leaders have been changed on all sections. + +\CHAPTER{Bibliography (Part I)} + +\erroronpage{I-783}{[55], l.-2}{FMi}{2023/04/04}{s} +all \> \u{them} all + +\erroronpage{I-785}{[73], l.-2}{kb/bb}{2023/04/04}{s} +the go-forward way for \LaTeX-coding \> \\ +the way for \LaTeX{} coding going forward + +\erroronpage{I-786}{[87], l.2}{kb/bb}{2023/04/04}{s} +p. \> pp. + +\erroronpage{I-786}{[88], l.2}{kb/bb}{2023/04/04}{s} +p. \> pp. + +\erroronpage{I-787}{[92], l.2}{kb/bb}{2023/04/04}{s} +Add: Vancouver, 1999 + +\erroronpage{I-788}{[100], l.3}{kb/bb}{2023/04/04}{s} +Publishing \> Publishing\u{,} + +\erroronpage{I-790}{[122], l.1}{kb/bb}{2023/04/04}{s} +In \u{ACM editor} ``Proceedings \> In ``\u{PODC'01: }Proceedings + +\erroronpage{I-790}{[122], l.1}{kb/bb}{2023/04/04}{s} +In \u{Unicode Consortium, editor} \> In + + +\CHAPTER{Front matter (Part II)} + +\erroronpage{II-x\ldots II-xxviii}{}{FMi}{2023/04/04}{s} +Dot leaders have been changed on all sections. + +\erroronpage{II-xiv}{heading}{bb/FMi}{2023/04/04}{s} +Multiple alignments: \env{align} \u{and \env{flalign}} +\>\\ +Multiple alignments: \env{align}\u{, \env{flalign}, and \env{alignat}} + +\erroronpage{II-xv}{chapter head}{FMi}{2023/04/04}{s} +formulas \> \u{F}ormulas + +\erroronpage{II-xvi}{chapter head}{FMi}{2023/04/04}{s} +documents \> \u{D}ocuments + +\erroronpage{II-xxi}{chapter head}{FMi}{2023/04/04}{s} +beyond \> \u{B}eyond + + + +\CHAPTER{Bibliography (Part II)} + +\erroronpage{II-799}{[43], l.-2}{FMi}{2023/04/04}{s} +all \> \u{them} all + +\erroronpage{II-801}{[62], l.-2}{kb/bb}{2023/04/04}{s} +the go-forward way for \LaTeX-coding \>\\ +the way for \LaTeX{} coding going forward + +\erroronpage{II-802}{[71], l.2}{kb/bb}{2023/04/04}{s} +p. \> pp. + +\erroronpage{II-802}{[72], l.2}{kb/bb}{2023/04/04}{s} +p. \> pp. + +\erroronpage{II-803}{[80], l.3}{kb/bb}{2023/04/04}{s} +Publishing \> Publishing\u{,} + + + + +\end{erratalist} + + +%<-------------------------- + +\section*{Errata for the digital version (not applicable to the print version)} + +All known errors to the digital version have already been incorporated in the product as distributed. + +%\begin{erratalist} +% +%\CHAPTER{General} +% +%\CHAPTER{Front matter} +% +%\end{erratalist} + + +%<-------------------------- + + +\section*{Errata common to the print and digital versions} + +The main matter is identical (also in page numbers) in the print and +the digital versions. Therefore most errata entries appear in this +section. + +\begin{erratalist} + + +\CHAPTER{General} + +\erroronpage{}{}{FMi}{2023/04/04}{s} +Some corrections result in index changes. These are not tracked here; +the index is always fully regenerated for new printings. + +\CHAPTER{Chapter 1 --- Introduction} + +\erroronpage{I-5}{para 4, l.4}{kb}{2023/04/04}{s} +\u{of} the bugs \> \u{with} the bugs +\\ Already corrected in the digital version. + + +\erroronpage{I-5}{para 5, l.5}{kb}{2023/04/04}{s} +not least \> \u{but} not least +\\ Already corrected in the digital version. + + +\CHAPTER{Chapter 2 --- The Structure of a \LaTeX{} Document} + +\erroronpage{I-34}{l.-1}{FMi}{2023/04/04}{s} +Moved first line of page 35 to 34. +\\ Already corrected in the digital version. + +\erroronpage{I-35}{l.1}{FMi}{2023/04/04}{s} +Moved first line of page 35 to 34. +\\ Already corrected in the digital version. + +\erroronpage{I-113}{listing}{FMi}{2023/05/14}{s} +Situation is the same in the 2023 distributions; listing output updated. +\\ Already corrected in the digital version. + + +\CHAPTER{Chapter 3 --- Basic Formatting Tools -- Paragraph \ldots} + + +\CHAPTER{Chapter 4 --- Basic Formatting Tools -- Larger \ldots} + + +\CHAPTER{Chapter 5 --- The Layout of the Page} + + +\CHAPTER{Chapter 6 --- Tabular Material} + + +\CHAPTER{Chapter 7 --- Mastering Floats} + + +\CHAPTER{Chapter 8 --- Graphics Generation and Manipulation} + +\erroronpage{I-619}{para -2, l.2}{FMi}{2023/05/30}{s} +in \u{light blue} \> in \u{red} + +\erroronpage{I-619}{exa 8-4-7}{FMi}{2023/05/30}{s} +The example uses \verb*/left color=red!20/ but this is not really +visible if the red is turned into some gray value in the book (which +is then made even lighter through \texttt{!20}). So it is better to +start from full red, i.e., \> \verb*/left color=red/ instead. +\\ Already corrected in the digital version. + +\CHAPTER{Chapter 9 --- Font Selection and Encodings} + +\erroronpage{I-669}{exa 9-3-11}{FMi}{2023/04/04}{s} +Changed line breaks in example. + +\erroronpage{I-708}{listing}{FMi}{2023/05/14}{s} +Situation is the same in the 2023 distributions; listing output updated. +\\ Already corrected in the digital version. + + +\CHAPTER{Chapter 10 --- Text and Symbol Fonts} + +\erroronpage{II-114}{table 10.89}{FMi}{2023/04/04}{s} +Added missing \texttt{U+00Fx} line. +There was a bug in code generating it. +\\ Already corrected in the digital version. + +\erroronpage{II-117}{table 10.92}{FMi}{2023/04/04}{s} +Added missing \texttt{U+00Fx} line. +There was a bug in code generating it. +\\ Already corrected in the digital version. + +\erroronpage{II-121}{table 10.96}{FMi}{2023/04/04}{s} +Added missing \texttt{U+00Fx} line. +There was a bug in code generating it. +\\ Already corrected in the digital version. + +\erroronpage{II-122}{table 10.98}{FMi}{2023/04/04}{s} +Added missing \texttt{U+00Fx} line. +There was a bug in code generating it. +\\ Already corrected in the digital version. + +\erroronpage{II-122}{table 10.99}{FMi}{2023/04/04}{s} +Added missing \texttt{U+00Fx} line. +There was a bug in code generating it. +\\ Already corrected in the digital version. + +\erroronpage{II-123}{table 10.100}{FMi}{2023/04/04}{s} +Added missing \texttt{U+00Fx} line. +There was a bug in code generating it. +\\ Already corrected in the digital version. + +\erroronpage{II-124}{table 10.103}{FMi}{2023/04/04}{s} +Added missing \texttt{U+00Fx} line. +There was a bug in code generating it. +\\ Already corrected in the digital version. + + + +\CHAPTER{Chapter 11 --- Higher Mathematics} + +\erroronpage{II-127}{para 1, l.5}{bb/FMi}{2023/04/04}{s} +\u{The} American Mathematical Society (AMS) \u{provides} a major +package, \pkg{amsmath}, which \u{makes} \ldots +\>\\ +\u{In the early nineties the} American Mathematical Society (AMS) +\u{provided} a major package, \pkg{amsmath}, which \u{made} \ldots +\\ Already corrected in the digital version. + +\erroronpage{II-129}{para -3, l.1}{bb/FMi}{2023/04/04}{s} +The principal documentation for these packages +\>\\ +The principal documentation for these \u{two} packages +\\ Already corrected in the digital version. + + +\erroronpage{II-129}{para -1, l.3}{bb}{2023/04/04}{s} +\u{lot} additions \> \u{many} additions +\\ Already corrected in the digital version. + + +\erroronpage{II-132}{table 11.1}{bb/FMi}{2023/04/04}{s} +Also mention \env{alignat}, \env{alignat*}, and \env{alignedat}. +\\ Already corrected in the digital version. + +\erroronpage{II-133}{para 4,l.2}{bb/FMi}{2023/04/04}{s} +Add: + +Furthermore, they move the equation tag out of the way if it would +otherwise overprint the formula. +\\ Already corrected in the digital version. + +\erroronpage{II-138}{heading}{bb/FMi}{2023/04/04}{s} +Multiple alignments: \env{align} \u{and \env{flalign}} +\> +Multiple alignments: \env{align}\u{, \env{flalign}, and \env{alignat}} +\\ Already corrected in the digital version. + +\erroronpage{II-138}{}{FMi}{2023/04/04}{s} +Moved para from 139 to end of this page. +\\ Already corrected in the digital version. + +\erroronpage{II-139}{para 1}{FMi}{2023/04/04}{s} +Moved para back to page 138. +\\ Already corrected in the digital version. + +\erroronpage{II-139}{bottom}{FMi}{2023/04/04}{s} +Add: + +Sometimes it is more convenient to explicitly specify all the +horizontal spacing yourself within the formula. For this you can use +an \env{alignat} environment. It differs from \env{align} in two ways: you have to +specify the number of \texttt{rl} pairs as an argument to the environment and +it does not add any spaces between the pairs, e.g., +\begin{verbatim} +\begin{alignat}{3} x &= y &\qquad X &= Y &\qquad a &= b+c \\ ... +\end{verbatim} +As usual, equation numbers can be altered with \cs{tag} or suppressed with \cs{notag}. +\\ Already corrected in the digital version. + + +\erroronpage{II-140}{para 1, l.2}{bb/FMi}{2023/04/04}{s} +Add: + +Do not forget to reset \cs{minalignsep} if you change it in this manner. +\\ Already corrected in the digital version. + +\erroronpage{II-140}{para 2, l.4}{bb/FMi}{2023/04/04}{s} +Add: + +You can think of them as subsidiary environments that can be used +within any of the display environments discussed so far (below we use +them inside equation). +\\ Already corrected in the digital version. + +\erroronpage{II-140}{para -1}{FMi}{2023/04/04}{s} +Paragraph moved to page 141. +\\ Already corrected in the digital version. + +\erroronpage{II-141}{}{FMi}{2023/04/04}{s} +One paragraph moved over from page 140. +\\ Already corrected in the digital version. + +\erroronpage{II-144}{para 2, l.-3}{FMi}{2023/04/04}{s} +the issue \> the \u{spacing} issue +\\ Already corrected in the digital version. + +\erroronpage{II-145}{para 2, l.1}{bb/FMi}{2023/04/04}{s} +Add: + +Another problem is that an empty line introduces an unwanted break +point in front of the display, thus \cs{predisplaypenalty} is no +longer honored. +\\ Already corrected in the digital version. + + +\CHAPTER{Chapter 12 --- Fonts in Formulas} + +\erroronpage{II-225}{heading}{FMi}{2023/04/04}{s} +Chapter title not properly capitalized. +\\ Already corrected in the digital version. + +\erroronpage{II-261}{para 3, l.3}{FMi}{2023/05/26}{s} +Yoda spoke it seems: \ldots \u{and compare we should} \> +\ldots \u{and you should compare} +\\ Already corrected in the digital version. + + +\CHAPTER{Chapter 13 --- Localizing Documents} + +\erroronpage{II-297}{heading}{FMi}{2023/04/04}{s} +Chapter title not properly capitalized. +\\ Already corrected in the digital version. + + +\CHAPTER{Chapter 14 --- Index Generation} + + +\CHAPTER{Chapter 15 --- Bibliography Generation} + +\erroronpage{II-435}{code}{FMi}{2023/05/26}{s} +\verb=\textcolor{See= \> \verb=\textcolor{blue}{See= +\\ Already corrected in the digital version. + + + +\CHAPTER{Chapter 16 --- Managing Citations} + + +\CHAPTER{Chapter 17 --- \LaTeX{} Package Documentation Tools} + + +\CHAPTER{Appendix A --- \LaTeX{} Overview for Preamble, \ldots} + + +\CHAPTER{Appendix B --- Tracing and Resolving Problems} + + +\CHAPTER{Appendix C --- Going Beyond} + +\erroronpage{II-297}{heading}{FMi}{2023/04/04}{s} +Appendix title not properly capitalized. +\\ Already corrected in the digital version. + +\CHAPTER{Biographies} + +\CHAPTER{Production Notes} + +\end{erratalist} + + + + + +\setcounter{collectmore}{3} + +\begin{multicols}{3}[Thanks to all who have found errors or + omissions. Listed are the people who found an errata entry first.] +\contributor{bb}{Barbara Beeton} +\contributor{FMi}{Frank Mittelbach} +\contributor{kb}{Karl Berry} +\end{multicols} + + +Other people have sent us corrections for errors already found. +Thanks to all of you! + +If you find further errors please report them to one of the authors, e.g., +\begin{quote}\ttfamily + frank.mittelbach@latex-project.org +\end{quote} +preferably in a form usable directly in this file, i.e., +\begin{flushleft} +|\erroronpage{|\textit{page-number}|}{|\textit{line-identification}|}{|% + \textit{your-initials}|}{|\textit{date}|}{}| \\ + \hspace*{2em}\textit{description of the erratum} +\end{flushleft} +Here is an example: +\begin{verbatim} +\erroronpage{5}{para 3, l.1}{FMi}{2023/06/21}{} + \u{LaTeX} \> \u{\LaTeX} +\end{verbatim} +\verb=\u= underlines a text fragment and \verb=\>= produces \>. +\end{document} + + + + +\seriouserroronpage{general}{}{FMi}{2004/06/12}{} + + To help you in assessing this errata document we have placed + exclamation marks in front of each entry that we consider essential + for correctly understanding the book contents. + +\erroronpage{general}{}{FMi}{2004/05/14}{} + + Due to the printing process there may be small alignment problems + between blue and black text on some pages. These can vary from book + to book depending on how the paper was handled between print + runs---such is the analog nature of printing on a press. + diff --git a/macros/latex/base/tlc3.pdf b/macros/latex/base/tlc3.pdf new file mode 100644 index 0000000000..83605eb82f Binary files /dev/null and b/macros/latex/base/tlc3.pdf differ diff --git a/macros/latex/base/tulm.fdd b/macros/latex/base/tulm.fdd index 243cbe30cc..c8dd8b95fc 100644 --- a/macros/latex/base/tulm.fdd +++ b/macros/latex/base/tulm.fdd @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright 2016-2021 +% Copyright (C) 2016-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/tulm.ins b/macros/latex/base/tulm.ins index a50060b201..85970a5133 100644 --- a/macros/latex/base/tulm.ins +++ b/macros/latex/base/tulm.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 2016-2022 +%% Copyright (C) 2016-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% @@ -48,7 +48,7 @@ reports for it can be opened at https://latex-project.org/bugs.html (but please observe conditions on bug reports sent to that address!) -Copyright (C) 2016-2022 +Copyright (C) 2016-2023 The LaTeX Project and any individual authors listed elsewhere in this file. diff --git a/macros/latex/base/tulm.pdf b/macros/latex/base/tulm.pdf index 990eba766b..d1bf3b1a88 100644 Binary files a/macros/latex/base/tulm.pdf and b/macros/latex/base/tulm.pdf differ diff --git a/macros/latex/base/unpack.ins b/macros/latex/base/unpack.ins index 21ba62a33a..5baa2b5447 100644 --- a/macros/latex/base/unpack.ins +++ b/macros/latex/base/unpack.ins @@ -3,7 +3,7 @@ %% driver files from the doc files in this package when run through %% LaTeX or TeX. %% -%% Copyright (C) 1993-2022 +%% Copyright (C) 1993-2023 %% The LaTeX Project and any individual authors listed elsewhere %% in this file. %% diff --git a/macros/latex/base/usrguide-historic.pdf b/macros/latex/base/usrguide-historic.pdf index ba663260c9..629e70e7bd 100644 Binary files a/macros/latex/base/usrguide-historic.pdf and b/macros/latex/base/usrguide-historic.pdf differ diff --git a/macros/latex/base/usrguide-historic.tex b/macros/latex/base/usrguide-historic.tex index ce35aaa77c..40865a2be9 100644 --- a/macros/latex/base/usrguide-historic.tex +++ b/macros/latex/base/usrguide-historic.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -36,7 +36,7 @@ \author{\copyright~Copyright 1995--2022, \LaTeX\ Project Team.\\ All rights reserved.% - \footnote{This file may distributed and/or modified under the + \footnote{This file may be distributed and/or modified under the conditions of the \LaTeX{} Project Public License, either version 1.3c of this license or (at your option) any later version. See the source \texttt{usrguide.tex} for full details.}% diff --git a/macros/latex/base/usrguide.pdf b/macros/latex/base/usrguide.pdf index 3bcdae3035..c9d445ae8a 100644 Binary files a/macros/latex/base/usrguide.pdf and b/macros/latex/base/usrguide.pdf differ diff --git a/macros/latex/base/usrguide.tex b/macros/latex/base/usrguide.tex index 32e12a1397..42d5e401f8 100644 --- a/macros/latex/base/usrguide.tex +++ b/macros/latex/base/usrguide.tex @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2020-2022 +% Copyright (C) 2020-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % @@ -32,17 +32,18 @@ \usepackage[T1]{fontenc} % needed for \textbackslash in tt \usepackage{csquotes} +\usepackage{url} \title{\LaTeX\ for authors --- current version} -\author{\copyright~Copyright 2020-2022, \LaTeX\ Project Team.\\ +\author{\copyright~Copyright 2020-2023, \LaTeX\ Project Team.\\ All rights reserved.% - \footnote{This file may distributed and/or modified under the + \footnote{This file may be distributed and/or modified under the conditions of the \LaTeX{} Project Public License, either version 1.3c of this license or (at your option) any later version. See the source \texttt{usrguide.tex} for full details.}% } -\date{2022-07-05} +\date{2023-05-23} \NewDocumentCommand\cs{m}{\texttt{\textbackslash\detokenize{#1}}} \NewDocumentCommand\marg{m}{\arg{#1}} @@ -340,6 +341,12 @@ in \pkg{amsmath} environments, which in the terms here would be defined as \NewDocumentCommand\\{!s !o}{ ... } \end{verbatim} +Also notable when using optional arguments in the last position is that \TeX{} +will necessarily look ahead for the argument opening token. This means that +the value of |\inputlineno| will be `out by one' if such a trailing optional +argument is \emph{not} present and the command ends a line; it will be one +greater than the line number containing the last mandatory argument. + \subsection{`Embellishments'} \label{sec:cmd:embellishment} @@ -636,7 +643,19 @@ processed argument can be further processed using a mapping function If only a single character \meta{token} is used for the split, any category code $13$ (active) character matching the \meta{token} will be replaced before the split takes place. -Spaces are trimmed at each end of each item parsed. +Spaces are trimmed at each end of each item parsed. Exactly one set +of braces will be stripped if an entire item is surrounded by them, +i.e.~the following inputs and outputs result (each separte item as +a brace group). +\begin{verbatim} +a ==> {a} +{a} ==> {a} +{a}b ==> {{a}b} +a,b ==> {a}{b} +{a},b ==> {a}{b} +a,{b} ==> {a}{b} +a,{b}c ==> {a}{{b}c} +\end{verbatim} \begin{decl} |\ProcessList| \arg{list} \arg{function} @@ -716,7 +735,7 @@ put that code at the end of the \meta{start code}. Nevertheless this Environments that use this feature can be nested. -\subsection{Fully-expandable document commands} +\subsection{Fully-expandable document commands\label{sec:ltcmd:expandable}} Document commands created using \cs{NewDocumentCommand}, etc.\@, are normally created so that they do not expand unexpectedly. This is done using engine @@ -724,7 +743,7 @@ features, so is more powerful than \LaTeXe{}'s \cs{protect} mechanism. There are \emph{very rare} occasion when it may be useful to create functions using a expansion-only grabber. This imposes a number of restrictions on the nature of the arguments accepted by a function, and the code it implements. -This facility should only be used when \emph{absolutely necessary}. +This facility should only be used when \emph{necessary}. \begin{decl} |\NewExpandableDocumentCommand| \arg{cmd} \arg{arg spec} \arg{code} \\ @@ -755,6 +774,25 @@ available: in the standard version. \end{itemize} +\subsection{Commands at the start of tabular cells} + +Creating commands that are used at the start of tabular cells imposes +some restrictions on the underlying implementation. The standard \LaTeX{} +tabular environments (\texttt{tabular}, etc.) use a mechanism which requires +that any command wrapping \cs{multicolumn} or similar must be +`expandable'. This is \emph{not} the case for commands created using +\cs{NewDocumentCommand}, etc., which as detailed in +Section~\ref{sec:ltcmd:expandable} use an engine feature which prevents +such `expansion'. Therefore, to create such wrappers for use at the start +of tabular cells, you must use \cs{NewExpandableDocumentCommand}, for example +\begin{verbatim} +\NewExpandableDocumentCommand\MyMultiCol{m}{\multicolumn{3}{c}{#1}} +\begin{tabular}{lcr} +a & b & c \\ +\MyMultiCol{stuff} \\ +\end{tabular} +\end{verbatim} + \subsection{Details about argument delimiters} In normal (non-expandable) commands, the delimited types look for the @@ -844,28 +882,28 @@ The argument specifications for document commands and environments are available for examination and use. \begin{decl} - |\GetDocumentCommandArgSpec| \arg{function} \\ + |\GetDocumentCommandArgSpec| \arg{cmd} \\ |\GetDocumentEnvironmentArgSpec| \arg{environment} \end{decl} These functions transfer the current argument specification for the -requested \meta{function} or \meta{environment} into the token list -variable \cs{ArgumentSpecification}. If the \meta{function} or +requested \meta{cmd} or \meta{environment} into the token list +variable \cs{ArgumentSpecification}. If the \meta{cmd} or \meta{environment} has no known argument specification then an error is issued. The assignment to \cs{ArgumentSpecification} is local to the current \TeX{} group. \begin{decl} - |\ShowDocumentCommandArgSpec| \arg{function} \\ + |\ShowDocumentCommandArgSpec| \arg{cmd} \\ |\ShowDocumentEnvironmentArgSpec| \arg{environment} \end{decl} These functions show the current argument specification for the -requested \meta{function} or \meta{environment} at the terminal. If -the \meta{function} or \meta{environment} has no known argument +requested \meta{cmd} or \meta{environment} at the terminal. If +the \meta{cmd} or \meta{environment} has no known argument specification then an error is issued. -\section{Copying and showing (robust) commands} +\section{Copying and showing (robust) commands and environments} If you want to (slightly) alter an existing command you may want to save the current definition under a new name and then use that in a @@ -911,9 +949,6 @@ token but need \enquote{constructing}, you can use \cs{ExpandArgs} as explained in Section~\ref{sec:preconstructing-csnames}. - - - \begin{decl} |\ShowCommand| \arg{cmd} \end{decl} @@ -926,6 +961,26 @@ also the actual payload code and in case of commands declared with \cs{NewDocumentCommand}, etc.\ it also gives you detailed information about the argument signature. +\begin{decl} + |\NewEnvironmentCopy| \arg{env} \arg{existing-env} \\ + |\RenewEnvironmentCopy| \arg{env} \arg{existing-env} \\ + |\DeclareEnvironmentCopy| \arg{env} \arg{existing-env} +\end{decl} + +This copies the definition for environment \meta{existing-env} to +\meta{env} (both the beginning and end code), i.e., it is simply +applying \cs{NewCommandCopy} twice to the internal commands that +define an environment, i.e., \cs{}\meta{env} and \cs{end}\meta{env}. +The differences between \cs{New...}, \cs{Renew...}, and +\cs{Declare...} are the usual ones. + +\begin{decl} + |\ShowEnvironment| \arg{env} +\end{decl} +This displays the meaning of the begin end end code for environment \meta{env}. + + + \section[Preconstructing command names \\ (or otherwise expanding arguments)] {Preconstructing command names (or otherwise expanding arguments)} @@ -1132,11 +1187,11 @@ therefore shows the same syntax peculiars as discussed above. Nevertheless, in practice they are usually sufficient. For example \begin{verbatim} -\newcommand\calulateheight[1]{% +\newcommand\calculateheight[1]{% \setlength\textheight{\dimeval{\topskip+\baselineskip*\inteval{#1-1}}}} \end{verbatim} sets the \cs{textheight} to the appropriate value if a page should -hold a specific number of text lines. Thus after |\calulateheight{40}| +hold a specific number of text lines. Thus after |\calculateheight{40}| it is set to \dimeval{\topskip+\baselineskip*\inteval{40-1}}, given the values \cs{topskip} (\dimeval{\topskip}) and \cs{baselineskip} (\dimeval{\baselineskip}) in the current document. @@ -1199,8 +1254,35 @@ cases \item Lowercasing \item Titlecasing (only applies for the start of the input) \end{itemize} + The command \cs{DeclareCaseChangeEquivalent} provides a way to substitute a command by an alternative version when it is found inside a case changing -situation. +situation. There are three commands for customising the case changing of +codepoints +\begin{decl} + |\DeclareLowercaseMapping| \oarg{locale} \arg{codepoint} \arg{output} \\ + |\DeclareTitlecaseMapping| \oarg{locale} \arg{codepoint} \arg{output} \\ + |\DeclareUppercaseMapping| \oarg{locale} \arg{codepoint} \arg{output} +\end{decl} +All three take a \meta{codepoint} (as an integer expression) and will +result in the \meta{output} being produced under the appropriate case changing +operation. The optional \meta{locale} can be given if the mapping should only +apply to a specific one: this is given in BCP-47 format +(\url{https://en.wikipedia.org/wiki/IETF_language_tag}). For example, +the kernel customises the mapping for U+01F0 (\v{j}) when uppercasing in +8-bit engines: +\begin{quotation} + |\DeclareUppercaseMapping{"01F0}{\v{J}}| +\end{quotation} +as there is no pre-composed \v{J} character, and this is problematic if +the engine does not support Unicode natively. Similarly, to set a locale +\texttt{xx} to behave in the same way as Turkish and retain the difference +between dotted- and dotless-i, one could use for example +\begin{quotation} + |\DeclareLowercaseMapping[xx]{"0049}{\i}|\\ + |\DeclareLowercaseMapping[xx]{"0130}{i}|\\ + |\DeclareUppercaseMapping[xx]{"0069}{\.{I}}|\\ + |\DeclareUppercaseMapping[xx]{"0131}{I}| +\end{quotation} \end{document} diff --git a/macros/latex/base/utf8ienc.dtx b/macros/latex/base/utf8ienc.dtx index a2b25fd3ab..f1623ee0e6 100644 --- a/macros/latex/base/utf8ienc.dtx +++ b/macros/latex/base/utf8ienc.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 1993-2022 +% Copyright (C) 1993-2023 % The LaTeX Project and any individual authors listed elsewhere % in this file. % diff --git a/macros/latex/base/utf8ienc.pdf b/macros/latex/base/utf8ienc.pdf index 5ada2a0c2f..0ebe463aa7 100644 Binary files a/macros/latex/base/utf8ienc.pdf and b/macros/latex/base/utf8ienc.pdf differ diff --git a/macros/latex/base/webcomp.pdf b/macros/latex/base/webcomp.pdf index 18aaaf71db..67c9d3aa62 100644 Binary files a/macros/latex/base/webcomp.pdf and b/macros/latex/base/webcomp.pdf differ -- cgit v1.2.3