summaryrefslogtreecommitdiff
path: root/macros/latex
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex')
-rw-r--r--macros/latex/contrib/l3kernel/CHANGELOG.md48
-rw-r--r--macros/latex/contrib/l3kernel/README.md2
-rw-r--r--macros/latex/contrib/l3kernel/expl3.dtx4
-rw-r--r--macros/latex/contrib/l3kernel/expl3.pdfbin623326 -> 623197 bytes
-rw-r--r--macros/latex/contrib/l3kernel/interface3.pdfbin1711150 -> 1717276 bytes
-rw-r--r--macros/latex/contrib/l3kernel/interface3.tex2
-rw-r--r--macros/latex/contrib/l3kernel/l3basics.dtx121
-rw-r--r--macros/latex/contrib/l3kernel/l3bootstrap.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3box.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3candidates.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3cctab.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3clist.dtx158
-rw-r--r--macros/latex/contrib/l3kernel/l3coffins.dtx35
-rw-r--r--macros/latex/contrib/l3kernel/l3color.dtx6
-rw-r--r--macros/latex/contrib/l3kernel/l3debug.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3deprecation.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3doc.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3doc.pdfbin558279 -> 558160 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3docstrip.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3docstrip.pdfbin152066 -> 151946 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3expan.dtx16
-rw-r--r--macros/latex/contrib/l3kernel/l3file.dtx5
-rw-r--r--macros/latex/contrib/l3kernel/l3flag.dtx8
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-assign.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-aux.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-basics.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-convert.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-expo.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-extended.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-logic.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-parse.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-random.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-round.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-traps.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-trig.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3fp.dtx5
-rw-r--r--macros/latex/contrib/l3kernel/l3fparray.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3int.dtx26
-rw-r--r--macros/latex/contrib/l3kernel/l3intarray.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3kernel-functions.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3keys.dtx24
-rw-r--r--macros/latex/contrib/l3kernel/l3legacy.dtx3
-rw-r--r--macros/latex/contrib/l3kernel/l3luatex.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3msg.dtx18
-rw-r--r--macros/latex/contrib/l3kernel/l3names.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3news.pdfbin395876 -> 395876 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news01.pdfbin122710 -> 122710 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news02.pdfbin150674 -> 150674 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news03.pdfbin148706 -> 148706 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news04.pdfbin114586 -> 114586 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news05.pdfbin112485 -> 112485 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news06.pdfbin151569 -> 151569 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news07.pdfbin128316 -> 128316 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news08.pdfbin163456 -> 163456 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news09.pdfbin250136 -> 250136 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news10.pdfbin150283 -> 150283 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news11.pdfbin170076 -> 170076 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news12.pdfbin204992 -> 204992 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3pdf.dtx3
-rw-r--r--macros/latex/contrib/l3kernel/l3prefixes.pdfbin81696 -> 81696 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3prg.dtx3
-rw-r--r--macros/latex/contrib/l3kernel/l3prop.dtx3
-rw-r--r--macros/latex/contrib/l3kernel/l3quark.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3regex.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3seq.dtx326
-rw-r--r--macros/latex/contrib/l3kernel/l3skip.dtx412
-rw-r--r--macros/latex/contrib/l3kernel/l3sort.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3str-convert.dtx8
-rw-r--r--macros/latex/contrib/l3kernel/l3str.dtx17
-rw-r--r--macros/latex/contrib/l3kernel/l3styleguide.pdfbin296576 -> 296462 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3styleguide.tex2
-rw-r--r--macros/latex/contrib/l3kernel/l3syntax-changes.pdfbin243221 -> 243101 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3syntax-changes.tex2
-rw-r--r--macros/latex/contrib/l3kernel/l3sys.dtx5
-rw-r--r--macros/latex/contrib/l3kernel/l3term-glossary.pdfbin215742 -> 218265 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3term-glossary.tex35
-rw-r--r--macros/latex/contrib/l3kernel/l3text-case.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3text-map.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3text-purify.dtx26
-rw-r--r--macros/latex/contrib/l3kernel/l3text.dtx94
-rw-r--r--macros/latex/contrib/l3kernel/l3tl-analysis.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3tl.dtx10
-rw-r--r--macros/latex/contrib/l3kernel/l3token.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3unicode.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/source3.pdfbin7203435 -> 7237559 bytes
-rw-r--r--macros/latex/contrib/l3kernel/source3.tex2
-rw-r--r--macros/latex/contrib/latexdemo/README4
-rw-r--r--macros/latex/contrib/latexdemo/latexdemo.dtx42
-rw-r--r--macros/latex/contrib/latexdemo/latexdemo.pdfbin459668 -> 482720 bytes
-rw-r--r--macros/latex/contrib/movement-arrows/README.md18
-rw-r--r--macros/latex/contrib/movement-arrows/movement-arrows.pdfbin0 -> 53782 bytes
-rw-r--r--macros/latex/contrib/movement-arrows/movement-arrows.sty77
-rw-r--r--macros/latex/contrib/movement-arrows/movement-arrows.tex249
-rw-r--r--macros/latex/contrib/templatetools/templatetools.dtx40
-rw-r--r--macros/latex/contrib/templatetools/templatetools.pdfbin441431 -> 442537 bytes
-rw-r--r--macros/latex/contrib/yb-book/DEPENDS.txt2
-rw-r--r--macros/latex/contrib/yb-book/yb-book.dtx107
-rw-r--r--macros/latex/contrib/yb-book/yb-book.pdfbin283982 -> 284729 bytes
98 files changed, 1439 insertions, 595 deletions
diff --git a/macros/latex/contrib/l3kernel/CHANGELOG.md b/macros/latex/contrib/l3kernel/CHANGELOG.md
index 9b2db54278..d418810401 100644
--- a/macros/latex/contrib/l3kernel/CHANGELOG.md
+++ b/macros/latex/contrib/l3kernel/CHANGELOG.md
@@ -7,6 +7,31 @@ this project uses date-based 'snapshot' version identifiers.
## [Unreleased]
+## [2023-05-22]
+
+### Added
+- Rounded out the `\use_i:nn...` functions to cover all cases taking
+ one argument from up to nine arguments
+- `\coffin_(g)reset_poles:N`
+- `\dim_to_decimal_in_<unit>:n`, for `<unit>` types
+ `cc`, `cm`, `dd`, `in`, `mm` and `pc`
+- `\int_if_zero:n(TF)`
+- `\str_mdfive_hash:n`
+
+### Changed
+- Remove `\noexpand` inside math mode in `\text_expand:n`
+- Re-implement `\dim_to_decimal_in_bp:n` and
+ `\dim_to_decimal_in_unit:nn` to be re-entrant (issue \#954)
+
+### Fixed
+- Omit `0123456789` from URL escaping (issue \#838)
+- Leave implicit chars unchanged in `\text_expand:n` (issue \#874)
+- Filtering/grouping applied to meta keys (issue \#940)
+- Issue correct error message if `bool` key is set
+ incorrectly using `.initial:n` (issue \#1013)
+- Set `\l_keys_key_str` in `.initial:n` (issue \#1013)
+- Handling of implicit chars in `\text_purify:n` (issue \#1208)
+
## [2023-05-15]
### Changed
@@ -888,7 +913,7 @@ this project uses date-based 'snapshot' version identifiers.
## [2019-10-28]
### Fixed
-- File searching when `\(pdf)filesize` is not available (fixes \#644)
+- File searching when `\(pdf)filesize` is not available (issue \#644)
## [2019-10-27]
@@ -988,7 +1013,7 @@ this project uses date-based 'snapshot' version identifiers.
## [2019-09-08]
### Fixed
-- Missing internal variant (fixes \#624)
+- Missing internal variant (issue \#624)
## [2019-09-05]
@@ -1266,7 +1291,7 @@ this project uses date-based 'snapshot' version identifiers.
## [2018-10-19]
### Fixed
-- Wrapping of text in messages, etc., for some line lengths (fixes \#491)
+- Wrapping of text in messages, etc., for some line lengths (issue \#491)
## [2018-10-17]
@@ -1281,7 +1306,7 @@ this project uses date-based 'snapshot' version identifiers.
- `\msg_interrupt:nn`, `\msg_log:n` and `\msg_term:n`
### Fixed
-- Handling of inheritance for choice keys (fixes \#483)
+- Handling of inheritance for choice keys (issue \#483)
## [2018-09-24]
@@ -1291,7 +1316,7 @@ this project uses date-based 'snapshot' version identifiers.
`\peek_meaning_collect_inline:Nn`
### Fixed
-- Handling of unknown keys when inheritance is active (fixes \#481)
+- Handling of unknown keys when inheritance is active (issue \#481)
## [2018-08-23]
@@ -1313,7 +1338,7 @@ this project uses date-based 'snapshot' version identifiers.
## [2018-06-01]
### Added
-- `CHANGELOG.md` (fixes \#460)
+- `CHANGELOG.md` (issue \#460)
### Fixed
- Loading `expl3` with LuaTeX/XeTeX and certain letter tokens set
@@ -1351,7 +1376,7 @@ this project uses date-based 'snapshot' version identifiers.
- Several internal optimisations
### Fixed
-- Expand boolean expression before calling `\chardef` (fixes \#461)
+- Expand boolean expression before calling `\chardef` (issue \#461)
### Removed
- Remove undocumented `\fp_function:Nw` and `\fp_new_function:Npn`
@@ -1380,15 +1405,15 @@ this project uses date-based 'snapshot' version identifiers.
the RNG
- Make prg break functions public
- Make scan marks mechanism public
-- Make `\prg_do_nothing:` long rather than nopar (fixes \#455)
+- Make `\prg_do_nothing:` long rather than nopar (issue \#455)
- Several performance improvements
- Documentation improvements
### Fixed
- Only index TF, T, F functions together if they are `expl3`
- functions (fixes \#453)
+ functions (issue \#453)
- Make `\infty` and `\pi` into errors in fp expressions
- (fixes \#357)
+ (issue \#357)
### Removed
- Deprecated functions expiring at end of 2017
@@ -1407,7 +1432,8 @@ this project uses date-based 'snapshot' version identifiers.
- Step functions have been added for dim variables,
e.g. `\dim_step_inline:nnnn`
-[Unreleased]: https://github.com/latex3/latex3/compare/2023-05-15...HEAD
+[Unreleased]: https://github.com/latex3/latex3/compare/2023-05-22...HEAD
+[2023-05-22]: https://github.com/latex3/latex3/compare/2023-05-15...2023-05-22
[2023-05-15]: https://github.com/latex3/latex3/compare/2023-05-11...2023-05-15
[2023-05-11]: https://github.com/latex3/latex3/compare/2023-05-05...2023-05-11
[2023-05-05]: https://github.com/latex3/latex3/compare/2023-04-20...2023-05-05
diff --git a/macros/latex/contrib/l3kernel/README.md b/macros/latex/contrib/l3kernel/README.md
index 44bb66a2f7..dd571168c5 100644
--- a/macros/latex/contrib/l3kernel/README.md
+++ b/macros/latex/contrib/l3kernel/README.md
@@ -1,7 +1,7 @@
LaTeX3 Programming Conventions
==============================
-Release 2023-05-15
+Release 2023-05-22
Overview
--------
diff --git a/macros/latex/contrib/l3kernel/expl3.dtx b/macros/latex/contrib/l3kernel/expl3.dtx
index cdd27753ee..622593cf8f 100644
--- a/macros/latex/contrib/l3kernel/expl3.dtx
+++ b/macros/latex/contrib/l3kernel/expl3.dtx
@@ -24,7 +24,7 @@
%
%<*driver|generic|package|2ekernel>
%</driver|generic|package|2ekernel>
-\def\ExplFileDate{2023-05-15}%
+\def\ExplFileDate{2023-05-22}%
%<*driver>
\documentclass[full]{l3doc}
\usepackage{graphicx}
@@ -51,7 +51,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/expl3.pdf b/macros/latex/contrib/l3kernel/expl3.pdf
index ae93ec6850..9d6d1226ec 100644
--- a/macros/latex/contrib/l3kernel/expl3.pdf
+++ b/macros/latex/contrib/l3kernel/expl3.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/interface3.pdf b/macros/latex/contrib/l3kernel/interface3.pdf
index 84f53f8947..e5733b848b 100644
--- a/macros/latex/contrib/l3kernel/interface3.pdf
+++ b/macros/latex/contrib/l3kernel/interface3.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/interface3.tex b/macros/latex/contrib/l3kernel/interface3.tex
index 7dea564c3f..f20b8d2d99 100644
--- a/macros/latex/contrib/l3kernel/interface3.tex
+++ b/macros/latex/contrib/l3kernel/interface3.tex
@@ -62,7 +62,7 @@ for those people who are interested.
{latex-team@latex-project.org}%
}%
}
-\date{Released 2023-05-15}
+\date{Released 2023-05-22}
\pagenumbering{roman}
\maketitle
diff --git a/macros/latex/contrib/l3kernel/l3basics.dtx b/macros/latex/contrib/l3kernel/l3basics.dtx
index fa09cc4806..291e93bf7b 100644
--- a/macros/latex/contrib/l3kernel/l3basics.dtx
+++ b/macros/latex/contrib/l3kernel/l3basics.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -925,52 +925,39 @@
% \end{texnote}
% \end{function}
%
-% \begin{function}[EXP]{\use_i:nn, \use_ii:nn}
+% \begin{function}[EXP]
+% {
+% \use_i:nn, \use_ii:nn ,
+% \use_i:nnn , \use_ii:nnn , \use_iii:nnn , \use_i_ii:nnn ,
+% \use_i:nnnn, \use_ii:nnnn, \use_iii:nnnn, \use_iv:nnnn ,
+% \use_i:nnnnn, \use_ii:nnnnn, \use_iii:nnnnn, \use_iv:nnnnn ,
+% \use_v:nnnnn ,
+% \use_i:nnnnnn, \use_ii:nnnnnn, \use_iii:nnnnnn, \use_iv:nnnnnn ,
+% \use_v:nnnnnn , \use_vi:nnnnnn ,
+% \use_i:nnnnnnn, \use_ii:nnnnnnn, \use_iii:nnnnnnn, \use_iv:nnnnnnn ,
+% \use_v:nnnnnnn , \use_vi:nnnnnnn , \use_vii:nnnnnnn ,
+% \use_i:nnnnnnnn, \use_ii:nnnnnnnn, \use_iii:nnnnnnnn, \use_iv:nnnnnnnn ,
+% \use_v:nnnnnnnn , \use_vi:nnnnnnnn , \use_vii:nnnnnnnn , \use_vii:nnnnnnnn ,
+% \use_i:nnnnnnnnn, \use_ii:nnnnnnnnn, \use_iii:nnnnnnnnn, \use_iv:nnnnnnnnn ,
+% \use_v:nnnnnnnnn , \use_vi:nnnnnnnnn , \use_vii:nnnnnnnnn , \use_viii:nnnnnnnnn ,
+% \use_ix:nnnnnnnnn
+% }
% \begin{syntax}
% \cs{use_i:nn} \Arg{arg_1} \Arg{arg_2}
-% \end{syntax}
-% These functions absorb two arguments from the input stream. The function
-% \cs{use_i:nn} discards the second argument, and leaves the content
-% of the first argument in the input stream. \cs{use_ii:nn} discards
-% the first argument and leaves the content of the second argument in
-% the input stream.
-% The category code
-% of these tokens is also fixed (if it has not already been by
-% some other absorption). A single expansion is needed for the
-% functions to take effect.
-% \begin{texnote}
-% These are equivalent to \LaTeXe{}'s \tn{@firstoftwo} and
-% \tn{@secondoftwo}.
-% \end{texnote}
-% \end{function}
-%
-% \begin{function}[EXP]{\use_i:nnn, \use_ii:nnn, \use_iii:nnn}
-% \begin{syntax}
% \cs{use_i:nnn} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3}
-% \end{syntax}
-% These functions absorb three arguments from the input stream. The
-% function \cs{use_i:nnn} discards the second and third arguments, and
-% leaves the content of the first argument in the input stream.
-% \cs{use_ii:nnn} and \cs{use_iii:nnn} work similarly, leaving the
-% content of second or third arguments in the input stream, respectively.
-% The category code
-% of these tokens is also fixed (if it has not already been by
-% some other absorption). A single expansion is needed for the
-% functions to take effect.
-% \end{function}
-%
-% \begin{function}[EXP]
-% {\use_i:nnnn, \use_ii:nnnn, \use_iii:nnnn, \use_iv:nnnn}
-% \begin{syntax}
% \cs{use_i:nnnn} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3} \Arg{arg_4}
-% \end{syntax}
-% These functions absorb four arguments from the input stream. The
-% function \cs{use_i:nnnn} discards the second, third and fourth
-% arguments, and leaves the content of the first argument in the input
-% stream.
-% \cs{use_ii:nnnn}, \cs{use_iii:nnnn} and \cs{use_iv:nnnn} work similarly,
-% leaving the content of second, third or fourth arguments in the input
-% stream, respectively. The category code
+% \cs{use_i:nnnnn} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3} \Arg{arg_4} \Arg{arg_5}
+% \cs{use_i:nnnnnn} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3} \Arg{arg_4} \Arg{arg_5} \Arg{arg_6}
+% \cs{use_i:nnnnnnn} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3} \Arg{arg_4} \Arg{arg_5} \Arg{arg_6} \Arg{arg_7}
+% \cs{use_i:nnnnnnnn} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3} \Arg{arg_4} \Arg{arg_5} \Arg{arg_6} \Arg{arg_7} \Arg{arg_8}
+% \cs{use_i:nnnnnnnnn} \Arg{arg_1} \Arg{arg_2} \Arg{arg_3} \Arg{arg_4} \Arg{arg_5} \Arg{arg_6} \Arg{arg_7} \Arg{arg_8} \Arg{arg_9}
+% \end{syntax}
+% These functions absorb a number ($n$) arguments from the input stream.
+% They then discard all arguments other than that indicated by the roman
+% numeral, which is left in the input stream. For example, \cs{use_i:nn}
+% discards the second argument, and leaves the content of the first
+% argument in the input stream.
+% The category code
% of these tokens is also fixed (if it has not already been by
% some other absorption). A single expansion is needed for the
% functions to take effect.
@@ -1662,7 +1649,18 @@
% \begin{macro}[EXP]
% {
% \use_i:nnn , \use_ii:nnn , \use_iii:nnn , \use_i_ii:nnn ,
-% \use_i:nnnn, \use_ii:nnnn, \use_iii:nnnn, \use_iv:nnnn
+% \use_i:nnnn, \use_ii:nnnn, \use_iii:nnnn, \use_iv:nnnn ,
+% \use_i:nnnnn, \use_ii:nnnnn, \use_iii:nnnnn, \use_iv:nnnnn ,
+% \use_v:nnnnn ,
+% \use_i:nnnnnn, \use_ii:nnnnnn, \use_iii:nnnnnn, \use_iv:nnnnnn ,
+% \use_v:nnnnnn , \use_vi:nnnnnn ,
+% \use_i:nnnnnnn, \use_ii:nnnnnnn, \use_iii:nnnnnnn, \use_iv:nnnnnnn ,
+% \use_v:nnnnnnn , \use_vi:nnnnnnn , \use_vii:nnnnnnn ,
+% \use_i:nnnnnnnn, \use_ii:nnnnnnnn, \use_iii:nnnnnnnn, \use_iv:nnnnnnnn ,
+% \use_v:nnnnnnnn , \use_vi:nnnnnnnn , \use_vii:nnnnnnnn , \use_vii:nnnnnnnn ,
+% \use_i:nnnnnnnnn, \use_ii:nnnnnnnnn, \use_iii:nnnnnnnnn, \use_iv:nnnnnnnnn ,
+% \use_v:nnnnnnnnn , \use_vi:nnnnnnnnn , \use_vii:nnnnnnnnn , \use_viii:nnnnnnnnn ,
+% \use_ix:nnnnnnnnn
% }
% We also need something for picking up arguments from a longer list.
% \begin{macrocode}
@@ -1674,6 +1672,41 @@
\cs_set:Npn \use_ii:nnnn #1#2#3#4 {#2}
\cs_set:Npn \use_iii:nnnn #1#2#3#4 {#3}
\cs_set:Npn \use_iv:nnnn #1#2#3#4 {#4}
+\cs_set:Npn \use_i:nnnnn #1#2#3#4#5 {#1}
+\cs_set:Npn \use_ii:nnnnn #1#2#3#4#5 {#2}
+\cs_set:Npn \use_iii:nnnnn #1#2#3#4#5 {#3}
+\cs_set:Npn \use_iv:nnnnn #1#2#3#4#5 {#4}
+\cs_set:Npn \use_v:nnnnn #1#2#3#4#5 {#5}
+\cs_set:Npn \use_i:nnnnnn #1#2#3#4#5#6 {#1}
+\cs_set:Npn \use_ii:nnnnnn #1#2#3#4#5#6 {#2}
+\cs_set:Npn \use_iii:nnnnnn #1#2#3#4#5#6 {#3}
+\cs_set:Npn \use_iv:nnnnnn #1#2#3#4#5#6 {#4}
+\cs_set:Npn \use_v:nnnnnn #1#2#3#4#5#6 {#5}
+\cs_set:Npn \use_vi:nnnnnn #1#2#3#4#5#6 {#6}
+\cs_set:Npn \use_i:nnnnnnn #1#2#3#4#5#6#7 {#1}
+\cs_set:Npn \use_ii:nnnnnnn #1#2#3#4#5#6#7 {#2}
+\cs_set:Npn \use_iii:nnnnnnn #1#2#3#4#5#6#7 {#3}
+\cs_set:Npn \use_iv:nnnnnnn #1#2#3#4#5#6#7 {#4}
+\cs_set:Npn \use_v:nnnnnnn #1#2#3#4#5#6#7 {#5}
+\cs_set:Npn \use_vi:nnnnnnn #1#2#3#4#5#6#7 {#6}
+\cs_set:Npn \use_vii:nnnnnnn #1#2#3#4#5#6#7 {#7}
+\cs_set:Npn \use_i:nnnnnnnn #1#2#3#4#5#6#7#8 {#1}
+\cs_set:Npn \use_ii:nnnnnnnn #1#2#3#4#5#6#7#8 {#2}
+\cs_set:Npn \use_iii:nnnnnnnn #1#2#3#4#5#6#7#8 {#3}
+\cs_set:Npn \use_iv:nnnnnnnn #1#2#3#4#5#6#7#8 {#4}
+\cs_set:Npn \use_v:nnnnnnnn #1#2#3#4#5#6#7#8 {#5}
+\cs_set:Npn \use_vi:nnnnnnnn #1#2#3#4#5#6#7#8 {#6}
+\cs_set:Npn \use_vii:nnnnnnnn #1#2#3#4#5#6#7#8 {#7}
+\cs_set:Npn \use_viii:nnnnnnnn #1#2#3#4#5#6#7#8 {#8}
+\cs_set:Npn \use_i:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {#1}
+\cs_set:Npn \use_ii:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {#2}
+\cs_set:Npn \use_iii:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {#3}
+\cs_set:Npn \use_iv:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {#4}
+\cs_set:Npn \use_v:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {#5}
+\cs_set:Npn \use_vi:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {#6}
+\cs_set:Npn \use_vii:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {#7}
+\cs_set:Npn \use_viii:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {#8}
+\cs_set:Npn \use_ix:nnnnnnnnn #1#2#3#4#5#6#7#8#9 {#9}
% \end{macrocode}
% \end{macro}
%
diff --git a/macros/latex/contrib/l3kernel/l3bootstrap.dtx b/macros/latex/contrib/l3kernel/l3bootstrap.dtx
index 03749f402a..8f69c22be3 100644
--- a/macros/latex/contrib/l3kernel/l3bootstrap.dtx
+++ b/macros/latex/contrib/l3kernel/l3bootstrap.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3box.dtx b/macros/latex/contrib/l3kernel/l3box.dtx
index 63cd2ac51a..3dc1a966de 100644
--- a/macros/latex/contrib/l3kernel/l3box.dtx
+++ b/macros/latex/contrib/l3kernel/l3box.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3candidates.dtx b/macros/latex/contrib/l3kernel/l3candidates.dtx
index 3f25a76e88..03639af043 100644
--- a/macros/latex/contrib/l3kernel/l3candidates.dtx
+++ b/macros/latex/contrib/l3kernel/l3candidates.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3cctab.dtx b/macros/latex/contrib/l3kernel/l3cctab.dtx
index 7d6c2ec300..2cbe46be18 100644
--- a/macros/latex/contrib/l3kernel/l3cctab.dtx
+++ b/macros/latex/contrib/l3kernel/l3cctab.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3clist.dtx b/macros/latex/contrib/l3kernel/l3clist.dtx
index 5abf32d8f0..f25ff97911 100644
--- a/macros/latex/contrib/l3kernel/l3clist.dtx
+++ b/macros/latex/contrib/l3kernel/l3clist.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -114,10 +114,10 @@
%
% \begin{function}{\clist_new:N, \clist_new:c}
% \begin{syntax}
-% \cs{clist_new:N} \meta{comma list}
+% \cs{clist_new:N} \meta{clist~var}
% \end{syntax}
-% Creates a new \meta{comma list} or raises an error if the name is
-% already taken. The declaration is global. The \meta{comma list}
+% Creates a new \meta{clist~var} or raises an error if the name is
+% already taken. The declaration is global. The \meta{clist~var}
% initially contains no items.
% \end{function}
%
@@ -138,9 +138,9 @@
% \begin{function}
% {\clist_clear:N, \clist_clear:c, \clist_gclear:N, \clist_gclear:c}
% \begin{syntax}
-% \cs{clist_clear:N} \meta{comma list}
+% \cs{clist_clear:N} \meta{clist~var}
% \end{syntax}
-% Clears all items from the \meta{comma list}.
+% Clears all items from the \meta{clist~var}.
% \end{function}
%
% \begin{function}
@@ -149,9 +149,9 @@
% \clist_gclear_new:N, \clist_gclear_new:c
% }
% \begin{syntax}
-% \cs{clist_clear_new:N} \meta{comma list}
+% \cs{clist_clear_new:N} \meta{clist~var}
% \end{syntax}
-% Ensures that the \meta{comma list} exists globally by applying
+% Ensures that the \meta{clist~var} exists globally by applying
% \cs{clist_new:N} if necessary, then applies
% \cs[index=clist_clear:N]{clist_(g)clear:N} to leave
% the list empty.
@@ -182,9 +182,9 @@
% \clist_gset_from_seq:Nc, \clist_gset_from_seq:cc
% }
% \begin{syntax}
-% \cs{clist_set_from_seq:NN} \meta{comma list} \meta{sequence}
+% \cs{clist_set_from_seq:NN} \meta{clist~var} \meta{sequence}
% \end{syntax}
-% Converts the data in the \meta{sequence} into a \meta{comma list}:
+% Converts the data in the \meta{sequence} into a \meta{clist~var}:
% the original \meta{sequence} is unchanged.
% Items which contain either spaces or commas are surrounded by braces.
% \end{function}
@@ -205,11 +205,11 @@
% \begin{function}[EXP, pTF, added=2012-03-03]
% {\clist_if_exist:N, \clist_if_exist:c}
% \begin{syntax}
-% \cs{clist_if_exist_p:N} \meta{comma list}
-% \cs{clist_if_exist:NTF} \meta{comma list} \Arg{true code} \Arg{false code}
+% \cs{clist_if_exist_p:N} \meta{clist~var}
+% \cs{clist_if_exist:NTF} \meta{clist~var} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests whether the \meta{comma list} is currently defined. This does
-% not check that the \meta{comma list} really is a comma list.
+% Tests whether the \meta{clist~var} is currently defined. This does
+% not check that the \meta{clist~var} really is a comma list.
% \end{function}
%
% \section{Adding data to comma lists}
@@ -226,16 +226,16 @@
% \clist_gset:co, \clist_gset:cx
% }
% \begin{syntax}
-% \cs{clist_set:Nn} \meta{comma list} |{|\meta{item_1},\ldots{},\meta{item_n}|}|
+% \cs{clist_set:Nn} \meta{clist~var} |{|\meta{item_1},\ldots{},\meta{item_n}|}|
% \end{syntax}
-% Sets \meta{comma list} to contain the \meta{items},
+% Sets \meta{clist~var} to contain the \meta{items},
% removing any previous content from the variable.
% Blank items are omitted, spaces are removed from both sides of each
% item, then a set of braces is removed if the resulting space-trimmed
% item is braced.
% To store some \meta{tokens} as a single \meta{item} even if the
% \meta{tokens} contain commas or spaces, add a set of braces:
-% \cs{clist_set:Nn} \meta{comma list} |{| \Arg{tokens} |}|.
+% \cs{clist_set:Nn} \meta{clist~var} |{| \Arg{tokens} |}|.
% \end{function}
%
% \begin{function}[updated = 2011-09-05]
@@ -250,15 +250,15 @@
% \clist_gput_left:co, \clist_gput_left:cx
% }
% \begin{syntax}
-% \cs{clist_put_left:Nn} \meta{comma list} |{|\meta{item_1},\ldots{},\meta{item_n}|}|
+% \cs{clist_put_left:Nn} \meta{clist~var} |{|\meta{item_1},\ldots{},\meta{item_n}|}|
% \end{syntax}
-% Appends the \meta{items} to the left of the \meta{comma list}.
+% Appends the \meta{items} to the left of the \meta{clist~var}.
% Blank items are omitted, spaces are removed from both sides of each
% item, then a set of braces is removed if the resulting space-trimmed
% item is braced.
% To append some \meta{tokens} as a single \meta{item} even if the
% \meta{tokens} contain commas or spaces, add a set of braces:
-% \cs{clist_put_left:Nn} \meta{comma list} |{| \Arg{tokens} |}|.
+% \cs{clist_put_left:Nn} \meta{clist~var} |{| \Arg{tokens} |}|.
% \end{function}
%
% \begin{function}[updated = 2011-09-05]
@@ -273,15 +273,15 @@
% \clist_gput_right:co, \clist_gput_right:cx
% }
% \begin{syntax}
-% \cs{clist_put_right:Nn} \meta{comma list} |{|\meta{item_1},\ldots{},\meta{item_n}|}|
+% \cs{clist_put_right:Nn} \meta{clist~var} |{|\meta{item_1},\ldots{},\meta{item_n}|}|
% \end{syntax}
-% Appends the \meta{items} to the right of the \meta{comma list}.
+% Appends the \meta{items} to the right of the \meta{clist~var}.
% Blank items are omitted, spaces are removed from both sides of each
% item, then a set of braces is removed if the resulting space-trimmed
% item is braced.
% To append some \meta{tokens} as a single \meta{item} even if the
% \meta{tokens} contain commas or spaces, add a set of braces:
-% \cs{clist_put_right:Nn} \meta{comma list} |{| \Arg{tokens} |}|.
+% \cs{clist_put_right:Nn} \meta{clist~var} |{| \Arg{tokens} |}|.
% \end{function}
%
% \section{Modifying comma lists}
@@ -297,17 +297,17 @@
% \clist_gremove_duplicates:N, \clist_gremove_duplicates:c
% }
% \begin{syntax}
-% \cs{clist_remove_duplicates:N} \meta{comma list}
+% \cs{clist_remove_duplicates:N} \meta{clist~var}
% \end{syntax}
-% Removes duplicate items from the \meta{comma list}, leaving the
-% left most copy of each item in the \meta{comma list}. The \meta{item}
+% Removes duplicate items from the \meta{clist~var}, leaving the
+% left most copy of each item in the \meta{clist~var}. The \meta{item}
% comparison takes place on a token basis, as for \cs{tl_if_eq:nnTF}.
% \begin{texnote}
-% This function iterates through every item in the \meta{comma list} and
+% This function iterates through every item in the \meta{clist~var} and
% does a comparison with the \meta{items} already checked. It is therefore
% relatively slow with large comma lists.
% Furthermore, it may fail if any of the items in the
-% \meta{comma list} contains |{|, |}|, or |#|
+% \meta{clist~var} contains |{|, |}|, or |#|
% (assuming the usual \TeX{} category codes apply).
% \end{texnote}
% \end{function}
@@ -320,9 +320,9 @@
% \clist_gremove_all:NV, \clist_gremove_all:cV
% }
% \begin{syntax}
-% \cs{clist_remove_all:Nn} \meta{comma list} \Arg{item}
+% \cs{clist_remove_all:Nn} \meta{clist~var} \Arg{item}
% \end{syntax}
-% Removes every occurrence of \meta{item} from the \meta{comma list}.
+% Removes every occurrence of \meta{item} from the \meta{clist~var}.
% The \meta{item} comparison takes place on a token basis, as for
% \cs{tl_if_eq:nnTF}.
% \begin{texnote}
@@ -337,9 +337,9 @@
% \clist_greverse:N, \clist_greverse:c
% }
% \begin{syntax}
-% \cs{clist_reverse:N} \meta{comma list}
+% \cs{clist_reverse:N} \meta{clist~var}
% \end{syntax}
-% Reverses the order of items stored in the \meta{comma list}.
+% Reverses the order of items stored in the \meta{clist~var}.
% \end{function}
%
% \begin{function}[added = 2014-07-18]{\clist_reverse:n}
@@ -372,10 +372,10 @@
%
% \begin{function}[EXP,pTF]{\clist_if_empty:N, \clist_if_empty:c}
% \begin{syntax}
-% \cs{clist_if_empty_p:N} \meta{comma list}
-% \cs{clist_if_empty:NTF} \meta{comma list} \Arg{true code} \Arg{false code}
+% \cs{clist_if_empty_p:N} \meta{clist~var}
+% \cs{clist_if_empty:NTF} \meta{clist~var} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if the \meta{comma list} is empty (containing no items).
+% Tests if the \meta{clist~var} is empty (containing no items).
% \end{function}
%
% \begin{function}[EXP, pTF, added = 2014-07-05]{\clist_if_empty:n}
@@ -383,7 +383,7 @@
% \cs{clist_if_empty_p:n} \Arg{comma list}
% \cs{clist_if_empty:nTF} \Arg{comma list} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if the \meta{comma list} is empty (containing no items).
+% Tests if the \meta{clist~var} is empty (containing no items).
% The rules for space trimming are as for other \texttt{n}-type
% comma-list functions, hence the comma list |{~,~,,~}| (without
% outer braces) is empty, while |{~,{},}| (without outer braces)
@@ -398,9 +398,9 @@
% \clist_if_in:nn, \clist_if_in:nV, \clist_if_in:no
% }
% \begin{syntax}
-% \cs{clist_if_in:NnTF} \meta{comma list} \Arg{item} \Arg{true code} \Arg{false code}
+% \cs{clist_if_in:NnTF} \meta{clist~var} \Arg{item} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if the \meta{item} is present in the \meta{comma list}.
+% Tests if the \meta{item} is present in the \meta{clist~var}.
% In the case of an \texttt{n}-type \meta{comma list}, the usual rules
% of space trimming and brace stripping apply. Hence,
% \begin{verbatim}
@@ -438,10 +438,10 @@
% \begin{function}[rEXP, updated = 2012-06-29]
% {\clist_map_function:NN, \clist_map_function:cN, \clist_map_function:nN}
% \begin{syntax}
-% \cs{clist_map_function:NN} \meta{comma list} \meta{function}
+% \cs{clist_map_function:NN} \meta{clist~var} \meta{function}
% \end{syntax}
% Applies \meta{function} to every \meta{item} stored in the
-% \meta{comma list}. The \meta{function} receives one argument for
+% \meta{clist~var}. The \meta{function} receives one argument for
% each iteration. The \meta{items} are returned from left to right.
% The function \cs{clist_map_inline:Nn} is in general more efficient
% than \cs{clist_map_function:NN}.
@@ -450,10 +450,10 @@
% \begin{function}[updated = 2012-06-29]
% {\clist_map_inline:Nn, \clist_map_inline:cn, \clist_map_inline:nn}
% \begin{syntax}
-% \cs{clist_map_inline:Nn} \meta{comma list} \Arg{inline function}
+% \cs{clist_map_inline:Nn} \meta{clist~var} \Arg{inline function}
% \end{syntax}
% Applies \meta{inline function} to every \meta{item} stored
-% within the \meta{comma list}. The \meta{inline function} should
+% within the \meta{clist~var}. The \meta{inline function} should
% consist of code which receives the \meta{item} as |#1|.
% The \meta{items} are returned from left to right.
% \end{function}
@@ -461,9 +461,9 @@
% \begin{function}[updated = 2012-06-29]
% {\clist_map_variable:NNn, \clist_map_variable:cNn, \clist_map_variable:nNn}
% \begin{syntax}
-% \cs{clist_map_variable:NNn} \meta{comma list} \meta{variable} \Arg{code}
+% \cs{clist_map_variable:NNn} \meta{clist~var} \meta{variable} \Arg{code}
% \end{syntax}
-% Stores each \meta{item} of the \meta{comma list} in turn in the
+% Stores each \meta{item} of the \meta{clist~var} in turn in the
% (token list) \meta{variable} and applies the \meta{code}. The
% \meta{code} will usually make use of the \meta{variable}, but this
% is not enforced. The assignments to the \meta{variable} are local.
@@ -479,7 +479,7 @@
% \cs{clist_map_tokens:nn} \Arg{comma list} \Arg{code}
% \end{syntax}
% Calls \meta{code} \Arg{item} for every \meta{item} stored in the
-% \meta{comma list}. The \meta{code} receives each \meta{item} as a
+% \meta{clist~var}. The \meta{code} receives each \meta{item} as a
% trailing brace group. If the \meta{code} consists of a single
% function this is equivalent to \cs{clist_map_function:nN}.
% \end{function}
@@ -542,12 +542,12 @@
% \begin{function}[EXP, added = 2012-07-13]
% {\clist_count:N, \clist_count:c, \clist_count:n}
% \begin{syntax}
-% \cs{clist_count:N} \meta{comma list}
+% \cs{clist_count:N} \meta{clist~var}
% \end{syntax}
-% Leaves the number of items in the \meta{comma list} in the input
+% Leaves the number of items in the \meta{clist~var} in the input
% stream as an \meta{integer denotation}. The total number of items
-% in a \meta{comma list} includes those which are duplicates,
-% \emph{i.e.}~every item in a \meta{comma list} is counted.
+% in a \meta{clist~var} includes those which are duplicates,
+% \emph{i.e.}~every item in a \meta{clist~var} is counted.
% \end{function}
%
% \section{Using the content of comma lists directly}
@@ -640,20 +640,20 @@
% \begin{function}[noTF, added = 2012-05-14, updated = 2019-02-16]
% {\clist_get:NN, \clist_get:cN}
% \begin{syntax}
-% \cs{clist_get:NN} \meta{comma list} \meta{token list variable}
+% \cs{clist_get:NN} \meta{clist~var} \meta{token list variable}
% \end{syntax}
-% Stores the left-most item from a \meta{comma list} in the
+% Stores the left-most item from a \meta{clist~var} in the
% \meta{token list variable} without removing it from the
-% \meta{comma list}. The \meta{token list variable} is assigned locally.
-% In the non-branching version, if the \meta{comma list} is empty the
+% \meta{clist~var}. The \meta{token list variable} is assigned locally.
+% In the non-branching version, if the \meta{clist~var} is empty the
% \meta{token list variable} is set to the marker value \cs{q_no_value}.
% \end{function}
%
% \begin{function}[updated = 2011-09-06]{\clist_pop:NN, \clist_pop:cN}
% \begin{syntax}
-% \cs{clist_pop:NN} \meta{comma list} \meta{token list variable}
+% \cs{clist_pop:NN} \meta{clist~var} \meta{token list variable}
% \end{syntax}
-% Pops the left-most item from a \meta{comma list} into the
+% Pops the left-most item from a \meta{clist~var} into the
% \meta{token list variable}, \emph{i.e.}~removes the item from the
% comma list and stores it in the \meta{token list variable}.
% Both of the variables are assigned locally.
@@ -661,38 +661,38 @@
%
% \begin{function}{\clist_gpop:NN, \clist_gpop:cN}
% \begin{syntax}
-% \cs{clist_gpop:NN} \meta{comma list} \meta{token list variable}
+% \cs{clist_gpop:NN} \meta{clist~var} \meta{token list variable}
% \end{syntax}
-% Pops the left-most item from a \meta{comma list} into the
+% Pops the left-most item from a \meta{clist~var} into the
% \meta{token list variable}, \emph{i.e.}~removes the item from the
% comma list and stores it in the \meta{token list variable}.
-% The \meta{comma list} is modified globally, while the assignment of
+% The \meta{clist~var} is modified globally, while the assignment of
% the \meta{token list variable} is local.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-14]{\clist_pop:NN, \clist_pop:cN}
% \begin{syntax}
-% \cs{clist_pop:NNTF} \meta{comma list} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{clist_pop:NNTF} \meta{clist~var} \meta{token list variable} \Arg{true code} \Arg{false code}
% \end{syntax}
-% If the \meta{comma list} is empty, leaves the \meta{false code} in the
+% If the \meta{clist~var} is empty, leaves the \meta{false code} in the
% input stream. The value of the \meta{token list variable} is
% not defined in this case and should not be relied upon. If the
-% \meta{comma list} is non-empty, pops the top item from the
-% \meta{comma list} in the \meta{token list variable}, \emph{i.e.}~removes
-% the item from the \meta{comma list}. Both the \meta{comma list} and the
+% \meta{clist~var} is non-empty, pops the top item from the
+% \meta{clist~var} in the \meta{token list variable}, \emph{i.e.}~removes
+% the item from the \meta{clist~var}. Both the \meta{clist~var} and the
% \meta{token list variable} are assigned locally.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-14]{\clist_gpop:NN, \clist_gpop:cN}
% \begin{syntax}
-% \cs{clist_gpop:NNTF} \meta{comma list} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{clist_gpop:NNTF} \meta{clist~var} \meta{token list variable} \Arg{true code} \Arg{false code}
% \end{syntax}
-% If the \meta{comma list} is empty, leaves the \meta{false code} in the
+% If the \meta{clist~var} is empty, leaves the \meta{false code} in the
% input stream. The value of the \meta{token list variable} is
% not defined in this case and should not be relied upon. If the
-% \meta{comma list} is non-empty, pops the top item from the
-% \meta{comma list} in the \meta{token list variable}, \emph{i.e.}~removes
-% the item from the \meta{comma list}. The \meta{comma list} is modified
+% \meta{clist~var} is non-empty, pops the top item from the
+% \meta{clist~var} in the \meta{token list variable}, \emph{i.e.}~removes
+% the item from the \meta{clist~var}. The \meta{clist~var} is modified
% globally, while the \meta{token list variable} is assigned locally.
% \end{function}
%
@@ -704,9 +704,9 @@
% \clist_gpush:cn, \clist_gpush:cV, \clist_gpush:co, \clist_gpush:cx
% }
% \begin{syntax}
-% \cs{clist_push:Nn} \meta{comma list} \Arg{items}
+% \cs{clist_push:Nn} \meta{clist~var} \Arg{items}
% \end{syntax}
-% Adds the \Arg{items} to the top of the \meta{comma list}.
+% Adds the \Arg{items} to the top of the \meta{clist~var}.
% Spaces are removed from both sides of each item as for any
% \texttt{n}-type comma list.
% \end{function}
@@ -716,14 +716,14 @@
% \begin{function}[added = 2014-07-17, EXP]
% {\clist_item:Nn, \clist_item:cn, \clist_item:nn}
% \begin{syntax}
-% \cs{clist_item:Nn} \meta{comma list} \Arg{int expr}
+% \cs{clist_item:Nn} \meta{clist~var} \Arg{int expr}
% \end{syntax}
-% Indexing items in the \meta{comma list} from~$1$ at the top (left), this
+% Indexing items in the \meta{clist~var} from~$1$ at the top (left), this
% function evaluates the \meta{int expr} and leaves the
% appropriate item from the comma list in the input stream. If the
% \meta{int expr} is negative, indexing occurs from the
% bottom (right) of the comma list. When the \meta{int expr}
-% is larger than the number of items in the \meta{comma list} (as
+% is larger than the number of items in the \meta{clist~var} (as
% calculated by \cs{clist_count:N}) then the function expands to
% nothing.
% \begin{texnote}
@@ -740,8 +740,8 @@
% \cs{clist_rand_item:N} \meta{clist~var}
% \cs{clist_rand_item:n} \Arg{comma list}
% \end{syntax}
-% Selects a pseudo-random item of the \meta{comma list}. If the
-% \meta{comma list} has no item, the result is empty.
+% Selects a pseudo-random item of the \meta{clist~var}/\meta{comma list}.
+% If the \meta{comma list} has no item, the result is empty.
% \begin{texnote}
% The result is returned within the \tn{unexpanded}
% primitive (\cs{exp_not:n}), which means that the \meta{item}
@@ -754,9 +754,9 @@
%
% \begin{function}[updated = 2021-04-29]{\clist_show:N, \clist_show:c}
% \begin{syntax}
-% \cs{clist_show:N} \meta{comma list}
+% \cs{clist_show:N} \meta{clist~var}
% \end{syntax}
-% Displays the entries in the \meta{comma list} in the terminal.
+% Displays the entries in the \meta{clist~var} in the terminal.
% \end{function}
%
% \begin{function}[updated = 2013-08-03]{\clist_show:n}
@@ -768,9 +768,9 @@
%
% \begin{function}[added = 2014-08-22, updated = 2021-04-29]{\clist_log:N, \clist_log:c}
% \begin{syntax}
-% \cs{clist_log:N} \meta{comma list}
+% \cs{clist_log:N} \meta{clist~var}
% \end{syntax}
-% Writes the entries in the \meta{comma list} in the log file. See
+% Writes the entries in the \meta{clist~var} in the log file. See
% also \cs{clist_show:N} which displays the result in the terminal.
% \end{function}
%
diff --git a/macros/latex/contrib/l3kernel/l3coffins.dtx b/macros/latex/contrib/l3kernel/l3coffins.dtx
index 759672403c..f44299c55d 100644
--- a/macros/latex/contrib/l3kernel/l3coffins.dtx
+++ b/macros/latex/contrib/l3kernel/l3coffins.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -187,6 +187,17 @@
% \meta{offset} should be given as a dimension expression.
% \end{function}
%
+% \begin{function}[added = 2023-05-17]{\coffin_reset_poles:N, \coffin_greset_poles:N}
+% \begin{syntax}
+% \cs{coffin_reset_poles:N} \meta{coffin}
+% \end{syntax}
+% Resets the poles of the \meta{coffin} to the standard set, removing any
+% custom or inherited poles. The poles will therefore be equal to those that
+% would be obtained from \cs{hcoffin_set:Nn} or similar; the bounding box
+% of the coffin is not reset, so any material outside of the formal bounding box
+% will not influence the poles.
+% \end{function}
+%
% \section{Coffin affine transformations}
%
% \begin{function}[updated = 2019-01-23]
@@ -666,7 +677,7 @@
\color_ensure_current:
#2
}
- \@@_update:N #1
+ \coffin_reset_poles:N #1
}
}
\cs_generate_variant:Nn \hcoffin_set:Nn { c }
@@ -679,7 +690,7 @@
\color_ensure_current:
#2
}
- \@@_gupdate:N #1
+ \coffin_greset_poles:N #1
}
}
\cs_generate_variant:Nn \hcoffin_gset:Nn { c }
@@ -704,13 +715,13 @@
\cs_new_protected:Npn \vcoffin_set:Nnn #1#2#3
{
\@@_set_vertical:NnnNN #1 {#2} {#3}
- \vbox_set:Nn \@@_update:N
+ \vbox_set:Nn \coffin_reset_poles:N
}
\cs_generate_variant:Nn \vcoffin_set:Nnn { c }
\cs_new_protected:Npn \vcoffin_gset:Nnn #1#2#3
{
\@@_set_vertical:NnnNN #1 {#2} {#3}
- \vbox_gset:Nn \@@_gupdate:N
+ \vbox_gset:Nn \coffin_greset_poles:N
}
\cs_generate_variant:Nn \vcoffin_gset:Nnn { c }
\cs_new_protected:Npn \@@_set_vertical:NnnNN #1#2#3#4#5
@@ -767,7 +778,7 @@
\cs_set_protected:Npn \hcoffin_set_end:
{
\hbox_set_end:
- \@@_update:N #1
+ \coffin_reset_poles:N #1
}
}
}
@@ -780,7 +791,7 @@
\cs_set_protected:Npn \hcoffin_gset_end:
{
\hbox_gset_end:
- \@@_gupdate:N #1
+ \coffin_greset_poles:N #1
}
}
}
@@ -801,14 +812,14 @@
{
\@@_set_vertical:NnNNNNw #1 {#2} \vbox_set:Nw
\vcoffin_set_end:
- \vbox_set_end: \@@_update:N
+ \vbox_set_end: \coffin_reset_poles:N
}
\cs_generate_variant:Nn \vcoffin_set:Nnw { c }
\cs_new_protected:Npn \vcoffin_gset:Nnw #1#2
{
\@@_set_vertical:NnNNNNw #1 {#2} \vbox_gset:Nw
\vcoffin_gset_end:
- \vbox_gset_end: \@@_gupdate:N
+ \vbox_gset_end: \coffin_greset_poles:N
}
\cs_generate_variant:Nn \vcoffin_gset:Nnw { c }
\cs_new_protected:Npn \@@_set_vertical:NnNNNNw #1#2#3#4#5#6
@@ -1033,16 +1044,16 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\@@_update:N, \@@_gupdate:N}
+% \begin{macro}{\coffin_reset_poles:N, \coffin_greset_poles:N}
% Simple shortcuts.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_update:N #1
+\cs_new_protected:Npn \coffin_reset_poles:N #1
{
\@@_reset_structure:N #1
\@@_update_corners:N #1
\@@_update_poles:N #1
}
-\cs_new_protected:Npn \@@_gupdate:N #1
+\cs_new_protected:Npn \coffin_greset_poles:N #1
{
\@@_greset_structure:N #1
\@@_gupdate_corners:N #1
diff --git a/macros/latex/contrib/l3kernel/l3color.dtx b/macros/latex/contrib/l3kernel/l3color.dtx
index 047467075c..c03bd0c4bb 100644
--- a/macros/latex/contrib/l3kernel/l3color.dtx
+++ b/macros/latex/contrib/l3kernel/l3color.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -252,8 +252,8 @@
%
% \begin{function}[EXP, pTF, added = 2022-08-12]{\color_if_exist:n}
% \begin{syntax}
-% \cs{color_if_exist:n} \Arg{name}
-% \cs{color_if_exist:n} \Arg{name} \Arg{true code} \Arg{false code}
+% \cs{color_if_exist_p:n} \Arg{name}
+% \cs{color_if_exist:nTF} \Arg{name} \Arg{true code} \Arg{false code}
% \end{syntax}
% Tests whether \meta{name} is currently defined to provide a color
% specification.
diff --git a/macros/latex/contrib/l3kernel/l3debug.dtx b/macros/latex/contrib/l3kernel/l3debug.dtx
index 79039b4773..b6d6099031 100644
--- a/macros/latex/contrib/l3kernel/l3debug.dtx
+++ b/macros/latex/contrib/l3kernel/l3debug.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3deprecation.dtx b/macros/latex/contrib/l3kernel/l3deprecation.dtx
index f9c788a097..05264251e4 100644
--- a/macros/latex/contrib/l3kernel/l3deprecation.dtx
+++ b/macros/latex/contrib/l3kernel/l3deprecation.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3doc.dtx b/macros/latex/contrib/l3kernel/l3doc.dtx
index 039ee830a8..1c789c1210 100644
--- a/macros/latex/contrib/l3kernel/l3doc.dtx
+++ b/macros/latex/contrib/l3kernel/l3doc.dtx
@@ -85,7 +85,7 @@ and all files in that bundle must be distributed together.
% require you to do updates, if the class changes.}}
%
% \author{\Team}
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
% \maketitle
% \tableofcontents
%
diff --git a/macros/latex/contrib/l3kernel/l3doc.pdf b/macros/latex/contrib/l3kernel/l3doc.pdf
index a83c0c03df..c87a456156 100644
--- a/macros/latex/contrib/l3kernel/l3doc.pdf
+++ b/macros/latex/contrib/l3kernel/l3doc.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3docstrip.dtx b/macros/latex/contrib/l3kernel/l3docstrip.dtx
index deff694c40..715bceeb30 100644
--- a/macros/latex/contrib/l3kernel/l3docstrip.dtx
+++ b/macros/latex/contrib/l3kernel/l3docstrip.dtx
@@ -63,7 +63,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3docstrip.pdf b/macros/latex/contrib/l3kernel/l3docstrip.pdf
index 1f63b51479..63e4c7157b 100644
--- a/macros/latex/contrib/l3kernel/l3docstrip.pdf
+++ b/macros/latex/contrib/l3kernel/l3docstrip.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3expan.dtx b/macros/latex/contrib/l3kernel/l3expan.dtx
index 28ac1c8123..9288a5271c 100644
--- a/macros/latex/contrib/l3kernel/l3expan.dtx
+++ b/macros/latex/contrib/l3kernel/l3expan.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -148,13 +148,17 @@
% \cs_generate_variant:Nn \foo:Nn { NV , cV }
% \end{verbatim}
% generates the functions |\foo:NV| and |\foo:cV| in the same
-% way. The \cs{cs_generate_variant:Nn} function can only be applied if
-% the \meta{parent control sequence} is already defined. If the \meta{parent
+% way. The \cs{cs_generate_variant:Nn} function should only be applied if
+% the \meta{parent control sequence} is already defined. (This is only
+% enforced if debugging support is enabled.)
+% If the \meta{parent
% control sequence} is protected or if the \meta{variant} involves any
% |x|~argument, then the \meta{variant control sequence} is also
% protected. The \meta{variant} is created globally, as is any
% \cs[no-index]{exp_args:N\meta{variant}} function needed to carry out the
-% expansion.
+% expansion. There is no need to re-apply \cs{cs_generate_variant:Nn} after
+% changing the definition of the parent function: the variant will always
+% use the current definition of the parent.
%
% Only |n|~and |N| arguments can be changed to other types. The only
% allowed changes are
@@ -168,6 +172,10 @@
% |N|-type parent exist, such as for \cs{tl_count:n} and
% \cs{tl_count:N}.
%
+% When creating variants for conditional functions,
+% \cs{prg_generate_conditional_variant:Nnn} provides a convenient way
+% of handling the related function set.
+%
% For backward compatibility it is currently possible to make |n|,
% |o|, |V|, |v|, |f|, |e|, or |x|-type variants of an |N|-type argument or
% |N| or |c|-type variants of an |n|-type argument. Both are
diff --git a/macros/latex/contrib/l3kernel/l3file.dtx b/macros/latex/contrib/l3kernel/l3file.dtx
index 4be6f56f80..c4e5f0b1ce 100644
--- a/macros/latex/contrib/l3kernel/l3file.dtx
+++ b/macros/latex/contrib/l3kernel/l3file.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -886,7 +886,8 @@
% \begin{function}[added = 2019-05-13, updated = 2019-09-20, pTF, EXP]
% {\file_compare_timestamp:nNn}
% \begin{syntax}
-% \cs{file_compare_timestamp:nNn} \Arg{file-1} \meta{comparator} \Arg{file-2} \Arg{true code} \Arg{false code}
+% \cs{file_compare_timestamp_p:nNn} \Arg{file-1} \meta{comparator} \Arg{file-2}
+% \cs{file_compare_timestamp:nNnTF} \Arg{file-1} \meta{comparator} \Arg{file-2} \Arg{true code} \Arg{false code}
% \end{syntax}
% Compares the file stamps on the two \meta{files} as indicated by
% the \meta{comparator}, and inserts either the \meta{true code}
diff --git a/macros/latex/contrib/l3kernel/l3flag.dtx b/macros/latex/contrib/l3kernel/l3flag.dtx
index 80981884fb..d34922db45 100644
--- a/macros/latex/contrib/l3kernel/l3flag.dtx
+++ b/macros/latex/contrib/l3kernel/l3flag.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -123,7 +123,8 @@
%
% \begin{function}[EXP,pTF]{\flag_if_exist:n}
% \begin{syntax}
-% \cs{flag_if_exist:n} \Arg{flag name}
+% \cs{flag_if_exist_p:n} \Arg{flag name}
+% \cs{flag_if_exist:nTF} \Arg{flag name} \Arg{true code} \Arg{false code}
% \end{syntax}
% This function returns \texttt{true} if the \meta{flag name}
% references a flag that has been defined previously, and
@@ -132,7 +133,8 @@
%
% \begin{function}[EXP,pTF]{\flag_if_raised:n}
% \begin{syntax}
-% \cs{flag_if_raised:n} \Arg{flag name}
+% \cs{flag_if_raised_p:n} \Arg{flag name}
+% \cs{flag_if_raised:nTF} \Arg{flag name} \Arg{true code} \Arg{false code}
% \end{syntax}
% This function returns \texttt{true} if the \meta{flag} has non-zero
% height, and \texttt{false} if the \meta{flag} has zero height.
diff --git a/macros/latex/contrib/l3kernel/l3fp-assign.dtx b/macros/latex/contrib/l3kernel/l3fp-assign.dtx
index af1b0b98be..1021bfb830 100644
--- a/macros/latex/contrib/l3kernel/l3fp-assign.dtx
+++ b/macros/latex/contrib/l3kernel/l3fp-assign.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
% \maketitle
%
% \begin{documentation}
diff --git a/macros/latex/contrib/l3kernel/l3fp-aux.dtx b/macros/latex/contrib/l3kernel/l3fp-aux.dtx
index e5c3a0f5a2..c138c06d2a 100644
--- a/macros/latex/contrib/l3kernel/l3fp-aux.dtx
+++ b/macros/latex/contrib/l3kernel/l3fp-aux.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3fp-basics.dtx b/macros/latex/contrib/l3kernel/l3fp-basics.dtx
index 17e2193713..d041b95689 100644
--- a/macros/latex/contrib/l3kernel/l3fp-basics.dtx
+++ b/macros/latex/contrib/l3kernel/l3fp-basics.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3fp-convert.dtx b/macros/latex/contrib/l3kernel/l3fp-convert.dtx
index fcc2b130e5..ee86a451c8 100644
--- a/macros/latex/contrib/l3kernel/l3fp-convert.dtx
+++ b/macros/latex/contrib/l3kernel/l3fp-convert.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3fp-expo.dtx b/macros/latex/contrib/l3kernel/l3fp-expo.dtx
index 43f1e9e0be..312d0a33ca 100644
--- a/macros/latex/contrib/l3kernel/l3fp-expo.dtx
+++ b/macros/latex/contrib/l3kernel/l3fp-expo.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3fp-extended.dtx b/macros/latex/contrib/l3kernel/l3fp-extended.dtx
index 91ff16141e..f11d8f5f2c 100644
--- a/macros/latex/contrib/l3kernel/l3fp-extended.dtx
+++ b/macros/latex/contrib/l3kernel/l3fp-extended.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3fp-logic.dtx b/macros/latex/contrib/l3kernel/l3fp-logic.dtx
index ee89eacb40..1796aa16b5 100644
--- a/macros/latex/contrib/l3kernel/l3fp-logic.dtx
+++ b/macros/latex/contrib/l3kernel/l3fp-logic.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3fp-parse.dtx b/macros/latex/contrib/l3kernel/l3fp-parse.dtx
index 082dbaf8ba..93bbc4a799 100644
--- a/macros/latex/contrib/l3kernel/l3fp-parse.dtx
+++ b/macros/latex/contrib/l3kernel/l3fp-parse.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3fp-random.dtx b/macros/latex/contrib/l3kernel/l3fp-random.dtx
index c4c718c72a..54979b8701 100644
--- a/macros/latex/contrib/l3kernel/l3fp-random.dtx
+++ b/macros/latex/contrib/l3kernel/l3fp-random.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3fp-round.dtx b/macros/latex/contrib/l3kernel/l3fp-round.dtx
index 98584be2f6..14e327ab17 100644
--- a/macros/latex/contrib/l3kernel/l3fp-round.dtx
+++ b/macros/latex/contrib/l3kernel/l3fp-round.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3fp-traps.dtx b/macros/latex/contrib/l3kernel/l3fp-traps.dtx
index 06630644e0..23857d73e6 100644
--- a/macros/latex/contrib/l3kernel/l3fp-traps.dtx
+++ b/macros/latex/contrib/l3kernel/l3fp-traps.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
% \maketitle
%
% \begin{documentation}
diff --git a/macros/latex/contrib/l3kernel/l3fp-trig.dtx b/macros/latex/contrib/l3kernel/l3fp-trig.dtx
index 24ac6a9115..a30c683e6c 100644
--- a/macros/latex/contrib/l3kernel/l3fp-trig.dtx
+++ b/macros/latex/contrib/l3kernel/l3fp-trig.dtx
@@ -40,7 +40,7 @@
% {latex-team@latex-project.org}^^A
% }^^A
% }
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3fp.dtx b/macros/latex/contrib/l3kernel/l3fp.dtx
index 88c323e415..29f1ed453e 100644
--- a/macros/latex/contrib/l3kernel/l3fp.dtx
+++ b/macros/latex/contrib/l3kernel/l3fp.dtx
@@ -49,7 +49,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -478,7 +478,8 @@
%
% \begin{function}[pTF, added = 2019-08-25]{\fp_if_nan:n}
% \begin{syntax}
-% \cs{fp_if_nan:n} \Arg{fp expr}
+% \cs{fp_if_nan_p:n} \Arg{fp expr}
+% \cs{fp_if_nan:nTF} \Arg{fp expr} \Arg{true code} \Arg{false code}
% \end{syntax}
% Evaluates the \meta{fp expr} and tests whether the result is exactly
% \nan{}. The test returns \texttt{false} for any other result, even
diff --git a/macros/latex/contrib/l3kernel/l3fparray.dtx b/macros/latex/contrib/l3kernel/l3fparray.dtx
index 5836d5bee7..33b17da6ad 100644
--- a/macros/latex/contrib/l3kernel/l3fparray.dtx
+++ b/macros/latex/contrib/l3kernel/l3fparray.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3int.dtx b/macros/latex/contrib/l3kernel/l3int.dtx
index f7d065d874..bf3c413b28 100644
--- a/macros/latex/contrib/l3kernel/l3int.dtx
+++ b/macros/latex/contrib/l3kernel/l3int.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -493,6 +493,17 @@
% is odd or even, as appropriate.
% \end{function}
%
+% \begin{function}[EXP,pTF, added = 2023-05-17]{\int_if_zero:n}
+% \begin{syntax}
+% \cs{int_if_zero_p:n} \Arg{int expr}
+% \cs{int_if_zero:nTF} \Arg{int expr}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function first evaluates the \meta{int expr}
+% as described for \cs{int_eval:n}. It then evaluates if this
+% is zero or not.
+% \end{function}
+%
% \section{Integer expression loops}
%
% \begin{function}[rEXP]{\int_do_until:nNnn}
@@ -1730,6 +1741,19 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}[pTF]{\int_if_zero:n}
+% \begin{macrocode}
+\prg_new_conditional:Npnn \int_if_zero:n #1 { p , T , F , TF }
+ {
+ \if_int_compare:w \@@_eval:w #1 = \c_zero_int
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}[EXP, noTF]{\int_case:nn}
% \begin{macro}{\@@_case:nnTF}
% \begin{macro}{\@@_case:nw, \@@_case_end:nw}
diff --git a/macros/latex/contrib/l3kernel/l3intarray.dtx b/macros/latex/contrib/l3kernel/l3intarray.dtx
index b671f5e4ed..3978f7f53a 100644
--- a/macros/latex/contrib/l3kernel/l3intarray.dtx
+++ b/macros/latex/contrib/l3kernel/l3intarray.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3kernel-functions.dtx b/macros/latex/contrib/l3kernel/l3kernel-functions.dtx
index 3542167a7a..f97ddf0a3f 100644
--- a/macros/latex/contrib/l3kernel/l3kernel-functions.dtx
+++ b/macros/latex/contrib/l3kernel/l3kernel-functions.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3keys.dtx b/macros/latex/contrib/l3kernel/l3keys.dtx
index 64a301d906..84d5bc1d96 100644
--- a/macros/latex/contrib/l3kernel/l3keys.dtx
+++ b/macros/latex/contrib/l3kernel/l3keys.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -1888,7 +1888,7 @@
\@@_cmd_set_direct:nn { \l_keys_path_str / unknown }
{
\msg_error:nnx { keys } { boolean-values-only }
- \l_keys_key_str
+ \l_keys_path_str
}
\@@_default_set:n { true }
}
@@ -2063,6 +2063,8 @@
%
% \begin{macro}{\@@_initialise:n}
% A set up for initialisation: just run the code if it exists.
+% We need to set the key string here, using the deprecated \texttt{tl}
+% as a piece of scratch space.
% \begin{macrocode}
\cs_new_protected:Npn \@@_initialise:n #1
{
@@ -2072,7 +2074,13 @@
{
\str_clear:N \l_@@_inherit_str
\cs_if_exist:cT { \c_@@_code_root_str \l_keys_path_str }
- { \@@_execute:nn \l_keys_path_str {#1} }
+ {
+ \exp_after:wN \@@_find_key_module:wNN
+ \l_keys_path_str \s_@@_stop
+ \l_keys_key_tl \l_keys_key_str
+ \tl_set_eq:NN \l_keys_key_tl \l_keys_key_str
+ \@@_execute:nn \l_keys_path_str {#1}
+ }
}
}
% \end{macrocode}
@@ -2097,7 +2105,7 @@
\@@_cmd_set:nn { \l_keys_path_str / unknown }
{
\msg_error:nnx { keys } { boolean-values-only }
- \l_keys_key_str
+ \l_keys_path_str
}
\@@_default_set:n { true }
\cs_if_exist:cF { if#1 }
@@ -2112,20 +2120,22 @@
%
% \begin{macro}{\@@_meta_make:n}
% \begin{macro}{\@@_meta_make:nn}
-% To create a meta-key, simply set up to pass data through.
+% To create a meta-key, simply set up to pass data through. The internal
+% function is used here as a meta key should respect the prevailing
+% filtering, etc.
% \begin{macrocode}
\cs_new_protected:Npn \@@_meta_make:n #1
{
\exp_args:NVo \@@_cmd_set_direct:nn \l_keys_path_str
{
- \exp_after:wN \keys_set:nn \exp_after:wN
+ \exp_after:wN \@@_set:nn \exp_after:wN
{ \l_@@_module_str } {#1}
}
}
\cs_new_protected:Npn \@@_meta_make:nn #1#2
{
\exp_args:NV \@@_cmd_set_direct:nn
- \l_keys_path_str { \keys_set:nn {#1} {#2} }
+ \l_keys_path_str { \@@_set:nn {#1} {#2} }
}
% \end{macrocode}
% \end{macro}
diff --git a/macros/latex/contrib/l3kernel/l3legacy.dtx b/macros/latex/contrib/l3kernel/l3legacy.dtx
index aa144fdb29..867d369f12 100644
--- a/macros/latex/contrib/l3kernel/l3legacy.dtx
+++ b/macros/latex/contrib/l3kernel/l3legacy.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -56,6 +56,7 @@
%
% \begin{function}[EXP,pTF]{\legacy_if:n}
% \begin{syntax}
+% \cs{legacy_if_p:n} \Arg{name}
% \cs{legacy_if:nTF} \Arg{name} \Arg{true code} \Arg{false code}
% \end{syntax}
% Tests if the \LaTeXe{}/plain \TeX{} conditional (generated by \tn{newif})
diff --git a/macros/latex/contrib/l3kernel/l3luatex.dtx b/macros/latex/contrib/l3kernel/l3luatex.dtx
index 048fd472b8..5849266ddb 100644
--- a/macros/latex/contrib/l3kernel/l3luatex.dtx
+++ b/macros/latex/contrib/l3kernel/l3luatex.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3msg.dtx b/macros/latex/contrib/l3kernel/l3msg.dtx
index c256def116..41812fd5f7 100644
--- a/macros/latex/contrib/l3kernel/l3msg.dtx
+++ b/macros/latex/contrib/l3kernel/l3msg.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -91,6 +91,18 @@
% \end{verbatim}
% will allow to filter out specifically messages from the \texttt{submodule}.
%
+% Some authors may find the need to include spaces as |~| characters
+% tedious. This can be avoided by locally reseting the cateogry code
+% of \verb*| |.
+% \begin{verbatim}
+% \char_set_catcode_space:n { `\ }
+% \msg_new:nnn { foo } { bar }
+% {Some message text using '#1' and usual message shorthands \{ \ \ \}.}
+% \char_set_catcode_ignore:n { `\ }
+% \end{verbatim}
+% although in general this may be confusing; simply writing the messages
+% using |~| characters is the method favored by the team.
+%
% \begin{function}[updated = 2011-08-16]{\msg_new:nnnn, \msg_new:nnn}
% \begin{syntax}
% \cs{msg_new:nnnn} \Arg{module} \Arg{message} \Arg{text} \Arg{more text}
@@ -1940,6 +1952,8 @@
{ Cannot~generate~null~char~as~a~space. }
\msg_new:nnn { char } { out-of-range }
{ Charcode~requested~out~of~engine~range. }
+\msg_new:nnn { dim } { zero-unit }
+ { Zero~unit~in~conversion. }
\msg_new:nnnn { kernel } { quote-in-shell }
{ Quotes~in~shell~command~'#1'. }
{ Shell~commands~cannot~contain~quotes~("). }
@@ -2218,7 +2232,7 @@
\prop_gput:Nnn \g_msg_module_type_prop { kernel } { }
\clist_map_inline:nn
{
- char , clist , coffin , debug , deprecation , msg ,
+ char , clist , coffin , debug , deprecation , dim, msg ,
quark , prg , prop , scanmark , seq , sys
}
{
diff --git a/macros/latex/contrib/l3kernel/l3names.dtx b/macros/latex/contrib/l3kernel/l3names.dtx
index 09ec8a83ba..97f4b0431d 100644
--- a/macros/latex/contrib/l3kernel/l3names.dtx
+++ b/macros/latex/contrib/l3kernel/l3names.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3news.pdf b/macros/latex/contrib/l3kernel/l3news.pdf
index 71a9e6840e..28d77fd1d6 100644
--- a/macros/latex/contrib/l3kernel/l3news.pdf
+++ b/macros/latex/contrib/l3kernel/l3news.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3news01.pdf b/macros/latex/contrib/l3kernel/l3news01.pdf
index 6a994a24c1..011b51961d 100644
--- a/macros/latex/contrib/l3kernel/l3news01.pdf
+++ b/macros/latex/contrib/l3kernel/l3news01.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3news02.pdf b/macros/latex/contrib/l3kernel/l3news02.pdf
index 5e76c8d5aa..0175fd31b2 100644
--- a/macros/latex/contrib/l3kernel/l3news02.pdf
+++ b/macros/latex/contrib/l3kernel/l3news02.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3news03.pdf b/macros/latex/contrib/l3kernel/l3news03.pdf
index 9c38abc8c8..ad2cd7dd33 100644
--- a/macros/latex/contrib/l3kernel/l3news03.pdf
+++ b/macros/latex/contrib/l3kernel/l3news03.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3news04.pdf b/macros/latex/contrib/l3kernel/l3news04.pdf
index 1b410c1ef8..d283d35e09 100644
--- a/macros/latex/contrib/l3kernel/l3news04.pdf
+++ b/macros/latex/contrib/l3kernel/l3news04.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3news05.pdf b/macros/latex/contrib/l3kernel/l3news05.pdf
index c3fb4f022b..d1e73ffb4b 100644
--- a/macros/latex/contrib/l3kernel/l3news05.pdf
+++ b/macros/latex/contrib/l3kernel/l3news05.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3news06.pdf b/macros/latex/contrib/l3kernel/l3news06.pdf
index 951757da63..fe6fb8ad49 100644
--- a/macros/latex/contrib/l3kernel/l3news06.pdf
+++ b/macros/latex/contrib/l3kernel/l3news06.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3news07.pdf b/macros/latex/contrib/l3kernel/l3news07.pdf
index fee9bbf2df..8e6967b08a 100644
--- a/macros/latex/contrib/l3kernel/l3news07.pdf
+++ b/macros/latex/contrib/l3kernel/l3news07.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3news08.pdf b/macros/latex/contrib/l3kernel/l3news08.pdf
index a858a42c43..d32b9bff99 100644
--- a/macros/latex/contrib/l3kernel/l3news08.pdf
+++ b/macros/latex/contrib/l3kernel/l3news08.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3news09.pdf b/macros/latex/contrib/l3kernel/l3news09.pdf
index c043e68add..2e54f340e3 100644
--- a/macros/latex/contrib/l3kernel/l3news09.pdf
+++ b/macros/latex/contrib/l3kernel/l3news09.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3news10.pdf b/macros/latex/contrib/l3kernel/l3news10.pdf
index 02e724712d..4039ae74b8 100644
--- a/macros/latex/contrib/l3kernel/l3news10.pdf
+++ b/macros/latex/contrib/l3kernel/l3news10.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3news11.pdf b/macros/latex/contrib/l3kernel/l3news11.pdf
index a521a6ca25..308e42b7ea 100644
--- a/macros/latex/contrib/l3kernel/l3news11.pdf
+++ b/macros/latex/contrib/l3kernel/l3news11.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3news12.pdf b/macros/latex/contrib/l3kernel/l3news12.pdf
index 166cdf0386..086869b52c 100644
--- a/macros/latex/contrib/l3kernel/l3news12.pdf
+++ b/macros/latex/contrib/l3kernel/l3news12.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3pdf.dtx b/macros/latex/contrib/l3kernel/l3pdf.dtx
index 0a76fc54e0..38896f7d87 100644
--- a/macros/latex/contrib/l3kernel/l3pdf.dtx
+++ b/macros/latex/contrib/l3kernel/l3pdf.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -131,6 +131,7 @@
%
% \begin{function}[pTF, EXP, added = 2021-02-10]{\pdf_version_compare:Nn}
% \begin{syntax}
+% \cs{pdf_version_compare_p:Nn} \meta{comparator} \Arg{version}
% \cs{pdf_version_compare:NnTF} \meta{comparator} \Arg{version} \Arg{true code} \Arg{false code}
% \end{syntax}
% Compares the version of the PDF being created with the \meta{version}
diff --git a/macros/latex/contrib/l3kernel/l3prefixes.pdf b/macros/latex/contrib/l3kernel/l3prefixes.pdf
index b065870c91..9476774444 100644
--- a/macros/latex/contrib/l3kernel/l3prefixes.pdf
+++ b/macros/latex/contrib/l3kernel/l3prefixes.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3prg.dtx b/macros/latex/contrib/l3kernel/l3prg.dtx
index c1d42e10be..7374a8d8b9 100644
--- a/macros/latex/contrib/l3kernel/l3prg.dtx
+++ b/macros/latex/contrib/l3kernel/l3prg.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -708,6 +708,7 @@
%
% \begin{function}[updated = 2011-09-05, EXP,pTF]{\mode_if_math:}
% \begin{syntax}
+% \cs{mode_if_math_p:}
% \cs{mode_if_math:TF} \Arg{true code} \Arg{false code}
% \end{syntax}
% Detects if \TeX{} is currently in maths mode.
diff --git a/macros/latex/contrib/l3kernel/l3prop.dtx b/macros/latex/contrib/l3kernel/l3prop.dtx
index 341b46bdff..259009a181 100644
--- a/macros/latex/contrib/l3kernel/l3prop.dtx
+++ b/macros/latex/contrib/l3kernel/l3prop.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -377,6 +377,7 @@
% \prop_if_in:cn, \prop_if_in:cV, \prop_if_in:co
% }
% \begin{syntax}
+% \cs{prop_if_in_p:Nn} \meta{property list} \Arg{key}
% \cs{prop_if_in:NnTF} \meta{property list} \Arg{key} \Arg{true code} \Arg{false code}
% \end{syntax}
% Tests if the \meta{key} is present in the \meta{property list},
diff --git a/macros/latex/contrib/l3kernel/l3quark.dtx b/macros/latex/contrib/l3kernel/l3quark.dtx
index 67a431db2f..d2f02ae06d 100644
--- a/macros/latex/contrib/l3kernel/l3quark.dtx
+++ b/macros/latex/contrib/l3kernel/l3quark.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3regex.dtx b/macros/latex/contrib/l3kernel/l3regex.dtx
index 629acfbf44..9110d54b85 100644
--- a/macros/latex/contrib/l3kernel/l3regex.dtx
+++ b/macros/latex/contrib/l3kernel/l3regex.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3seq.dtx b/macros/latex/contrib/l3kernel/l3seq.dtx
index 601083909e..3044da987c 100644
--- a/macros/latex/contrib/l3kernel/l3seq.dtx
+++ b/macros/latex/contrib/l3kernel/l3seq.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -61,29 +61,29 @@
%
% \begin{function}{\seq_new:N, \seq_new:c}
% \begin{syntax}
-% \cs{seq_new:N} \meta{sequence}
+% \cs{seq_new:N} \meta{seq~var}
% \end{syntax}
-% Creates a new \meta{sequence} or raises an error if the name is
-% already taken. The declaration is global. The \meta{sequence}
+% Creates a new \meta{seq~var} or raises an error if the name is
+% already taken. The declaration is global. The \meta{seq~var}
% initially contains no items.
% \end{function}
%
% \begin{function}{\seq_clear:N, \seq_clear:c, \seq_gclear:N, \seq_gclear:c}
% \begin{syntax}
-% \cs{seq_clear:N} \meta{sequence}
+% \cs{seq_clear:N} \meta{seq~var}
% \end{syntax}
-% Clears all items from the \meta{sequence}.
+% Clears all items from the \meta{seq~var}.
% \end{function}
%
% \begin{function}
% {\seq_clear_new:N, \seq_clear_new:c, \seq_gclear_new:N, \seq_gclear_new:c}
% \begin{syntax}
-% \cs{seq_clear_new:N} \meta{sequence}
+% \cs{seq_clear_new:N} \meta{seq~var}
% \end{syntax}
-% Ensures that the \meta{sequence} exists globally by applying
+% Ensures that the \meta{seq~var} exists globally by applying
% \cs{seq_new:N} if necessary, then applies
% \cs[index=seq_clear:N]{seq_(g)clear:N} to leave
-% the \meta{sequence} empty.
+% the \meta{seq~var} empty.
% \end{function}
%
% \begin{function}
@@ -92,10 +92,10 @@
% \seq_gset_eq:NN, \seq_gset_eq:cN, \seq_gset_eq:Nc, \seq_gset_eq:cc
% }
% \begin{syntax}
-% \cs{seq_set_eq:NN} \meta{sequence_1} \meta{sequence_2}
+% \cs{seq_set_eq:NN} \meta{seq~var_1} \meta{seq~var_2}
% \end{syntax}
-% Sets the content of \meta{sequence_1} equal to that of
-% \meta{sequence_2}.
+% Sets the content of \meta{seq~var_1} equal to that of
+% \meta{seq~var_2}.
% \end{function}
%
% \begin{function}[added = 2014-07-17]
@@ -108,9 +108,9 @@
% \seq_gset_from_clist:Nn, \seq_gset_from_clist:cn
% }
% \begin{syntax}
-% \cs{seq_set_from_clist:NN} \meta{sequence} \meta{comma-list}
+% \cs{seq_set_from_clist:NN} \meta{seq~var} \meta{comma-list}
% \end{syntax}
-% Converts the data in the \meta{comma list} into a \meta{sequence}:
+% Converts the data in the \meta{comma list} into a \meta{seq~var}:
% the original \meta{comma list} is unchanged.
% \end{function}
%
@@ -130,16 +130,16 @@
% \seq_gset_split:Nnn, \seq_gset_split:NnV
% }
% \begin{syntax}
-% \cs{seq_set_split:Nnn} \meta{sequence} \Arg{delimiter} \Arg{token list}
+% \cs{seq_set_split:Nnn} \meta{seq~var} \Arg{delimiter} \Arg{token list}
% \end{syntax}
% Splits the \meta{token list} into \meta{items} separated
-% by \meta{delimiter}, and assigns the result to the \meta{sequence}.
+% by \meta{delimiter}, and assigns the result to the \meta{seq~var}.
% Spaces on both sides of each \meta{item} are ignored,
% then one set of outer braces is removed (if any);
% this space trimming behaviour is identical to that of
% \pkg{l3clist} functions. Empty \meta{items} are preserved by
% \cs{seq_set_split:Nnn}, and can be removed afterwards using
-% \cs{seq_remove_all:Nn} \meta{sequence} |{}|.
+% \cs{seq_remove_all:Nn} \meta{seq~var} |{}|.
% The \meta{delimiter} may not contain |{|, |}| or |#|
% (assuming \TeX{}'s normal category code r\'egime).
% If the \meta{delimiter} is empty, the \meta{token list} is split
@@ -153,15 +153,15 @@
% \seq_gset_split_keep_spaces:Nnn, \seq_gset_split_keep_spaces:NnV
% }
% \begin{syntax}
-% \cs{seq_set_split_keep_spaces:Nnn} \meta{sequence} \Arg{delimiter} \Arg{token list}
+% \cs{seq_set_split_keep_spaces:Nnn} \meta{seq~var} \Arg{delimiter} \Arg{token list}
% \end{syntax}
% Splits the \meta{token list} into \meta{items} separated
-% by \meta{delimiter}, and assigns the result to the \meta{sequence}.
+% by \meta{delimiter}, and assigns the result to the \meta{seq~var}.
% One set of outer braces is removed (if any) but any surrounding spaces
% are retained: any braces \emph{inside} one or more spaces are
% therefore kept. Empty \meta{items} are preserved by
% \cs{seq_set_split_keep_spaces:Nnn}, and can be removed afterwards using
-% \cs{seq_remove_all:Nn} \meta{sequence} |{}|.
+% \cs{seq_remove_all:Nn} \meta{seq~var} |{}|.
% The \meta{delimiter} may not contain |{|, |}| or |#|
% (assuming \TeX{}'s normal category code r\'egime).
% If the \meta{delimiter} is empty, the \meta{token list} is split
@@ -172,21 +172,21 @@
% \begin{function}
% {\seq_concat:NNN, \seq_concat:ccc, \seq_gconcat:NNN, \seq_gconcat:ccc}
% \begin{syntax}
-% \cs{seq_concat:NNN} \meta{sequence_1} \meta{sequence_2} \meta{sequence_3}
+% \cs{seq_concat:NNN} \meta{seq~var_1} \meta{seq~var_2} \meta{seq~var_3}
% \end{syntax}
-% Concatenates the content of \meta{sequence_2} and \meta{sequence_3}
-% together and saves the result in \meta{sequence_1}. The items in
-% \meta{sequence_2} are placed at the left side of the new sequence.
+% Concatenates the content of \meta{seq~var_2} and \meta{seq~var_3}
+% together and saves the result in \meta{seq~var_1}. The items in
+% \meta{seq~var_2} are placed at the left side of the new sequence.
% \end{function}
%
% \begin{function}[EXP, pTF, added=2012-03-03]
% {\seq_if_exist:N, \seq_if_exist:c}
% \begin{syntax}
-% \cs{seq_if_exist_p:N} \meta{sequence}
-% \cs{seq_if_exist:NTF} \meta{sequence} \Arg{true code} \Arg{false code}
+% \cs{seq_if_exist_p:N} \meta{seq~var}
+% \cs{seq_if_exist:NTF} \meta{seq~var} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests whether the \meta{sequence} is currently defined. This does not
-% check that the \meta{sequence} really is a sequence variable.
+% Tests whether the \meta{seq~var} is currently defined. This does not
+% check that the \meta{seq~var} really is a sequence variable.
% \end{function}
%
% \section{Appending data to sequences}
@@ -202,9 +202,9 @@
% \seq_gput_left:co, \seq_gput_left:cx
% }
% \begin{syntax}
-% \cs{seq_put_left:Nn} \meta{sequence} \Arg{item}
+% \cs{seq_put_left:Nn} \meta{seq~var} \Arg{item}
% \end{syntax}
-% Appends the \meta{item} to the left of the \meta{sequence}.
+% Appends the \meta{item} to the left of the \meta{seq~var}.
% \end{function}
%
% \begin{function}{
@@ -218,9 +218,9 @@
% \seq_gput_right:co, \seq_gput_right:cx
% }
% \begin{syntax}
-% \cs{seq_put_right:Nn} \meta{sequence} \Arg{item}
+% \cs{seq_put_right:Nn} \meta{seq~var} \Arg{item}
% \end{syntax}
-% Appends the \meta{item} to the right of the \meta{sequence}.
+% Appends the \meta{item} to the right of the \meta{seq~var}.
% \end{function}
%
% \section{Recovering items from sequences}
@@ -234,86 +234,86 @@
%
% \begin{function}[updated = 2012-05-14]{\seq_get_left:NN, \seq_get_left:cN}
% \begin{syntax}
-% \cs{seq_get_left:NN} \meta{sequence} \meta{token list variable}
+% \cs{seq_get_left:NN} \meta{seq~var} \meta{token list variable}
% \end{syntax}
-% Stores the left-most item from a \meta{sequence} in the
+% Stores the left-most item from a \meta{seq~var} in the
% \meta{token list variable} without removing it from the
-% \meta{sequence}. The \meta{token list variable} is assigned locally.
-% If \meta{sequence} is empty the \meta{token list variable}
+% \meta{seq~var}. The \meta{token list variable} is assigned locally.
+% If \meta{seq~var} is empty the \meta{token list variable}
% is set to the special marker \cs{q_no_value}.
% \end{function}
%
% \begin{function}[updated = 2012-05-19]{\seq_get_right:NN, \seq_get_right:cN}
% \begin{syntax}
-% \cs{seq_get_right:NN} \meta{sequence} \meta{token list variable}
+% \cs{seq_get_right:NN} \meta{seq~var} \meta{token list variable}
% \end{syntax}
-% Stores the right-most item from a \meta{sequence} in the
+% Stores the right-most item from a \meta{seq~var} in the
% \meta{token list variable} without removing it from the
-% \meta{sequence}. The \meta{token list variable} is assigned locally.
-% If \meta{sequence} is empty the \meta{token list variable}
+% \meta{seq~var}. The \meta{token list variable} is assigned locally.
+% If \meta{seq~var} is empty the \meta{token list variable}
% is set to the special marker \cs{q_no_value}.
% \end{function}
%
% \begin{function}[updated = 2012-05-14]{\seq_pop_left:NN, \seq_pop_left:cN}
% \begin{syntax}
-% \cs{seq_pop_left:NN} \meta{sequence} \meta{token list variable}
+% \cs{seq_pop_left:NN} \meta{seq~var} \meta{token list variable}
% \end{syntax}
-% Pops the left-most item from a \meta{sequence} into the
+% Pops the left-most item from a \meta{seq~var} into the
% \meta{token list variable}, \emph{i.e.}~removes the item from the
% sequence and stores it in the \meta{token list variable}.
-% Both of the variables are assigned locally. If \meta{sequence} is
+% Both of the variables are assigned locally. If \meta{seq~var} is
% empty the \meta{token list variable} is set to
% the special marker \cs{q_no_value}.
% \end{function}
%
% \begin{function}[updated = 2012-05-14]{\seq_gpop_left:NN, \seq_gpop_left:cN}
% \begin{syntax}
-% \cs{seq_gpop_left:NN} \meta{sequence} \meta{token list variable}
+% \cs{seq_gpop_left:NN} \meta{seq~var} \meta{token list variable}
% \end{syntax}
-% Pops the left-most item from a \meta{sequence} into the
+% Pops the left-most item from a \meta{seq~var} into the
% \meta{token list variable}, \emph{i.e.}~removes the item from the
% sequence and stores it in the \meta{token list variable}.
-% The \meta{sequence} is modified globally, while the assignment of
+% The \meta{seq~var} is modified globally, while the assignment of
% the \meta{token list variable} is local.
-% If \meta{sequence} is empty the \meta{token list variable} is set to
+% If \meta{seq~var} is empty the \meta{token list variable} is set to
% the special marker \cs{q_no_value}.
% \end{function}
%
% \begin{function}[updated = 2012-05-19]{\seq_pop_right:NN, \seq_pop_right:cN}
% \begin{syntax}
-% \cs{seq_pop_right:NN} \meta{sequence} \meta{token list variable}
+% \cs{seq_pop_right:NN} \meta{seq~var} \meta{token list variable}
% \end{syntax}
-% Pops the right-most item from a \meta{sequence} into the
+% Pops the right-most item from a \meta{seq~var} into the
% \meta{token list variable}, \emph{i.e.}~removes the item from the
% sequence and stores it in the \meta{token list variable}.
-% Both of the variables are assigned locally. If \meta{sequence} is
+% Both of the variables are assigned locally. If \meta{seq~var} is
% empty the \meta{token list variable} is set to
% the special marker \cs{q_no_value}.
% \end{function}
%
% \begin{function}[updated = 2012-05-19]{\seq_gpop_right:NN, \seq_gpop_right:cN}
% \begin{syntax}
-% \cs{seq_gpop_right:NN} \meta{sequence} \meta{token list variable}
+% \cs{seq_gpop_right:NN} \meta{seq~var} \meta{token list variable}
% \end{syntax}
-% Pops the right-most item from a \meta{sequence} into the
+% Pops the right-most item from a \meta{seq~var} into the
% \meta{token list variable}, \emph{i.e.}~removes the item from the
% sequence and stores it in the \meta{token list variable}.
-% The \meta{sequence} is modified globally, while the assignment of
+% The \meta{seq~var} is modified globally, while the assignment of
% the \meta{token list variable} is local.
-% If \meta{sequence} is empty the \meta{token list variable} is set to
+% If \meta{seq~var} is empty the \meta{token list variable} is set to
% the special marker \cs{q_no_value}.
% \end{function}
%
% \begin{function}[added = 2014-07-17, EXP]{\seq_item:Nn, \seq_item:cn}
% \begin{syntax}
-% \cs{seq_item:Nn} \meta{sequence} \Arg{integer expression}
+% \cs{seq_item:Nn} \meta{seq~var} \Arg{integer expression}
% \end{syntax}
-% Indexing items in the \meta{sequence} from~$1$ at the top (left), this
+% Indexing items in the \meta{seq~var} from~$1$ at the top (left), this
% function evaluates the \meta{integer expression} and leaves the
% appropriate item from the sequence in the input stream. If the
% \meta{integer expression} is negative, indexing occurs from the
% bottom (right) of the sequence. If the \meta{integer expression}
-% is larger than the number of items in the \meta{sequence} (as
+% is larger than the number of items in the \meta{seq~var} (as
% calculated by \cs{seq_count:N}) then the function expands to
% nothing.
% \begin{texnote}
@@ -328,8 +328,8 @@
% \begin{syntax}
% \cs{seq_rand_item:N} \meta{seq~var}
% \end{syntax}
-% Selects a pseudo-random item of the \meta{sequence}. If the
-% \meta{sequence} is empty the result is empty.
+% Selects a pseudo-random item of the \meta{seq~var}. If the
+% \meta{seq~var} is empty the result is empty.
% This is not available in older versions of \XeTeX{}.
% \begin{texnote}
% The result is returned within the \tn{unexpanded}
@@ -348,91 +348,91 @@
% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]
% {\seq_get_left:NN, \seq_get_left:cN}
% \begin{syntax}
-% \cs{seq_get_left:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{seq_get_left:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
% \end{syntax}
-% If the \meta{sequence} is empty, leaves the \meta{false code} in the
+% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
% input stream. The value of the \meta{token list variable} is
% not defined in this case and should not be relied upon. If the
-% \meta{sequence} is non-empty, stores the left-most item from the
-% \meta{sequence}
+% \meta{seq~var} is non-empty, stores the left-most item from the
+% \meta{seq~var}
% in the \meta{token list variable} without removing it from the
-% \meta{sequence}, then leaves the \meta{true code} in the input stream.
+% \meta{seq~var}, then leaves the \meta{true code} in the input stream.
% The \meta{token list variable} is assigned locally.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-19]
% {\seq_get_right:NN, \seq_get_right:cN}
% \begin{syntax}
-% \cs{seq_get_right:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{seq_get_right:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
% \end{syntax}
-% If the \meta{sequence} is empty, leaves the \meta{false code} in the
+% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
% input stream. The value of the \meta{token list variable} is
% not defined in this case and should not be relied upon. If the
-% \meta{sequence} is non-empty, stores the right-most item from the
-% \meta{sequence}
+% \meta{seq~var} is non-empty, stores the right-most item from the
+% \meta{seq~var}
% in the \meta{token list variable} without removing it from the
-% \meta{sequence}, then leaves the \meta{true code} in the input stream.
+% \meta{seq~var}, then leaves the \meta{true code} in the input stream.
% The \meta{token list variable} is assigned locally.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]
% {\seq_pop_left:NN, \seq_pop_left:cN}
% \begin{syntax}
-% \cs{seq_pop_left:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{seq_pop_left:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
% \end{syntax}
-% If the \meta{sequence} is empty, leaves the \meta{false code} in the
+% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
% input stream. The value of the \meta{token list variable} is
% not defined in this case and should not be relied upon. If the
-% \meta{sequence} is non-empty, pops the left-most item from the
-% \meta{sequence}
+% \meta{seq~var} is non-empty, pops the left-most item from the
+% \meta{seq~var}
% in the \meta{token list variable}, \emph{i.e.}~removes the item from the
-% \meta{sequence}, then leaves the \meta{true code} in the input stream.
-% Both the \meta{sequence} and the \meta{token list variable} are assigned
+% \meta{seq~var}, then leaves the \meta{true code} in the input stream.
+% Both the \meta{seq~var} and the \meta{token list variable} are assigned
% locally.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]
% {\seq_gpop_left:NN, \seq_gpop_left:cN}
% \begin{syntax}
-% \cs{seq_gpop_left:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{seq_gpop_left:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
% \end{syntax}
-% If the \meta{sequence} is empty, leaves the \meta{false code} in the
+% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
% input stream. The value of the \meta{token list variable} is
% not defined in this case and should not be relied upon. If the
-% \meta{sequence} is non-empty, pops the left-most item from the \meta{sequence}
+% \meta{seq~var} is non-empty, pops the left-most item from the \meta{seq~var}
% in the \meta{token list variable}, \emph{i.e.}~removes the item from the
-% \meta{sequence}, then leaves the \meta{true code} in the input stream.
-% The \meta{sequence} is modified globally, while the \meta{token list variable}
+% \meta{seq~var}, then leaves the \meta{true code} in the input stream.
+% The \meta{seq~var} is modified globally, while the \meta{token list variable}
% is assigned locally.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-19]
% {\seq_pop_right:NN, \seq_pop_right:cN}
% \begin{syntax}
-% \cs{seq_pop_right:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{seq_pop_right:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
% \end{syntax}
-% If the \meta{sequence} is empty, leaves the \meta{false code} in the
+% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
% input stream. The value of the \meta{token list variable} is
% not defined in this case and should not be relied upon. If the
-% \meta{sequence} is non-empty, pops the right-most item from the \meta{sequence}
+% \meta{seq~var} is non-empty, pops the right-most item from the \meta{seq~var}
% in the \meta{token list variable}, \emph{i.e.}~removes the item from the
-% \meta{sequence}, then leaves the \meta{true code} in the input stream.
-% Both the \meta{sequence} and the \meta{token list variable} are assigned
+% \meta{seq~var}, then leaves the \meta{true code} in the input stream.
+% Both the \meta{seq~var} and the \meta{token list variable} are assigned
% locally.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-19]
% {\seq_gpop_right:NN, \seq_gpop_right:cN}
% \begin{syntax}
-% \cs{seq_gpop_right:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{seq_gpop_right:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
% \end{syntax}
-% If the \meta{sequence} is empty, leaves the \meta{false code} in the
+% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
% input stream. The value of the \meta{token list variable} is
% not defined in this case and should not be relied upon. If the
-% \meta{sequence} is non-empty, pops the right-most item from the \meta{sequence}
+% \meta{seq~var} is non-empty, pops the right-most item from the \meta{seq~var}
% in the \meta{token list variable}, \emph{i.e.}~removes the item from the
-% \meta{sequence}, then leaves the \meta{true code} in the input stream.
-% The \meta{sequence} is modified globally, while the
+% \meta{seq~var}, then leaves the \meta{true code} in the input stream.
+% The \meta{seq~var} is modified globally, while the
% \meta{token list variable} is assigned locally.
% \end{function}
%
@@ -449,13 +449,13 @@
% \seq_gremove_duplicates:N, \seq_gremove_duplicates:c
% }
% \begin{syntax}
-% \cs{seq_remove_duplicates:N} \meta{sequence}
+% \cs{seq_remove_duplicates:N} \meta{seq~var}
% \end{syntax}
-% Removes duplicate items from the \meta{sequence}, leaving the
-% left most copy of each item in the \meta{sequence}. The \meta{item}
+% Removes duplicate items from the \meta{seq~var}, leaving the
+% left most copy of each item in the \meta{seq~var}. The \meta{item}
% comparison takes place on a token basis, as for \cs{tl_if_eq:nnTF}.
% \begin{texnote}
-% This function iterates through every item in the \meta{sequence} and
+% This function iterates through every item in the \meta{seq~var} and
% does a comparison with the \meta{items} already checked. It is therefore
% relatively slow with large sequences.
% \end{texnote}
@@ -467,9 +467,9 @@
% \seq_gremove_all:Nn, \seq_gremove_all:cn
% }
% \begin{syntax}
-% \cs{seq_remove_all:Nn} \meta{sequence} \Arg{item}
+% \cs{seq_remove_all:Nn} \meta{seq~var} \Arg{item}
% \end{syntax}
-% Removes every occurrence of \meta{item} from the \meta{sequence}.
+% Removes every occurrence of \meta{item} from the \meta{seq~var}.
% The \meta{item} comparison takes place on a token basis, as for
% \cs{tl_if_eq:nnTF}.
% \end{function}
@@ -480,12 +480,12 @@
% \cs{seq_set_item:Nnn} \meta{seq~var} \Arg{int expr} \Arg{item}
% \cs{seq_set_item:NnnTF} \meta{seq~var} \Arg{int expr} \Arg{item} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Removes the item of \meta{sequence} at the position given by
+% Removes the item of \meta{seq~var} at the position given by
% evaluating the \meta{int expr} and replaces it by
% \meta{item}. Items are indexed from $1$ on the left/top of the
-% \meta{sequence}, or from $-1$ on the right/bottom. If the
+% \meta{seq~var}, or from $-1$ on the right/bottom. If the
% \meta{int expr} is zero or is larger (in absolute value)
-% than the number of items in the sequence, the \meta{sequence} is not
+% than the number of items in the sequence, the \meta{seq~var} is not
% modified. In these cases, \cs{seq_set_item:Nnn} raises an error
% while \cs{seq_set_item:NnnTF} runs the \meta{false code}. In cases
% where the assignment was successful, \meta{true code} is run
@@ -498,19 +498,19 @@
% \seq_greverse:N, \seq_greverse:c
% }
% \begin{syntax}
-% \cs{seq_reverse:N} \meta{sequence}
+% \cs{seq_reverse:N} \meta{seq~var}
% \end{syntax}
-% Reverses the order of the items stored in the \meta{sequence}.
+% Reverses the order of the items stored in the \meta{seq~var}.
% \end{function}
%
% \begin{function}[added = 2017-02-06]
% {\seq_sort:Nn, \seq_sort:cn, \seq_gsort:Nn, \seq_gsort:cn}
% \begin{syntax}
-% \cs{seq_sort:Nn} \meta{sequence} \Arg{comparison code}
+% \cs{seq_sort:Nn} \meta{seq~var} \Arg{comparison code}
% \end{syntax}
-% Sorts the items in the \meta{sequence} according to the
+% Sorts the items in the \meta{seq~var} according to the
% \meta{comparison code}, and assigns the result to
-% \meta{sequence}. The details of sorting comparison are
+% \meta{seq~var}. The details of sorting comparison are
% described in Section~\ref{sec:l3sort:mech}.
% \end{function}
%
@@ -536,10 +536,10 @@
%
% \begin{function}[EXP,pTF]{\seq_if_empty:N, \seq_if_empty:c}
% \begin{syntax}
-% \cs{seq_if_empty_p:N} \meta{sequence}
-% \cs{seq_if_empty:NTF} \meta{sequence} \Arg{true code} \Arg{false code}
+% \cs{seq_if_empty_p:N} \meta{seq~var}
+% \cs{seq_if_empty:NTF} \meta{seq~var} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if the \meta{sequence} is empty (containing no items).
+% Tests if the \meta{seq~var} is empty (containing no items).
% \end{function}
%
% \begin{function}[TF]
@@ -548,9 +548,9 @@
% \seq_if_in:cn, \seq_if_in:cV, \seq_if_in:cv, \seq_if_in:co, \seq_if_in:cx
% }
% \begin{syntax}
-% \cs{seq_if_in:NnTF} \meta{sequence} \Arg{item} \Arg{true code} \Arg{false code}
+% \cs{seq_if_in:NnTF} \meta{seq~var} \Arg{item} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if the \meta{item} is present in the \meta{sequence}.
+% Tests if the \meta{item} is present in the \meta{seq~var}.
% \end{function}
%
% \section{Mapping over sequences}
@@ -562,10 +562,10 @@
% \begin{function}[rEXP, updated = 2012-06-29]
% {\seq_map_function:NN, \seq_map_function:cN}
% \begin{syntax}
-% \cs{seq_map_function:NN} \meta{sequence} \meta{function}
+% \cs{seq_map_function:NN} \meta{seq~var} \meta{function}
% \end{syntax}
% Applies \meta{function} to every \meta{item} stored in the
-% \meta{sequence}. The \meta{function} will receive one argument for
+% \meta{seq~var}. The \meta{function} will receive one argument for
% each iteration. The \meta{items} are returned from left to right.
% To pass further arguments to the \meta{function}, see
% \cs{seq_map_tokens:Nn}.
@@ -577,10 +577,10 @@
% \begin{function}[updated = 2012-06-29]
% {\seq_map_inline:Nn, \seq_map_inline:cn}
% \begin{syntax}
-% \cs{seq_map_inline:Nn} \meta{sequence} \Arg{inline function}
+% \cs{seq_map_inline:Nn} \meta{seq~var} \Arg{inline function}
% \end{syntax}
% Applies \meta{inline function} to every \meta{item} stored
-% within the \meta{sequence}. The \meta{inline function} should
+% within the \meta{seq~var}. The \meta{inline function} should
% consist of code which will receive the \meta{item} as |#1|.
% The \meta{items} are returned from left to right.
% \end{function}
@@ -588,15 +588,15 @@
% \begin{function}[rEXP, added = 2019-08-30]
% {\seq_map_tokens:Nn, \seq_map_tokens:cn}
% \begin{syntax}
-% \cs{seq_map_tokens:Nn} \meta{sequence} \Arg{code}
+% \cs{seq_map_tokens:Nn} \meta{seq~var} \Arg{code}
% \end{syntax}
% Analogue of \cs{seq_map_function:NN} which maps several tokens
% instead of a single function. The \meta{code} receives each item in
-% the \meta{sequence} as a trailing brace group. For instance,
+% the \meta{seq~var} as a trailing brace group. For instance,
% \begin{verbatim}
% \seq_map_tokens:Nn \l_my_seq { \prg_replicate:nn { 2 } }
% \end{verbatim}
-% expands to twice each item in the \meta{sequence}: for each item in
+% expands to twice each item in the \meta{seq~var}: for each item in
% |\l_my_seq| the function \cs{prg_replicate:nn} receives |2| and
% \meta{item} as its two arguments. The function
% \cs{seq_map_inline:Nn} is typically faster but it is not expandable.
@@ -608,14 +608,14 @@
% \seq_map_variable:cNn, \seq_map_variable:ccn
% }
% \begin{syntax}
-% \cs{seq_map_variable:NNn} \meta{sequence} \meta{variable} \Arg{code}
+% \cs{seq_map_variable:NNn} \meta{seq~var} \meta{variable} \Arg{code}
% \end{syntax}
-% Stores each \meta{item} of the \meta{sequence} in turn in the (token
+% Stores each \meta{item} of the \meta{seq~var} in turn in the (token
% list) \meta{variable} and applies the \meta{code}. The \meta{code}
% will usually make use of the \meta{variable}, but this is not
% enforced. The assignments to the \meta{variable} are local. Its
-% value after the loop is the last \meta{item} in the \meta{sequence},
-% or its original value if the \meta{sequence} is empty. The
+% value after the loop is the last \meta{item} in the \meta{seq~var},
+% or its original value if the \meta{seq~var} is empty. The
% \meta{items} are returned from left to right.
% \end{function}
%
@@ -662,7 +662,7 @@
% \cs{seq_map_break:}
% \end{syntax}
% Used to terminate a \cs[no-index]{seq_map_\ldots} function before all
-% entries in the \meta{sequence} have been processed. This
+% entries in the \meta{seq~var} have been processed. This
% normally takes place within a conditional statement, for example
% \begin{verbatim}
% \seq_map_inline:Nn \l_my_seq
@@ -689,7 +689,7 @@
% \cs{seq_map_break:n} \Arg{code}
% \end{syntax}
% Used to terminate a \cs[no-index]{seq_map_\ldots} function before all
-% entries in the \meta{sequence} have been processed, inserting
+% entries in the \meta{seq~var} have been processed, inserting
% the \meta{code} after the mapping has ended. This
% normally takes place within a conditional statement, for example
% \begin{verbatim}
@@ -715,13 +715,13 @@
% \begin{function}[added = 2011-12-22, updated = 2020-07-16]
% {\seq_set_map:NNn, \seq_gset_map:NNn}
% \begin{syntax}
-% \cs{seq_set_map:NNn} \meta{sequence_1} \meta{sequence_2} \Arg{inline function}
+% \cs{seq_set_map:NNn} \meta{seq~var_1} \meta{seq~var_2} \Arg{inline function}
% \end{syntax}
% Applies \meta{inline function} to every \meta{item} stored
-% within the \meta{sequence_2}. The \meta{inline function} should
+% within the \meta{seq~var_2}. The \meta{inline function} should
% consist of code which will receive the \meta{item} as |#1|.
% The sequence resulting applying \meta{inline function} to each
-% \meta{item} is assigned to \meta{sequence_1}.
+% \meta{item} is assigned to \meta{seq~var_1}.
% \begin{texnote}
% Contrarily to other mapping functions, \cs{seq_map_break:} cannot
% be used in this function, and would lead to low-level \TeX{} errors.
@@ -731,14 +731,14 @@
% \begin{function}[added = 2020-07-16]
% {\seq_set_map_x:NNn, \seq_gset_map_x:NNn}
% \begin{syntax}
-% \cs{seq_set_map_x:NNn} \meta{sequence_1} \meta{sequence_2} \Arg{inline function}
+% \cs{seq_set_map_x:NNn} \meta{seq~var_1} \meta{seq~var_2} \Arg{inline function}
% \end{syntax}
% Applies \meta{inline function} to every \meta{item} stored
-% within the \meta{sequence_2}. The \meta{inline function} should
+% within the \meta{seq~var_2}. The \meta{inline function} should
% consist of code which will receive the \meta{item} as |#1|.
% The sequence resulting from \texttt{x}-expanding
% \meta{inline function} applied to each \meta{item}
-% is assigned to \meta{sequence_1}. As such, the code
+% is assigned to \meta{seq~var_1}. As such, the code
% in \meta{inline function} should be expandable.
% \begin{texnote}
% Contrarily to other mapping functions, \cs{seq_map_break:} cannot
@@ -748,12 +748,12 @@
%
% \begin{function}[EXP, added = 2012-07-13]{\seq_count:N, \seq_count:c}
% \begin{syntax}
-% \cs{seq_count:N} \meta{sequence}
+% \cs{seq_count:N} \meta{seq~var}
% \end{syntax}
-% Leaves the number of items in the \meta{sequence} in the input
+% Leaves the number of items in the \meta{seq~var} in the input
% stream as an \meta{integer denotation}. The total number of items
-% in a \meta{sequence} includes those which are empty and duplicates,
-% \emph{i.e.}~every item in a \meta{sequence} is unique.
+% in a \meta{seq~var} includes those which are empty and duplicates,
+% \emph{i.e.}~every item in a \meta{seq~var} is unique.
% \end{function}
%
% \section{Using the content of sequences directly}
@@ -825,71 +825,71 @@
%
% \begin{function}[updated = 2012-05-14]{\seq_get:NN, \seq_get:cN}
% \begin{syntax}
-% \cs{seq_get:NN} \meta{sequence} \meta{token list variable}
+% \cs{seq_get:NN} \meta{seq~var} \meta{token list variable}
% \end{syntax}
-% Reads the top item from a \meta{sequence} into the
+% Reads the top item from a \meta{seq~var} into the
% \meta{token list variable} without removing it from the
-% \meta{sequence}. The \meta{token list variable} is assigned locally.
-% If \meta{sequence} is empty the \meta{token list variable} is set to
+% \meta{seq~var}. The \meta{token list variable} is assigned locally.
+% If \meta{seq~var} is empty the \meta{token list variable} is set to
% the special marker \cs{q_no_value}.
% \end{function}
%
% \begin{function}[updated = 2012-05-14]{\seq_pop:NN, \seq_pop:cN}
% \begin{syntax}
-% \cs{seq_pop:NN} \meta{sequence} \meta{token list variable}
+% \cs{seq_pop:NN} \meta{seq~var} \meta{token list variable}
% \end{syntax}
-% Pops the top item from a \meta{sequence} into the
+% Pops the top item from a \meta{seq~var} into the
% \meta{token list variable}. Both of the variables are assigned
-% locally. If \meta{sequence} is empty the \meta{token list variable}
+% locally. If \meta{seq~var} is empty the \meta{token list variable}
% is set to the special marker \cs{q_no_value}.
% \end{function}
%
% \begin{function}[updated = 2012-05-14]{\seq_gpop:NN, \seq_gpop:cN}
% \begin{syntax}
-% \cs{seq_gpop:NN} \meta{sequence} \meta{token list variable}
+% \cs{seq_gpop:NN} \meta{seq~var} \meta{token list variable}
% \end{syntax}
-% Pops the top item from a \meta{sequence} into the
-% \meta{token list variable}. The \meta{sequence} is modified globally,
+% Pops the top item from a \meta{seq~var} into the
+% \meta{token list variable}. The \meta{seq~var} is modified globally,
% while the \meta{token list variable} is assigned locally. If
-% \meta{sequence} is empty the \meta{token list variable} is set to
+% \meta{seq~var} is empty the \meta{token list variable} is set to
% the special marker \cs{q_no_value}.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]{\seq_get:NN, \seq_get:cN}
% \begin{syntax}
-% \cs{seq_get:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{seq_get:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
% \end{syntax}
-% If the \meta{sequence} is empty, leaves the \meta{false code} in the
+% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
% input stream. The value of the \meta{token list variable} is
% not defined in this case and should not be relied upon. If the
-% \meta{sequence} is non-empty, stores the top item from a
-% \meta{sequence} in the \meta{token list variable} without removing it from
-% the \meta{sequence}. The \meta{token list variable} is assigned locally.
+% \meta{seq~var} is non-empty, stores the top item from a
+% \meta{seq~var} in the \meta{token list variable} without removing it from
+% the \meta{seq~var}. The \meta{token list variable} is assigned locally.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]{\seq_pop:NN, \seq_pop:cN}
% \begin{syntax}
-% \cs{seq_pop:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{seq_pop:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
% \end{syntax}
-% If the \meta{sequence} is empty, leaves the \meta{false code} in the
+% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
% input stream. The value of the \meta{token list variable} is
% not defined in this case and should not be relied upon. If the
-% \meta{sequence} is non-empty, pops the top item from the
-% \meta{sequence} in the \meta{token list variable}, \emph{i.e.}~removes the
-% item from the \meta{sequence}. Both the \meta{sequence} and the
+% \meta{seq~var} is non-empty, pops the top item from the
+% \meta{seq~var} in the \meta{token list variable}, \emph{i.e.}~removes the
+% item from the \meta{seq~var}. Both the \meta{seq~var} and the
% \meta{token list variable} are assigned locally.
% \end{function}
%
% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]{\seq_gpop:NN, \seq_gpop:cN}
% \begin{syntax}
-% \cs{seq_gpop:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code}
+% \cs{seq_gpop:NNTF} \meta{seq~var} \meta{token list variable} \Arg{true code} \Arg{false code}
% \end{syntax}
-% If the \meta{sequence} is empty, leaves the \meta{false code} in the
+% If the \meta{seq~var} is empty, leaves the \meta{false code} in the
% input stream. The value of the \meta{token list variable} is
% not defined in this case and should not be relied upon. If the
-% \meta{sequence} is non-empty, pops the top item from the \meta{sequence}
+% \meta{seq~var} is non-empty, pops the top item from the \meta{seq~var}
% in the \meta{token list variable}, \emph{i.e.}~removes the item from the
-% \meta{sequence}. The \meta{sequence} is modified globally, while the
+% \meta{seq~var}. The \meta{seq~var} is modified globally, while the
% \meta{token list variable} is assigned locally.
% \end{function}
%
@@ -903,9 +903,9 @@
% \seq_gpush:co, \seq_gpush:cx
% }
% \begin{syntax}
-% \cs{seq_push:Nn} \meta{sequence} \Arg{item}
+% \cs{seq_push:Nn} \meta{seq~var} \Arg{item}
% \end{syntax}
-% Adds the \Arg{item} to the top of the \meta{sequence}.
+% Adds the \Arg{item} to the top of the \meta{seq~var}.
% \end{function}
%
% \section{Sequences as sets}
@@ -1026,16 +1026,16 @@
%
% \begin{function}[updated = 2021-04-29]{\seq_show:N, \seq_show:c}
% \begin{syntax}
-% \cs{seq_show:N} \meta{sequence}
+% \cs{seq_show:N} \meta{seq~var}
% \end{syntax}
-% Displays the entries in the \meta{sequence} in the terminal.
+% Displays the entries in the \meta{seq~var} in the terminal.
% \end{function}
%
% \begin{function}[added = 2014-08-12, updated = 2021-04-29]{\seq_log:N, \seq_log:c}
% \begin{syntax}
-% \cs{seq_log:N} \meta{sequence}
+% \cs{seq_log:N} \meta{seq~var}
% \end{syntax}
-% Writes the entries in the \meta{sequence} in the log file.
+% Writes the entries in the \meta{seq~var} in the log file.
% \end{function}
%
% \end{documentation}
diff --git a/macros/latex/contrib/l3kernel/l3skip.dtx b/macros/latex/contrib/l3kernel/l3skip.dtx
index 8b2af6bb35..bf174f74dd 100644
--- a/macros/latex/contrib/l3kernel/l3skip.dtx
+++ b/macros/latex/contrib/l3kernel/l3skip.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -503,7 +503,8 @@
% one \enquote{big point} when converted to (\TeX{}) points.
% \end{function}
%
-% \begin{function}[added = 2014-07-15, EXP]{\dim_to_decimal_in_bp:n}
+% \begin{function}[added = 2014-07-15, updated = 2023-05-20, EXP]
+% {\dim_to_decimal_in_bp:n}
% \begin{syntax}
% \cs{dim_to_decimal_in_bp:n} \Arg{dim expr}
% \end{syntax}
@@ -519,6 +520,59 @@
% \end{verbatim}
% leaves |0.99628| in the input stream, \emph{i.e.}~the magnitude of
% one (\TeX{}) point when converted to big points.
+% \begin{texnote}
+% The implementation of this functions is re-entrant: the result of
+% \begin{verbatim}
+% \dim_to_decimal_in_bp:n { <n>bp }
+% \end{verbatim}
+% will be the value \meta{n}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[added = 2023-05-20, EXP]
+% {
+% \dim_to_decimal_in_cc:n ,
+% \dim_to_decimal_in_cm:n ,
+% \dim_to_decimal_in_dd:n ,
+% \dim_to_decimal_in_in:n ,
+% \dim_to_decimal_in_mm:n ,
+% \dim_to_decimal_in_pc:n
+% }
+% \begin{syntax}
+% \cs{dim_to_decimal_in_cm:n} \Arg{dim expr}
+% \end{syntax}
+% Evaluates the \meta{dim expr}, and leaves the result,
+% expressed with the appropriate scaling in the input stream, with
+% \emph{no units}. If the decimal part of the result is zero, it is omitted,
+% together with the decimal marker. The precisions of the result is limited
+% to a maximum of five decimal places with trailing zeros omitted.
+%
+% The maximum \TeX{} allowable dimension value (available as
+% \tn{maxdimen} in plain \TeX{} and \LaTeX{} and \cs{c_max_dim} in
+% \pkg{expl3}) can only be expressed exactly in the units
+% \texttt{pt}, \texttt{bp} and \texttt{sp}. Expressed in different units,
+% the maximum allowable input value to five decimal places is\\
+% \begin{center}
+% \begin{tabular}{@{}>{$}r<{$}@{\,}l@{}}
+% 1276.00215 & cc \\
+% 575.83174 & cm \\
+% 226.70540 & in \\
+% 15312.02584 & dd \\
+% 5758.31742 & mm \\
+% 1365.33333 & pc \\
+% \end{tabular}
+% \end{center}
+% Values given to five decimal places larger that these will result in \TeX{}
+% errors; the behavior if additional decimal places are given depends on the
+% \TeX{} internals and thus larger values are \emph{not} supported by
+% \pkg{expl3}.
+% \begin{texnote}
+% The implementation of this functions is re-entrant: the result of
+% \begin{verbatim}
+% \dim_to_decimal_in_<unit>:n { <n><unit> }
+% \end{verbatim}
+% will be the value \meta{n}.
+% \end{texnote}
% \end{function}
%
% \begin{function}[added = 2015-05-18, EXP]{\dim_to_decimal_in_sp:n}
@@ -537,23 +591,25 @@
% \end{syntax}
% Evaluates the \meta{dim exprs}, and leaves the value of
% \meta{dim expr_1}, expressed in a unit given by \meta{dim expr_2}, in
-% the input stream. The result is a decimal number, rounded by \TeX{}
-% to four or five decimal places. If the decimal part of the result
+% the input stream. If the decimal part of the result
% is zero, it is omitted, together with the decimal marker.
+% The precisions of the result is limited
+% to a maximum of five decimal places with trailing zeros omitted.
%
% For example
% \begin{verbatim}
% \dim_to_decimal_in_unit:nn { 1bp } { 1mm }
% \end{verbatim}
-% leaves |0.35277| in the input stream, \emph{i.e.}~the magnitude of
-% one big point when converted to millimetres.
-%
-% Note that this function is not optimised for any particular output
-% and as such may give different results to \cs{dim_to_decimal_in_bp:n}
-% or \cs{dim_to_decimal_in_sp:n}. In particular, the latter is able to
-% take a wider range of input values as it is not limited by the ability
-% to calculate a ratio using \eTeX{} primitives, which is required
-% internally by \cs{dim_to_decimal_in_unit:nn}.
+% leaves |0.35278| in the input stream, \emph{i.e.}~the magnitude of
+% one big point when expressed in millimetres. The conversions do
+% \emph{not} guarantee that \TeX{} would yield identical results
+% for the direct input in an equality test, hence
+% \begin{verbatim}
+% \dim_compare:nNnTF
+% { \dim_to_decimal_in_unit:nn { 1bp } { 1mm } mm }
+% { 1bp }
+% \end{verbatim}
+% will take the \texttt{false} branch.
% \end{function}
%
% \begin{function}[EXP, added = 2012-05-08, tested = m3fp-convert002]
@@ -1683,44 +1739,334 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}[EXP]{\dim_to_decimal_in_bp:n}
-% Conversion to big points is done using a scaling inside \cs{@@_eval:w}
-% as \eTeX{} does that using $64$-bit precision. Here, $800/803$ is the
-% integer fraction for $72/72.27$. This is a common case so is hand-coded
-% for accuracy (and speed).
-% \begin{macrocode}
-\cs_new:Npn \dim_to_decimal_in_bp:n #1
- { \dim_to_decimal:n { ( #1 ) * 800 / 803 } }
-% \end{macrocode}
+% \begin{macro}[EXP]{\dim_to_fp:n}
+% Defined in \pkg{l3fp-convert}, documented here.
% \end{macro}
%
+% \subsection{Conversion of \texttt{dim} to other units}
+%
+% The conversion from \texttt{pt} or \texttt{sp} to other units is complicated
+% by the fact that \TeX{}'s conversion to \texttt{sp} involves rounding and
+% hard-coded ratios. In order to give re-entrant outcomes, we therefore need
+% to do quite a bit of work: see
+% \url{https://github.com/latex3/latex3/issues/954} for detailed discussion.
+% After dealing with the trivial case, we therefore have some work to do.
+% The code to do this is contributed by Ruixi Zhang.
+%
% \begin{macro}[EXP]{\dim_to_decimal_in_sp:n}
-% Another hard-coded conversion: this one is necessary to avoid things going
-% off-scale.
+% The one eeasy case: the only requirement here is that we avoid an
+% overflow.
% \begin{macrocode}
\cs_new:Npn \dim_to_decimal_in_sp:n #1
{ \int_value:w \@@_eval:w #1 \@@_eval_end: }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[EXP]{\dim_to_decimal_in_unit:nn}
-% An analogue of \cs{dim_ratio:nn} that produces a decimal number as its
-% result, rather than a rational fraction for use within dimension
-% expressions.
+% \begin{macro}[EXP]
+% {
+% \dim_to_decimal_in_bp:n ,
+% \dim_to_decimal_in_cc:n ,
+% \dim_to_decimal_in_cm:n ,
+% \dim_to_decimal_in_dd:n ,
+% \dim_to_decimal_in_in:n ,
+% \dim_to_decimal_in_mm:n ,
+% \dim_to_decimal_in_pc:n
+% }
+% \begin{macro}[EXP]{\@@_to_decimal_aux:w}
+% We first set up a helper macro \cs[no-index]{@@_tmp:w} which takes two
+% arguments. The first argument is one of the following engine-defined
+% units: |in|,~|pc|, |cm|, |mm|, |bp|, |dd|, |cc|, |nd|, and~|nc|.
+% The second argument is $\frac{1}{2}\delta^{-1}$ in reduced fraction,
+% where $\delta>1$~is the engine-defined conversion factor for each unit.
+% Note that $\delta$~must be strictly larger than~$1$ for the following
+% algorithm to work.
+%
+% Here is how the algorithm works: Suppose that a user inputs a
+% non-negative dimension in a unit that has conversion factor~$\delta>1$.
+% Then this dimension is internally represented as $X$\,sp, where
+% $X=\lfloor N\delta\rfloor$ for some integer $N\ge0$. We then seek a
+% formula to express this $N$ using~$X$.
+% The \cs[no-index]{dim_to_decimal_in_<unit>:n} functions shall return
+% the number $N/2^{16}$ in decimal. This way, we guarantee the returned
+% decimal followed by the original unit will parse to exactly~$X$\,sp.
+%
+% So how do we get $N$ from~$X$? Well, since $X=\lfloor N\delta\rfloor$,
+% we have $X\le N\delta<X+1$ and $X\delta^{-1}\le N<(X+1)\delta^{-1}$.
+% Let's focus on the midpoint of this bounding interval for~$N$. The
+% midpoint is $(X+\frac{1}{2})\delta^{-1}$. The fact $\delta>1$ implies
+% that the bounding interval is shorter than~$1$ in length. Thus,
+% (1)~$\hbox{midpoint}+\frac{1}{2}>N$ and
+% (2)~$\hbox{midpoint}+\frac{1}{2}<N+1$. In other words,
+% $N=\lfloor\hbox{midpoint}+\frac{1}{2}\rfloor$. As long as we can
+% rewrite the midpoint as the result of a ``scaling operation'' of \eTeX,
+% the $\lfloor\ldots+\frac{1}{2}\rfloor$ part will follow naturally.
+% Indeed we can: $\hbox{midpoint}=(2X+1)\times(\frac{1}{2}\delta^{-1})$.
+%
+% Addendum: If $\delta\ge2$, then the bounding interval for~$N$ is at
+% most~$\frac{1}{2}$ wide in length. In this case, the leftpoint
+% $X\delta^{-1}$ suffices as $N=\lfloor X\delta^{-1}+\frac{1}{2}\rfloor$.
+% Six out of the nine units listed above can be handled in this way,
+% which is much simpler than using midpoint. But three remaining units
+% have $1<\delta<2$; they are |bp|~($\delta=7227/7200$),
+% |nd|~($\delta=685/642$), and |dd|~($\delta=1238/1157$),
+% and these three must be handled using midpoint.
+% For consistency, we shall use the midpoint approach for all nine units.
+% \begin{macrocode}
+\group_begin:
+ \cs_set_protected:Npn \@@_tmp:w #1#2
+ {
+ \cs_new:cpn { dim_to_decimal_in_ #1 :n } ##1
+ {
+ \exp_after:wN \@@_to_decimal_aux:w
+ \int_value:w \@@_eval:w ##1 \@@_eval_end: ; #2 ;
+ }
+ }
+% \end{macrocode}
+% Conversions to other units are now coded.
+% Consult the pdf\/\TeX{} source for each conversion factor~$\delta$.
+% Each factor $\frac{1}{2}\delta^{-1}$ is hand-coded
+% for accuracy (and speed).
% \begin{macrocode}
-\cs_new:Npn \dim_to_decimal_in_unit:nn #1#2
+ \@@_tmp:w { in } { 50 / 7227 } % delta = 7227/100
+ \@@_tmp:w { pc } { 1 / 24 } % delta = 12/1
+ \@@_tmp:w { cm } { 127 / 7227 } % delta = 7227/254
+ \@@_tmp:w { mm } { 1270 / 7227 } % delta = 7227/2540
+ \@@_tmp:w { bp } { 400 / 803 } % delta = 7227/7200
+ \@@_tmp:w { dd } { 1157 / 2476 } % delta = 1238/1157
+ \@@_tmp:w { cc } { 1157 / 29712 } % delta = 14856/1157
+\group_end:
+% \end{macrocode}
+% The tokens after \cs{@@_to_decimal_aux:w} shall have the following form:
+% |<number>;<half of delta inverse>;|, where |<number>| represents the
+% input dimension in |sp| unit.
+% If |<number>| is positive, then |#1| is its leading digit and |#2|
+% (possibly empty) is all the remaining digits;
+% If |<number>| is zero, then |#1| is~|0|$_{12}$ and |#2| is empty;
+% If |<number>| is negative, then |#1| is its sign~|-|$_{12}$ and |#2|
+% is all its digits.
+% In all three cases, |#1#2| is the original |<number>|. We can use |#1|
+% to decide whether to use the |-1| formula or the |+1| formula.
+% \begin{macrocode}
+\cs_new:Npn \@@_to_decimal_aux:w #1#2 ; #3 ;
{
\dim_to_decimal:n
{
- 1pt *
- \dim_ratio:nn {#1} {#2}
+% \end{macrocode}
+% We need different formulae depending on whether the user input dimension
+% is negative or not.
+% For negative dimension (internally represented as $X$\,sp), the formula
+% is $(2X-1)\times(\frac{1}{2}\delta^{-1})$.
+% For non-negative dimension, the formula
+% is $(2X+1)\times(\frac{1}{2}\delta^{-1})$.
+% The intermediate step doubles the dimension~$X$.
+% To avoid overflow, we must invoke \cs[no-index]{int_eval:n}.
+% \begin{macrocode}
+ \int_eval:n
+ { ( 2 * #1#2 \if:w #1 - - \else: + \fi: 1 ) * #3 }
+% \end{macrocode}
+% Now we append~|sp| to finish the dimension specification.
+% \begin{macrocode}
+ sp
}
}
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
-% \begin{macro}[EXP]{\dim_to_fp:n}
-% Defined in \pkg{l3fp-convert}, documented here.
+% \begin{macro}[EXP]{\dim_to_decimal_in_unit:nn}
+% \begin{macrocode}
+\cs_new:Npn \dim_to_decimal_in_unit:nn #1#2
+ {
+ \exp_after:wN \@@_chk_unit:w
+ \int_value:w \@@_eval:w #2 \@@_eval_end: ; {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_chk_unit:w}
+% The tokens after \cs{@@_chk_unit:w} shall have the following form:
+% |<number2>;{<dimexpr1>}|, where |<number2>| represents |<dimexpr2>| in
+% |sp| unit.
+% If |#1| is~|0|$_{12}$, the \enquote{unit} |<dimexpr2>| must also be zero.
+% So we throw out a ``division by zero'' error message at this point.
+% Otherwise, if |#1| is~|-|$_{12}$, we shall negate both |<dimexpr1>| and
+% |<dimexpr2>| for later procedures.
+% \begin{macrocode}
+\cs_new:Npn \@@_chk_unit:w #1#2;#3
+ {
+ \token_if_eq_charcode:NNTF #1 0
+ { \msg_expandable_error:nn { dim } { zero-unit } }
+ {
+ \exp_after:wN \@@_branch_unit:w
+ \int_value:w \if:w #1 - - \fi: \@@_eval:w #3 \exp_after:wN ;
+ \int_value:w \if:w #1 - - \fi: #1#2 ;
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_branch_unit:w}
+% The tokens after \cs{@@_branch_unit:w} shall have the following form:
+% |<number1>;<number2>;|, where |<number1>| represents |<dimexpr1>| in
+% |sp| unit (whose sign is taken care of) and |<number2>| represents the
+% absolute value of |<dimexpr2>| in |sp| unit (which is strictly positive).
+%
+% As explained, the formulae $(2X\pm1)\times(\frac{1}{2}\delta^{-1})$ work
+% if and only if $\delta=|<number2>|/65536>1$. This corresponds to
+% |<dimexpr2>| strictly larger than 1\,pt in absolute value.
+% In this case, we simply call \cs{@@_to_decimal_aux:w} and supply
+% $\frac{1}{2}\delta^{-1}=32768/|<number2>|$ as |<half of delta inverse>|.
+%
+% Otherwise if $|<number2>|=65536$, then |<dimexpr2>| is 1\,pt in absolute
+% value and we call \cs{dim_to_decimal:n} directly.
+%
+% Otherwise $0<|<number2>|<65536$ and we shall proceed differently.
+%
+% For unit less than 1\,pt, write $n=|<number2>|$, then $\delta=n/65536<1$.
+% The midpoint formulae are not optimal. Let's go back to the inequalities
+% $X\delta^{-1}\le N<(X+1)\delta^{-1}$. Since now $\delta<1$, the bounding
+% interval is wider than~$1$ in length. Consider the ceiling integer
+% $M=\lceil X\delta^{-1}\rceil$, then $X\delta^{-1}\le M<(X+1)\delta^{-1}$,
+% or equivalently $X\le M\delta<X+1$, and thus $\lfloor M\delta\rfloor=X$.
+% The key point here is that we \emph{don't} need to solve for~$N$;
+% in fact, any integer that can reproduce~$X$ (such as~$M$) is good enough.
+% So the algorithm goes like this: (1)~Compute rounding of $X\delta^{-1}$,
+% i.e., $M'=\lfloor X\delta^{-1}+\frac{1}{2}\rfloor$; this $M'$ could be
+% either $M$ or $M-1$. (2)~Check if $\lfloor M'\delta\rfloor=X$, i.e.,
+% whether our candidate $M'$ can reproduce~$X$. If so, then this $M'$ is
+% good enough; if not, then we add one to~$M'$.
+%
+% But when $0<n<65536$, we cannot delay the problem of overflow any more.
+% For $X\delta^{-1}=X\times65536/n$, where $X$ can go up to $2^{30}-1$ and
+% $n$ can be as small as~$1$, the result is well over $2^{31}-1$ (largest
+% integer allowed within |\numexpr|).
+% For example, |\dim_to_decimal_in_unit:nn { \maxdimen } { 1sp }|.
+% Here, all inputs are legal, so we should be able to output |1073741823|
+% \emph{without} causing arithmetic overflow.
+%
+% As a workaround, let's write $X=qn+r$ with some $q\ge0$ and $0\le r<n$.
+% Then $X\delta^{-1}=65536q+65536r/n$, and so
+% $M'=65536q+\lfloor65536r/n+\frac{1}{2}\rfloor=65536q+R'$.
+% Computing $R'$ will never overflow. If this $R'$ can reproduce~$r$, then
+% it is good enough; otherwise we add one to~$R'$. In the end, we shall
+% output $q+R'/65536$ in decimal.
+%
+% Note: $q=\lfloor X/n\rfloor=\lfloor\frac{2X-n}{2n}+\frac{1}{2}\rfloor$
+% represents the ``integer'' part, while $0\le R'\le65536$ represents the
+% ``fractional'' part. (Can $R'=65536$ really happen? Didn't investigate.)
+% \begin{macrocode}
+\cs_new:Npn \@@_branch_unit:w #1;#2;
+ {
+ \int_compare:nNnTF {#2} > { 65536 }
+ { \@@_to_decimal_aux:w #1 ; 32768 / #2 ; }
+ {
+ \int_compare:nNnTF {#2} = { 65536 }
+ { \dim_to_decimal:n { #1sp } }
+ { \@@_get_quotient:w #1 ; #2 ; }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_get_quotient:w}
+% We wish to get the quotient $q$ via rounding of $\frac{2X-n}{2n}$.
+% When $0\le X<n/2$, we have $\frac{2X-n}{2n}<0$. So, strictly speaking,
+% |\numexpr| performs its rounding as
+% $\lceil\frac{2X-n}{2n}-\frac{1}{2}\rceil$, not exactly what we want.
+% However, lucky for us, only $X=0$ makes
+% $\lceil\frac{2X-n}{2n}-\frac{1}{2}\rceil=-1\neq0$ (we want~$0$);
+% all other $0<X<n/2$ make $\lceil\frac{2X-n}{2n}-\frac{1}{2}\rceil=0=q$.
+% Thus, let's filter out $X=0$ early.
+% If $X\neq0$, we extract its sign and leave the sign to the back.
+% The sign does not participate in any calculations (also the code works
+% with positive integers only). The sign is used at the last stages when
+% we parse the decimal output.
+%
+% After \cs{@@_get_quotient:w} has done its job, either we have the
+% decimal~|0|, or we have \cs{@@_get_remainder:w} followed by
+% $q$|;|$\lvert X\rvert$|;|$n$|;<sign of X>;|.
+% \begin{macrocode}
+\cs_new:Npn \@@_get_quotient:w #1#2;#3;
+ {
+ \token_if_eq_charcode:NNTF #1 0
+ { 0 }
+ {
+ \token_if_eq_charcode:NNTF #1 -
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_get_remainder:w
+ \int_eval:w ( 2 * #2 - #3 ) / ( 2 * #3 ) ;
+ #2 ; #3 ; - ;
+ }
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_get_remainder:w
+ \int_eval:w ( 2 * #1#2 - #3 ) / ( 2 * #3 ) ;
+ #1#2 ; #3 ; ;
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_get_remainder:w}
+% \cs{@@_get_remainder:w} does not need to read the sign.
+% After finding the remainder~$r$, the number~$\lvert X\rvert$ is no longer
+% needed. We should then have \cs{@@_convert_remainder:w} followed by
+% $r$|;|$n$|;|$q$|;<sign of X>;|.
+% \begin{macrocode}
+\cs_new:Npn \@@_get_remainder:w #1;#2;#3;
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_convert_remainder:w
+ \int_eval:w #2 - #1 * #3 ;
+ #3 ; #1 ;
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_convert_remainder:w}
+% This is trivial. We compute $R'=\lfloor65536r/n+\frac{1}{2}\rfloor$,
+% then leave \cs{@@_test_candidate:w} followed by
+% $R'$|;|$r$|;|$n$|;|$q$|;<sign of X>;|.
+% \begin{macrocode}
+\cs_new:Npn \@@_convert_remainder:w #1;#2;
+ {
+ \exp_after:wN \exp_after:wN \exp_after:wN \@@_test_candidate:w
+ \int_eval:w #1 * 65536 / #2 ;
+ #1 ; #2 ;
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_test_candidate:w}
+% Now the fun part: We take $R'$, $r$ and~$n$ to test whether
+% $r=\lfloor R'\delta\rfloor$. This is done as a dimension comparison.
+% The left-hand side, $r$, is simply |r sp|. The right-hand side,
+% $\lfloor R'\delta\rfloor$, is exactly |<R' as decimal><dimen = n sp>|.
+% If the result is true, then we've found~$R'$;
+% otherwise we add one to~$R'$.
+% After this step, $r$ and~$n$ are no longer needed. We should then have
+% \cs{@@_parse_decimal:w} followed by $R'$|;|$q$|;<sign of X>;|.
+% \begin{macrocode}
+\cs_new:Npn \@@_test_candidate:w #1;#2;#3;
+ {
+ \dim_compare:nNnTF { #2sp } =
+ { \dim_to_decimal:n { #1sp } \@@_eval:w #3sp \@@_eval_end: }
+ { \@@_parse_decimal:w #1 ; }
+ {
+ \exp_after:wN \@@_parse_decimal:w
+ \int_eval:w #1 + 1 ;
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[EXP]{\@@_parse_decimal:w, \@@_parse_decimal_aux:w}
+% The Grand Finale: We sum $q$ and $R'/65536$ together, and negate the
+% result if necessary. These are all done expandably.
+% If $0<R'/65536<1$, the integer summation is naturally terminated at the
+% decimal point. If $R'/65536=0$ (or~$1$?), the summation is terminated
+% at the semicolon. The auxiliary function \cs{@@_parse_decimal_aux:w}
+% takes care of both cases.
+% \begin{macrocode}
+\cs_new:Npn \@@_parse_decimal:w #1;#2;#3;
+ {
+ \exp_after:wN \@@_parse_decimal_aux:w
+ \int_value:w #3 \int_eval:w #2 + \dim_to_decimal:n { #1sp } ;
+ }
+\cs_new:Npn \@@_parse_decimal_aux:w #1 ; {#1}
+% \end{macrocode}
% \end{macro}
%
% \subsection{Viewing \texttt{dim} variables}
diff --git a/macros/latex/contrib/l3kernel/l3sort.dtx b/macros/latex/contrib/l3kernel/l3sort.dtx
index 5f2b7335bc..e73b6b39ab 100644
--- a/macros/latex/contrib/l3kernel/l3sort.dtx
+++ b/macros/latex/contrib/l3kernel/l3sort.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3str-convert.dtx b/macros/latex/contrib/l3kernel/l3str-convert.dtx
index 5608305e28..2f2c4f36c7 100644
--- a/macros/latex/contrib/l3kernel/l3str-convert.dtx
+++ b/macros/latex/contrib/l3kernel/l3str-convert.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -1717,14 +1717,14 @@
}
\prg_new_conditional:Npnn \@@_if_escape_url:n #1 { TF }
{
- \if_int_compare:w `#1 < "41 \exp_stop_f:
- \@@_if_contains_char:nnTF { "-.<> } {#1}
+ \if_int_compare:w `#1 < "30 \exp_stop_f:
+ \@@_if_contains_char:nnTF { "-. } {#1}
\prg_return_true: \prg_return_false:
\else:
\if_int_compare:w `#1 > "7E \exp_stop_f:
\prg_return_false:
\else:
- \@@_if_contains_char:nnTF { [ ] } {#1}
+ \@@_if_contains_char:nnTF { : ; = ? @ [ ] } {#1}
\prg_return_false: \prg_return_true:
\fi:
\fi:
diff --git a/macros/latex/contrib/l3kernel/l3str.dtx b/macros/latex/contrib/l3kernel/l3str.dtx
index bb7c1e9f23..3322a2289d 100644
--- a/macros/latex/contrib/l3kernel/l3str.dtx
+++ b/macros/latex/contrib/l3kernel/l3str.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -787,6 +787,14 @@
% not to \texttt{\i}).
% \end{function}
%
+% \begin{function}[added = 2023-05-19, EXP]{\str_mdfive_hash:n, \str_mdfive_hash:e}
+% \begin{syntax}
+% \cs{str_mdfive_hash:n} \Arg{tl}
+% \end{syntax}
+% Expands to the MD5 sum generated from the \meta{tl}, which is converted
+% to a \meta{string} as described for \cs{tl_to_str:n}.
+% \end{function}
+%
% \section{Viewing strings}
%
% \begin{function}[added = 2015-09-18, updated = 2021-04-29]
@@ -2081,6 +2089,13 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}[EXP]{\str_mdfive_hash:n, \str_mdfive_hash:e}
+% \begin{macrocode}
+\cs_new:Npn \str_mdfive_hash:n #1 { \tex_mdfivesum:D { \tl_to_str:n {#1} } }
+\cs_new:Npn \str_mdfive_hash:e #1 { \tex_mdfivesum:D {#1} }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{variable}
% {
% \c_ampersand_str,
diff --git a/macros/latex/contrib/l3kernel/l3styleguide.pdf b/macros/latex/contrib/l3kernel/l3styleguide.pdf
index 76b087f846..1a83be2d01 100644
--- a/macros/latex/contrib/l3kernel/l3styleguide.pdf
+++ b/macros/latex/contrib/l3kernel/l3styleguide.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3styleguide.tex b/macros/latex/contrib/l3kernel/l3styleguide.tex
index 5c83920436..4c1a0087c6 100644
--- a/macros/latex/contrib/l3kernel/l3styleguide.tex
+++ b/macros/latex/contrib/l3kernel/l3styleguide.tex
@@ -32,7 +32,7 @@ The released version of this bundle is available from CTAN.
{latex-team@latex-project.org}%
}%
}
-\date{Released 2023-05-15}
+\date{Released 2023-05-22}
\begin{document}
diff --git a/macros/latex/contrib/l3kernel/l3syntax-changes.pdf b/macros/latex/contrib/l3kernel/l3syntax-changes.pdf
index 6f8bc1166d..aad08104ac 100644
--- a/macros/latex/contrib/l3kernel/l3syntax-changes.pdf
+++ b/macros/latex/contrib/l3kernel/l3syntax-changes.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3syntax-changes.tex b/macros/latex/contrib/l3kernel/l3syntax-changes.tex
index 8218429e71..847089ac7a 100644
--- a/macros/latex/contrib/l3kernel/l3syntax-changes.tex
+++ b/macros/latex/contrib/l3kernel/l3syntax-changes.tex
@@ -32,7 +32,7 @@ The released version of this bundle is available from CTAN.
{latex-team@latex-project.org}%
}%
}
-\date{Released 2023-05-15}
+\date{Released 2023-05-22}
\newcommand{\TF}{\textit{(TF)}}
diff --git a/macros/latex/contrib/l3kernel/l3sys.dtx b/macros/latex/contrib/l3kernel/l3sys.dtx
index e7280bb33c..2180d4085b 100644
--- a/macros/latex/contrib/l3kernel/l3sys.dtx
+++ b/macros/latex/contrib/l3kernel/l3sys.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -90,6 +90,7 @@
% \sys_if_engine_xetex:
% }
% \begin{syntax}
+% \cs{sys_if_engine_pdftex_p:}
% \cs{sys_if_engine_pdftex:TF} \Arg{true code} \Arg{false code}
% \end{syntax}
% Conditionals which allow engine-specific code to be used. The names
@@ -161,6 +162,7 @@
% \sys_if_output_pdf:
% }
% \begin{syntax}
+% \cs{sys_if_output_dvi_p:}
% \cs{sys_if_output_dvi:TF} \Arg{true code} \Arg{false code}
% \end{syntax}
% Conditionals which give the current output mode the \TeX{} run is
@@ -183,6 +185,7 @@
% \sys_if_platform_windows:
% }
% \begin{syntax}
+% \cs{sys_if_platform_unix_p:}
% \cs{sys_if_platform_unix:TF} \Arg{true code} \Arg{false code}
% \end{syntax}
% Conditionals which allow platform-specific code to be used. The names
diff --git a/macros/latex/contrib/l3kernel/l3term-glossary.pdf b/macros/latex/contrib/l3kernel/l3term-glossary.pdf
index 11c4fbb8f7..238b5bb93e 100644
--- a/macros/latex/contrib/l3kernel/l3term-glossary.pdf
+++ b/macros/latex/contrib/l3kernel/l3term-glossary.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/l3term-glossary.tex b/macros/latex/contrib/l3kernel/l3term-glossary.tex
index 9fae8221bb..c70b135373 100644
--- a/macros/latex/contrib/l3kernel/l3term-glossary.tex
+++ b/macros/latex/contrib/l3kernel/l3term-glossary.tex
@@ -32,7 +32,7 @@ The released version of this bundle is available from CTAN.
{latex-team@latex-project.org}%
}%
}
-\date{Released 2023-05-15}
+\date{Released 2023-05-22}
\newcommand{\TF}{\textit{(TF)}}
@@ -48,7 +48,7 @@ This file describes aspects of \TeX{} programming that are relevant in a
Tokenization.
Treatment of spaces, such as the trap that \verb|\~~a| is equivalent to
-\verb|\~a| in expl syntax, or that \verb|~| fails to give a space at the
+\verb|\~a| in \pkg{expl3} syntax, or that \verb|~| fails to give a space at the
beginning of a line.
\section{Structure of tokens}
@@ -146,4 +146,35 @@ removed) becomes the argument. Note that explicit space characters at
the start of the argument are \emph{not} ignored in this case (and they
prevent brace-stripping).
+\section{Handling of hash tokens}
+
+\TeX{} uses the hash (octothorpe) character |#| to denote parameters for
+macros: these must be numbered sequentially. To allow handling of nested
+macros, \TeX{} requires that for each nesting level, hash tokens are doubled.
+For example
+\begin{verbatim}
+\cs_new:Npn \mypkg_outer:N #1
+ {
+ \cs_new:Npn \mypkg_inner:N ##1
+ {
+ #1
+ ##1
+ }
+ }
+\end{verbatim}
+would define both |\mypkg_outer:N| and |\mypkg_inner:N| as taking
+exactly one argument. If we then do
+\begin{verbatim}
+\mypkg_outer:N \foo
+\cs_show:N \mypkg_inner:N
+\end{verbatim}
+\TeX{} will report
+\begin{verbatim}
+> \mypkg_inner:N=\long macro:#1->\foo #1.
+\end{verbatim}
+i.e.~the hash is not doubled, but is now the parameter of this macro.
+
+Exactly the same concept applies to anywhere that inline code is nested in
+\pkg{expl3}, for example inline mapping code, key definitions, etc.
+
\end{document}
diff --git a/macros/latex/contrib/l3kernel/l3text-case.dtx b/macros/latex/contrib/l3kernel/l3text-case.dtx
index b0aa1ceba9..37172a6eb0 100644
--- a/macros/latex/contrib/l3kernel/l3text-case.dtx
+++ b/macros/latex/contrib/l3kernel/l3text-case.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3text-map.dtx b/macros/latex/contrib/l3kernel/l3text-map.dtx
index d46ab15e38..223b778517 100644
--- a/macros/latex/contrib/l3kernel/l3text-map.dtx
+++ b/macros/latex/contrib/l3kernel/l3text-map.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3text-purify.dtx b/macros/latex/contrib/l3kernel/l3text-purify.dtx
index e6c967ca0f..a851e247a2 100644
--- a/macros/latex/contrib/l3kernel/l3text-purify.dtx
+++ b/macros/latex/contrib/l3kernel/l3text-purify.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -93,7 +93,7 @@
% \begin{macro}[EXP]{\@@_purify_math_cmd:NN}
% \begin{macro}[EXP]{\@@_purify_math_cmd:Nn}
% \begin{macro}[EXP]{\@@_purify_replace:N}
-% \begin{macro}[EXP]{\@@_purify_replace:n}
+% \begin{macro}[EXP]{\@@_purify_replace_auxi:n, \@@_purify_replace_auxii:n}
% \begin{macro}[EXP]{\@@_purify_expand:N, \@@_purify_protect:N, \@@_purify_encoding:N}
% \begin{macro}[EXP]{\@@_purify_encoding_escape:NN}
% As in the other parts of the module, we start off with a standard
@@ -271,20 +271,24 @@
{ \token_if_active_p:N #1 }
}
{
- \exp_args:Nv \@@_purify_replace:n
+ \exp_args:Nv \@@_purify_replace_auxi:n
{ l_@@_purify_ \token_to_str:N #1 _tl }
}
{
- \token_if_cs:NTF #1
- { \@@_purify_expand:N #1 }
- {
- \exp_args:Ne \@@_purify_store:n
- { \@@_token_to_explicit:N #1 }
- \@@_purify_loop:w
- }
+ \exp_args:Ne \@@_purify_replace_auxii:n
+ { \@@_token_to_explicit:N #1 }
+ }
+ }
+\cs_new:Npn \@@_purify_replace_auxi:n #1 { \@@_purify_loop:w #1 }
+\cs_new:Npn \@@_purify_replace_auxii:n #1
+ {
+ \token_if_cs:NTF #1
+ { \@@_purify_expand:N #1 }
+ {
+ \@@_purify_store:n {#1}
+ \@@_purify_loop:w
}
}
-\cs_new:Npn \@@_purify_replace:n #1 { \@@_purify_loop:w #1 }
\cs_new:Npn \@@_purify_expand:N #1
{
\str_if_eq:nnTF {#1} { \protect }
diff --git a/macros/latex/contrib/l3kernel/l3text.dtx b/macros/latex/contrib/l3kernel/l3text.dtx
index 5190bd4d8e..fcd1331b7d 100644
--- a/macros/latex/contrib/l3kernel/l3text.dtx
+++ b/macros/latex/contrib/l3kernel/l3text.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -522,7 +522,13 @@
{ \token_if_mathchardef_p:N #1 }
{
\char_generate:nn {#1}
- { \char_value_catcode:n {#1} }
+ {
+ \if_int_compare:w \char_value_catcode:n {#1} = 10 \exp_stop_f:
+ 10
+ \else:
+ 12
+ \fi:
+ }
}
{#1}
}
@@ -914,13 +920,7 @@
% \begin{macro}[EXP]{\@@_expand_loop:w}
% \begin{macro}[EXP]{\@@_expand_group:n}
% \begin{macro}[EXP]{\@@_expand_space:w}
-% \begin{macro}[EXP]
-% {
-% \@@_expand_N_type:N ,
-% \@@_expand_N_type_auxi:N ,
-% \@@_expand_N_type_auxii:N ,
-% \@@_expand_N_type_auxiii:N
-% }
+% \begin{macro}[EXP]{\@@_expand_N_type:N}
% \begin{macro}[EXP]{\@@_expand_math_search:NNN}
% \begin{macro}[EXP]{\@@_expand_math_loop:Nw}
% \begin{macro}[EXP]{\@@_expand_math_N_type:NN}
@@ -1030,75 +1030,6 @@
\@@_expand_loop:w
}
% \end{macrocode}
-% Before we get into the real work, we have to watch out for problematic
-% implicit characters: spaces and grouping tokens. Converting these to
-% explicit characters later would lead to real issues as they are \emph{not}
-% \texttt{N}-type. A space is the easy case, so it's dealt with first:
-% just insert the explicit token and continue the loop.
-% \begin{macrocode}
-\cs_new:Npx \@@_expand_N_type:N #1
- {
- \exp_not:N \@@_if_s_recursion_tail_stop_do:Nn #1
- { \exp_not:N \@@_expand_end:w }
- \exp_not:N \bool_lazy_any:nTF
- {
- { \exp_not:N \token_if_eq_meaning_p:NN #1 \c_space_token }
- {
- \exp_not:N \token_if_eq_meaning_p:NN #1
- \c_@@_chardef_space_token
- }
- {
- \exp_not:N \token_if_eq_meaning_p:NN #1
- \c_@@_mathchardef_space_token
- }
- }
- { \exp_not:N \@@_expand_space:w \c_space_tl }
- { \exp_not:N \@@_expand_N_type_auxi:N #1 }
- }
-% \end{macrocode}
-% Implicit |{|/|}| offer two issues. First, the token could be an implicit
-% brace character: we need to avoid turning that into a brace group, so filter
-% out the cases manually. Then we handle the case where an implicit group is
-% present. That is done in an \enquote{open-ended} way: there's the possibility
-% the closing token is hidden somewhere.
-% \begin{macrocode}
-\cs_new:Npn \@@_expand_N_type_auxi:N #1
- {
- \bool_lazy_or:nnTF
- { \token_if_eq_meaning_p:NN #1 \c_@@_chardef_group_begin_token }
- { \token_if_eq_meaning_p:NN #1 \c_@@_mathchardef_group_begin_token }
- {
- \@@_expand_store:o \c_left_brace_str
- \@@_expand_loop:w
- }
- {
- \bool_lazy_or:nnTF
- { \token_if_eq_meaning_p:NN #1 \c_@@_chardef_group_end_token }
- { \token_if_eq_meaning_p:NN #1 \c_@@_mathchardef_group_end_token }
- {
- \@@_expand_store:o \c_right_brace_str
- \@@_expand_loop:w
- }
- { \@@_expand_N_type_auxii:N #1 }
- }
- }
-\cs_new:Npn \@@_expand_N_type_auxii:N #1
- {
- \token_if_eq_meaning:NNTF #1 \c_group_begin_token
- {
- { \if_false: } \fi:
- \@@_expand_loop:w
- }
- {
- \token_if_eq_meaning:NNTF #1 \c_group_end_token
- {
- \if_false: { \fi: }
- \@@_expand_loop:w
- }
- { \@@_expand_N_type_auxiii:N #1 }
- }
- }
-% \end{macrocode}
% The first step in dealing with \texttt{N}-type tokens is to look for
% math mode material: that needs to be left alone. The starting function
% has to be split into two as we need \cs{quark_if_recursion_tail_stop:N}
@@ -1108,8 +1039,10 @@
% through unchanged, just checking the \texttt{N}-type ones against the
% end marker.
% \begin{macrocode}
-\cs_new:Npn \@@_expand_N_type_auxiii:N #1
+\cs_new:Npn \@@_expand_N_type:N #1
{
+ \@@_if_s_recursion_tail_stop_do:Nn #1
+ { \@@_expand_end:w }
\exp_after:wN \@@_expand_math_search:NNN
\exp_after:wN #1 \l_text_math_delims_tl
\q_@@_recursion_tail \q_@@_recursion_tail
@@ -1144,7 +1077,8 @@
{
\@@_if_s_recursion_tail_stop_do:Nn #2
{ \@@_expand_end:w }
- \@@_expand_store:n {#2}
+ \token_if_eq_meaning:NNF #2 \exp_not:N
+ { \@@_expand_store:n {#2} }
\token_if_eq_meaning:NNTF #2 #1
{ \@@_expand_loop:w }
{ \@@_expand_math_loop:Nw #1 }
diff --git a/macros/latex/contrib/l3kernel/l3tl-analysis.dtx b/macros/latex/contrib/l3kernel/l3tl-analysis.dtx
index 2e84945989..8ae8a5d41e 100644
--- a/macros/latex/contrib/l3kernel/l3tl-analysis.dtx
+++ b/macros/latex/contrib/l3kernel/l3tl-analysis.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3tl.dtx b/macros/latex/contrib/l3kernel/l3tl.dtx
index 958273893b..1e113ee3b4 100644
--- a/macros/latex/contrib/l3kernel/l3tl.dtx
+++ b/macros/latex/contrib/l3kernel/l3tl.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
@@ -462,7 +462,7 @@
%
% \subsection{Using token lists}
%
-% \begin{function}[EXP]{\tl_to_str:n, \tl_to_str:V}
+% \begin{function}[EXP]{\tl_to_str:n, \tl_to_str:V, \tl_to_str:v}
% \begin{syntax}
% \cs{tl_to_str:n} \Arg{token list}
% \end{syntax}
@@ -470,7 +470,7 @@
% resulting character tokens in the input stream. A \meta{string}
% is a series of tokens with category code $12$ (other) with the exception
% of spaces, which retain category code $10$ (space).
-% This function requires only a single expansion.
+% The base function requires only a single expansion.
% Its argument \emph{must} be braced.
% \begin{texnote}
% This is the \eTeX{} primitive \tn{detokenize}.
@@ -2642,10 +2642,10 @@
%
% \subsection{Using token lists}
%
-% \begin{macro}{\tl_to_str:n, \tl_to_str:V}
+% \begin{macro}{\tl_to_str:n, \tl_to_str:V, \tl_to_str:v}
% Another name for a primitive: defined in \pkg{l3basics}.
% \begin{macrocode}
-\cs_generate_variant:Nn \tl_to_str:n { V }
+\cs_generate_variant:Nn \tl_to_str:n { V , v }
% \end{macrocode}
% \end{macro}
%
diff --git a/macros/latex/contrib/l3kernel/l3token.dtx b/macros/latex/contrib/l3kernel/l3token.dtx
index 7b5467246f..d8eeca44ab 100644
--- a/macros/latex/contrib/l3kernel/l3token.dtx
+++ b/macros/latex/contrib/l3kernel/l3token.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3unicode.dtx b/macros/latex/contrib/l3kernel/l3unicode.dtx
index 899937914e..f667a37efd 100644
--- a/macros/latex/contrib/l3kernel/l3unicode.dtx
+++ b/macros/latex/contrib/l3kernel/l3unicode.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2023-05-15}
+% \date{Released 2023-05-22}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/source3.pdf b/macros/latex/contrib/l3kernel/source3.pdf
index 84fa054d5f..ffe5d5de9b 100644
--- a/macros/latex/contrib/l3kernel/source3.pdf
+++ b/macros/latex/contrib/l3kernel/source3.pdf
Binary files differ
diff --git a/macros/latex/contrib/l3kernel/source3.tex b/macros/latex/contrib/l3kernel/source3.tex
index e12bd2b98d..5d7b26ceff 100644
--- a/macros/latex/contrib/l3kernel/source3.tex
+++ b/macros/latex/contrib/l3kernel/source3.tex
@@ -53,7 +53,7 @@ for those people who are interested.
{latex-team@latex-project.org}%
}%
}
-\date{Released 2023-05-15}
+\date{Released 2023-05-22}
\pagenumbering{roman}
\maketitle
diff --git a/macros/latex/contrib/latexdemo/README b/macros/latex/contrib/latexdemo/README
index 04fa9576cb..263b72eedf 100644
--- a/macros/latex/contrib/latexdemo/README
+++ b/macros/latex/contrib/latexdemo/README
@@ -10,9 +10,9 @@ the result inside a conditional sequence. This allows to print the
result only if it would compile, which can be done with code such
as:
-\begin{filecontents*}{\democodefile}
+\begin{DefineCode}
\so{letterspacing}
-\end{filecontents*}
+\end{DefineCode}
\ifcsdef{so}{%
Commands of package \package{soul}:
diff --git a/macros/latex/contrib/latexdemo/latexdemo.dtx b/macros/latex/contrib/latexdemo/latexdemo.dtx
index 436d515546..91928b02e9 100644
--- a/macros/latex/contrib/latexdemo/latexdemo.dtx
+++ b/macros/latex/contrib/latexdemo/latexdemo.dtx
@@ -2,11 +2,11 @@
% !TeX spellcheck = en-US
%
% File: latexdemo.sty
-% Version: 2014/06/27 v0.1
+% Version: 2023/03/26 v0.2
% Author: Matthias Pospiech
% Email: <matthias@pospiech.eu>
%
-% Copyright (C) 2014 by Matthias Pospiech (matthias@pospiech.eu)
+% Copyright (C) 2023 by Matthias Pospiech (matthias@pospiech.eu)
% ---------------------------------------------------------------------------
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
@@ -32,7 +32,7 @@
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{latexdemo}
%<*package>
- [2014/06/27 v0.1 typeset code and resulting output]
+ [2023/03/26 v0.2 typeset code and resulting output]
%</package>
%
%<*driver>
@@ -116,7 +116,7 @@
% code must be written to an external file.
%
% The commands provided by this package are based on the packages
-% \package{listings}, \package{mdframed} and \package{filecontents}.
+% \package{listings}, \package{mdframed} and the enviroment \environment{filecontents}.
%
% \section{Basic example}
% \label{sec:example:basic}
@@ -127,12 +127,12 @@
% \iffalse
%<*example>
% \fi
-\begin{filecontents*}{\democodefile}
+\begin{DefineCode}
\so{letterspacing}, \\
\ul{underlining}, \\
\st{overstriking} \\
and \hl{highlighting}.
-\end{filecontents*}
+\end{DefineCode}
% \iffalse
%</example>
% \fi
@@ -146,12 +146,12 @@ and \hl{highlighting}.
%<*example>
% \fi
\begin{lstlisting}[style=demostyle]
-\begin{filecontents*}{\democodefile}
+\begin{DefineCode}
\so{letterspacing}, \\
\ul{underlining}, \\
\st{overstriking} \\
and \hl{highlighting}.
-\end{filecontents*}
+\end{DefineCode}
\ifcsdef{so}{%
%
@@ -173,15 +173,15 @@ and \hl{highlighting}.
% \subsection{Define code}
% This package requires the example code to be written to an external file. The
% filename is saved in the command sequence \cs{democodefile}. The output is done
-% with the \environment{filecontents} environment:
+% with the \environment{DefineCode} environment:
%
% \iffalse
%<*example>
% \fi
\begin{lstlisting}[style=demostyle]
-\begin{filecontents*}{\democodefile}
+\begin{DefineCode}
... code ...
-\end{filecontents*}
+\end{DefineCode}
\end{lstlisting}
% \iffalse
%</example>
@@ -228,14 +228,14 @@ and \hl{highlighting}.
%<*example>
% \fi
\begin{lstlisting}[style=demostyle]
-\begin{filecontents*}{\democodefile}
+\begin{DefineCode}
This code shows some basic math: $a^2 + b^2 = c^2$.
-\end{filecontents*}
+\end{DefineCode}
\end{lstlisting}
%
-\begin{filecontents*}{\democodefile}
+\begin{DefineCode}
This code shows some basic math: $a^2 + b^2 = c^2$.
-\end{filecontents*}
+\end{DefineCode}
% \iffalse
%</example>
% \fi
@@ -341,8 +341,6 @@ This code shows some basic math: $a^2 + b^2 = c^2$.
%% Programming
\RequirePackage{xspace}
\RequirePackage{etoolbox}
-%% Write contents to files
-\RequirePackage{filecontents}
%% Packages for frames
\RequirePackage{mdframed}
\RequirePackage{framed}
@@ -457,6 +455,16 @@ This code shows some basic math: $a^2 + b^2 = c^2$.
% \end{macrocode}
% \end{macro}
%
+% \begin{environment}{DefineCode}
+% Define code for demonstration using the enviroment \environment{DefineCode} which is based on the enviroment \environment{filecontents*}.
+% \begin{macrocode}
+ \newenvironment{DefineCode}{%
+ \csname filecontents*\endcsname[overwrite]{\democodefile}%
+}{%
+ \csname endfilecontents*\endcsname%
+}
+% \end{macrocode}
+% \end{environment}
%
% \begin{macro}{\PrintDemo}
% Print code and result using the key-value syntax
diff --git a/macros/latex/contrib/latexdemo/latexdemo.pdf b/macros/latex/contrib/latexdemo/latexdemo.pdf
index d4b4009b23..26fd551895 100644
--- a/macros/latex/contrib/latexdemo/latexdemo.pdf
+++ b/macros/latex/contrib/latexdemo/latexdemo.pdf
Binary files differ
diff --git a/macros/latex/contrib/movement-arrows/README.md b/macros/latex/contrib/movement-arrows/README.md
new file mode 100644
index 0000000000..af657e5518
--- /dev/null
+++ b/macros/latex/contrib/movement-arrows/README.md
@@ -0,0 +1,18 @@
+# `movement-arrows` package
+
+Copyright 2017-2023 by Alan Munn <amunn@msu.edu>
+
+This package supplies simple support for drawing movement arrows on example sentences. It automatically adjusts spacing between examples or gloss lines to make room for the arrows. Arrows can also be annotated with labels. The package uses TikZ as a base, and various properties of the arrows can be adjusted using TikZ styles.
+
+The package has been tested with the `gb4e`, `linguex`, and `ExPex` example packages.
+
+This package may be distributed and/or modified under the conditions of
+the LaTeX Project Public License, either version 1.3 of this license or
+any later version. The latest version of this license is in
+http://www.latex-project.org/lppl.txt and version 1.3 or later is part
+of all distributions of LaTeX version 2005/12/01 or later.
+
+This package has the LPPL maintenance status "maintained".
+
+The Current Maintainer of this package is Alan Munn.
+
diff --git a/macros/latex/contrib/movement-arrows/movement-arrows.pdf b/macros/latex/contrib/movement-arrows/movement-arrows.pdf
new file mode 100644
index 0000000000..f57b5f8595
--- /dev/null
+++ b/macros/latex/contrib/movement-arrows/movement-arrows.pdf
Binary files differ
diff --git a/macros/latex/contrib/movement-arrows/movement-arrows.sty b/macros/latex/contrib/movement-arrows/movement-arrows.sty
new file mode 100644
index 0000000000..fdfbe6b781
--- /dev/null
+++ b/macros/latex/contrib/movement-arrows/movement-arrows.sty
@@ -0,0 +1,77 @@
+% movement-arrows
+% Draw movement arrows on example sentences including glossed sentences
+% Copyright 2023 by Alan Munn <amunn@msu.edu>
+%
+%
+% This package may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% of this license or any later version.
+% The latest version of this license is in
+% http://www.latex-project.org/lppl.txt
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% This package has the LPPL maintenance status `maintained'.
+%
+% The Current Maintainer of this package is Alan Munn.
+%%
+% Version 1.0 2023-05-21 Initial release
+%
+\def\MVA@version{1.0}
+\ProvidesPackage{movement-arrows}[2023/05/21 v \MVA@version]
+\@ifpackageloaded{gb4e}{\noautomath}{}
+\RequirePackage{tikz}
+\usetikzlibrary{ext.paths.ortho}
+\RequirePackage{etoolbox}
+\RequirePackage{calc}
+\NewDocumentCommand{\mkword}{om}{%
+\IfNoValueTF{#1}
+{\tikz[remember picture, baseline=(#2.base)] \node[anchor=base,inner sep=0pt, outer sep=0pt] (#2) {#2};}
+{\tikz[remember picture, baseline=(#1.base)] \node[anchor=base,inner sep=0pt, outer sep=0pt] (#1) {#2};}
+}
+\tikzset{
+ arrow/.style={->,shorten >=3pt,shorten <=3pt},
+ circ/.style = {
+ draw,circle,solid,
+ node contents=#1,
+ fill=white,
+ inner xsep=.2em,
+ inner ysep=0pt
+}
+}
+\newlength{\arrowheight}
+\setlength{\arrowheight}{2.5ex}
+\newlength{\extraexheight}
+\setlength{\extraexheight}{1ex}
+\newlength{\MVA@arrowht}
+\setlength{\MVA@arrowht}{\arrowheight}
+\newlength{\MVA@strutheight}
+\newcommand*\MVA@arrowstrut{%
+ \setlength{\MVA@strutheight}{\MVA@arrowht+\extraexheight}%
+ {\vrule height 0pt depth \MVA@strutheight width 0pt}}
+\let\arrowstrut\MVA@arrowstrut
+
+\NewDocumentCommand{\arrow}{somm}{
+\IfBooleanTF{#1}
+{\setlength{\MVA@arrowht}{-\arrowheight}
+\def\MVA@rightanchor{north}\let\MVA@leftanchor\MVA@rightanchor}
+{\setlength{\MVA@arrowht}{\arrowheight}
+\def\MVA@rightanchor{base}\let\MVA@leftanchor\MVA@rightanchor}
+\IfNoValueTF{#2}
+{
+\begin{tikzpicture}[remember picture,overlay]
+\draw[arrow] (#3.\MVA@rightanchor) r-du[du distance=\MVA@arrowht] (#4.\MVA@leftanchor);
+\end{tikzpicture}
+}
+{\begin{tikzpicture}[remember picture,overlay]
+\draw[arrow] (#3.\MVA@rightanchor) r-du[du distance=\MVA@arrowht] node[#2] {} (#4.\MVA@leftanchor);
+\end{tikzpicture}}
+\MVA@arrowstrut
+\setlength{\MVA@arrowht}{0ex}
+}
+
+\AtBeginDocument{%
+\ifdefined\eachwordone\preto{\eachwordone}{\MVA@arrowstrut}\renewcommand\glt{\vskip -1.2\arrowheight}
+\let\trans=\glt
+\fi}
+
diff --git a/macros/latex/contrib/movement-arrows/movement-arrows.tex b/macros/latex/contrib/movement-arrows/movement-arrows.tex
new file mode 100644
index 0000000000..c402f4efbf
--- /dev/null
+++ b/macros/latex/contrib/movement-arrows/movement-arrows.tex
@@ -0,0 +1,249 @@
+\documentclass[11pt]{article}
+\usepackage{calc}
+\usepackage{fontspec}
+\usepackage[lmargin=.75in,rmargin=.75in,tmargin=1in,bmargin=1in]{geometry}
+\usepackage{titling}
+\usepackage{array, booktabs,tabularx}
+\usepackage{enumitem}
+\usepackage{fancyvrb}
+\usepackage{listings}
+\usepackage{url}
+\usepackage[sf,small]{titlesec}
+\usepackage[section]{placeins}
+\usepackage[colorlinks=true]{hyperref}
+\setmonofont{Inconsolatazi4}
+\usepackage{gb4e}
+\usepackage{movement-arrows}
+\usepackage{parskip}
+
+\DefineShortVerb{\|}
+\title{The \texttt{movement-arrows} package}
+\author{Alan Munn\\amunn@msu.edu}
+\date{Version 1.0\\May 21, 2023}
+
+\lstset{%
+ basicstyle=\ttfamily\small,
+ commentstyle=\itshape\ttfamily\small,
+ showspaces=false,
+ showstringspaces=false,
+ breaklines=true,
+ breakautoindent=true,
+ aboveskip=\baselineskip,
+ language=TeX,
+ frame=single
+ captionpos=t
+ }
+
+\newcommand*{\pkg}[1]{\texttt{#1}}
+\newcolumntype{t}[1]{>{\ttfamily}#1}
+\newcolumntype{T}{>{\ttfamily}c}
+\newcommand*{\bs}{\textbackslash}
+\setlength{\droptitle}{-1in}
+\renewcommand{\abstractname}{\sffamily Abstract}
+
+
+
+\begin{document}
+\maketitle
+\thispagestyle{empty}
+\begin{abstract}{\noindent
+The |movement-arrows| package supplies simple support for drawing movement arrows on example sentences. It automatically adjusts spacing between examples or gloss lines to make room for the arrows. Arrows can also be annotated with labels. The package uses TikZ as a base, and various properties of the arrows can be adjusted using TikZ styles. The package has been tested with the \pkg{gb4e}, \pkg{linguex}, and \pkg{ExPex} example packages.
+
+
+}
+\end{abstract}
+\section{Package commands}
+\begin{table}[htpb]
+\centering
+\begin{tabularx}{.9\textwidth}{t{l}X}
+\toprule
+\bs markwd[<name>]\{<word>\} & marks a word or phrase for arrow placement; if \pkg{word} is a single word with no formatting, \pkg{name} will be set to \pkg{word}. If \pkg{word} is a phrase or contains formatting, a \pkg{name} must be given.\\
+\bs arrow[<options>]\{<start>\}\{<end>\} & add an arrow between start and end nodes defined with \pkg{\bs markwd}. \pkg{\bs arrow*} draws an arrow above the words.\\
+\bs arrowheight & length for the depth that the vertical line of the arrow drops\\
+\bs extraexheight & length to add more space after a line with an arrow\\
+\bottomrule
+\end{tabularx}
+\caption{Package commands}
+\end{table}
+\section{Basic usage}
+The way the package works is that you mark words in your example sentence using the |\mkword| macro and then use the |\arrow| macro to connect the words. So with the following code (using \pkg{gb4e} as our example package), we can get the result in (\ref{where}). Note that you must compile the document twice to place the arrow correctly, because the package uses the TikZ |[remember picture]| function.
+
+
+\begin{quote}
+\begin{lstlisting}
+\begin{exe}
+\ex \mkword{Where} did this move from \mkword{t}?
+\arrow{t}{Where}
+\end{exe}
+\end{lstlisting}
+\end{quote}
+
+\begin{exe}
+\ex \mkword{Where} did this move from \mkword{t}?
+\arrow{t}{Where}
+\label{where}
+\end{exe}
+
+This is the simplest use of the |\mkword| macro: it automatically creates a node with the same name as the word. This only works, however, if the word is a single word with no other formatting.
+
+For example, if instead of representing traces with \emph{t} we use copies or a subscripted trace, we need to explicitly state the node name in the optional argument of |\mkword|. Here’s a revised example:
+\clearpage
+\begin{quote}
+\begin{lstlisting}
+\begin{exe}
+\ex \mkword[Where]{Where\textsubscript{i}} did
+this move from \mkword[t]{t\textsubscript{i}}?
+\arrow{t}{Where}
+\end{exe}
+\end{lstlisting}
+\end{quote}
+
+\begin{exe}
+\ex \mkword[Where]{Where\textsubscript{i}} did this move from \mkword[t]{t\textsubscript{i}}?
+\arrow{t}{Where}
+\label{where2}
+\end{exe}
+\subsection{Adding labels}
+The optional argument can be used to add a label to an arrow. There is one built-in label style called |circ|. Other styles can be created by the user if needed. The |circ| style is defined as follows:
+
+\begin{quote}
+\begin{lstlisting}
+\tikzset{
+ circ/.style = {
+ draw,circle,solid,
+ node contents=#1,
+ fill=white,
+ inner xsep=.2em,
+ inner ysep=0pt,
+}}
+\end{lstlisting}
+\end{quote}
+
+So to add a circled number “1” to the previous example we add |circ=1|:
+
+\begin{quote}
+\begin{lstlisting}
+\begin{exe}
+\ex \mkword[Where]{Where\textsubscript{i}} did
+this move from \mkword[t]{t\textsubscript{i}}?
+\arrow[circ=1]{t}{Where}
+\end{exe}
+\end{lstlisting}
+\end{quote}
+
+\begin{exe}
+\ex \mkword[Where]{Where\textsubscript{i}} did
+this move from \mkword[t]{t\textsubscript{i}}?
+\arrow[circ=1]{t}{Where}
+\end{exe}
+\subsection{Glossed examples}
+The package automatically adjusts the vertical spacing between gloss elements and the first line to accommodate the arrows. Here’s a glossed example. In this example, because we want the arrow to point in the middle of \emph{een auto}, since it’s a phrase that has moved, we need to manually adjust the spacing between \emph{a} and \emph{car} in the gloss line. Alternatively we could just use either \emph{een} or \emph{auto} as the marked node and then no adjustment would be needed. This code also makes use of the |\extraexheight| length to increase the spacing after the second arrow in the example set.
+\clearpage
+\begin{quote}
+\begin{lstlisting}
+\begin{exe}
+\ex
+\begin{xlist}
+\ex{\gll\ldots dat Jan \mkword[een]{een auto} gisteren \mkword{t} gekregen heeft.\\
+\ldots that John {a \hspace*{1em} car} yesterday t gotten has \\
+\ldots that John a car yesterday.}
+\arrow{t}{een}
+\addtolength{\extraexheight}{1ex}
+\ex \mkword{Where} did this move from \mkword{t}?
+\arrow[circ=1]{t}{Where}
+\ex Another example.
+\end{xlist}
+\end{exe}
+\end{lstlisting}
+\end{quote}
+
+\begin{exe}
+\ex
+\begin{xlist}
+\ex{\gll\ldots dat Jan \mkword[een]{een auto} gisteren \mkword{t} gekregen heeft.\\
+\ldots that John {a \hspace*{1em} car} yesterday t gotten has \\
+\ldots that John a car yesterday.}
+\arrow{t}{een}
+\addtolength{\extraexheight}{1ex}
+\ex \mkword{Where} did this move from \mkword{t}?
+\arrow[circ=1]{t}{Where}
+\ex Another example.
+\end{xlist}
+\end{exe}
+\subsection{Adding colour or changing the line style}
+The package uses TikZ styles to style the arrow and the label. The label style |circ| can be modified by using adding parameters directly. The arrow style can be modified by using |\tikzset{arrow/.append style={...}|. Here is some examples of both usages.
+
+\begin{quote}
+\begin{lstlisting}
+\begin{exe}
+\tikzset{arrow/.append style={{red,dashed,very thick}}}
+\ex \mkword[Where]{Where\textsubscript{i}} did
+this move from \mkword[t]{t\textsubscript{i}}?
+\arrow[cyan,circ=1]{t}{Where}
+\end{exe}
+\end{lstlisting}
+\end{quote}
+
+
+\begin{exe}
+\tikzset{arrow/.append style={{red,dashed,very thick}}}
+\ex \mkword[Where]{Where\textsubscript{i}} did
+this move from \mkword[t]{t\textsubscript{i}}?
+\arrow[cyan,circ=1,thin]{t}{Where}
+\end{exe}
+
+\subsection{Multiple arrows on one example}
+If we want to have more than arrow on a single example, it may make sense to have them offset from one another. The position of the labels may also need to be manually adjusted. This is quite easy to do. The length of the vertical line in the arrow is set by the length |\arrowheight|. The position of the label can be moved by adding a |xshift| value. Here’s an example:
+\clearpage
+\begin{quote}
+\begin{lstlisting}
+\begin{exe}
+\ex \mkword{What} \mkword{has} \mkword[twh]{<what>} \mkword[thas]{<has>} moved?
+\arrow[circ=1,xshift=1em]{thas}{has}
+\setlength{\arrowheight}{4.5ex}
+\arrow[circ=2]{twh}{What}
+\end{exe}
+\end{lstlisting}
+\end{quote}
+
+\begin{exe}
+\ex \mkword{What} \mkword{has} \mkword[twh]{<what>} \mkword[thas]{<has>} moved?
+\arrow[circ=1,xshift=1em]{thas}{has}
+\setlength{\arrowheight}{4.5ex}
+\arrow[circ=2]{twh}{What}
+\end{exe}
+
+For examples like this, some manual vertical spacing may be needed to prevent subsequent lines of text from overlapping the arrow.
+
+\subsection{Arrows on top of words}
+The starred version of |\arrow|, |\arrow*| will draw the arrow above the words rather than the default position below the words. At the moment, no automatic spacing is done for arrows above, which means you will need to add vertical space yourself. I may consider adding automatic spacing here too, but at the moment this is not a priority, especially since at least in \pkg{gb4e} the |\sn| version of |\ex| will produce a blank line very simply. Here’s the previous example using a combination of over- and under-arrows:
+
+\begin{quote}
+\begin{lstlisting}
+\begin{exe}
+\sn
+\ex \mkword{What} \mkword{has} \mkword[twh]{<what>} \mkword[thas]{<has>}
+moved?
+\arrow[circ=1]{thas}{has}
+\arrow*[circ=2]{twh}{What}
+\end{exe}
+\end{lstlisting}
+\end{quote}
+
+\begin{exe}
+\sn
+\ex \mkword{What} \mkword{has} \mkword[twh]{<what>} \mkword[thas]{<has>}
+moved? \arrow[circ=1]{thas}{has} \arrow*[circ=2]{twh}{What}
+\end{exe}
+
+
+
+\section{Version history}
+The first version of this package was written in 2017, but never released publicly. The use of the \pkg{tikz-extra} package |paths.ortho| allowed for the current code to be massively simplified. Bug reports and feature requests are welcome at the \href{https://github.com/amunn/movement-arrows/issues}{GitHub bug tracker}.
+\section{Acknowledgements}
+Thanks to the TeX Stackexchange community, from whom I have learned many things, especially about TikZ. The earliest version of the package used code created by user Jake in response to \href{https://tex.stackexchange.com/q/55068/}{a question} I asked. This has now be superseded by the |paths.ortho| methods, but the style described there is quite useful in and of itself. I’ve also benefitted from discussions and suggestions with user percusse.
+
+
+
+
+\end{document} \ No newline at end of file
diff --git a/macros/latex/contrib/templatetools/templatetools.dtx b/macros/latex/contrib/templatetools/templatetools.dtx
index 7cecc11565..56c587902e 100644
--- a/macros/latex/contrib/templatetools/templatetools.dtx
+++ b/macros/latex/contrib/templatetools/templatetools.dtx
@@ -2,11 +2,11 @@
% !TeX spellcheck = en-US
%
% File: templatetools.sty
-% Version: 2014/06/27 v0.1
+% Version: 2023/03/26 v0.1
% Author: Matthias Pospiech
% Email: <matthias@pospiech.eu>
%
-% Copyright (C) 2014 by Matthias Pospiech <matthias@pospiech.eu>
+% Copyright (C) 2023 by Matthias Pospiech <matthias@pospiech.eu>
% ---------------------------------------------------------------------------
% This work may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either version 1.3
@@ -32,7 +32,7 @@
%<package>\NeedsTeXFormat{LaTeX2e}[1999/12/01]
%<package>\ProvidesPackage{templatetools}
%<*package>
- [2014/06/27 v0.1 Collection of conditional commands useful inside templates]
+ [2023/03/26 v0.2 Collection of conditional commands useful inside templates]
%</package>
%
%<*driver>
@@ -46,7 +46,7 @@
%
\usepackage{lmodern}
-\usepackage{templatetools}[2014/06/27]
+\usepackage{templatetools}[2023/03/26]
\EnableCrossrefs % (default) Every new macro name used within a macrocode or
% macrocode∗ environment will produce an index entry.
@@ -92,7 +92,8 @@
% Right brace \} Tilde \~}
%
%
-% \changes{v0.1}{2014/06/27}{Converted to DTX file}
+% \changes{v0.1}{2017-10-12}{Converted to DTX file}
+% \changes{v0.2}{2023/03/26}{Added checking of bib environments}
%
% \DoNotIndex{\newcommand,\newenvironment}
%
@@ -358,6 +359,9 @@ text which is considerably longer than the width of the column \\
% \DescribeMacro{\IfGlossariesStyleDefined}
% \marg{style name}\marg{is defined} \AfterLastParam
%
+% \subsection{Bib environments}
+% \DescribeMacro{\IfBibEnvironmentDefined}
+% \marg{environment name}\marg{is defined} \AfterLastParam
%
% \subsection{Template Definitions}
% The following commands in principle define only macros, but in contrast to
@@ -406,12 +410,12 @@ text which is considerably longer than the width of the column \\
% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}[1994/12/01]
\ProvidesPackage{templatetools}
- [2014/06/27 v0.1 Collection of conditional commands useful inside templates]
+ [2023/03/26 v0.2 Collection of conditional commands useful inside templates]
% \end{macrocode}
% \begin{macrocode}
%%% --- Necessary Packages
%%% ------------------------------------------------------------------
-\RequirePackage{ifpdf}
+\RequirePackage{iftex}
\RequirePackage{etoolbox}
\RequirePackage{ltxcmds}
\RequirePackage{array} % for column types
@@ -544,7 +548,7 @@ text which is considerably longer than the width of the column \\
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\IfElsePackageLoaded\}
+% \begin{macro}{\IfElsePackageLoaded}
% Wrapper to \cs{ltx@ifpackageloaded}
% \begin{macrocode}
\let\IfElsePackageLoaded\ltx@ifpackageloaded
@@ -813,8 +817,24 @@ text which is considerably longer than the width of the column \\
% Thanks to \person{cgnieder} on
%\href{http://tex.stackexchange.com/questions/95639/test-if-a-listings-or-glossaries-style-is-valid}{tex.stackexchange.com}
% for the help to implement the command.
-
-
+%
+% \subsection{BibLaTeX Enivronemnts}
+%
+% \iffalse
+% ------------------------------------------------------------------
+% tests the existens of a bib environment
+% ------------------------------------------------------------------
+% \fi
+%
+% \begin{macro}{\IfBibEnvironmentDefined}
+% Checks if a bib environment is defined.
+% \begin{macrocode}
+\newcommand{\IfBibEnvironmentDefined}[1]{\ifcsdef{blx@env@#1}}
+% \end{macrocode}
+% \end{macro}
+%
+% Thanks to \person{egreg} on \href{https://tex.stackexchange.com/questions/451911/check-if-a-bib-environment-is-defined}{tex.stackexchange.com} for the help to implement the command.
+%
% \subsection{Template definitions}
%
% \iffalse
diff --git a/macros/latex/contrib/templatetools/templatetools.pdf b/macros/latex/contrib/templatetools/templatetools.pdf
index 9febccfab4..aae712014e 100644
--- a/macros/latex/contrib/templatetools/templatetools.pdf
+++ b/macros/latex/contrib/templatetools/templatetools.pdf
Binary files differ
diff --git a/macros/latex/contrib/yb-book/DEPENDS.txt b/macros/latex/contrib/yb-book/DEPENDS.txt
index caa266e1d2..6d00722666 100644
--- a/macros/latex/contrib/yb-book/DEPENDS.txt
+++ b/macros/latex/contrib/yb-book/DEPENDS.txt
@@ -1,5 +1,7 @@
hard pgf
+hard pgfopts
hard xkeyval
+hard textpos
hard geometry
hard anyfontsize
hard chngcntr
diff --git a/macros/latex/contrib/yb-book/yb-book.dtx b/macros/latex/contrib/yb-book/yb-book.dtx
index 49953412a4..105aec54c1 100644
--- a/macros/latex/contrib/yb-book/yb-book.dtx
+++ b/macros/latex/contrib/yb-book/yb-book.dtx
@@ -50,7 +50,7 @@
%<class>\NeedsTeXFormat{LaTeX2e}
%<class>\ProvidesClass{yb-book}
%<*class>
-[19.05.20230 0.2.1 YB Branded Book Style]
+[22.05.20230 0.3.0 YB Branded Book Style]
%</class>
%<*driver>
\documentclass{ltxdoc}
@@ -245,28 +245,27 @@ Hello, world!
% \changes{v0.1.0}{2022/01/09}{Initial version}
% \changes{v0.2.0}{2022/10/02}{Started using l3build}
-% First, we use |xkeyval| package for package options parsing:
+% First, we parse package options:
+% \changes{v0.3.0}{2023/05/22}{The \texttt{pgfopts} package is now used to parse package options.}
% \begin{macrocode}
-\RequirePackage{xkeyval}
-\makeatletter
-\newif\ifyb@draft
-\DeclareOptionX{draft}{\yb@drafttrue}
-\newif\ifyb@compact
-\DeclareOptionX{compact}{\yb@compacttrue}
-\newif\ifyb@manuscript
-\DeclareOptionX{manuscript}{\yb@manuscripttrue}
-\ProcessOptionsX
-\makeatother
+\RequirePackage{pgfopts}
+\pgfkeys{
+ /yb/.cd,
+ draft/.store in=\yb@draft,
+ compact/.store in=\yb@compact,
+ manuscript/.store in=\yb@manuscript,
+}
+\ProcessPgfPackageOptions{/yb}
% \end{macrocode}
% Then, depending on the options like |draft| and |manuscript|, we preset
% options of the class |book| and then load it:
% \begin{macrocode}
-\makeatletter\ifyb@draft
+\makeatletter\ifdefined\yb@draft
\PassOptionsToClass{11pt}{book}
\PassOptionsToClass{oneside}{book}
\else
- \ifyb@manuscript
+ \ifdefined\yb@manuscript
\PassOptionsToClass{12pt}{book}
\PassOptionsToClass{oneside}{book}
\else
@@ -283,10 +282,10 @@ Hello, world!
\RequirePackage{geometry}
\geometry{paperwidth=6in, paperheight=9in, bindingoffset=0.25in,
left=0.75in, right=0.75in, top=0.75in, bottom=1.25in}
-\makeatletter\ifyb@draft
+\makeatletter\ifdefined\yb@draft
\geometry{a4paper, margin=1in, left=1.5in}
\else
- \ifyb@manuscript
+ \ifdefined\yb@manuscript
\geometry{a4paper, margin=1.2in}
\fi
\fi\makeatother
@@ -336,9 +335,9 @@ Hello, world!
% \begin{macrocode}
\RequirePackage{setspace}
\setstretch{1.2}
- \makeatletter\ifyb@draft\setstretch{1.1}\fi\makeatother
- \makeatletter\ifyb@compact\setstretch{1.0}\fi\makeatother
- \makeatletter\ifyb@manuscript\setstretch{1.1}\fi\makeatother
+ \makeatletter\ifdefined\yb@draft\setstretch{1.1}\fi\makeatother
+ \makeatletter\ifdefined\yb@compact\setstretch{1.0}\fi\makeatother
+ \makeatletter\ifdefined\yb@manuscript\setstretch{1.1}\fi\makeatother
% \end{macrocode}
% \end{macro}
@@ -384,7 +383,7 @@ Hello, world!
% \begin{macro}{microtype}
% Then, we include |microtype| for better rendering:
% \begin{macrocode}
-\makeatletter\ifyb@draft\else
+\makeatletter\ifdefined\yb@draft\else
\RequirePackage[letterspace=-50]{microtype}
\fi\makeatother
% \end{macrocode}
@@ -393,7 +392,7 @@ Hello, world!
% \begin{macro}{libertine}
% Then, we include |libertine|, for a good looking font:
% \begin{macrocode}
-\makeatletter\ifyb@manuscript
+\makeatletter\ifdefined\yb@manuscript
\RequirePackage[tt=false,type1=true]{libertine}
\fi\makeatother
% \end{macrocode}
@@ -404,14 +403,14 @@ Hello, world!
% \begin{macrocode}
\makeatletter
\let\yb@oldsection\section
-\ifyb@draft
+\ifdefined\yb@draft
\RequirePackage[medium]{titlesec}
\else
\RequirePackage[raggedright]{titlesec}
\titlespacing{\section}{0in}{6pt}{6pt}[1in]
\renewcommand\section{\newpage\yb@oldsection}
\fi
-\ifyb@compact
+\ifdefined\yb@compact
\renewcommand\section{\vspace{2em}\yb@oldsection}
\fi
\makeatother
@@ -420,29 +419,33 @@ Hello, world!
% Then, if it's a |draft|, we put a watermark comment:
% \begin{macrocode}
-\makeatletter\ifyb@draft
-\RequirePackage{fancyhdr}
-\pagestyle{fancy}
-\renewcommand\headrulewidth{0pt}
-\renewcommand\footrulewidth{0pt}
-\fancyhf{}
-\fancyhead[L,C,LO,CO]{}
-\fancyhead[R,RO]{
- \begin{textblock}{4}(11.5,1)
- \tikz \node [color=gray, rotate=270,font=\ttfamily\scriptsize, text width=5in] at (0,0) {
- Copyright \textcopyright{} \the\year{} by \theauthor{}.
- All rights reserved. No part of the contents of
- this book may be reproduced or transmitted in any
- form or by any means without the written permission
- of the publisher. This particular manuscript is
- printed for \textbf{\thereviewer{}} and may be used only
- for one-time review. The manuscript has to be destroyed
- after the review.
- }
- \end{textblock}
-}
-\fancyfoot[C,CO]{\small\ttfamily
- page \#\thepage{} of \pageref{LastPage}}
+\makeatletter\ifdefined\yb@draft
+ \RequirePackage[absolute]{textpos}
+ \TPGrid{16}{16}
+ \RequirePackage{fancyhdr}
+ \pagestyle{fancy}
+ \renewcommand\headrulewidth{0pt}
+ \renewcommand\footrulewidth{0pt}
+ \setlength{\headheight}{16pt}
+ \fancyhf{}
+ \fancyhead[L,C,LO,CO]{}
+ \fancyhead[R,RO]{
+ \begin{textblock}{4}(11.5,1)
+ \tikz \node [color=gray, rotate=270,
+ font=\ttfamily\scriptsize, text width=5in] at (0,0) {
+ Copyright \textcopyright{} \the\year{} by \theauthor{}.
+ All rights reserved. No part of the contents of
+ this book may be reproduced or transmitted in any
+ form or by any means without the written permission
+ of the publisher. This particular manuscript is
+ printed for \textbf{\thereviewer{}} and may be used only
+ for one-time review. The manuscript has to be destroyed
+ after the review.
+ };
+ \end{textblock}
+ }
+ \fancyfoot[C,CO,CE]{\small\ttfamily
+ page \#\thepage{} of \pageref{LastPage}}
\fi\makeatother
% \end{macrocode}
@@ -472,7 +475,7 @@ Hello, world!
% Then, we define |\ybPrintTitlePage| command:
% \begin{macrocode}
\makeatletter\newcommand\ybPrintTitlePage{
- \ifyb@draft\else
+ \ifdefined\yb@draft\else
\begin{titlepage}
\ttfamily
\vspace*{\fill}
@@ -502,8 +505,8 @@ Hello, world!
% Then, we define |ybPrintTOC| command to print table of contents:
% \begin{macrocode}
\makeatletter\newcommand\ybPrintTOC{
- \ifyb@draft\else
- \ifyb@compact\else\cleardoublepage\fi
+ \ifdefined\yb@draft\else
+ \ifdefined\yb@compact\else\cleardoublepage\fi
{\setstretch{0.7}\tableofcontents}
\fi
}\makeatother
@@ -518,7 +521,7 @@ Hello, world!
\makeindex
\indexsetup{othercode={\hyphenpenalty=10000}}
\makeatletter\newcommand\ybPrintIndex[1][Index]{
- \ifyb@draft\else
+ \ifdefined\yb@draft\else
\cleardoublepage
{
\setstretch{1.0}
@@ -568,7 +571,7 @@ Hello, world!
``#1''\\\raggedleft---#2 #3%
\fi%
}
- \ifyb@draft%
+ \ifdefined\yb@draft%
\begin{wrapfigure}{r}{0.4\textwidth}%
\begin{mdframed}[style=quoteodd]%
\yb@body%
@@ -610,7 +613,7 @@ Hello, world!
\makeatletter\newcommand\ybPrintBibliography{%
\AtNextBibliography{\small}%
\raggedright%
- \ifyb@manuscript%
+ \ifdefined\yb@manuscript%
\setlength\bibitemsep{0pt}%
\newpage%
\begin{multicols}{2}
diff --git a/macros/latex/contrib/yb-book/yb-book.pdf b/macros/latex/contrib/yb-book/yb-book.pdf
index e12566d90c..75d400f858 100644
--- a/macros/latex/contrib/yb-book/yb-book.pdf
+++ b/macros/latex/contrib/yb-book/yb-book.pdf
Binary files differ