summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/l3kernel
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-05-26 03:05:34 +0000
committerNorbert Preining <norbert@preining.info>2021-05-26 03:05:34 +0000
commit8982c52e00ffb3fb5a913fc60913ebd9070f091a (patch)
tree6a395986e3502fefcf42364f8dd87519b45a2441 /macros/latex/contrib/l3kernel
parent07dc96bc3bbd691fc52aca15a172eaf41a89d873 (diff)
CTAN sync 202105260305
Diffstat (limited to 'macros/latex/contrib/l3kernel')
-rw-r--r--macros/latex/contrib/l3kernel/CHANGELOG.md28
-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.pdfbin623415 -> 623415 bytes
-rw-r--r--macros/latex/contrib/l3kernel/interface3.pdfbin1707327 -> 1721185 bytes
-rw-r--r--macros/latex/contrib/l3kernel/interface3.tex2
-rw-r--r--macros/latex/contrib/l3kernel/l3basics.dtx50
-rw-r--r--macros/latex/contrib/l3kernel/l3bootstrap.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3box.dtx24
-rw-r--r--macros/latex/contrib/l3kernel/l3candidates.dtx6
-rw-r--r--macros/latex/contrib/l3kernel/l3cctab.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3clist.dtx210
-rw-r--r--macros/latex/contrib/l3kernel/l3coffins.dtx61
-rw-r--r--macros/latex/contrib/l3kernel/l3color.dtx27
-rw-r--r--macros/latex/contrib/l3kernel/l3debug.dtx21
-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/l3docstrip.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3docstrip.pdfbin151697 -> 151699 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3expan.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3file.dtx72
-rw-r--r--macros/latex/contrib/l3kernel/l3flag.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-assign.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-aux.dtx4
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-basics.dtx20
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-convert.dtx4
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-expo.dtx24
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-extended.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-logic.dtx6
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-parse.dtx10
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-random.dtx12
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-round.dtx34
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-traps.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3fp-trig.dtx8
-rw-r--r--macros/latex/contrib/l3kernel/l3fp.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3fparray.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3int.dtx38
-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.dtx110
-rw-r--r--macros/latex/contrib/l3kernel/l3legacy.dtx58
-rw-r--r--macros/latex/contrib/l3kernel/l3luatex.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3msg.dtx126
-rw-r--r--macros/latex/contrib/l3kernel/l3names.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3news.pdfbin395934 -> 395907 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news01.pdfbin122713 -> 122713 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news02.pdfbin150672 -> 150672 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news03.pdfbin148707 -> 148707 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news04.pdfbin114588 -> 114588 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news05.pdfbin112485 -> 112485 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news06.pdfbin151572 -> 151572 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news07.pdfbin128312 -> 128312 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news08.pdfbin163405 -> 163455 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news09.pdfbin250134 -> 250134 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news10.pdfbin150289 -> 150289 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news11.pdfbin170069 -> 170069 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3news12.pdfbin204992 -> 204992 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3pdf.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3prefixes.csv1
-rw-r--r--macros/latex/contrib/l3kernel/l3prefixes.pdfbin79776 -> 79815 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3prg.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3prop.dtx272
-rw-r--r--macros/latex/contrib/l3kernel/l3quark.dtx7
-rw-r--r--macros/latex/contrib/l3kernel/l3regex.dtx361
-rw-r--r--macros/latex/contrib/l3kernel/l3seq.dtx39
-rw-r--r--macros/latex/contrib/l3kernel/l3skip.dtx84
-rw-r--r--macros/latex/contrib/l3kernel/l3sort.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3str-convert.dtx32
-rw-r--r--macros/latex/contrib/l3kernel/l3str.dtx59
-rw-r--r--macros/latex/contrib/l3kernel/l3styleguide.pdfbin296129 -> 296127 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3styleguide.tex2
-rw-r--r--macros/latex/contrib/l3kernel/l3syntax-changes.pdfbin242807 -> 242808 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3syntax-changes.tex2
-rw-r--r--macros/latex/contrib/l3kernel/l3sys.dtx60
-rw-r--r--macros/latex/contrib/l3kernel/l3term-glossary.pdfbin231193 -> 231186 bytes
-rw-r--r--macros/latex/contrib/l3kernel/l3term-glossary.tex2
-rw-r--r--macros/latex/contrib/l3kernel/l3text-case.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3text-purify.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/l3text.dtx4
-rw-r--r--macros/latex/contrib/l3kernel/l3tl-analysis.dtx64
-rw-r--r--macros/latex/contrib/l3kernel/l3tl.dtx163
-rw-r--r--macros/latex/contrib/l3kernel/l3token.dtx14
-rw-r--r--macros/latex/contrib/l3kernel/l3unicode.dtx2
-rw-r--r--macros/latex/contrib/l3kernel/source3.pdfbin6780088 -> 6837939 bytes
-rw-r--r--macros/latex/contrib/l3kernel/source3.tex2
85 files changed, 1468 insertions, 705 deletions
diff --git a/macros/latex/contrib/l3kernel/CHANGELOG.md b/macros/latex/contrib/l3kernel/CHANGELOG.md
index 1813e73d11..a474281557 100644
--- a/macros/latex/contrib/l3kernel/CHANGELOG.md
+++ b/macros/latex/contrib/l3kernel/CHANGELOG.md
@@ -7,6 +7,29 @@ this project uses date-based 'snapshot' version identifiers.
## [Unreleased]
+## [2021-05-25]
+
+### Added
+- `\msg_note:nnnnnn` (issue #911)
+- `\str_compare:nNnTF` (issue #927)
+- `\sys_timer:`
+- `\prop_concat:NNN`, `\prop_put_from_keyval:Nn` (issue #924)
+- Functions to show and log various datatypes (issue #241):
+ `\coffin_show:Nnn`, `\coffin_show:N`, `\coffin_log:Nnn`, `\coffin_log:N`,
+ `\color_log:n`, `\group_show_list:`, `\group_log_list:`,
+ `\ior_show:N`, `\ior_log:N`, `\iow_show:N`, `\iow_log:N`,
+ `\tl_log_analysis:N`, `\tl_log_analysis:n`
+- `\legacy_if_set_true:n`, `\legacy_if_set_false:n`, `\legacy_if_set:nn`
+
+### Fixed
+- Checking brace balance in all regex functions (issue #377)
+- Removing duplicates in clists when items contain commas (issue #917)
+
+### Changed
+- Slight speed up in some elementary int/dim/skip/muskip operations and
+ in setting tl or clist variables equal.
+- Speed up mapping functions in l3clist, l3prop, l3seq, l3tl
+
## [2021-05-11]
### Added
@@ -19,7 +42,7 @@ this project uses date-based 'snapshot' version identifiers.
- Control sequences and category codes in regex replacements (issue #909)
### Changed
-- Speed up \group_align_safe_begin: (pull #906)
+- Speed up `\group_align_safe_begin:` (pull #906)
## [2021-05-07]
@@ -897,7 +920,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/2021-05-11...HEAD
+[Unreleased]: https://github.com/latex3/latex3/compare/2021-05-25...HEAD
+[2021-05-25]: https://github.com/latex3/latex3/compare/2021-05-11...2021-05-25
[2021-05-11]: https://github.com/latex3/latex3/compare/2021-05-07...2021-05-11
[2021-05-07]: https://github.com/latex3/latex3/compare/2021-02-18...2021-05-07
[2021-02-18]: https://github.com/latex3/latex3/compare/2021-02-06...2021-02-18
diff --git a/macros/latex/contrib/l3kernel/README.md b/macros/latex/contrib/l3kernel/README.md
index 3127e246c5..7901e34905 100644
--- a/macros/latex/contrib/l3kernel/README.md
+++ b/macros/latex/contrib/l3kernel/README.md
@@ -1,7 +1,7 @@
LaTeX3 Programming Conventions
==============================
-Release 2021-05-11
+Release 2021-05-25
Overview
--------
diff --git a/macros/latex/contrib/l3kernel/expl3.dtx b/macros/latex/contrib/l3kernel/expl3.dtx
index 16632dbd99..8f3af5c389 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{2021-05-11}%
+\def\ExplFileDate{2021-05-25}%
%<*driver>
\documentclass[full]{l3doc}
\usepackage{graphicx}
@@ -51,7 +51,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/expl3.pdf b/macros/latex/contrib/l3kernel/expl3.pdf
index 7872487af2..315735ab1d 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 4ab31e9042..5af9196861 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 c41b45bf4e..70cf4f0938 100644
--- a/macros/latex/contrib/l3kernel/interface3.tex
+++ b/macros/latex/contrib/l3kernel/interface3.tex
@@ -54,7 +54,7 @@ for those people who are interested.
{latex-team@latex-project.org}%
}%
}
-\date{Released 2021-05-11}
+\date{Released 2021-05-25}
\pagenumbering{roman}
\maketitle
diff --git a/macros/latex/contrib/l3kernel/l3basics.dtx b/macros/latex/contrib/l3kernel/l3basics.dtx
index 47c746ee43..7fe36b480c 100644
--- a/macros/latex/contrib/l3kernel/l3basics.dtx
+++ b/macros/latex/contrib/l3kernel/l3basics.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -108,6 +108,18 @@
% |}| if standard category codes apply.
% \end{function}
%
+% \begin{function}[added = 2021-05-11]{\group_show_list:, \group_log_list:}
+% \begin{syntax}
+% \cs{group_show_list:}
+% \cs{group_log_list:}
+% \end{syntax}
+% Display (to the terminal or log file) a list of the groups that are
+% currently opened. This is intended for tracking down problems.
+% \begin{texnote}
+% This is a wrapper around the \tn{showgroups} primitive.
+% \end{texnote}
+% \end{function}
+%
% \section{Control sequences and functions}
%
% As \TeX{} is a macro language, creating new functions means
@@ -2941,11 +2953,12 @@
{
\bool_if:NTF #3
{
- \str_if_eq:eeF { }
+ \cs_set_nopar:Npx \@@_tmp:w
{ \tl_map_function:nN {#2} \@@_generate_from_signature:n }
+ \tl_if_empty:oF \@@_tmp:w
{
- \__kernel_msg_error:nnx { kernel } { non-base-function }
- { \token_to_str:N #5 }
+ \__kernel_msg_error:nnxxx { kernel } { non-base-function }
+ { \token_to_str:N #5 } {#2} { \@@_tmp:w }
}
\cs_generate_from_arg_count:NNnn
#5 #4 { \tl_count:n {#2} } {#6}
@@ -3152,6 +3165,35 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\group_show_list:, \group_log_list:, \@@_group_show:NN}
+% Wrapper around \tn{showgroups}. Getting \TeX{} to write to the log
+% without interruption the run is done by altering the interaction
+% mode.
+% \begin{macrocode}
+\cs_new_protected:Npn \group_show_list:
+ { \@@_group_show:NN \use_none:n 1 }
+\cs_new_protected:Npn \group_log_list:
+ { \@@_group_show:NN \int_zero:N 0 }
+\cs_new_protected:Npn \@@_group_show:NN #1#2
+ {
+ \use:x
+ {
+ #1 \tex_interactionmode:D
+ \int_set:Nn \tex_tracingonline:D {#2}
+ \int_set:Nn \tex_errorcontextlines:D { -1 }
+ \exp_not:N \exp_after:wN \scan_stop:
+ \tex_showgroups:D
+ \int_set:Nn \tex_interactionmode:D
+ { \int_use:N \tex_interactionmode:D }
+ \int_set:Nn \tex_tracingonline:D
+ { \int_use:N \tex_tracingonline:D }
+ \int_set:Nn \tex_errorcontextlines:D
+ { \int_use:N \tex_errorcontextlines:D }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \subsection{Decomposing a macro definition}
%
% \begin{macro}{\cs_prefix_spec:N}
diff --git a/macros/latex/contrib/l3kernel/l3bootstrap.dtx b/macros/latex/contrib/l3kernel/l3bootstrap.dtx
index 40047fe446..d9b59d5e06 100644
--- a/macros/latex/contrib/l3kernel/l3bootstrap.dtx
+++ b/macros/latex/contrib/l3kernel/l3bootstrap.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3box.dtx b/macros/latex/contrib/l3kernel/l3box.dtx
index 1eb6848d85..f9cef57a96 100644
--- a/macros/latex/contrib/l3kernel/l3box.dtx
+++ b/macros/latex/contrib/l3kernel/l3box.dtx
@@ -43,15 +43,37 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
% \begin{documentation}
%
+% Box variables contain typeset material that can be inserted on the
+% page or in other boxes. Their contents cannot be converted back to
+% lists of tokens.
% There are three kinds of box operations: horizontal mode denoted
% with prefix |\hbox_|, vertical mode with prefix |\vbox_|, and the
% generic operations working in both modes with prefix |\box_|.
+% For instance, a new box variable containing the words \enquote{Hello,
+% world!} (in a horizontal box) can be obtained by the following code.
+% \begin{verbatim}
+% \box_new:N \l_hello_box
+% \hbox_set:Nn \l_hello_box { Hello, ~ world! }
+% \end{verbatim}
+% The argument is typeset inside a \TeX{} group so that any variables
+% assigned during the construction of this box restores its value
+% afterwards.
+%
+% Box variables from \pkg{l3box} are compatible with those of \LaTeXe{}
+% and plain \TeX{} and can be used interchangeably. The \pkg{l3box}
+% commands to construct boxes, such as \cs{hbox:n} or \cs{hbox_set:Nn},
+% are \enquote{color-safe}, meaning that
+% \begin{verbatim}
+% \hbox:n { \color_select:n { blue } Hello, } ~ world!
+% \end{verbatim}
+% will result in \enquote{Hello,} taking the color blue, but
+% \enquote{world!} remaining with the prevailing color outside the box.
%
% \section{Creating and initialising boxes}
%
diff --git a/macros/latex/contrib/l3kernel/l3candidates.dtx b/macros/latex/contrib/l3kernel/l3candidates.dtx
index 84fd99a2b0..4cbda2d01b 100644
--- a/macros/latex/contrib/l3kernel/l3candidates.dtx
+++ b/macros/latex/contrib/l3kernel/l3candidates.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -1694,7 +1694,7 @@
{ \@@_range_collect_unbraced:w #1 ; { } #2 }
\cs_new:Npn \@@_range_collect_braced:w #1 ; #2#3
{
- \if_int_compare:w #1 > 1 \exp_stop_f:
+ \if_int_compare:w #1 > \c_one_int
\exp_after:wN \@@_range_collect_braced:w
\int_value:w \int_eval:n { #1 - 1 } \exp_after:wN ;
\fi:
@@ -1702,7 +1702,7 @@
}
\cs_new:Npn \@@_range_collect_unbraced:w #1 ; #2#3
{
- \if_int_compare:w #1 > 1 \exp_stop_f:
+ \if_int_compare:w #1 > \c_one_int
\exp_after:wN \@@_range_collect_unbraced:w
\int_value:w \int_eval:n { #1 - 1 } \exp_after:wN ;
\fi:
diff --git a/macros/latex/contrib/l3kernel/l3cctab.dtx b/macros/latex/contrib/l3kernel/l3cctab.dtx
index 9a0bc54933..9be46ebd85 100644
--- a/macros/latex/contrib/l3kernel/l3cctab.dtx
+++ b/macros/latex/contrib/l3kernel/l3cctab.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3clist.dtx b/macros/latex/contrib/l3kernel/l3clist.dtx
index f61fedb483..147fb46675 100644
--- a/macros/latex/contrib/l3kernel/l3clist.dtx
+++ b/macros/latex/contrib/l3kernel/l3clist.dtx
@@ -44,21 +44,22 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
% \begin{documentation}
%
-% Comma lists contain ordered data where items can be added to the left
-% or right end of the list. This data type allows basic list
+% Comma lists (in short, |clist|) contain ordered data where items can
+% be added to the left or right end of the list. This data type allows
+% basic list
% manipulations such as adding/removing items, applying a function to
% every item, removing duplicate items, extracting a given item, using
% the comma list with specified separators, and so on. Sequences
% (defined in \pkg{l3seq}) are safer, faster, and provide more features,
% so they should often be preferred to comma lists. Comma lists are
% mostly useful when interfacing with \LaTeXe{} or other code that
-% expects or provides comma list data.
+% expects or provides items separated by commas.
%
% Several items can be added at once. To ease input of comma lists from
% data provided by a user outside an \cs{ExplSyntaxOn} \ldots{}
@@ -75,10 +76,10 @@
% \end{verbatim}
% results in |\l_my_clist| containing |a,b,c~\d,{e~},{{f}}| namely the
% five items |a|, |b|, |c~\d|, |e~| and~|{f}|. Comma lists normally do
-% not contain empty items so the following gives an empty comma list:
+% not contain empty or blank items so the following gives an empty comma list:
% \begin{verbatim}
% \clist_clear_new:N \l_my_clist
-% \clist_put_right:Nn \l_my_clist { , ~ , , }
+% \clist_set:Nn \l_my_clist { , ~ , , }
% \clist_if_empty:NTF \l_my_clist { true } { false }
% \end{verbatim}
% and it leaves \texttt{true} in the input stream. To include an
@@ -86,6 +87,17 @@
% or ends with a space, or is a single brace group), surround it with
% braces.
%
+% Any |n|-type token list is a valid comma list input for \pkg{l3clist}
+% functions, which will split the token list at every comma and process
+% the items as described above. On the other hand, |N|-type functions
+% expect comma list variables, which are particular token list variables
+% in which this processing of items (and removal of blank items) has
+% already occurred. Because comma list variables are token list
+% variables, expanding them once yields their items separated by commas,
+% and \pkg{l3tl} functions such as \cs{tl_show:N} can be applied to
+% them. (These functions often have \pkg{l3clist} analogues, which
+% should be preferred.)
+%
% Almost all operations on comma lists are
% noticeably slower than those on sequences so converting the data to
% sequences using \cs{seq_set_from_clist:Nn} (see \pkg{l3seq}) may be
@@ -156,7 +168,10 @@
% \cs{clist_set_eq:NN} \meta{comma list_1} \meta{comma list_2}
% \end{syntax}
% Sets the content of \meta{comma list_1} equal to that of
-% \meta{comma list_2}.
+% \meta{comma list_2}. To set a token list variable equal to a comma
+% list variable, use \cs{tl_set_eq:NN}. Conversely, setting a comma
+% list variable to a token list is unadvisable unless one checks
+% space-trimming and related issues.
% \end{function}
%
% \begin{function}[added = 2014-07-17]
@@ -831,22 +846,6 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{variable}{\q_@@_recursion_tail,\q_@@_recursion_stop}
-% Internal recursion quarks.
-% \begin{macrocode}
-\quark_new:N \q_@@_recursion_tail
-\quark_new:N \q_@@_recursion_stop
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{macro}[EXP]{\@@_if_recursion_tail_break:nN,\@@_if_recursion_tail_stop:n}
-% Functions to query recursion quarks.
-% \begin{macrocode}
-\__kernel_quark_new_test:N \@@_if_recursion_tail_break:nN
-\__kernel_quark_new_test:N \@@_if_recursion_tail_stop:n
-% \end{macrocode}
-% \end{macro}
-%
% \begin{macro}{\@@_tmp:w}
% A temporary function for various purposes.
% \begin{macrocode}
@@ -888,11 +887,11 @@
{
\exp_after:wN \@@_sanitize:Nn \exp_after:wN \c_empty_tl
\exp:w \@@_trim_next:w \prg_do_nothing:
- #1 , \q_@@_recursion_tail , \q_@@_recursion_stop
+ #1 , \s_@@_stop \prg_break: , \prg_break_point:
}
\cs_new:Npn \@@_sanitize:Nn #1#2
{
- \@@_if_recursion_tail_stop:n {#2}
+ \@@_use_none_delimit_by_s_stop:w #2 \s_@@_stop
#1 \@@_wrap_item:w #2 ,
\exp_after:wN \@@_sanitize:Nn \exp_after:wN ,
\exp:w \@@_trim_next:w \prg_do_nothing:
@@ -910,10 +909,7 @@
% \item is empty, or
% \item consists of a single braced group.
% \end{itemize}
-% All \pkg{l3clist} functions go through the same test when they need
-% to determine whether to brace an item, so it is not a problem that
-% this test has false positives such as \enquote{\cs{s_@@_mark}
-% \texttt{?}}. If the argument starts or end with a space or contains
+% If the argument starts or ends with a space or contains
% a comma then one of the three arguments of \cs{@@_if_wrap:w} will
% have its end delimiter (partly) in one of the three copies of |#1|
% in \cs{@@_if_wrap:nTF}; this has a knock-on effect meaning that the
@@ -1394,7 +1390,13 @@
\clist_map_inline:Nn #2
{
\clist_if_in:NnF \l_@@_internal_remove_clist {##1}
- { \clist_put_right:Nn \l_@@_internal_remove_clist {##1} }
+ {
+ \tl_put_right:Nx \l_@@_internal_remove_clist
+ {
+ \clist_if_empty:NF \l_@@_internal_remove_clist { , }
+ \@@_if_wrap:nTF {##1} { \exp_not:n { {##1} } } { \exp_not:n {##1} }
+ }
+ }
}
#1 #2 \l_@@_internal_remove_clist
}
@@ -1654,28 +1656,38 @@
%
% \begin{macro}{\clist_map_function:NN, \clist_map_function:cN}
% \UnitTested
-% \begin{macro}{\@@_map_function:nw}
+% \begin{macro}{\@@_map_function:Nw, \@@_map_function_end:w}
% If the variable is empty, the mapping is skipped (otherwise,
% that comma-list would be seen as consisting of one empty item).
-% Then loop over the comma-list, grabbing one comma-delimited
-% item at a time. The end is marked by \cs{q_@@_recursion_tail}.
-% The auxiliary function \cs{@@_map_function:nw} is also used
-% in \cs{clist_map_inline:Nn}.
+% Then loop over the comma-list, grabbing eight comma-delimited items
+% at a time. The end is marked by \cs{s_@@_stop}, which may not appear
+% in any of the items. Once the last group of eight items has been
+% reached, we go through them more slowly using
+% \cs{@@_map_function_end:w}. The auxiliary function
+% \cs{@@_map_function:Nw} is also used in some other clist mappings.
% \begin{macrocode}
\cs_new:Npn \clist_map_function:NN #1#2
{
\clist_if_empty:NF #1
{
- \exp_last_unbraced:NNo \@@_map_function:nw #2 #1
- , \q_@@_recursion_tail ,
+ \exp_after:wN \@@_map_function:Nw \exp_after:wN #2 #1 ,
+ \s_@@_stop , \s_@@_stop , \s_@@_stop , \s_@@_stop ,
+ \s_@@_stop , \s_@@_stop , \s_@@_stop , \s_@@_stop ,
\prg_break_point:Nn \clist_map_break: { }
}
}
-\cs_new:Npn \@@_map_function:nw #1#2 ,
+\cs_new:Npn \@@_map_function:Nw #1 #2, #3, #4, #5, #6, #7, #8, #9,
+ {
+ \@@_use_none_delimit_by_s_stop:w
+ #9 \@@_map_function_end:w \s_@@_stop
+ #1 {#2} #1 {#3} #1 {#4} #1 {#5} #1 {#6} #1 {#7} #1 {#8} #1 {#9}
+ \@@_map_function:Nw #1
+ }
+\cs_new:Npn \@@_map_function_end:w \s_@@_stop #1#2
{
- \@@_if_recursion_tail_break:nN {#2} \clist_map_break:
+ \@@_use_none_delimit_by_s_stop:w #2 \clist_map_break: \s_@@_stop
#1 {#2}
- \@@_map_function:nw {#1}
+ \@@_map_function_end:w \s_@@_stop
}
\cs_generate_variant:Nn \clist_map_function:NN { c }
% \end{macrocode}
@@ -1697,12 +1709,13 @@
\cs_new:Npn \clist_map_function:nN #1#2
{
\exp_after:wN \@@_map_function_n:Nn \exp_after:wN #2
- \exp:w \@@_trim_next:w \prg_do_nothing: #1 , \q_@@_recursion_tail ,
+ \exp:w \@@_trim_next:w \prg_do_nothing: #1 ,
+ \s_@@_stop \clist_map_break: ,
\prg_break_point:Nn \clist_map_break: { }
}
\cs_new:Npn \@@_map_function_n:Nn #1 #2
{
- \@@_if_recursion_tail_break:nN {#2} \clist_map_break:
+ \@@_use_none_delimit_by_s_stop:w #2 \s_@@_stop
\@@_map_unbrace:wn #2 , #1
\exp_after:wN \@@_map_function_n:Nn \exp_after:wN #1
\exp:w \@@_trim_next:w \prg_do_nothing:
@@ -1736,9 +1749,11 @@
\int_gincr:N \g__kernel_prg_map_int
\cs_gset_protected:cpn
{ @@_map_ \int_use:N \g__kernel_prg_map_int :w } ##1 {#2}
- \exp_last_unbraced:Nco \@@_map_function:nw
+ \exp_last_unbraced:Nco \@@_map_function:Nw
{ @@_map_ \int_use:N \g__kernel_prg_map_int :w }
- #1 , \q_@@_recursion_tail ,
+ #1 ,
+ \s_@@_stop , \s_@@_stop , \s_@@_stop , \s_@@_stop ,
+ \s_@@_stop , \s_@@_stop , \s_@@_stop , \s_@@_stop ,
\prg_break_point:Nn \clist_map_break:
{ \int_gdecr:N \g__kernel_prg_map_int }
}
@@ -1756,65 +1771,63 @@
% \begin{macro}{\clist_map_variable:NNn, \clist_map_variable:cNn}
% \UnitTested
% \begin{macro}{\clist_map_variable:nNn}
-% \begin{macro}{\@@_map_variable:Nnw}
-% As for other comma-list mappings, filter out the case of
-% an empty list. Same approach as \cs{clist_map_function:Nn},
-% additionally we store each item in the given variable.
-% As for inline mappings, space trimming for the \texttt{n}
-% variant is done by storing the comma list in a variable.
-% The quark test is done before assigning the item to the variable:
-% this avoids storing a quark which the user wouldn't expect.
-% The strange \cs{use:n} avoids unlikely problems when |#2| would
-% contain \cs{q_@@_recursion_stop}.
+% \begin{macro}{\@@_map_variable:Nnn}
+% The |N|-type version is a straightforward application of
+% \cs{clist_map_tokens:Nn}, calling \cs{@@_map_variable:Nnn} for each
+% item to assign the variable and run the user's code. The |n|-type
+% version is \emph{not} implemented in terms of the |n|-type function
+% \cs{clist_map_tokens:Nn}, because here we are allowed to clean up
+% the |n|-type comma list non-expandably.
% \begin{macrocode}
\cs_new_protected:Npn \clist_map_variable:NNn #1#2#3
- {
- \clist_if_empty:NF #1
- {
- \exp_args:Nno \use:nn
- { \@@_map_variable:Nnw #2 {#3} }
- #1
- , \q_@@_recursion_tail , \q_@@_recursion_stop
- \prg_break_point:Nn \clist_map_break: { }
- }
- }
+ { \clist_map_tokens:Nn #1 { \@@_map_variable:Nnn #2 {#3} } }
+\cs_generate_variant:Nn \clist_map_variable:NNn { c }
+\cs_new_protected:Npn \@@_map_variable:Nnn #1#2#3
+ { \tl_set:Nn #1 {#3} #2 }
\cs_new_protected:Npn \clist_map_variable:nNn #1
{
\clist_set:Nn \l_@@_internal_clist {#1}
\clist_map_variable:NNn \l_@@_internal_clist
}
-\cs_new_protected:Npn \@@_map_variable:Nnw #1#2#3,
- {
- \@@_if_recursion_tail_stop:n {#3}
- \tl_set:Nn #1 {#3}
- \use:n {#2}
- \@@_map_variable:Nnw #1 {#2}
- }
-\cs_generate_variant:Nn \clist_map_variable:NNn { c }
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\clist_map_tokens:Nn, \clist_map_tokens:cn}
-% \begin{macro}{\@@_map_tokens:nw}
+% \begin{macro}{\@@_map_tokens:nw, \@@_map_tokens_end:w}
% Essentially a copy of \cs{clist_map_function:NN} with braces added.
% \begin{macrocode}
\cs_new:Npn \clist_map_tokens:Nn #1#2
{
\clist_if_empty:NF #1
{
- \exp_last_unbraced:Nno \@@_map_function:nw {#2} #1
- , \q_@@_recursion_tail ,
+ \exp_last_unbraced:Nno \@@_map_tokens:nw {#2} #1 ,
+ \s_@@_stop , \s_@@_stop , \s_@@_stop , \s_@@_stop ,
+ \s_@@_stop , \s_@@_stop , \s_@@_stop , \s_@@_stop ,
\prg_break_point:Nn \clist_map_break: { }
}
}
+\cs_new:Npn \@@_map_tokens:nw #1 #2, #3, #4, #5, #6, #7, #8, #9,
+ {
+ \@@_use_none_delimit_by_s_stop:w
+ #9 \@@_map_tokens_end:w \s_@@_stop
+ \use:n {#1} {#2} \use:n {#1} {#3} \use:n {#1} {#4} \use:n {#1} {#5}
+ \use:n {#1} {#6} \use:n {#1} {#7} \use:n {#1} {#8} \use:n {#1} {#9}
+ \@@_map_tokens:nw {#1}
+ }
+\cs_new:Npn \@@_map_tokens_end:w \s_@@_stop \use:n #1#2
+ {
+ \@@_use_none_delimit_by_s_stop:w #2 \clist_map_break: \s_@@_stop
+ #1 {#2}
+ \@@_map_tokens_end:w \s_@@_stop
+ }
\cs_generate_variant:Nn \clist_map_tokens:Nn { c }
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\clist_map_tokens:nn, \@@_map_tokens_n:nw, \@@_use_ii_i:nn}
+% \begin{macro}{\clist_map_tokens:nn, \@@_map_tokens_n:nw}
% Similar to \cs{clist_map_function:nN} but with a different way of
% grabbing items because we cannot use \cs{exp_after:wN} to pass the
% \meta{code}.
@@ -1822,20 +1835,19 @@
\cs_new:Npn \clist_map_tokens:nn #1#2
{
\@@_map_tokens_n:nw {#2}
- \prg_do_nothing: #1 , \q_@@_recursion_tail ,
+ \prg_do_nothing: #1 , \s_@@_stop \clist_map_break: ,
\prg_break_point:Nn \clist_map_break: { }
}
\cs_new:Npn \@@_map_tokens_n:nw #1#2 ,
{
\tl_if_empty:oF { \use_none:nn #2 ? }
{
- \exp_args:No \@@_if_recursion_tail_break:nN {#2} \clist_map_break:
- \tl_trim_spaces_apply:oN {#2} \@@_use_ii_i:nn
+ \@@_use_none_delimit_by_s_stop:w #2 \s_@@_stop
+ \tl_trim_spaces_apply:oN {#2} \use_ii_i:nn
\@@_map_unbrace:wn , {#1}
}
\@@_map_tokens_n:nw {#1} \prg_do_nothing:
}
-\cs_new:Npn \@@_use_ii_i:nn #1#2 { #2 #1 }
% \end{macrocode}
% \end{macro}
%
@@ -1869,22 +1881,26 @@
}
}
\cs_generate_variant:Nn \clist_count:N { c }
-\cs_new:Npx \clist_count:n #1
+\cs_new:Npn \@@_count:n #1 { + 1 }
+\cs_set_protected:Npn \@@_tmp:w #1
{
- \exp_not:N \int_eval:n
+ \cs_new:Npn \clist_count:n ##1
{
- 0
- \exp_not:N \@@_count:w \c_space_tl
- #1 \exp_not:n { , \q_@@_recursion_tail , \q_@@_recursion_stop }
+ \int_eval:n
+ {
+ 0
+ \@@_count:w #1
+ ##1 , \s_@@_stop \prg_break: , \prg_break_point:
+ }
+ }
+ \cs_new:Npn \@@_count:w ##1 ,
+ {
+ \@@_use_none_delimit_by_s_stop:w ##1 \s_@@_stop
+ \tl_if_blank:nF {##1} { + 1 }
+ \@@_count:w #1
}
}
-\cs_new:Npn \@@_count:n #1 { + 1 }
-\cs_new:Npx \@@_count:w #1 ,
- {
- \exp_not:n { \exp_args:Nf \@@_if_recursion_tail_stop:n } {#1}
- \exp_not:N \tl_if_blank:nF {#1} { + 1 }
- \exp_not:N \@@_count:w \c_space_tl
- }
+\exp_args:No \@@_tmp:w \c_space_tl
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1907,15 +1923,15 @@
% quarks), 5: the rest of the comma list, 6: a \meta{continuation}
% function (\texttt{use_ii} or \texttt{use_iii} with its
% \meta{separator} argument), 7: junk, and 8: the temporary result,
-% which is built in a brace group following \cs{q_@@_stop}. The
+% which is built in a brace group following \cs{s_@@_stop}. The
% \meta{separator} and the first of the three items are placed in the
% result, then we use the \meta{continuation}, placing the remaining
% two items after it. When we begin this loop, the three items really
-% belong to the comma list, the first \cs{q_@@_mark} is taken as a
+% belong to the comma list, the first \cs{s_@@_mark} is taken as a
% delimiter to the \texttt{use_ii} function, and the continuation is
% \texttt{use_ii} itself. When we reach the last two items of the
-% original token list, \cs{q_@@_mark} is taken as a third item, and now
-% the second \cs{q_@@_mark} serves as a delimiter to \texttt{use_ii},
+% original token list, \cs{s_@@_mark} is taken as a third item, and now
+% the second \cs{s_@@_mark} serves as a delimiter to \texttt{use_ii},
% switching to the other \meta{continuation}, \texttt{use_iii}, which
% uses the \meta{separator between final two}.
% \begin{macrocode}
@@ -1993,7 +2009,7 @@
{ \@@_use:Nw #1#2 ; }
{
\@@_use_none_delimit_by_s_mark:w #4 #1 \s_@@_mark
- \tl_trim_spaces_apply:oN {#4} \@@_use_ii_i:nn
+ \tl_trim_spaces_apply:oN {#4} \use_ii_i:nn
\@@_map_unbrace:wn , { #2 ; }
}
#3 ; \prg_do_nothing:
diff --git a/macros/latex/contrib/l3kernel/l3coffins.dtx b/macros/latex/contrib/l3kernel/l3coffins.dtx
index e0cdd606b3..dfeb71e9ec 100644
--- a/macros/latex/contrib/l3kernel/l3coffins.dtx
+++ b/macros/latex/contrib/l3kernel/l3coffins.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -381,6 +381,31 @@
% which displays the result in the terminal.
% \end{function}
%
+% \begin{function}[added = 2021-05-11]
+% {\coffin_show:N, \coffin_show:c, \coffin_log:N, \coffin_log:c}
+% \begin{syntax}
+% \cs{coffin_show:N} \meta{coffin}
+% \cs{coffin_log:N} \meta{coffin}
+% \end{syntax}
+% Shows full details of poles and contents of the \meta{coffin} in the
+% terminal or log file. See \cs{coffin_show_structure:N} and
+% \cs{box_show:N} to show separately the pole structure and the
+% contents.
+% \end{function}
+%
+% \begin{function}[added = 2021-05-11]
+% {\coffin_show:Nnn, \coffin_show:cnn, \coffin_log:Nnn, \coffin_log:cnn}
+% \begin{syntax}
+% \cs{coffin_show:Nnn} \meta{coffin} \Arg{intexpr_1} \Arg{intexpr_2}
+% \cs{coffin_log:Nnn} \meta{coffin} \Arg{intexpr_1} \Arg{intexpr_2}
+% \end{syntax}
+% Shows poles and contents of the \meta{coffin} in the terminal or log
+% file, showing the first \meta{intexpr_1} items in the coffin, and
+% descending into \meta{intexpr_2} group levels. See
+% \cs{coffin_show_structure:N} and \cs{box_show:Nnn} to show
+% separately the pole structure and the contents.
+% \end{function}
+%
% \section{Constants and variables}
%
% \begin{variable}{\c_empty_coffin}
@@ -2481,6 +2506,40 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}
+% {
+% \coffin_show:N, \coffin_show:c, \coffin_log:N, \coffin_log:c,
+% \coffin_show:Nnn, \coffin_show:cnn, \coffin_log:Nnn, \coffin_log:cnn,
+% \@@_show:NNNnn
+% }
+% Essentially a combination of \cs{coffin_show_structure:N} and
+% \cs{box_show:Nnn}, but we need to avoid having two prompts, so we
+% use \cs{__kernel_msg_term:nnxxxx} instead of
+% \cs{__kernel_msg_show:nnxxxx} in the |show| case.
+% \begin{macrocode}
+\cs_new_protected:Npn \coffin_show:N #1
+ { \coffin_show:Nnn #1 \c_max_int \c_max_int }
+\cs_generate_variant:Nn \coffin_show:N { c }
+\cs_new_protected:Npn \coffin_log:N #1
+ { \coffin_log:Nnn #1 \c_max_int \c_max_int }
+\cs_generate_variant:Nn \coffin_log:N { c }
+\cs_new_protected:Npn \coffin_show:Nnn
+ { \@@_show:NNNnn \__kernel_msg_term:nnxxxx \box_show:Nnn }
+\cs_generate_variant:Nn \coffin_show:Nnn { c }
+\cs_new_protected:Npn \coffin_log:Nnn
+ { \@@_show:NNNnn \__kernel_msg_log:nnxxxx \box_show:Nnn }
+\cs_generate_variant:Nn \coffin_log:Nnn { c }
+\cs_new_protected:Npn \@@_show:NNNnn #1#2#3#4#5
+ {
+ \@@_if_exist:NT #3
+ {
+ \@@_show_structure:NN #1 #3
+ #2 #3 {#4} {#5}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \subsection{Messages}
%
% \begin{macrocode}
diff --git a/macros/latex/contrib/l3kernel/l3color.dtx b/macros/latex/contrib/l3kernel/l3color.dtx
index 9b72bdc466..8efa83b1ab 100644
--- a/macros/latex/contrib/l3kernel/l3color.dtx
+++ b/macros/latex/contrib/l3kernel/l3color.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -235,12 +235,13 @@
% it to be saved to a name.
% \end{function}
%
-% \begin{function}{\color_show:n}
+% \begin{function}[added = 2021-05-11]{\color_show:n, \color_log:n}
% \begin{syntax}
% \cs{color_show:n} \Arg{name}
+% \cs{color_log:n} \Arg{name}
% \end{syntax}
% Displays the color specification stored in the \meta{name} on the
-% terminal.
+% terminal or log file.
% \end{function}
%
% \section{Selecting colors}
@@ -2508,21 +2509,25 @@
%
% \subsection{Diagnostics}
%
-% \begin{macro}{\color_show:n}
-% \begin{macro}{\@@_show:n}
+% \begin{macro}{\color_show:n, \color_log:n, \@@_show:Nn}
+% \begin{macro}[EXP]{\@@_show:n}
% Extract the information about a color and format for the user: the approach
% is similar to the keys module here.
% \begin{macrocode}
-\cs_new_protected:Npn \color_show:n #1
+\cs_new_protected:Npn \color_show:n
+ { \@@_show:Nn \__kernel_msg_show:nnxxxx }
+\cs_new_protected:Npn \color_log:n
+ { \@@_show:Nn \__kernel_msg_log:nnxxxx }
+\cs_new_protected:Npn \@@_show:Nn #1#2
{
- \__kernel_msg_show:nnxxxx { color } { show }
- {#1}
+ #1 { color } { show }
+ {#2}
{
- \@@_if_defined:nT {#1}
+ \@@_if_defined:nT {#2}
{
- \exp_args:Nv \@@_show:n { l_@@_named_ #1 _tl }
+ \exp_args:Nv \@@_show:n { l_@@_named_ #2 _tl }
\prop_map_function:cN
- { l_@@_named_ #1 _prop }
+ { l_@@_named_ #2 _prop }
\msg_show_item_unbraced:nn
}
}
diff --git a/macros/latex/contrib/l3kernel/l3debug.dtx b/macros/latex/contrib/l3kernel/l3debug.dtx
index b7eb9d0215..1ac920d00e 100644
--- a/macros/latex/contrib/l3kernel/l3debug.dtx
+++ b/macros/latex/contrib/l3kernel/l3debug.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -491,7 +491,7 @@
% \cs{clist_concat:NNN}''.
%
% Instead of changing \emph{the} definition of the macros, we'll
-% create a copy of such macros, say, |__debug_clist_concat:NNN| which
+% create a copy of such macros, say, \cs[no-index]{@@_clist_concat:NNN} which
% will be defined as
% |<debug code with #1, #2 and #3>\clist_concat:NNN#1#2#3|. For that
% we need to identify the signature of every function and build the
@@ -569,8 +569,7 @@
\__kernel_msg_new:nnn { debug } { bad-arg-type }
{ Wrong~argument~type~#1. }
% \end{macrocode}
-% The macro below is a modifiec copy of
-% |\__cs_generate_variant_loop_base:N| to get the base form of an
+% The macro below gets the base form of an
% argument type given a variant. It serves only to differentiate
% arguments which should be braced from ones which shouldn't. If all
% were to be braced this would be unnecessary. I moved the |n| and |N|
@@ -647,7 +646,7 @@
\tex_endlinechar:D -1 \scan_stop:
\tl_map_inline:nn {#3}
{
- \cs_if_exist:cTF { __debug_ \cs_to_str:N ##1 }
+ \cs_if_exist:cTF { @@_ \cs_to_str:N ##1 }
{ \@@_add_to_debug_code:Nnn }
{ \@@_setup_debug_code:Nnn }
##1 {#1} {#2}
@@ -656,7 +655,7 @@
}
\cs_set_protected:Npn \@@_setup_debug_code:Nnn #1#2#3
{
- \cs_gset_eq:cN { __debug_ \cs_to_str:N #1 } #1
+ \cs_gset_eq:cN { @@_ \cs_to_str:N #1 } #1
\@@_generate_parameter_list:NNN #1 \l_@@_tmpa_tl \l_@@_tmpb_tl
\exp_args:Nx \tex_scantokens:D
{
@@ -665,7 +664,7 @@
\tl_use:N \l_@@_tmpa_tl
{
\tl_to_str:n {#2}
- \exp_not:c { __debug_ \cs_to_str:N #1 }
+ \exp_not:c { @@_ \cs_to_str:N #1 }
\tl_use:N \l_@@_tmpb_tl
\tl_to_str:n {#3}
}
@@ -678,7 +677,7 @@
\cs_set:Npn \exp_not:N \@@_tmp:w
####1 \tl_to_str:n { macro: }
####2 \tl_to_str:n { -> }
- ####3 \c_backslash_str \tl_to_str:n { __debug_ }
+ ####3 \c_backslash_str \tl_to_str:n { @@_ }
\cs_to_str:N #1
####4 \s_@@_stop
{
@@ -688,7 +687,7 @@
\tex_def:D \exp_not:N #1 ####2
{
####3 \tl_to_str:n {#2}
- \c_backslash_str __debug_ \cs_to_str:N #1
+ \c_backslash_str @@_ \cs_to_str:N #1
####4 \tl_to_str:n {#3}
}
}
@@ -808,6 +807,7 @@
\box_set_eq:NN
\box_set_eq_drop:NN
\box_set_to_last:N
+ \clist_clear:N
\clist_set_eq:NN
\dim_zero:N
\dim_set:Nn
@@ -838,6 +838,7 @@
\skip_add:Nn
\skip_sub:Nn
\__kernel_tl_set:Nx
+ \tl_clear:N
\tl_set_eq:NN
\tl_put_left:Nn
\tl_put_left:NV
@@ -870,6 +871,7 @@
\box_gset_eq_drop:NN
\box_gset_to_last:N
\cctab_gset:Nn
+ \clist_gclear:N
\clist_gset_eq:NN
\dim_gset_eq:NN
\dim_gzero:N
@@ -900,6 +902,7 @@
\skip_gadd:Nn
\skip_gsub:Nn
\__kernel_tl_gset:Nx
+ \tl_gclear:N
\tl_gset_eq:NN
\tl_gput_left:Nn
\tl_gput_left:NV
diff --git a/macros/latex/contrib/l3kernel/l3deprecation.dtx b/macros/latex/contrib/l3kernel/l3deprecation.dtx
index 42e7283436..7e7f6bd37b 100644
--- a/macros/latex/contrib/l3kernel/l3deprecation.dtx
+++ b/macros/latex/contrib/l3kernel/l3deprecation.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3doc.dtx b/macros/latex/contrib/l3kernel/l3doc.dtx
index aa9fce6c58..d3154c8c9e 100644
--- a/macros/latex/contrib/l3kernel/l3doc.dtx
+++ b/macros/latex/contrib/l3kernel/l3doc.dtx
@@ -79,7 +79,7 @@ and all files in that bundle must be distributed together.
%
% \title{The \cls{l3doc} class}
% \author{\Team}
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
% \maketitle
% \tableofcontents
%
diff --git a/macros/latex/contrib/l3kernel/l3docstrip.dtx b/macros/latex/contrib/l3kernel/l3docstrip.dtx
index fa01fb954e..62399e23c6 100644
--- a/macros/latex/contrib/l3kernel/l3docstrip.dtx
+++ b/macros/latex/contrib/l3kernel/l3docstrip.dtx
@@ -63,7 +63,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3docstrip.pdf b/macros/latex/contrib/l3kernel/l3docstrip.pdf
index 8d05bf60a8..acd52e68c5 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 163e867881..949b70c2aa 100644
--- a/macros/latex/contrib/l3kernel/l3expan.dtx
+++ b/macros/latex/contrib/l3kernel/l3expan.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3file.dtx b/macros/latex/contrib/l3kernel/l3file.dtx
index a89f6540c6..d3f57f9deb 100644
--- a/macros/latex/contrib/l3kernel/l3file.dtx
+++ b/macros/latex/contrib/l3kernel/l3file.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -151,6 +151,21 @@
% to other programmers.
% \end{function}
%
+% \begin{function}[added = 2021-05-11]
+% {
+% \ior_show:N, \ior_show:c, \ior_log:N, \ior_log:c,
+% \iow_show:N, \iow_show:c, \iow_log:N, \iow_log:c
+% }
+% \begin{syntax}
+% \cs{ior_show:N} \meta{stream}
+% \cs{ior_log:N} \meta{stream}
+% \cs{iow_show:N} \meta{stream}
+% \cs{iow_log:N} \meta{stream}
+% \end{syntax}
+% Display (to the terminal or log file) the file name associated to
+% the (read or write) \meta{stream}.
+% \end{function}
+%
% \begin{function}[added = 2017-06-27]
% {
% \ior_show_list:, \ior_log_list:,
@@ -1118,6 +1133,29 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\ior_show:N, \ior_log:N, \@@_show:NN}
+% Seek the stream in the \cs{g_@@_streams_prop} list, then show the
+% stream as open or closed accordingly.
+% \begin{macrocode}
+\cs_new_protected:Npn \ior_show:N { \@@_show:NN \tl_show:n }
+\cs_generate_variant:Nn \ior_show:N { c }
+\cs_new_protected:Npn \ior_log:N { \@@_show:NN \tl_log:n }
+\cs_generate_variant:Nn \ior_log:N { c }
+\cs_new_protected:Npn \@@_show:NN #1#2
+ {
+ \__kernel_chk_defined:NT #2
+ {
+ \prop_get:NVNTF \g_@@_streams_prop #2 \l_@@_internal_tl
+ {
+ \exp_args:Nx #1
+ { \token_to_str:N #2 ~ open: ~ \l_@@_internal_tl }
+ }
+ { \exp_args:Nx #1 { \token_to_str:N #2 ~ closed } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\ior_show_list:, \ior_log_list:}
% \begin{macro}{\@@_list:N}
% Show the property lists, but with some \enquote{pretty printing}.
@@ -1354,6 +1392,13 @@
%
% \subsubsection{Variables and constants}
%
+% \begin{variable}{\l_@@_internal_tl}
+% Used as a short-term scratch variable.
+% \begin{macrocode}
+\tl_new:N \l_@@_internal_tl
+% \end{macrocode}
+% \end{variable}
+%
% \begin{variable}{\c_log_iow, \c_term_iow}
% Here we allocate two output streams for writing to the transcript
% file only (\cs{c_log_iow}) and to both the terminal and transcript
@@ -1520,6 +1565,29 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}{\iow_show:N, \iow_log:N, \@@_show:NN}
+% Seek the stream in the \cs{g_@@_streams_prop} list, then show the
+% stream as open or closed accordingly.
+% \begin{macrocode}
+\cs_new_protected:Npn \iow_show:N { \@@_show:NN \tl_show:n }
+\cs_generate_variant:Nn \iow_show:N { c }
+\cs_new_protected:Npn \iow_log:N { \@@_show:NN \tl_log:n }
+\cs_generate_variant:Nn \iow_log:N { c }
+\cs_new_protected:Npn \@@_show:NN #1#2
+ {
+ \__kernel_chk_defined:NT #2
+ {
+ \prop_get:NVNTF \g_@@_streams_prop #2 \l_@@_internal_tl
+ {
+ \exp_args:Nx #1
+ { \token_to_str:N #2 ~ open: ~ \l_@@_internal_tl }
+ }
+ { \exp_args:Nx #1 { \token_to_str:N #2 ~ closed } }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\iow_show_list:, \iow_log_list:}
% \begin{macro}{\@@_list:N}
% Done as for input, but with a copy of the auxiliary so the name is correct.
@@ -3130,7 +3198,7 @@
\@@_str_cmp:nn
{ \@@_timestamp:n {#1} }
{ \@@_timestamp:n {#2} }
- #3 0 \exp_stop_f:
+ #3 \c_zero_int
\prg_return_true:
\else:
\prg_return_false:
diff --git a/macros/latex/contrib/l3kernel/l3flag.dtx b/macros/latex/contrib/l3kernel/l3flag.dtx
index 1b8dfa7c7a..74f3cf439c 100644
--- a/macros/latex/contrib/l3kernel/l3flag.dtx
+++ b/macros/latex/contrib/l3kernel/l3flag.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3fp-assign.dtx b/macros/latex/contrib/l3kernel/l3fp-assign.dtx
index 59eb0b65df..eb4500db35 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 2021-05-11}
+% \date{Released 2021-05-25}
% \maketitle
%
% \begin{documentation}
diff --git a/macros/latex/contrib/l3kernel/l3fp-aux.dtx b/macros/latex/contrib/l3kernel/l3fp-aux.dtx
index 1811a17475..c98bcf9035 100644
--- a/macros/latex/contrib/l3kernel/l3fp-aux.dtx
+++ b/macros/latex/contrib/l3kernel/l3fp-aux.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -1222,7 +1222,7 @@
\if_meaning:w 0 #1
\exp_after:wN \@@_small_int_true:wTF
\int_value:w \if_meaning:w 2 #5 - \fi:
- \if_int_compare:w #2 > 0 \exp_stop_f:
+ \if_int_compare:w #2 > \c_zero_int
1 0000 0000
\else:
#3
diff --git a/macros/latex/contrib/l3kernel/l3fp-basics.dtx b/macros/latex/contrib/l3kernel/l3fp-basics.dtx
index 0a5662979d..1fd4ce1656 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 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -1846,15 +1846,15 @@
\cs_new:Npn \@@_sqrt_auxiii_o:wnnnnnnnn
#1; #2#3#4#5#6#7#8#9
{
- \if_int_compare:w #1 > 1 \exp_stop_f:
+ \if_int_compare:w #1 > \c_one_int
\exp_after:wN \@@_sqrt_auxiv_o:NNNNNw
\int_value:w \@@_int_eval:w (#1#2 %)
\else:
- \if_int_compare:w #1#2 > 1 \exp_stop_f:
+ \if_int_compare:w #1#2 > \c_one_int
\exp_after:wN \@@_sqrt_auxv_o:NNNNNw
\int_value:w \@@_int_eval:w (#1#2#3 %)
\else:
- \if_int_compare:w #1#2#3 > 1 \exp_stop_f:
+ \if_int_compare:w #1#2#3 > \c_one_int
\exp_after:wN \@@_sqrt_auxvi_o:NNNNNw
\int_value:w \@@_int_eval:w (#1#2#3#4 %)
\else:
@@ -1872,7 +1872,7 @@
{ \@@_sqrt_auxviii_o:nnnnnnn {0000000#1} {#2#3#4#5#6} }
\cs_new:Npn \@@_sqrt_auxvii_o:NNNNNw 1#1#2#3#4#5#6;
{
- \if_int_compare:w #1#2 = 0 \exp_stop_f:
+ \if_int_compare:w #1#2 = \c_zero_int
\exp_after:wN \@@_sqrt_auxx_o:Nnnnnnnn
\fi:
\@@_sqrt_auxviii_o:nnnnnnn {00000000} {000#1#2#3#4#5}
@@ -1967,11 +1967,11 @@
% \begin{macrocode}
\cs_new:Npn \@@_sqrt_auxxii_o:nnnnnnnnw 0; #1#2#3#4#5#6#7#8 #9;
{
- \if_int_compare:w #1#2 > 0 \exp_stop_f:
- \if_int_compare:w #1#2 = 1 \exp_stop_f:
- \if_int_compare:w #3#4 = 0 \exp_stop_f:
- \if_int_compare:w #5#6 = 0 \exp_stop_f:
- \if_int_compare:w #7#8 = 0 \exp_stop_f:
+ \if_int_compare:w #1#2 > \c_zero_int
+ \if_int_compare:w #1#2 = \c_one_int
+ \if_int_compare:w #3#4 = \c_zero_int
+ \if_int_compare:w #5#6 = \c_zero_int
+ \if_int_compare:w #7#8 = \c_zero_int
\@@_sqrt_auxxiii_o:w
\fi:
\fi:
diff --git a/macros/latex/contrib/l3kernel/l3fp-convert.dtx b/macros/latex/contrib/l3kernel/l3fp-convert.dtx
index 097da442af..edf9984671 100644
--- a/macros/latex/contrib/l3kernel/l3fp-convert.dtx
+++ b/macros/latex/contrib/l3kernel/l3fp-convert.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -324,7 +324,7 @@
\cs_new:Npn \@@_to_decimal_large:Nnnw #1#2#3#4;
{
\exp_after:wN \@@_trim_zeros:w \int_value:w
- \if_int_compare:w #2 > 0 \exp_stop_f:
+ \if_int_compare:w #2 > \c_zero_int
#2
\fi:
\exp_stop_f:
diff --git a/macros/latex/contrib/l3kernel/l3fp-expo.dtx b/macros/latex/contrib/l3kernel/l3fp-expo.dtx
index 0be0e3f605..213885a701 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 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -182,7 +182,7 @@
{ %^^A todo: ln(1) should be "exact zero", not "underflow"
\exp_after:wN \@@_sanitize:Nw
\int_value:w % for the overall sign
- \if_int_compare:w #1 < 1 \exp_stop_f:
+ \if_int_compare:w #1 < \c_one_int
2
\else:
0
@@ -492,7 +492,7 @@
{ \@@_ln_Taylor_loop:www 21 ; {0000}{0000}{0000}{0000}{0000}{0000} ; }
\cs_new:Npn \@@_ln_Taylor_loop:www #1; #2; #3;
{
- \if_int_compare:w #1 = 1 \exp_stop_f:
+ \if_int_compare:w #1 = \c_one_int
\@@_ln_Taylor_break:w
\fi:
\exp_after:wN \@@_fixed_div_int:wwN \c_@@_one_fixed_tl #1;
@@ -564,7 +564,7 @@
\or:
\exp_after:wN \@@_ln_exponent_one:ww \int_value:w
\else:
- \if_int_compare:w #2 > 0 \exp_stop_f:
+ \if_int_compare:w #2 > \c_zero_int
\exp_after:wN \@@_ln_exponent_small:NNww
\exp_after:wN 0
\exp_after:wN \@@_fixed_sub:wwn \int_value:w
@@ -655,7 +655,7 @@
\exp_after:wN \@@_sanitize:Nw
\exp_after:wN 0
\int_value:w #1 \@@_int_eval:w
- \if_int_compare:w #4 < 0 \exp_stop_f:
+ \if_int_compare:w #4 < \c_zero_int
\exp_after:wN \use_i:nn
\else:
\exp_after:wN \use_ii:nn
@@ -707,7 +707,7 @@
{ \@@_exp_Taylor_loop:www 10 ; #1 ; #1 ; \s_@@_stop }
\cs_new:Npn \@@_exp_Taylor_loop:www #1; #2; #3;
{
- \if_int_compare:w #1 = 1 \exp_stop_f:
+ \if_int_compare:w #1 = \c_one_int
\exp_after:wN \@@_exp_Taylor_break:Nww
\fi:
\@@_fixed_div_int:wwN #3 ; #1 ;
@@ -1001,7 +1001,7 @@
\s_@@ \@@_chk:w 1 #1#2#3; \s_@@ \@@_chk:w #4#5
{
\if_int_compare:w \@@_str_if_eq:nn { #2 #3 }
- { 1 {1000} {0000} {0000} {0000} } = 0 \exp_stop_f:
+ { 1 {1000} {0000} {0000} {0000} } = \c_zero_int
\if_int_compare:w #4 #1 = 32 \exp_stop_f:
\exp_after:wN \@@_case_return_ii_o:ww
\fi:
@@ -1013,7 +1013,7 @@
\exp_after:wN #5
\or:
\if_meaning:w 2 #5 \exp_after:wN \reverse_if:N \fi:
- \if_int_compare:w #2 > 0 \exp_stop_f:
+ \if_int_compare:w #2 > \c_zero_int
\exp_after:wN \@@_case_return_o:Nww
\exp_after:wN \c_inf_fp
\else:
@@ -1048,7 +1048,7 @@
\exp_after:wN \@@_sanitize:Nw
\exp_after:wN 0
\int_value:w
- \if:w #1 \if_int_compare:w #3 > 0 \exp_stop_f: 0 \else: 2 \fi:
+ \if:w #1 \if_int_compare:w #3 > \c_zero_int 0 \else: 2 \fi:
\exp_after:wN \@@_pow_npos_aux:NNnww
\exp_after:wN +
\exp_after:wN \@@_fixed_to_float_o:wN
@@ -1080,7 +1080,7 @@
}
\cs_new:Npn \@@_pow_exponent:wnN #1; #2
{
- \if_int_compare:w #2 > 0 \exp_stop_f:
+ \if_int_compare:w #2 > \c_zero_int
\exp_after:wN \@@_pow_exponent:Nwnnnnnw % n\ln(10) - (-\ln(x))
\exp_after:wN +
\else:
@@ -1112,7 +1112,7 @@
}
\cs_new:Npn \@@_pow_B:wwN #1#2#3#4#5#6; #7;
{
- \if_int_compare:w #7 < 0 \exp_stop_f:
+ \if_int_compare:w #7 < \c_zero_int
\exp_after:wN \@@_pow_C_neg:w \int_value:w -
\else:
\if_int_compare:w #7 < 22 \exp_stop_f:
@@ -1177,7 +1177,7 @@
\if_case:w \@@_pow_neg_case:w #4 ;
\exp_after:wN \@@_pow_neg_aux:wNN
\or:
- \if_int_compare:w \@@_int_eval:w #1 / 2 = 1 \exp_stop_f:
+ \if_int_compare:w \@@_int_eval:w #1 / 2 = \c_one_int
\@@_invalid_operation_o:Nww ^ #3; #4;
\exp:w \exp_end_continue_f:w
\exp_after:wN \exp_after:wN
diff --git a/macros/latex/contrib/l3kernel/l3fp-extended.dtx b/macros/latex/contrib/l3kernel/l3fp-extended.dtx
index 44ae9a5d7d..d8d10634f9 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 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3fp-logic.dtx b/macros/latex/contrib/l3kernel/l3fp-logic.dtx
index 165d955d7b..3292b9f11e 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 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -214,7 +214,7 @@
\if_int_compare:w #4 < #1 - \fi: 1
\fi:
\else:
- \if_int_compare:w #1#4 = 0 \exp_stop_f:
+ \if_int_compare:w #1#4 = \c_zero_int
0
\else:
1
@@ -257,7 +257,7 @@
\use_none:n #1
\use_none:n #4
\if_int_compare:w
- \@@_compare_back_any:ww #1 #2 ; #4 #5 ; = 0 \exp_stop_f:
+ \@@_compare_back_any:ww #1 #2 ; #4 #5 ; = \c_zero_int
\else:
2 \exp_after:wN \prg_break:
\fi:
diff --git a/macros/latex/contrib/l3kernel/l3fp-parse.dtx b/macros/latex/contrib/l3kernel/l3fp-parse.dtx
index dcfa86e227..7c5f6a6e37 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 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -1757,7 +1757,7 @@
\if_meaning:w \scan_stop: #1
\if_int_compare:w
\@@_str_if_eq:nn { \s_@@ } { \exp_not:N #1 }
- = 0 \exp_stop_f:
+ = \c_zero_int
0
\__kernel_msg_expandable_error:nnn
{ fp } { after-e } { floating~point~ }
@@ -1771,7 +1771,7 @@
\else:
\if_int_compare:w
\@@_str_if_eq:nn { \int_value:w #1 } { \tex_the:D #1 }
- = 0 \exp_stop_f:
+ = \c_zero_int
\int_value:w #1
\else:
0
@@ -2265,7 +2265,7 @@
\if_catcode:w \scan_stop: \exp_not:N #2
\if_int_compare:w
\@@_str_if_eq:nn { \s_@@_expr_mark } { \exp_not:N #2 }
- = 0 \exp_stop_f:
+ = \c_zero_int
\exp_after:wN \exp_after:wN
\exp_after:wN \@@_parse_infix_mark:NNN
\else:
@@ -2317,7 +2317,7 @@
\if_catcode:w \scan_stop: \exp_not:N #2
\if_int_compare:w
\@@_str_if_eq:nn { \s_@@_expr_mark } { \exp_not:N #2 }
- = 0 \exp_stop_f:
+ = \c_zero_int
\exp_after:wN \exp_after:wN
\exp_after:wN \@@_parse_infix_mark:NNN
\else:
diff --git a/macros/latex/contrib/l3kernel/l3fp-random.dtx b/macros/latex/contrib/l3kernel/l3fp-random.dtx
index 7b854343ed..d801f89d82 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 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -396,19 +396,19 @@
\if_meaning:w 1 #1
\if_int_compare:w
\@@_use_i_until_s:nw #3 ; > \c_@@_prec_int
- 1 \exp_stop_f:
+ \c_one_int
\fi:
\fi:
}
- { 1 \exp_stop_f: }
+ { \c_one_int }
}
\cs_new:Npn \@@_randint_o:w #1; #2; @
{
\if_case:w
\@@_randint_badarg:w #1;
\@@_randint_badarg:w #2;
- \if:w 1 \@@_compare_back:ww #2; #1; 1 \exp_stop_f: \fi:
- 0 \exp_stop_f:
+ \if:w 1 \@@_compare_back:ww #2; #1; \c_one_int \fi:
+ \c_zero_int
\@@_randint_auxi_o:ww #1; #2;
\or:
\@@_invalid_operation_tl_o:ff
@@ -632,7 +632,7 @@
}
\cs_new:Npn \@@_randint:n #1
{
- \if_int_compare:w #1 < 1 \exp_stop_f:
+ \if_int_compare:w #1 < \c_one_int
\__kernel_msg_expandable_error:nnnn
{ kernel } { randint-backward-range } { 1 } {#1}
\@@_randint:ww #1; 1;
diff --git a/macros/latex/contrib/l3kernel/l3fp-round.dtx b/macros/latex/contrib/l3kernel/l3fp-round.dtx
index 5012e48e9b..4832e89517 100644
--- a/macros/latex/contrib/l3kernel/l3fp-round.dtx
+++ b/macros/latex/contrib/l3kernel/l3fp-round.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -198,21 +198,21 @@
\cs_new:Npn \@@_round_to_ninf:NNN #1 #2 #3
{
\if_meaning:w 2 #1
- \if_int_compare:w #3 > 0 \exp_stop_f:
+ \if_int_compare:w #3 > \c_zero_int
\@@_round_return_one:
\fi:
\fi:
- 0 \exp_stop_f:
+ \c_zero_int
}
-\cs_new:Npn \@@_round_to_zero:NNN #1 #2 #3 { 0 \exp_stop_f: }
+\cs_new:Npn \@@_round_to_zero:NNN #1 #2 #3 { \c_zero_int }
\cs_new:Npn \@@_round_to_pinf:NNN #1 #2 #3
{
\if_meaning:w 0 #1
- \if_int_compare:w #3 > 0 \exp_stop_f:
+ \if_int_compare:w #3 > \c_zero_int
\@@_round_return_one:
\fi:
\fi:
- 0 \exp_stop_f:
+ \c_zero_int
}
\cs_new:Npn \@@_round_to_nearest:NNN #1 #2 #3
{
@@ -225,7 +225,7 @@
\fi:
\fi:
\fi:
- 0 \exp_stop_f:
+ \c_zero_int
}
\cs_new:Npn \@@_round_to_nearest_ninf:NNN #1 #2 #3
{
@@ -238,14 +238,14 @@
\fi:
\fi:
\fi:
- 0 \exp_stop_f:
+ \c_zero_int
}
\cs_new:Npn \@@_round_to_nearest_zero:NNN #1 #2 #3
{
\if_int_compare:w #3 > \c_@@_five_int
\@@_round_return_one:
\fi:
- 0 \exp_stop_f:
+ \c_zero_int
}
\cs_new:Npn \@@_round_to_nearest_pinf:NNN #1 #2 #3
{
@@ -258,7 +258,7 @@
\fi:
\fi:
\fi:
- 0 \exp_stop_f:
+ \c_zero_int
}
\cs_new_eq:NN \@@_round:NNN \@@_round_to_nearest:NNN
% \end{macrocode}
@@ -286,7 +286,7 @@
\if_int_odd:w 0 \if_meaning:w 0 #3 1 \fi:
\if_meaning:w 5 #3 1 \fi:
\exp_stop_f:
- \if_int_compare:w \@@_int_eval:w #4 > 0 \exp_stop_f:
+ \if_int_compare:w \@@_int_eval:w #4 > \c_zero_int
1 +
\fi:
\fi:
@@ -311,7 +311,7 @@
\if_int_odd:w \if_meaning:w 0 #1 1 \else:
\if_meaning:w 5 #1 1 \else:
0 \fi: \fi: \exp_stop_f:
- \if_int_compare:w \@@_int_eval:w #2 > 0 \exp_stop_f:
+ \if_int_compare:w \@@_int_eval:w #2 > \c_zero_int
\@@_int_eval:w 1 +
\fi:
\fi:
@@ -350,10 +350,10 @@
\cs_new_eq:NN \@@_round_to_ninf_neg:NNN \@@_round_to_pinf:NNN
\cs_new:Npn \@@_round_to_zero_neg:NNN #1 #2 #3
{
- \if_int_compare:w #3 > 0 \exp_stop_f:
+ \if_int_compare:w #3 > \c_zero_int
\@@_round_return_one:
\fi:
- 0 \exp_stop_f:
+ \c_zero_int
}
\cs_new_eq:NN \@@_round_to_pinf_neg:NNN \@@_round_to_ninf:NNN
\cs_new_eq:NN \@@_round_to_nearest_neg:NNN \@@_round_to_nearest:NNN
@@ -364,7 +364,7 @@
\if_int_compare:w #3 < \c_@@_five_int \else:
\@@_round_return_one:
\fi:
- 0 \exp_stop_f:
+ \c_zero_int
}
\cs_new_eq:NN \@@_round_to_nearest_pinf_neg:NNN
\@@_round_to_nearest_ninf:NNN
@@ -525,12 +525,12 @@
{
\exp_after:wN \@@_round_normal:NNwNnn
\int_value:w \@@_int_eval:w
- \if_int_compare:w #2 > 0 \exp_stop_f:
+ \if_int_compare:w #2 > \c_zero_int
1 \int_value:w #2
\exp_after:wN \@@_round_pack:Nw
\int_value:w \@@_int_eval:w 1#3 +
\else:
- \if_int_compare:w #3 > 0 \exp_stop_f:
+ \if_int_compare:w #3 > \c_zero_int
1 \int_value:w #3 +
\fi:
\fi:
diff --git a/macros/latex/contrib/l3kernel/l3fp-traps.dtx b/macros/latex/contrib/l3kernel/l3fp-traps.dtx
index c4dbfa4d15..1a376b8eda 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 2021-05-11}
+% \date{Released 2021-05-25}
% \maketitle
%
% \begin{documentation}
diff --git a/macros/latex/contrib/l3kernel/l3fp-trig.dtx b/macros/latex/contrib/l3kernel/l3fp-trig.dtx
index 669642d2e8..0a2c9f8616 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 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -1311,7 +1311,7 @@
7 - \@@_int_eval:w
\fi:
\if_int_compare:w
- \@@_ep_compare:wwww #2,#3; #5,#6; > 0 \exp_stop_f:
+ \@@_ep_compare:wwww #2,#3; #5,#6; > \c_zero_int
3 -
\exp_after:wN \@@_reverse_args:Nww
\fi:
@@ -1398,7 +1398,7 @@
% \begin{macrocode}
\cs_new:Npn \@@_atan_Taylor_loop:www #1; #2; #3;
{
- \if_int_compare:w #1 = -1 \exp_stop_f:
+ \if_int_compare:w #1 = - \c_one_int
\@@_atan_Taylor_break:w
\fi:
\exp_after:wN \@@_fixed_div_int:wwN \c_@@_one_fixed_tl #1;
@@ -1550,7 +1550,7 @@
\cs_new:Npn \@@_asin_normal_o:NfwNnnnnw
#1#2#3 \s_@@ \@@_chk:w 1#4#5#6#7#8#9;
{
- \if_int_compare:w #5 < 1 \exp_stop_f:
+ \if_int_compare:w #5 < \c_one_int
\exp_after:wN \@@_use_none_until_s:w
\fi:
\if_int_compare:w \@@_int_eval:w #5 + #6#7 + #8#9 = 1000 0001 ~
diff --git a/macros/latex/contrib/l3kernel/l3fp.dtx b/macros/latex/contrib/l3kernel/l3fp.dtx
index 27ee89c073..3a007cb6a6 100644
--- a/macros/latex/contrib/l3kernel/l3fp.dtx
+++ b/macros/latex/contrib/l3kernel/l3fp.dtx
@@ -49,7 +49,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3fparray.dtx b/macros/latex/contrib/l3kernel/l3fparray.dtx
index a66073e073..76cd235b62 100644
--- a/macros/latex/contrib/l3kernel/l3fparray.dtx
+++ b/macros/latex/contrib/l3kernel/l3fparray.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3int.dtx b/macros/latex/contrib/l3kernel/l3int.dtx
index 5994a193c6..505afcd9ee 100644
--- a/macros/latex/contrib/l3kernel/l3int.dtx
+++ b/macros/latex/contrib/l3kernel/l3int.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -1088,13 +1088,14 @@
%
% \begin{macro}{\int_eval:n}
% \begin{macro}{\int_eval:w}
-% Wrapper for \cs{@@_eval:w}: can be used in an integer expression
-% or directly in the input stream.
-% When debugging, use parentheses to catch early termination.
+% Wrapper for \cs{@@_eval:w}: can be used in an integer expression or
+% directly in the input stream. It is very slightly faster to use
+% \tn{the} rather than \tn{number} to turn the expression to a number.
+% When debugging, we introduce parentheses to catch early termination (see \pkg{l3debug}).
% \begin{macrocode}
\cs_new:Npn \int_eval:n #1
- { \int_value:w \@@_eval:w #1 \@@_eval_end: }
-\cs_new:Npn \int_eval:w { \int_value:w \@@_eval:w }
+ { \tex_the:D \@@_eval:w #1 \@@_eval_end: }
+\cs_new:Npn \int_eval:w { \tex_the:D \@@_eval:w }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1399,15 +1400,17 @@
% \begin{macro}{\int_gsub:Nn, \int_gsub:cn}
% \UnitTested
% Adding and subtracting to and from a counter.
+% Including here the optional |by| would slow down these operations
+% by a few percent.
% \begin{macrocode}
\cs_new_protected:Npn \int_add:Nn #1#2
- { \tex_advance:D #1 by \@@_eval:w #2 \@@_eval_end: }
+ { \tex_advance:D #1 \@@_eval:w #2 \@@_eval_end: }
\cs_new_protected:Npn \int_sub:Nn #1#2
- { \tex_advance:D #1 by - \@@_eval:w #2 \@@_eval_end: }
+ { \tex_advance:D #1 - \@@_eval:w #2 \@@_eval_end: }
\cs_new_protected:Npn \int_gadd:Nn #1#2
- { \tex_global:D \tex_advance:D #1 by \@@_eval:w #2 \@@_eval_end: }
+ { \tex_global:D \tex_advance:D #1 \@@_eval:w #2 \@@_eval_end: }
\cs_new_protected:Npn \int_gsub:Nn #1#2
- { \tex_global:D \tex_advance:D #1 by - \@@_eval:w #2 \@@_eval_end: }
+ { \tex_global:D \tex_advance:D #1 - \@@_eval:w #2 \@@_eval_end: }
\cs_generate_variant:Nn \int_add:Nn { c }
\cs_generate_variant:Nn \int_gadd:Nn { c }
\cs_generate_variant:Nn \int_sub:Nn { c }
@@ -1452,12 +1455,14 @@
% \begin{macro}{\int_gset:Nn, \int_gset:cn}
% \UnitTested
% As integers are register-based \TeX{} issues an error
-% if they are not defined.
+% if they are not defined. While the |=| sign is optional, this
+% version with |=| is slightly quicker than without, while adding the
+% optional space after |=| slows things down minutely.
% \begin{macrocode}
\cs_new_protected:Npn \int_set:Nn #1#2
- { #1 ~ \@@_eval:w #2 \@@_eval_end: }
+ { #1 = \@@_eval:w #2 \@@_eval_end: }
\cs_new_protected:Npn \int_gset:Nn #1#2
- { \tex_global:D #1 ~ \@@_eval:w #2 \@@_eval_end: }
+ { \tex_global:D #1 = \@@_eval:w #2 \@@_eval_end: }
\cs_generate_variant:Nn \int_set:Nn { c }
\cs_generate_variant:Nn \int_gset:Nn { c }
% \end{macrocode}
@@ -1468,13 +1473,10 @@
%
% \begin{macro}{\int_use:N, \int_use:c}
% \UnitTested
-% Here is how counters are accessed:
+% Here is how counters are accessed.
+% We hand-code the |c| variant for some speed gain.
% \begin{macrocode}
\cs_new_eq:NN \int_use:N \tex_the:D
-% \end{macrocode}
-% We hand-code this for some speed gain:
-% \begin{macrocode}
-%\cs_generate_variant:Nn \int_use:N { c }
\cs_new:Npn \int_use:c #1 { \tex_the:D \cs:w #1 \cs_end: }
% \end{macrocode}
% \end{macro}
diff --git a/macros/latex/contrib/l3kernel/l3intarray.dtx b/macros/latex/contrib/l3kernel/l3intarray.dtx
index f67e937989..6f8215023c 100644
--- a/macros/latex/contrib/l3kernel/l3intarray.dtx
+++ b/macros/latex/contrib/l3kernel/l3intarray.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3kernel-functions.dtx b/macros/latex/contrib/l3kernel/l3kernel-functions.dtx
index 428774aa93..51b6fe2a82 100644
--- a/macros/latex/contrib/l3kernel/l3kernel-functions.dtx
+++ b/macros/latex/contrib/l3kernel/l3kernel-functions.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3keys.dtx b/macros/latex/contrib/l3kernel/l3keys.dtx
index 8f5f984c79..113760c969 100644
--- a/macros/latex/contrib/l3kernel/l3keys.dtx
+++ b/macros/latex/contrib/l3kernel/l3keys.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -1006,7 +1006,7 @@
% comma and |#2| will be the active equals sign.
% \begin{macrocode}
\group_begin:
- \cs_set_protected:Npn \@@_tmp:NN #1#2
+ \cs_set_protected:Npn \@@_tmp:w #1#2
{
% \end{macrocode}
%
@@ -1016,10 +1016,27 @@
% The use of \cs{s_@@_mark} here prevents loss of braces from the key
% argument.
% \begin{macrocode}
- \cs_new:Npn \keyval_parse:nnn ##1 ##2 ##3
+ \cs_if_exist:NTF \tex_expanded:D
{
- \group_align_safe_begin:
- \@@_loop_active:nnw {##1} {##2} \s_@@_mark ##3 #1 \s_@@_tail #1
+ \cs_new:Npn \keyval_parse:nnn ##1 ##2 ##3
+ {
+ \__kernel_exp_not:w \tex_expanded:D
+ {
+ {
+ \@@_loop_active:nnw {##1} {##2}
+ \s_@@_mark ##3 #1 \s_@@_tail #1
+ }
+ }
+ }
+ }
+ {
+ \cs_new:Npn \keyval_parse:nnn ##1 ##2 ##3
+ {
+ \group_align_safe_begin:
+ \@@_loop_active:nnw {##1} {##2}
+ \s_@@_mark ##3 #1 \s_@@_tail #1
+ \group_align_safe_end:
+ }
}
\cs_new_eq:NN \keyval_parse:NNn \keyval_parse:nnn
% \end{macrocode}
@@ -1258,17 +1275,17 @@
\cs_new:Npn \@@_end_loop_active:w
\s_@@_tail
\@@_loop_other:nnw ##1 \s_@@_mark \s_@@_tail , \s_@@_tail ,
- { \group_align_safe_end: }
+ { }
% \end{macrocode}
% \end{macro}
%
-% The parsing loops are done, so here ends the definition of \cs{@@_tmp:NN},
+% The parsing loops are done, so here ends the definition of \cs{@@_tmp:w},
% which will finally set up the macros.
% \begin{macrocode}
}
\char_set_catcode_active:n { `\, }
\char_set_catcode_active:n { `\= }
- \@@_tmp:NN , =
+ \@@_tmp:w , =
\group_end:
% \end{macrocode}
%
@@ -1279,24 +1296,32 @@
% \cs{exp_not:n} with the correct arguments. Afterwards they insert the next
% iteration of the other loop.
% \begin{macrocode}
-\cs_new:Npn \@@_pair:nnnn #1 #2 #3 #4
- {
- \@@_if_blank:w \s_@@_mark #2 \s_@@_nil \s_@@_stop \@@_blank_key_error:w
- \s_@@_mark \s_@@_stop
- \group_align_safe_end:
- \exp_not:n { #4 { #2 } { #1 } }
- \group_align_safe_begin:
- \@@_loop_other:nnw {#3} {#4}
- }
-\cs_new:Npn \@@_key:nn #1 #2
- {
- \@@_if_blank:w \s_@@_mark #1 \s_@@_nil \s_@@_stop \@@_blank_key_error:w
- \s_@@_mark \s_@@_stop
- \group_align_safe_end:
- \exp_not:n { #2 { #1 } }
- \group_align_safe_begin:
- \@@_loop_other:nnw {#2}
- }
+\group_begin:
+ \cs_set_protected:Npn \@@_tmp:w #1#2
+ {
+ \cs_new:Npn \@@_pair:nnnn ##1 ##2 ##3 ##4
+ {
+ \@@_if_blank:w \s_@@_mark ##2 \s_@@_nil \s_@@_stop \@@_blank_key_error:w
+ \s_@@_mark \s_@@_stop
+ #1
+ \exp_not:n { ##4 {##2} {##1} }
+ #2
+ \@@_loop_other:nnw {##3} {##4}
+ }
+ \cs_new:Npn \@@_key:nn ##1 ##2
+ {
+ \@@_if_blank:w \s_@@_mark ##1 \s_@@_nil \s_@@_stop \@@_blank_key_error:w
+ \s_@@_mark \s_@@_stop
+ #1
+ \exp_not:n { ##2 {##1} }
+ #2
+ \@@_loop_other:nnw {##2}
+ }
+ }
+ \cs_if_exist:NTF \tex_expanded:D
+ { \@@_tmp:w { } { } }
+ { \@@_tmp:w \group_align_safe_end: \group_align_safe_begin: }
+\group_end:
% \end{macrocode}
% \end{macro}
%
@@ -1318,11 +1343,10 @@
% \begin{macrocode}
\cs_new:Npn \@@_blank_true:w \s_@@_mark \s_@@_stop \@@_trim:nN #1 \@@_key:nn
{ \@@_loop_other:nnw }
-\cs_new:Npn \@@_blank_key_error:w
- \s_@@_mark \s_@@_stop \group_align_safe_end: \exp_not:n #1
+\cs_new:Npn \@@_blank_key_error:w #1 \@@_loop_other:nnw
{
- \__kernel_msg_expandable_error:nn
- { keyval } { blank-key-name }
+ \__kernel_msg_expandable_error:nn { keyval } { blank-key-name }
+ \@@_loop_other:nnw
}
% \end{macrocode}
% \end{macro}
@@ -1346,7 +1370,7 @@
% worth it.
% \begin{macrocode}
\group_begin:
- \cs_set_protected:Npn \@@_tmp:n #1
+ \cs_set_protected:Npn \@@_tmp:w #1
{
\cs_new:Npn \@@_trim:nN ##1
{
@@ -1387,7 +1411,7 @@
##2
{ ##2 { ##1 } }
}
- \@@_tmp:n { ~ }
+ \@@_tmp:w { ~ }
\group_end:
% \end{macrocode}
% \end{macro}
@@ -1642,14 +1666,14 @@
% Searching for a property means finding the last |.| in the input,
% and storing the text before and after it. Everything is turned into
% strings, so there is no problem using an \texttt{x}-type expansion. Since
-% |\__keys_trim_spaces:n| will turn its argument into a string anyway, this
+% \cs{@@_trim_spaces:n} will turn its argument into a string anyway, this
% function uses \cs{cs_set_nopar:Npx} instead of \cs{tl_set:Nx} to gain some
% speed.
% \begin{macrocode}
\cs_new_protected:Npn \@@_property_find:n #1
{
- \cs_set_nopar:Npx \l__keys_property_str { \__keys_trim_spaces:n { #1 } }
- \exp_after:wN \@@_property_find_auxi:w \l__keys_property_str
+ \cs_set_nopar:Npx \l_@@_property_str { \@@_trim_spaces:n { #1 } }
+ \exp_after:wN \@@_property_find_auxi:w \l_@@_property_str
\s_@@_nil \@@_property_find_auxii:w
. \s_@@_nil \@@_property_find_err:w
}
@@ -1662,7 +1686,7 @@
\@@_property_find_err:w
{
\cs_set_nopar:Npx \l_keys_path_str
- { \str_if_empty:NF \l__keys_module_str { \l__keys_module_str / } #1 }
+ { \str_if_empty:NF \l_@@_module_str { \l_@@_module_str / } #1 }
\@@_property_find_auxi:w #2 \s_@@_nil \@@_property_find_auxiii:w . \s_@@_nil
\@@_property_find_auxiv:w
}
@@ -1675,15 +1699,15 @@
#1 \s_@@_nil \@@_property_find_auxiii:w
\s_@@_mark \s_@@_nil \@@_property_find_auxiv:w
{
- \cs_set_nopar:Npx \l__keys_property_str { . #1 }
+ \cs_set_nopar:Npx \l_@@_property_str { . #1 }
\cs_set_nopar:Npx \l_keys_path_str
- { \exp_after:wN \__keys_trim_spaces:n \exp_after:wN { \l_keys_path_str } }
+ { \exp_after:wN \@@_trim_spaces:n \exp_after:wN { \l_keys_path_str } }
\tl_set_eq:NN \l_keys_path_tl \l_keys_path_str
}
\cs_new_protected:Npn \@@_property_find_err:w
#1 \s_@@_nil #2 \@@_property_find_err:w
{
- \str_clear:N \l__keys_property_str
+ \str_clear:N \l_@@_property_str
\__kernel_msg_error:nnn { keys } { no-property } {#1}
}
% \end{macrocode}
@@ -2753,6 +2777,10 @@
% of groups which apply to a key with the list of those which have been
% set active. That requires two mappings, and again a different outcome
% depending on whether opt-in or opt-out is set.
+% We cannot replace the clist mapping by \cs{clist_if_in:NnTF} because
+% catcodes may not be the same; they cannot be normalized easily in the
+% clist because of the remote possibility that some items need braces
+% if they involve commas or leading/trailing spaces.
% \begin{macrocode}
\cs_new_protected:Npn \@@_check_groups:
{
@@ -3060,7 +3088,7 @@
% much faster to just directly strip spaces around |/|.
% \begin{macrocode}
\group_begin:
- \cs_set:Npn \@@_tmp:n #1
+ \cs_set:Npn \@@_tmp:w #1
{
\cs_new:Npn \@@_trim_spaces:n ##1
{
@@ -3072,7 +3100,7 @@
\s_@@_mark \@@_trim_spaces_auxiii:w
}
}
- \@@_tmp:n { ~ }
+ \@@_tmp:w { ~ }
\group_end:
\cs_new:Npn \@@_trim_spaces_auxi:w #1 ~ / #2 \s_@@_nil #3
{
diff --git a/macros/latex/contrib/l3kernel/l3legacy.dtx b/macros/latex/contrib/l3kernel/l3legacy.dtx
index 05b98fed56..1055137bb6 100644
--- a/macros/latex/contrib/l3kernel/l3legacy.dtx
+++ b/macros/latex/contrib/l3kernel/l3legacy.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -63,6 +63,28 @@
% \meta{name} of the conditional should \emph{omit} the leading \texttt{if}.
% \end{function}
%
+% \begin{function}[added = 2021-05-10]
+% {
+% \legacy_if_set_true:n, \legacy_if_set_false:n,
+% \legacy_if_gset_true:n, \legacy_if_gset_false:n
+% }
+% \begin{syntax}
+% \cs{legacy_if_set_true:n} \Arg{name}
+% \cs{legacy_if_set_false:n} \Arg{name}
+% \end{syntax}
+% Sets the \LaTeXe{}/plain \TeX{} conditional |\if|\meta{name}
+% (generated by \tn{newif}) to be \texttt{true} or \texttt{false}.
+% \end{function}
+%
+% \begin{function}[added = 2021-05-10]{\legacy_if_set:nn, \legacy_if_gset:nn}
+% \begin{syntax}
+% \cs{legacy_if_set:nn} \Arg{name} \Arg{boolexpr}
+% \end{syntax}
+% Sets the \LaTeXe{}/plain \TeX{} conditional |\if|\meta{name}
+% (generated by \tn{newif}) to the result of evaluating the
+% \meta{boolean expression}.
+% \end{function}
+%
% \end{documentation}
%
% \begin{implementation}
@@ -91,6 +113,40 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}
+% {
+% \legacy_if_set_true:n, \legacy_if_set_false:n,
+% \legacy_if_gset_true:n, \legacy_if_gset_false:n
+% }
+% A friendly wrapper.
+% \begin{macrocode}
+\cs_new_protected:Npn \legacy_if_set_true:n #1
+ { \cs_set_eq:cN { if#1 } \if_true: }
+\cs_new_protected:Npn \legacy_if_set_false:n #1
+ { \cs_set_eq:cN { if#1 } \if_false: }
+\cs_new_protected:Npn \legacy_if_gset_true:n #1
+ { \cs_gset_eq:cN { if#1 } \if_true: }
+\cs_new_protected:Npn \legacy_if_gset_false:n #1
+ { \cs_gset_eq:cN { if#1 } \if_false: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\legacy_if_set:nn, \legacy_if_gset:nn}
+% A more elaborate wrapper.
+% \begin{macrocode}
+\cs_new_protected:Npn \legacy_if_set:nn #1#2
+ {
+ \bool_if:nTF {#2} \legacy_if_set_true:n \legacy_if_set_false:n
+ {#1}
+ }
+\cs_new_protected:Npn \legacy_if_gset:nn #1#2
+ {
+ \bool_if:nTF {#2} \legacy_if_gset_true:n \legacy_if_gset_false:n
+ {#1}
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macrocode}
%</package>
% \end{macrocode}
diff --git a/macros/latex/contrib/l3kernel/l3luatex.dtx b/macros/latex/contrib/l3kernel/l3luatex.dtx
index 35c8df065d..19487b5047 100644
--- a/macros/latex/contrib/l3kernel/l3luatex.dtx
+++ b/macros/latex/contrib/l3kernel/l3luatex.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3msg.dtx b/macros/latex/contrib/l3kernel/l3msg.dtx
index ed2169b94f..a46d268a48 100644
--- a/macros/latex/contrib/l3kernel/l3msg.dtx
+++ b/macros/latex/contrib/l3kernel/l3msg.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -274,6 +274,25 @@
% course the sense of the message may be impaired). The four arguments are
% converted to strings before being added to the message text: the
% \texttt{x}-type variants should be used to expand material.
+% Note that this expansion takes place with the standard definitions in
+% effect, which means that shorthands such as |\~| or |\\| are
+% \emph{not} available; instead one should use \cs{iow_char:N} |\~| and
+% \cs{iow_newline:}, respectively.
+% The following message classes exist:
+% \begin{itemize}
+% \item \texttt{fatal}, ending the \TeX{} run;
+% \item \texttt{critical}, ending the file being input;
+% \item \texttt{error}, interrupting the \TeX{} run without ending it;
+% \item \texttt{warning}, written to terminal and log file, for
+% important messages that may require corrections by the user;
+% \item \texttt{note} (less common than \texttt{info}) for important
+% information messages written to the terminal and log file;
+% \item \texttt{info} for normal information messages written to the log
+% file only;
+% \item \texttt{term} and \texttt{log} for un-decorated messages written
+% to the terminal and log file, or to the log file only;
+% \item \texttt{none} for suppressed messages.
+% \end{itemize}
%
% \begin{function}[updated = 2012-08-11]
% {
@@ -365,8 +384,17 @@
% is not interrupted.
% \end{function}
%
-% \begin{function}[updated = 2012-08-11]
+% \begin{function}[added = 2021-05-18]
% {
+% \msg_note:nnnnnn ,
+% \msg_note:nnnnn ,
+% \msg_note:nnnn ,
+% \msg_note:nnn ,
+% \msg_note:nn ,
+% \msg_note:nnxxxx ,
+% \msg_note:nnxxx ,
+% \msg_note:nnxx ,
+% \msg_note:nnx ,
% \msg_info:nnnnnn ,
% \msg_info:nnnnn ,
% \msg_info:nnnn ,
@@ -378,15 +406,28 @@
% \msg_info:nnx
% }
% \begin{syntax}
+% \cs{msg_note:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four}
% \cs{msg_info:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four}
% \end{syntax}
% Issues \meta{module} information \meta{message}, passing
% \meta{arg one} to \meta{arg four} to the text-creating functions.
-% The information text is added to the log file.
+% For the more common \cs{msg_info:nnnnnn}, the information text is
+% added to the log file only, while \cs{msg_note:nnnnnn} adds the
+% info text to both the log file and the terminal. The \TeX{} run is
+% not interrupted.
% \end{function}
%
% \begin{function}[updated = 2012-08-11]
% {
+% \msg_term:nnnnnn ,
+% \msg_term:nnnnn ,
+% \msg_term:nnnn ,
+% \msg_term:nnn ,
+% \msg_term:nn ,
+% \msg_term:nnxxxx ,
+% \msg_term:nnxxx ,
+% \msg_term:nnxx ,
+% \msg_term:nnx ,
% \msg_log:nnnnnn ,
% \msg_log:nnnnn ,
% \msg_log:nnnn ,
@@ -398,33 +439,15 @@
% \msg_log:nnx
% }
% \begin{syntax}
-% \cs{msg_log:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four}
-% \end{syntax}
-% Issues \meta{module} information \meta{message}, passing
-% \meta{arg one} to \meta{arg four} to the text-creating functions.
-% The information text is added to the log file: the output
-% is briefer than \cs{msg_info:nnnnnn}.
-% \end{function}
-%
-% \begin{function}[added = 2020-07-16]
-% {
-% \msg_term:nnnnnn ,
-% \msg_term:nnnnn ,
-% \msg_term:nnnn ,
-% \msg_term:nnn ,
-% \msg_term:nn ,
-% \msg_term:nnxxxx ,
-% \msg_term:nnxxx ,
-% \msg_term:nnxx ,
-% \msg_term:nnx
-% }
-% \begin{syntax}
% \cs{msg_term:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four}
+% \cs{msg_log:nnnnnn} \Arg{module} \Arg{message} \Arg{arg one} \Arg{arg two} \Arg{arg three} \Arg{arg four}
% \end{syntax}
% Issues \meta{module} information \meta{message}, passing
% \meta{arg one} to \meta{arg four} to the text-creating functions.
-% The information text is printed on the terminal (and added to the
-% log file): the output is similar to that of \cs{msg_log:nnnnnn}.
+% The output is briefer than \cs{msg_info:nnnnnn}, omitting for
+% instance the module name. It is added to the log file by
+% \cs{msg_log:nnnnnn} while \cs{msg_term:nnnnnn} also prints it on the
+% terminal.
% \end{function}
%
% \begin{function}[updated = 2012-08-11]
@@ -557,6 +580,9 @@
% \end{syntax}
% Changes the behaviour of messages of \meta{class one} so that they
% are processed using the code for those of \meta{class two}.
+% Each \meta{class} can be one of \texttt{fatal}, \texttt{critical},
+% \texttt{error}, \texttt{warning}, \texttt{note}, \texttt{info},
+% \texttt{term}, \texttt{log}, \texttt{none}.
% \end{function}
%
% \begin{function}[updated = 2012-04-27]{\msg_redirect_module:nnn}
@@ -968,7 +994,7 @@
\cs_new:Npn \@@_text:nn #1#2
{
\exp_args:Nf \@@_text:n { \msg_module_type:n {#1} }
- \msg_module_name:n {#1} ~
+ \exp_args:Nf \@@_text:n { \msg_module_name:n {#1} }
#2
}
\cs_new:Npn \@@_text:n #1
@@ -1193,6 +1219,16 @@
%
% \begin{macro}
% {
+% \@@_info_aux:Nnn ,
+% \msg_note:nnnnnn ,
+% \msg_note:nnnnn ,
+% \msg_note:nnnn ,
+% \msg_note:nnn ,
+% \msg_note:nn ,
+% \msg_note:nnxxxx ,
+% \msg_note:nnxxx ,
+% \msg_note:nnxx ,
+% \msg_note:nnx ,
% \msg_info:nnnnnn ,
% \msg_info:nnnnn ,
% \msg_info:nnnn ,
@@ -1203,18 +1239,25 @@
% \msg_info:nnxx ,
% \msg_info:nnx
% }
-% Information only goes into the log.
+% Information has no decoration and goes either to the log or both
+% log and terminal.
% \begin{macrocode}
+ \@@_class_new:nn { note }
+ {
+ \@@_info_aux:Nnn \iow_term:n {#1}
+ { \use:c { \c_@@_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6} }
+ }
\@@_class_new:nn { info }
{
- \str_set:Nx \l_@@_text_str { \msg_info_text:n {#1} }
- \str_set:Nx \l_@@_name_str { \msg_module_name:n {#1} }
- \iow_log:n { }
- \iow_wrap:nxnN
- {
- \l_@@_text_str : ~
- \use:c { \c_@@_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6}
- }
+ \@@_info_aux:Nnn \iow_log:n {#1}
+ { \use:c { \c_@@_text_prefix_tl #1 / #2 } {#3} {#4} {#5} {#6} }
+ }
+ \cs_new_protected:Npn \@@_info_aux:Nnn #1#2#3
+ {
+ \str_set:Nx \l_@@_text_str { \msg_info_text:n {#2} }
+ \str_set:Nx \l_@@_name_str { \msg_module_name:n {#2} }
+ #1 { }
+ \iow_wrap:nxnN { \l_@@_text_str : ~ #3 }
{
( \l_@@_name_str )
\prg_replicate:nn
@@ -1224,8 +1267,8 @@
}
{ ~ }
}
- { } \iow_log:n
- \iow_log:n { }
+ { } #1
+ #1 { }
}
% \end{macrocode}
% \end{macro}
@@ -1761,6 +1804,7 @@
% \begin{macro}
% {
% \__kernel_msg_log:nnnnnn, \__kernel_msg_log:nnxxxx,
+% \__kernel_msg_term:nnnnnn, \__kernel_msg_term:nnxxxx,
% \__kernel_msg_show:nnnnnn, \__kernel_msg_show:nnxxxx
% }
% For showing messages.
@@ -1768,6 +1812,9 @@
\cs_new_protected:Npn \__kernel_msg_log:nnnnnn #1
{ \msg_log:nnnnnn { LaTeX / #1 } }
\cs_generate_variant:Nn \__kernel_msg_log:nnnnnn { nnxxxx }
+\cs_new_protected:Npn \__kernel_msg_term:nnnnnn #1
+ { \msg_term:nnnnnn { LaTeX / #1 } }
+\cs_generate_variant:Nn \__kernel_msg_term:nnnnnn { nnxxxx }
\cs_new_protected:Npn \__kernel_msg_show:nnnnnn #1
{ \msg_show:nnnnnn { LaTeX / #1 } }
\cs_generate_variant:Nn \__kernel_msg_show:nnnnnn { nnxxxx }
@@ -1865,6 +1912,7 @@
\c_@@_coding_error_text_tl
Functions~defined~through~\iow_char:N\\cs_new:Nn~must~have~
a~signature~consisting~of~only~normal~arguments~'N'~and~'n'.~
+ The~signature~'#2'~of~'#1'~contains~other~arguments~'#3'.~
To~define~variants~use~\iow_char:N\\cs_generate_variant:Nn~
and~to~define~other~functions~use~\iow_char:N\\cs_new:Npn.
}
@@ -1986,7 +2034,7 @@
\__kernel_msg_new:nnnn { quark } { invalid-function }
{ Quark~test~function~'#1'~is~invalid. }
{
- \c__msg_coding_error_text_tl
+ \c_@@_coding_error_text_tl
LaTeX~has~been~asked~to~create~quark~test~function~'#1'~
\tl_if_empty:nTF {#2}
{ but~that~name~ }
diff --git a/macros/latex/contrib/l3kernel/l3names.dtx b/macros/latex/contrib/l3kernel/l3names.dtx
index 44239f2348..673bd468c1 100644
--- a/macros/latex/contrib/l3kernel/l3names.dtx
+++ b/macros/latex/contrib/l3kernel/l3names.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3news.pdf b/macros/latex/contrib/l3kernel/l3news.pdf
index 187147d56c..e79384c1d3 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 58d8d08397..2b760f2b63 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 382e0212ad..74c040702c 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 46912dfb9f..2d8c13844a 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 a41de356e1..144f5d83f1 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 11357e96ce..6b38ed0724 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 4ec096a2d6..57a37a4151 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 d13185fb0f..9f4718a792 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 4ae5d0c89b..bfc2a6e8f9 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 65b65444fc..605f9f9035 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 3817070064..01306b40db 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 27d0e8042d..b5524b799e 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 5a9e0fe8f8..3ed63c140f 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 71a0f85469..f3ec7e241d 100644
--- a/macros/latex/contrib/l3kernel/l3pdf.dtx
+++ b/macros/latex/contrib/l3kernel/l3pdf.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3prefixes.csv b/macros/latex/contrib/l3kernel/l3prefixes.csv
index cf57038603..9be48664a0 100644
--- a/macros/latex/contrib/l3kernel/l3prefixes.csv
+++ b/macros/latex/contrib/l3kernel/l3prefixes.csv
@@ -163,6 +163,7 @@ pdfxform,l3pdfmanagement,The LaTeX Project,https://www.latex-project.org/latex3.
peek,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2012-09-27,2012-09-27,
percent,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
pgf,pgf,The PGF/TikZ Team,https://pgf-tikz.github.io,https://github.com/pgf-tikz/pgf,https://github.com/pgf-tikz/pgf/issues,2020-07-03,2020-07-03,
+pgfmxfp,pgfmath-xfp,Jonathan P. Spratte,https://github.com/Skillmon/ltx_pgfmath-xfp,https://github.com/Skillmon/ltx_pgfmath-xfp,https://github.com/Skillmon/ltx_pgfmath-xfp/issues,2021-05-20,2021-05-20,
pi,l3kernel,The LaTeX Project,https://www.latex-project.org/latex3.html,https://github.com/latex3/latex3.git,https://github.com/latex3/latex3/issues,2018-05-12,2018-05-12,
pkgploader,pkgploader,Michiel Helvensteijn,,,,2014-02-05,2014-02-05,
platex,platex,Japanese TeX Development Community,https://github.com/texjporg/platex,https://github.com/texjporg/platex.git,https://github.com/texjporg/platex/issues,2020-09-30,2020-09-30,
diff --git a/macros/latex/contrib/l3kernel/l3prefixes.pdf b/macros/latex/contrib/l3kernel/l3prefixes.pdf
index 345295840d..26fe7ef3ad 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 eedb4f271a..8539c24ff2 100644
--- a/macros/latex/contrib/l3kernel/l3prg.dtx
+++ b/macros/latex/contrib/l3kernel/l3prg.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3prop.dtx b/macros/latex/contrib/l3kernel/l3prop.dtx
index 371f894c42..16609f3af8 100644
--- a/macros/latex/contrib/l3kernel/l3prop.dtx
+++ b/macros/latex/contrib/l3kernel/l3prop.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -51,10 +51,11 @@
%
% \LaTeX3 implements a \enquote{property list} data type, which contain
% an unordered list of entries each of which consists of a \meta{key} and
-% an associated \meta{value}. The \meta{key} and \meta{value} may both be
-% any \meta{balanced text}. It is possible to map functions to property lists
-% such that the function is applied to every key--value pair within
-% the list.
+% an associated \meta{value}. The \meta{key} and \meta{value} may both
+% be any \meta{balanced text}, but the \meta{key} is processed using
+% \cs{tl_to_str:n}, meaning that category codes are ignored. It is
+% possible to map functions to property lists such that the function is
+% applied to every key--value pair within the list.
%
% Each entry in a property list must have a unique \meta{key}: if an entry is
% added to a property list which already contains the \meta{key} then the new
@@ -63,7 +64,7 @@
%
% Property lists are intended for storing key-based information for use within
% code. This is in contrast to key--value lists, which are a form of
-% \emph{input} parsed by the \pkg{keys} module.
+% \emph{input} parsed by the \pkg{l3keys} module.
%
% \section{Creating and initialising property lists}
%
@@ -124,6 +125,12 @@
% \end{syntax}
% Sets \meta{prop~var} to contain key--value pairs given in the second
% argument. If duplicate keys appear only one of the values is kept.
+%
+% Spaces are trimmed around every \meta{key} and every \meta{value},
+% and if the result of trimming spaces consists of a single brace
+% group then a set of outer braces is removed. This enables both the
+% \meta{key} and the \meta{value} to contain spaces, commas or equal
+% signs. The \meta{key} is then processed by \cs{tl_to_str:n}.
% \end{function}
%
% \begin{function}[added = 2017-11-28, updated = 2019-08-25]
@@ -137,11 +144,12 @@
% \end{syntax}
% Creates a new constant \meta{prop~var} or raises an error if the
% name is already taken. The \meta{prop~var} is set globally to
-% contain key--value pairs given in the second argument.
-% If duplicate keys appear only one of the values is kept.
+% contain key--value pairs given in the second argument, processed in
+% the way described for \cs{prop_set_from_keyval:Nn}. If duplicate
+% keys appear only one of the values is kept.
% \end{function}
%
-% \section{Adding entries to property lists}
+% \section{Adding and updating property list entries}
%
% \begin{function}[updated = 2012-07-09]
% {
@@ -162,12 +170,12 @@
% \cs{prop_put:Nnn} \meta{property list} \Arg{key} \Arg{value}
% \end{syntax}
% Adds an entry to the \meta{property list} which may be accessed
-% using the \meta{key} and which has \meta{value}. Both the \meta{key}
-% and \meta{value} may contain any \meta{balanced text}. The \meta{key}
-% is stored after processing with \cs{tl_to_str:n}, meaning that
-% category codes are ignored. If the \meta{key} is already present
-% in the \meta{property list}, the existing entry is overwritten
-% by the new \meta{value}.
+% using the \meta{key} and which has \meta{value}. If the \meta{key}
+% is already present in the \meta{property list}, the existing entry
+% is overwritten by the new \meta{value}. Both the \meta{key} and
+% \meta{value} may contain any \meta{balanced text}. The \meta{key} is
+% stored after processing with \cs{tl_to_str:n}, meaning that category
+% codes are ignored.
% \end{function}
%
% \begin{function}
@@ -178,12 +186,51 @@
% \begin{syntax}
% \cs{prop_put_if_new:Nnn} \meta{property list} \Arg{key} \Arg{value}
% \end{syntax}
-% If the \meta{key} is present in the \meta{property list} then
-% no action is taken. If the \meta{key} is not present in the
-% \meta{property list} then a new entry is added. Both the \meta{key}
-% and \meta{value} may contain any \meta{balanced text}. The \meta{key}
-% is stored after processing with \cs{tl_to_str:n}, meaning that
-% category codes are ignored.
+% If the \meta{key} is present in the \meta{property list} then no
+% action is taken. Otherwise, a new entry is added as described for
+% \cs{prop_put:Nnn}.
+% \end{function}
+%
+% \begin{function}[added = 2021-05-16]
+% {
+% \prop_concat:NNN, \prop_concat:ccc,
+% \prop_gconcat:NNN, \prop_gconcat:ccc
+% }
+% \begin{syntax}
+% \cs{prop_concat:NNN} \meta{prop~var_1} \meta{prop~var_2} \meta{prop~var_3}
+% \end{syntax}
+% Combines the key--value pairs of \meta{prop~var_2} and
+% \meta{prop~var_3}, and saves the result in \meta{prop~var_1}. If a
+% key appears in both \meta{prop~var_2} and \meta{prop~var_3} then the
+% last value, namely the value in \meta{prop~var_3} is kept while the
+% other is discarded.
+% \end{function}
+%
+% \begin{function}[added = 2021-05-16]
+% {
+% \prop_put_from_keyval:Nn, \prop_put_from_keyval:cn,
+% \prop_gput_from_keyval:Nn, \prop_gput_from_keyval:cn,
+% }
+% \begin{syntax}
+% \cs{prop_put_from_keyval:Nn} \meta{prop~var}
+% \{
+% \meta{key1} |=| \meta{value1} |,|
+% \meta{key2} |=| \meta{value2} |,| \ldots{}
+% \}
+% \end{syntax}
+% Updates the \meta{prop~var} by adding entries for each key--value
+% pair given in the second argument. The addition is done through
+% \cs{prop_put:Nnn}, hence if the \meta{prop~var} already contains
+% some of the keys, the corresponding values are discarded and
+% replaced by those given in the key--value list. If duplicate keys
+% appear in the key--value list then only one of the values is kept.
+%
+% The function is equivalent to storing the key--value pairs in a
+% temporary property variable using \cs{prop_set_from_keyval:Nn}, then
+% combining \meta{prop~var} with the temporary variable using
+% \cs{prop_concat:NNN}. In particular, the \meta{keys} and
+% \meta{values} are space-trimmed and unbraced as described in
+% \cs{prop_set_from_keyval:Nn}.
% \end{function}
%
% \section{Recovering values from property lists}
@@ -722,15 +769,42 @@
% \end{variable}
%
% \begin{variable}{\l_@@_internal_prop}
-% Property list used by \cs{prop_set_from_keyval:Nn} and others.
+% Property list used by \cs{prop_concat:NNN},
+% \cs{prop_set_from_keyval:Nn} and others.
% \begin{macrocode}
\prop_new:N \l_@@_internal_prop
% \end{macrocode}
% \end{variable}
%
+% \begin{macro}
+% {
+% \prop_concat:NNN, \prop_concat:ccc,
+% \prop_gconcat:NNN, \prop_gconcat:ccc, \@@_concat:NNNN
+% }
+% Combine two property lists. We cannot use a simple
+% \cs{tl_concat:NNN} because there may be some duplicate keys between
+% the two property lists.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_concat:NNN
+ { \@@_concat:NNNN \prop_set_eq:NN }
+\cs_generate_variant:Nn \prop_concat:NNN { ccc }
+\cs_new_protected:Npn \prop_gconcat:NNN
+ { \@@_concat:NNNN \prop_gset_eq:NN }
+\cs_generate_variant:Nn \prop_gconcat:NNN { ccc }
+\cs_new_protected:Npn \@@_concat:NNNN #1#2#3#4
+ {
+ \prop_set_eq:NN \l_@@_internal_prop #3
+ \prop_map_tokens:Nn #4 { \prop_put:Nnn \l_@@_internal_prop }
+ #1 #2 \l_@@_internal_prop
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}{\prop_set_from_keyval:Nn, \prop_set_from_keyval:cn}
% \begin{macro}{\prop_gset_from_keyval:Nn, \prop_gset_from_keyval:cn}
% \begin{macro}{\prop_const_from_keyval:Nn, \prop_const_from_keyval:cn}
+% \begin{macro}{\prop_put_from_keyval:Nn, \prop_put_from_keyval:cn}
+% \begin{macro}{\prop_gput_from_keyval:Nn, \prop_gput_from_keyval:cn}
% \begin{macro}
% {
% \@@_from_keyval:n,
@@ -783,6 +857,22 @@
\prop_clear:N \l_@@_internal_prop
}
\cs_generate_variant:Nn \prop_const_from_keyval:Nn { c }
+\cs_new_protected:Npn \prop_put_from_keyval:Nn #1#2
+ {
+ \prop_set_eq:NN \l_@@_internal_prop #1
+ \@@_from_keyval:n {#2}
+ \prop_set_eq:NN #1 \l_@@_internal_prop
+ \prop_clear:N \l_@@_internal_prop
+ }
+\cs_generate_variant:Nn \prop_put_from_keyval:Nn { c }
+\cs_new_protected:Npn \prop_gput_from_keyval:Nn #1#2
+ {
+ \prop_set_eq:NN \l_@@_internal_prop #1
+ \@@_from_keyval:n {#2}
+ \prop_gset_eq:NN #1 \l_@@_internal_prop
+ \prop_clear:N \l_@@_internal_prop
+ }
+\cs_generate_variant:Nn \prop_gput_from_keyval:Nn { c }
\cs_new_protected:Npn \@@_from_keyval:n #1
{
\@@_from_keyval_loop:w \prg_do_nothing: #1 ,
@@ -808,10 +898,10 @@
{ \@@_from_keyval_value:w #1 \s_@@_mark }
\cs_new_protected:Npn \@@_from_keyval_value:w #1 \s_@@_mark #2 \s_@@_stop #3#4
{
- \tl_if_empty:nF { #3 #1 #2 }
+ \tl_if_single:nTF {#2}
+ { \prop_put:Nnn \l_@@_internal_prop {#3} {#1} }
{
- \str_if_eq:nnTF {#2} { = }
- { \prop_put:Nnn \l_@@_internal_prop {#3} {#1} }
+ \tl_if_empty:nF { #3 #1 #2 }
{
\__kernel_msg_error:nnx { prop } { prop-keyval }
{ \exp_not:o {#4} }
@@ -823,6 +913,8 @@
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+% \end{macro}
%
% \subsection{Accessing data in property lists}
%
@@ -956,29 +1048,22 @@
% \end{macro}
%
% \begin{macro}[EXP]{\prop_item:Nn, \prop_item:cn}
-% \begin{macro}[EXP]{\@@_item_Nn:nwwn}
+% \begin{macro}[EXP]{\@@_item:nnn}
% Getting the value corresponding to a key in a property list in an
-% expandable fashion is similar to mapping some tokens. Go through
-% the property list one \meta{key}--\meta{value} pair at a time: the
-% arguments of \cs{@@_item_Nn:nwn} are the \meta{key} we are looking
-% for, a \meta{key} of the property list, and its associated value.
-% The \meta{keys} are compared (as strings). If they match, the
-% \meta{value} is returned, within \cs{exp_not:n}. The loop
-% terminates even if the \meta{key} is missing, and yields an empty
-% value, because we have appended the appropriate
-% \meta{key}--\meta{empty value} pair to the property list.
+% expandable fashion simply uses \cs{prop_map_tokens:Nn} to go through
+% the property list. The auxiliary \cs{@@_item:nnn} receives the
+% search string~|#1|, the key~|#2| and the value~|#3| and returns as
+% appropriate.
% \begin{macrocode}
\cs_new:Npn \prop_item:Nn #1#2
{
- \exp_last_unbraced:Noo \@@_item_Nn:nwwn { \tl_to_str:n {#2} } #1
- \@@_pair:wn \tl_to_str:n {#2} \s_@@ { }
- \prg_break_point:
+ \exp_args:NNo \prop_map_tokens:Nn #1
+ { \exp_after:wN \@@_item:nnn \exp_after:wN { \tl_to_str:n {#2} } }
}
-\cs_new:Npn \@@_item_Nn:nwwn #1#2 \@@_pair:wn #3 \s_@@ #4
+\cs_new:Npn \@@_item:nnn #1#2#3
{
- \str_if_eq:eeTF {#1} {#3}
- { \prg_break:n { \exp_not:n {#4} } }
- { \@@_item_Nn:nwwn {#1} }
+ \str_if_eq:eeT {#1} {#2}
+ { \prop_map_break:n { \exp_not:n {#3} } }
}
\cs_generate_variant:Nn \prop_item:Nn { c }
% \end{macrocode}
@@ -1159,7 +1244,7 @@
% \prop_if_in:Nn, \prop_if_in:NV, \prop_if_in:No,
% \prop_if_in:cn, \prop_if_in:cV, \prop_if_in:co
% }
-% \begin{macro}[EXP]{\@@_if_in:nwwn, \@@_if_in:N}
+% \begin{macro}[EXP]{\@@_if_in:nnn}
% Testing expandably if a key is in a property list
% requires to go through the key--value pairs one by one.
% This is rather slow, and a faster test would be
@@ -1172,44 +1257,19 @@
% }
% \end{verbatim}
% but \cs{@@_split:NnTF} is non-expandable.
-%
-% Instead, the key is compared to each key in turn using
-% \cs{str_if_eq:ee}, which is expandable. To terminate the mapping,
-% we append to the property list the key that is searched for. This
-% second \cs{tl_to_str:n} is not expanded at the start, but only when
-% included in the \cs{str_if_eq:ee}. It cannot make the breaking
-% mechanism choke, because the arbitrary token list material is
-% enclosed in braces. The second argument of \cs{@@_if_in:nwwn} is
-% most often empty. When the \meta{key} is found in the list,
-% \cs{@@_if_in:N} receives \cs{@@_pair:wn}, and if it is
-% found as the extra item, the function receives
-% \cs{q_@@_recursion_tail}, easily recognizable.
-%
-% Here, \cs{prop_map_function:NN} is not sufficient for the mapping,
-% since it can only map a single token, and cannot carry the key that
-% is searched for.
+% Instead, we use \cs{prop_map_tokens:Nn} to compare the search key to
+% each key in turn using \cs{str_if_eq:ee}, which is expandable.
% \begin{macrocode}
\prg_new_conditional:Npnn \prop_if_in:Nn #1#2 { p , T , F , TF }
{
- \exp_last_unbraced:Noo \@@_if_in:nwwn { \tl_to_str:n {#2} } #1
- \@@_pair:wn \tl_to_str:n {#2} \s_@@ { }
- \q_@@_recursion_tail
- \prg_break_point:
- }
-\cs_new:Npn \@@_if_in:nwwn #1#2 \@@_pair:wn #3 \s_@@ #4
- {
- \str_if_eq:eeTF {#1} {#3}
- { \@@_if_in:N }
- { \@@_if_in:nwwn {#1} }
+ \exp_args:NNo \prop_map_tokens:Nn #1
+ { \exp_after:wN \@@_if_in:nnn \exp_after:wN { \tl_to_str:n {#2} } }
+ \prg_return_false:
}
-\cs_new:Npn \@@_if_in:N #1
+\cs_new:Npn \@@_if_in:nnn #1#2#3
{
- \if_meaning:w \q_@@_recursion_tail #1
- \prg_return_false:
- \else:
- \prg_return_true:
- \fi:
- \prg_break:
+ \str_if_eq:eeT {#1} {#2}
+ { \prop_map_break:n { \use_i:nn \prg_return_true: } }
}
\prg_generate_conditional_variant:Nnn \prop_if_in:Nn
{ NV , No , c , cV , co } { p , T , F , TF }
@@ -1249,25 +1309,36 @@
% \prop_map_function:NN, \prop_map_function:Nc,
% \prop_map_function:cN, \prop_map_function:cc
% }
-% \begin{macro}{\@@_map_function:Nwwn}
-% The argument delimited by \cs{@@_pair:wn} is empty except at the end
-% of the loop where it is \cs{prg_break:}. No need for any quark
-% test.
+% \begin{macro}{\@@_map_function:Nw}
+% The even-numbered arguments of \cs{@@_map_function:Nw} are keys,
+% hence have string catcodes, except at the end where they are
+% \cs{fi:} \cs{prop_map_break:}. The \cs{fi:} ends the \cs{if_false:}
+% |#|\meta{even} \cs{fi:} construction and we jump out of the loop.
+% No need for any quark test.
% \begin{macrocode}
\cs_new:Npn \prop_map_function:NN #1#2
{
\exp_after:wN \use_i_ii:nnn
- \exp_after:wN \@@_map_function:Nwwn
+ \exp_after:wN \@@_map_function:Nw
\exp_after:wN #2
#1
- \prg_break: \@@_pair:wn \s_@@ { } \prg_break_point:
+ \@@_pair:wn \fi: \prop_map_break: \s_@@ { }
+ \@@_pair:wn \fi: \prop_map_break: \s_@@ { }
+ \@@_pair:wn \fi: \prop_map_break: \s_@@ { }
+ \@@_pair:wn \fi: \prop_map_break: \s_@@ { }
\prg_break_point:Nn \prop_map_break: { }
}
-\cs_new:Npn \@@_map_function:Nwwn #1#2 \@@_pair:wn #3 \s_@@ #4
+\cs_new:Npn \@@_map_function:Nw #1
+ \@@_pair:wn #2 \s_@@ #3
+ \@@_pair:wn #4 \s_@@ #5
+ \@@_pair:wn #6 \s_@@ #7
+ \@@_pair:wn #8 \s_@@ #9
{
- #2
- #1 {#3} {#4}
- \@@_map_function:Nwwn #1
+ \if_false: #2 \fi: #1 {#2} {#3}
+ \if_false: #4 \fi: #1 {#4} {#5}
+ \if_false: #6 \fi: #1 {#6} {#7}
+ \if_false: #8 \fi: #1 {#8} {#9}
+ \@@_map_function:Nw #1
}
\cs_generate_variant:Nn \prop_map_function:NN { Nc , c , cc }
% \end{macrocode}
@@ -1303,26 +1374,35 @@
% \end{macro}
%
% \begin{macro}[rEXP]{\prop_map_tokens:Nn, \prop_map_tokens:cn}
-% \begin{macro}{\@@_map_tokens:nwwn}
+% \begin{macro}{\@@_map_tokens:nw}
% The mapping is very similar to \cs{prop_map_function:NN}. The
% \cs{use_i:nn} removes the leading \cs{s_@@}. The odd construction
% |\use:n {#1}| allows |#1| to contain any token without interfering
-% with \cs{prop_map_break:}. The loop stops when the argument
-% delimited by \cs{@@_pair:wn} is \cs{prg_break:} instead of being
-% empty.
+% with \cs{prop_map_break:}. The loop stops when the \meta{key}
+% between \cs{@@_pair:wn} and \cs{s_@@} is \cs{fi:}
+% \cs{prop_map_break:} instead of being a string.
% \begin{macrocode}
\cs_new:Npn \prop_map_tokens:Nn #1#2
{
\exp_last_unbraced:Nno
- \use_i:nn { \@@_map_tokens:nwwn {#2} } #1
- \prg_break: \@@_pair:wn \s_@@ { } \prg_break_point:
+ \use_i:nn { \@@_map_tokens:nw {#2} } #1
+ \@@_pair:wn \fi: \prop_map_break: \s_@@ { }
+ \@@_pair:wn \fi: \prop_map_break: \s_@@ { }
+ \@@_pair:wn \fi: \prop_map_break: \s_@@ { }
+ \@@_pair:wn \fi: \prop_map_break: \s_@@ { }
\prg_break_point:Nn \prop_map_break: { }
}
-\cs_new:Npn \@@_map_tokens:nwwn #1#2 \@@_pair:wn #3 \s_@@ #4
+\cs_new:Npn \@@_map_tokens:nw #1
+ \@@_pair:wn #2 \s_@@ #3
+ \@@_pair:wn #4 \s_@@ #5
+ \@@_pair:wn #6 \s_@@ #7
+ \@@_pair:wn #8 \s_@@ #9
{
- #2
- \use:n {#1} {#3} {#4}
- \@@_map_tokens:nwwn {#1}
+ \if_false: #2 \fi: \use:n {#1} {#2} {#3}
+ \if_false: #4 \fi: \use:n {#1} {#4} {#5}
+ \if_false: #6 \fi: \use:n {#1} {#6} {#7}
+ \if_false: #8 \fi: \use:n {#1} {#8} {#9}
+ \@@_map_tokens:nw {#1}
}
\cs_generate_variant:Nn \prop_map_tokens:Nn { c }
% \end{macrocode}
diff --git a/macros/latex/contrib/l3kernel/l3quark.dtx b/macros/latex/contrib/l3kernel/l3quark.dtx
index 10ccfa7483..ebad07808f 100644
--- a/macros/latex/contrib/l3kernel/l3quark.dtx
+++ b/macros/latex/contrib/l3kernel/l3quark.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -55,7 +55,8 @@
%
% \section{Quarks}
%
-% Quarks are control sequences that expand to themselves and should
+% Quarks are control sequences (and in fact, token lists) that expand
+% to themselves and should
% therefore \emph{never} be executed directly in the code.
% This would result in an endless loop!
%
@@ -90,8 +91,6 @@
% \cs{tl_if_eq:NNTF}. A set of special quark testing functions is set up
% below. All the quark testing functions are expandable although the
% ones testing only single tokens are much faster.
-% An example of the quark testing functions and their use in recursion
-% can be seen in the implementation of \cs{clist_map_function:NN}.
%
% \section{Defining quarks}
%
diff --git a/macros/latex/contrib/l3kernel/l3regex.dtx b/macros/latex/contrib/l3kernel/l3regex.dtx
index 4962ca6fa2..7f384c8d56 100644
--- a/macros/latex/contrib/l3kernel/l3regex.dtx
+++ b/macros/latex/contrib/l3kernel/l3regex.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -1574,7 +1574,7 @@
\tl_put_right:Nx \l_@@_internal_a_tl
{
\exp_after:wN \@@_escape_loop:N \g_@@_internal_tl
- { break } \prg_break_point:
+ \scan_stop: \prg_break_point:
}
\exp_after:wN
\group_end:
@@ -1620,7 +1620,7 @@
%
% \begin{macro}
% {
-% \@@_escape_break:w, \@@_escape_/break:w,
+% \@@_escape_\scan_stop::w, \@@_escape_/\scan_stop::w,
% \@@_escape_/a:w, \@@_escape_/e:w, \@@_escape_/f:w,
% \@@_escape_/n:w, \@@_escape_/r:w, \@@_escape_/t:w
% }
@@ -1630,8 +1630,8 @@
% backslash. Spaces are ignored, and |\a|, |\e|, |\f|, |\n|, |\r|,
% |\t| take their meaning here.
% \begin{macrocode}
-\cs_new_eq:NN \@@_escape_break:w \prg_break:
-\cs_new:cpn { @@_escape_/break:w }
+\cs_new_eq:cN { @@_escape_ \iow_char:N\\scan_stop: :w } \prg_break:
+\cs_new:cpn { @@_escape_/ \iow_char:N\\scan_stop: :w }
{
\__kernel_msg_expandable_error:nn { regex } { trailing-backslash }
\prg_break:
@@ -1691,7 +1691,10 @@
% \begin{macrocode}
\cs_new:Npn \@@_escape_x_test:N #1
{
- \str_if_eq:nnTF {#1} { break } { ; }
+ \if_meaning:w \scan_stop: #1
+ \exp_after:wN \use_i:nnn \exp_after:wN ;
+ \fi:
+ \use:n
{
\if_charcode:w \c_space_token #1
\exp_after:wN \@@_escape_x_test:N
@@ -1719,7 +1722,10 @@
% \begin{macrocode}
\cs_new:Npn \@@_escape_x:N #1
{
- \str_if_eq:nnTF {#1} { break } { ; }
+ \if_meaning:w \scan_stop: #1
+ \exp_after:wN \use_i:nnn \exp_after:wN ;
+ \fi:
+ \use:n
{
\@@_hexadecimal_use:NTF #1
{ ; \@@_escape_loop:N }
@@ -1736,7 +1742,10 @@
% \begin{macrocode}
\cs_new:Npn \@@_escape_x_loop:N #1
{
- \str_if_eq:nnTF {#1} { break }
+ \if_meaning:w \scan_stop: #1
+ \exp_after:wN \use_ii:nnn
+ \fi:
+ \use_ii:nn
{ ; \@@_escape_x_loop_error:n { } {#1} }
{
\@@_hexadecimal_use:NTF #1
@@ -2251,7 +2260,7 @@
\prg_do_nothing: \prg_do_nothing:
}
{ }
- \if_int_compare:w \l_@@_group_level_int > 0 \exp_stop_f:
+ \if_int_compare:w \l_@@_group_level_int > \c_zero_int
\__kernel_msg_error:nnx { regex } { missing-rparen }
{ \int_use:N \l_@@_group_level_int }
\prg_replicate:nn
@@ -3017,7 +3026,7 @@
}
\cs_new_protected:Npn \@@_compile_group_end:
{
- \if_int_compare:w \l_@@_group_level_int > 0 \exp_stop_f:
+ \if_int_compare:w \l_@@_group_level_int > \c_zero_int
\tl_build_put_right:Nn \l_@@_build_tl { \if_false: { \fi: } }
\tl_build_end:N \l_@@_build_tl
\exp_args:NNNx
@@ -3597,7 +3606,7 @@
{
\@@_class:NnnnN \c_true_bool
{
- \if_int_compare:w "##3 = 0 \exp_stop_f:
+ \if_int_compare:w "##3 = \c_zero_int
\@@_item_exact_cs:n
{ \exp_after:wN \cs_to_str:N ##1 }
\else:
@@ -4314,7 +4323,7 @@
% \begin{macrocode}
\cs_new_protected:Npn \@@_class_repeat:nN #1#2
{
- \if_int_compare:w #1 = 0 \exp_stop_f:
+ \if_int_compare:w #1 = \c_zero_int
\@@_build_transitions_lazyness:NNNNN #2
\@@_action_free:n \l_@@_right_state_int
\@@_tests_action_cost:n \l_@@_left_state_int
@@ -4374,9 +4383,8 @@
% \begin{macrocode}
\cs_new_protected:Npn \@@_group_aux:nnnnN #1#2#3#4#5
{
- \if_int_compare:w #3 = 0 \exp_stop_f:
+ \if_int_compare:w #3 = \c_zero_int
\@@_build_new_state:
-%<assert>\assert_int:n { \l_@@_max_state_int = \l_@@_right_state_int + 1 }
\@@_build_transition_right:nNn \@@_action_free_group:n
\l_@@_left_state_int \l_@@_right_state_int
\fi:
@@ -4479,7 +4487,7 @@
% \begin{macrocode}
\cs_new_protected:Npn \@@_group_repeat:nn #1#2
{
- \if_int_compare:w #2 = 0 \exp_stop_f:
+ \if_int_compare:w #2 = \c_zero_int
\int_set:Nn \l_@@_max_state_int
{ \l_@@_left_state_int - 1 }
\@@_build_new_state:
@@ -4499,7 +4507,7 @@
% \begin{macrocode}
\cs_new_protected:Npn \@@_group_submatches:nNN #1#2#3
{
- \if_int_compare:w #1 > - 1 \exp_stop_f:
+ \if_int_compare:w #1 > - \c_one_int
\@@_toks_put_left:Nx #2 { \@@_action_submatch:nN {#1} < }
\@@_toks_put_left:Nx #3 { \@@_action_submatch:nN {#1} > }
\fi:
@@ -4523,7 +4531,7 @@
\l_@@_right_state_int \l_@@_max_state_int
\int_set_eq:NN \l_@@_internal_a_int \l_@@_left_state_int
\int_set_eq:NN \l_@@_internal_b_int \l_@@_max_state_int
- \if_int_compare:w \int_eval:n {#1} > 1 \exp_stop_f:
+ \if_int_compare:w \int_eval:n {#1} > \c_one_int
\int_set:Nn \l_@@_internal_c_int
{
( #1 - 1 )
@@ -4562,7 +4570,7 @@
% \begin{macrocode}
\cs_new_protected:Npn \@@_group_repeat:nnN #1#2#3
{
- \if_int_compare:w #2 = 0 \exp_stop_f:
+ \if_int_compare:w #2 = \c_zero_int
\@@_group_submatches:nNN {#1}
\l_@@_left_state_int \l_@@_right_state_int
\int_set:Nn \l_@@_internal_a_int
@@ -4633,7 +4641,7 @@
\@@_build_transition_right:nNn \@@_action_free:n
\l_@@_right_state_int \l_@@_max_state_int
}
- \if_int_compare:w #2 = 0 \exp_stop_f:
+ \if_int_compare:w #2 = \c_zero_int
\int_set:Nn \l_@@_right_state_int
{ \l_@@_left_state_int - 1 }
\else:
@@ -5588,7 +5596,7 @@
{ \@@_replacement_normal:n ##1 }
{#1}
\prg_do_nothing: \prg_do_nothing:
- \if_int_compare:w \l_@@_replacement_csnames_int > 0 \exp_stop_f:
+ \if_int_compare:w \l_@@_replacement_csnames_int > \c_zero_int
\__kernel_msg_error:nnx { regex } { replacement-missing-rbrace }
{ \int_use:N \l_@@_replacement_csnames_int }
\tl_build_put_right:Nx \l_@@_build_tl
@@ -5747,7 +5755,7 @@
{
\tl_build_put_right:Nn \l_@@_build_tl
{ \@@_query_submatch:n { \int_eval:n { #1 + ##1 } } }
- \if_int_compare:w \l_@@_replacement_csnames_int = 0 \exp_stop_f:
+ \if_int_compare:w \l_@@_replacement_csnames_int = \c_zero_int
\tl_put_right:Nn \l_@@_balance_tl
{
+ \@@_submatch_balance:n
@@ -5869,7 +5877,7 @@
% \begin{macrocode}
\cs_new_protected:Npn \@@_replacement_rbrace:N #1
{
- \if_int_compare:w \l_@@_replacement_csnames_int > 0 \exp_stop_f:
+ \if_int_compare:w \l_@@_replacement_csnames_int > \c_zero_int
\tl_build_put_right:Nn \l_@@_build_tl { \cs_end: }
\int_decr:N \l_@@_replacement_csnames_int
\else:
@@ -5885,7 +5893,7 @@
% \begin{macrocode}
\cs_new_protected:Npn \@@_replacement_lbrace:N #1
{
- \if_int_compare:w \l_@@_replacement_csnames_int > 0 \exp_stop_f:
+ \if_int_compare:w \l_@@_replacement_csnames_int > \c_zero_int
\__kernel_msg_error:nnn { regex } { cu-lbrace } { u }
\else:
\@@_replacement_normal:n {#1}
@@ -5990,7 +5998,7 @@
\char_set_catcode_group_begin:N \^^@
\cs_new_protected:Npn \@@_replacement_c_B:w
{
- \if_int_compare:w \l_@@_replacement_csnames_int = 0 \exp_stop_f:
+ \if_int_compare:w \l_@@_replacement_csnames_int = \c_zero_int
\int_incr:N \l_@@_balance_int
\fi:
\@@_replacement_char:nNN
@@ -6030,7 +6038,7 @@
\char_set_catcode_group_end:N \^^@
\cs_new_protected:Npn \@@_replacement_c_E:w
{
- \if_int_compare:w \l_@@_replacement_csnames_int = 0 \exp_stop_f:
+ \if_int_compare:w \l_@@_replacement_csnames_int = \c_zero_int
\int_decr:N \l_@@_balance_int
\fi:
\@@_replacement_char:nNN
@@ -6091,7 +6099,7 @@
% \begin{macrocode}
\cs_new_protected:Npn \@@_replacement_c_S:w #1#2
{
- \if_int_compare:w `#2 = 0 \exp_stop_f:
+ \if_int_compare:w `#2 = \c_zero_int
\__kernel_msg_error:nn { regex } { replacement-null-space }
\fi:
\tex_lccode:D `\ = `#2 \scan_stop:
@@ -6298,8 +6306,8 @@
% \end{variable}
%
% \begin{variable}{@@_begin, @@_end}
-% Those flags are raised to indicate extra begin-group
-% or end-group tokens when extracting submatches.
+% Those flags are raised to indicate begin-group or end-group tokens
+% that had to be added when extracting submatches.
% \begin{macrocode}
\flag_new:n { @@_begin }
\flag_new:n { @@_end }
@@ -6340,6 +6348,15 @@
% \end{macrocode}
% \end{variable}
%
+% \begin{variable}{\l_@@_added_begin_int, \l_@@_added_end_int}
+% Keep track of the number of left/right braces to add when performing
+% a regex operation such as a replacement.
+% \begin{macrocode}
+\int_new:N \l_@@_added_begin_int
+\int_new:N \l_@@_added_end_int
+% \end{macrocode}
+% \end{variable}
+%
% \begin{macro}{\@@_return:}
% This function triggers either \cs{prg_return_false:} or
% \cs{prg_return_true:} as appropriate to whether a match was found or
@@ -6512,39 +6529,47 @@
%
% \begin{macro}{\@@_group_end_extract_seq:N}
% The end-points of submatches are stored as entries of two arrays
-% from \cs{l_@@_min_submatch_int} to
-% \cs{l_@@_submatch_int} (exclusive). Extract the relevant ranges
-% into \cs{l_@@_internal_a_tl}. We detect unbalanced results using
-% the two flags \texttt{__regex_begin} and \texttt{__regex_end}, raised
-% whenever we see too many begin-group or end-group tokens in a
-% submatch.
+% from \cs{l_@@_min_submatch_int} to \cs{l_@@_submatch_int}
+% (exclusive). Extract the relevant ranges into \cs{g_@@_internal_tl},
+% separated by \cs{@@_tmp:w} |{}|. We keep track in the two flags
+% \texttt{__regex_begin} and \texttt{__regex_end} of the number of
+% begin-group or end-group tokens added to make each of these items
+% overall balanced. At this step, |}{| is counted as being balanced
+% (same number of begin-group and end-group tokens). This problem is
+% caught by \cs{@@_extract_check:w}, explained later. After
+% complaining about any begin-group or end-group tokens we had to add,
+% we are ready to construct the user's sequence outside the group.
% \begin{macrocode}
\cs_new_protected:Npn \@@_group_end_extract_seq:N #1
{
\flag_clear:n { @@_begin }
\flag_clear:n { @@_end }
- \seq_set_from_function:NnN \l_@@_internal_seq
+ \cs_set_eq:NN \@@_tmp:w \scan_stop:
+ \__kernel_tl_gset:Nx \g_@@_internal_tl
{
\int_step_function:nnN { \l_@@_min_submatch_int }
- { \l_@@_submatch_int - 1 }
- }
- \@@_extract_seq_aux:n
- \int_compare:nNnF
- {
- \flag_height:n { @@_begin } +
- \flag_height:n { @@_end }
+ { \l_@@_submatch_int - 1 } \@@_extract_seq_aux:n
+ \@@_tmp:w
}
- = 0
+ \int_set:Nn \l_@@_added_begin_int
+ { \flag_height:n { @@_begin } }
+ \int_set:Nn \l_@@_added_end_int
+ { \flag_height:n { @@_end } }
+ \tex_afterassignment:D \@@_extract_check:w
+ \__kernel_tl_gset:Nx \g_@@_internal_tl
+ { \g_@@_internal_tl \if_false: { \fi: } }
+ \int_compare:nNnT
+ { \l_@@_added_begin_int + \l_@@_added_end_int } > 0
{
\__kernel_msg_error:nnxxx { regex } { result-unbalanced }
{ splitting~or~extracting~submatches }
- { \flag_height:n { @@_end } }
- { \flag_height:n { @@_begin } }
+ { \int_use:N \l_@@_added_begin_int }
+ { \int_use:N \l_@@_added_end_int }
}
- \seq_set_map_x:NNn \l_@@_internal_seq \l_@@_internal_seq {##1}
- \exp_args:NNNo
- \group_end:
- \tl_set:Nn #1 { \l_@@_internal_seq }
+ \group_end:
+ \cs_set_eq:NN \@@_tmp:w \@@_extract_map_loop:w
+ \seq_set_from_function:NnN #1
+ { \@@_extract_map:N } \exp_not:n
}
% \end{macrocode}
% \end{macro}
@@ -6557,25 +6582,134 @@
% \begin{macrocode}
\cs_new:Npn \@@_extract_seq_aux:n #1
{
+ \@@_tmp:w { }
\exp_after:wN \@@_extract_seq_aux:ww
\int_value:w \@@_submatch_balance:n {#1} ; #1;
}
\cs_new:Npn \@@_extract_seq_aux:ww #1; #2;
{
- \if_int_compare:w #1 < 0 \exp_stop_f:
- \flag_raise:n { @@_end }
- \prg_replicate:nn {-#1} { \exp_not:n { { \if_false: } \fi: } }
+ \if_int_compare:w #1 < \c_zero_int
+ \prg_replicate:nn {-#1}
+ {
+ \flag_raise:n { @@_begin }
+ \exp_not:n { { \if_false: } \fi: }
+ }
\fi:
\@@_query_submatch:n {#2}
- \if_int_compare:w #1 > 0 \exp_stop_f:
- \flag_raise:n { @@_begin }
- \prg_replicate:nn {#1} { \exp_not:n { \if_false: { \fi: } } }
+ \if_int_compare:w #1 > \c_zero_int
+ \prg_replicate:nn {#1}
+ {
+ \flag_raise:n { @@_end }
+ \exp_not:n { \if_false: { \fi: } }
+ }
\fi:
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\@@_extract:}
+% \begin{macro}
+% {
+% \@@_extract_check:w, \@@_extract_check:n,
+% \@@_extract_check_loop:w, \@@_extract_check_end:w
+% }
+% In \cs{@@_group_end_extract_seq:N} we had to expand
+% \cs{g_@@_internal_tl} to turn \cs{if_false:} constructions into
+% actual begin-group and end-group tokens. This is done with a
+% \cs{__kernel_tl_gset:Nx} assignment, and \cs{@@_extract_check:w} is
+% run immediately after this assignment ends, thanks to the
+% \tn{afterassignment} primitive. If all of the items were properly
+% balanced (enough begin-group tokens before end-group tokens, so |}{|
+% is not) then \cs{@@_extract_check:w} is called just before the
+% closing brace of the \cs{__kernel_tl_gset:Nx} (thanks to our sneaky
+% \cs{if_false:} |{| \cs{fi:} |}| construction), and finds that there
+% is nothing left to expand. If any of the items is unbalanced, the
+% assignment gets ended early by an extra end-group token, and our
+% check finds more tokens needing to be expanded in a new
+% \cs{__kernel_tl_gset:Nx} assignment. We need to add a begin-group
+% and an end-group tokens to the unbalanced item, namely to the last
+% item found so far, which we reach through a loop.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_extract_check:w
+ {
+ \exp_after:wN \@@_extract_check:n
+ \exp_after:wN { \if_false: } \fi:
+ }
+\cs_new_protected:Npn \@@_extract_check:n #1
+ {
+ \tl_if_empty:nF {#1}
+ {
+ \int_incr:N \l_@@_added_begin_int
+ \int_incr:N \l_@@_added_end_int
+ \tex_afterassignment:D \@@_extract_check:w
+ \__kernel_tl_gset:Nx \g_@@_internal_tl
+ {
+ \exp_after:wN \@@_extract_check_loop:w
+ \g_@@_internal_tl
+ \@@_tmp:w \@@_extract_check_end:w
+ #1
+ }
+ }
+ }
+\cs_new:Npn \@@_extract_check_loop:w #1 \@@_tmp:w #2
+ {
+ #2
+ \exp_not:o {#1}
+ \@@_tmp:w { }
+ \@@_extract_check_loop:w \prg_do_nothing:
+ }
+% \end{macrocode}
+% Arguments of \cs{@@_extract_check_end:w} are: |#1| is the part of
+% the item before the extra end-group token; |#2| is junk; |#3| is
+% \cs{prg_do_nothing:} followed by the not-yet-expanded part of the
+% item after the extra end-group token. In the replacement text, the
+% first brace and the \cs{if_false:} |{| \cs{fi:} |}| construction are
+% the added begin-group and end-group tokens (the latter being not-yet
+% expanded, just like~|#3|), while the closing brace after
+% \cs{exp_not:o} |{#1}| replaces the extra end-group token that had
+% ended the assignment early. In particular this means that the
+% character code of that end-group token is lost.
+% \begin{macrocode}
+\cs_new:Npn \@@_extract_check_end:w
+ \exp_not:o #1#2 \@@_extract_check_loop:w #3 \@@_tmp:w
+ {
+ { \exp_not:o {#1} }
+ #3
+ \if_false: { \fi: }
+ \@@_tmp:w
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]
+% {
+% \@@_extract_map:N,
+% \@@_extract_map_aux:NNn,
+% \@@_extract_map_loop:w
+% }
+% This receives a |seq| internal function and maps it over all items
+% in \cs{g_@@_internal_tl}. This token list takes the form
+% \cs{@@_tmp:w} |{}| \meta{item_1} \cs{@@_tmp:w} |{}| \meta{item_2}
+% \ldots{} \cs{@@_tmp:w}, and the calling code has set \cs{@@_tmp:w}
+% equal to \cs{@@_extract_map_loop:w}. The loop is otherwise pretty
+% standard, with \cs{prg_do_nothing:} to avoid losing braces.
+% \begin{macrocode}
+\cs_new:Npn \@@_extract_map:N #1
+ {
+ \exp_after:wN \@@_extract_map_aux:NNn
+ \exp_after:wN #1
+ \g_@@_internal_tl \use_none:nnn
+ }
+\cs_new:Npn \@@_extract_map_aux:NNn #1#2#3
+ { #3 #2 #1 \prg_do_nothing: }
+\cs_new:Npn \@@_extract_map_loop:w #1#2 \@@_tmp:w #3
+ {
+ \exp_after:wN #1 \exp_after:wN {#2}
+ #3 \@@_extract_map_loop:w #1 \prg_do_nothing:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_extract:, \@@_extract_aux:w}
% Our task here is to store the list of end-points of submatches, and
% store them in appropriate array entries, from
% \cs{l_@@_zeroth_submatch_int} upwards. First, we store in
@@ -6598,19 +6732,24 @@
\__kernel_intarray_gset:Nnn \g_@@_submatch_prev_intarray
{ \l_@@_zeroth_submatch_int } { \l_@@_start_pos_int }
\int_zero:N \l_@@_internal_a_int
- \clist_map_inline:Nn \l_@@_success_submatches_tl
- {
- \if_int_compare:w \l_@@_internal_a_int < \l_@@_capturing_group_int
- \__kernel_intarray_gset:Nnn \g_@@_submatch_begin_intarray
- { \@@_int_eval:w \l_@@_zeroth_submatch_int + \l_@@_internal_a_int } {##1}
- \else:
- \__kernel_intarray_gset:Nnn \g_@@_submatch_end_intarray
- { \@@_int_eval:w \l_@@_zeroth_submatch_int + \l_@@_internal_a_int - \l_@@_capturing_group_int } {##1}
- \fi:
- \int_incr:N \l_@@_internal_a_int
- }
+ \exp_after:wN \@@_extract_aux:w \l_@@_success_submatches_tl
+ \prg_break_point: \@@_use_none_delimit_by_q_recursion_stop:w ,
+ \q_@@_recursion_stop
\fi:
}
+\cs_new_protected:Npn \@@_extract_aux:w #1 ,
+ {
+ \prg_break: #1 \prg_break_point:
+ \if_int_compare:w \l_@@_internal_a_int < \l_@@_capturing_group_int
+ \__kernel_intarray_gset:Nnn \g_@@_submatch_begin_intarray
+ { \@@_int_eval:w \l_@@_zeroth_submatch_int + \l_@@_internal_a_int } {#1}
+ \else:
+ \__kernel_intarray_gset:Nnn \g_@@_submatch_end_intarray
+ { \@@_int_eval:w \l_@@_zeroth_submatch_int + \l_@@_internal_a_int - \l_@@_capturing_group_int } {#1}
+ \fi:
+ \int_incr:N \l_@@_internal_a_int
+ \@@_extract_aux:w
+ }
% \end{macrocode}
% \end{macro}
%
@@ -6708,36 +6847,65 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\@@_group_end_replace:N}
-% If the brace balance is not $0$, raise an error. Then set the user's
-% variable |#1| to the \texttt{x}-expansion of
-% \cs{l_@@_internal_a_tl}, adding the appropriate braces to produce
-% a balanced result. And end the group.
+% \begin{macro}
+% {
+% \@@_group_end_replace:N, \@@_group_end_replace_try:,
+% \@@_group_end_replace_check:w, \@@_group_end_replace_check:n
+% }
+% At this stage \cs{l_@@_internal_a_tl} (|x|-expands to the desired
+% result). Guess from \cs{l_@@_balance_int} the number of braces to
+% add before or after the result then try expanding. The simplest
+% case is when \cs{l_@@_internal_a_tl} together with the braces we
+% insert via \cs{prg_replicate:nn} give a balanced result, and the
+% assignment ends at the \cs{if_false:} |{| \cs{fi:} |}| construction:
+% then \cs{@@_group_end_replace_check:w} sees that there is no
+% material left and we successfully found the result. The harder case
+% is that expanding \cs{l_@@_internal_a_tl} may produce extra closing
+% braces and end the assignment early. Then we grab the remaining code
+% using; importantly, what follows has not yet been expanded so that
+% \cs{@@_group_end_replace_check:n} grabs everything until the last
+% brace in \cs{@@_group_end_replace_try:}, letting us try again with
+% an extra surrounding pair of braces.
% \begin{macrocode}
\cs_new_protected:Npn \@@_group_end_replace:N #1
{
- \if_int_compare:w \l_@@_balance_int = 0 \exp_stop_f:
- \else:
- \__kernel_msg_error:nnxxx { regex } { result-unbalanced }
- { replacing }
- { \int_max:nn { - \l_@@_balance_int } { 0 } }
- { \int_max:nn { \l_@@_balance_int } { 0 } }
- \fi:
- \use:x
+ \int_set:Nn \l_@@_added_begin_int
+ { \int_max:nn { - \l_@@_balance_int } { 0 } }
+ \int_set:Nn \l_@@_added_end_int
+ { \int_max:nn { \l_@@_balance_int } { 0 } }
+ \@@_group_end_replace_try:
+ \int_compare:nNnT { \l_@@_added_begin_int + \l_@@_added_end_int } > 0
{
- \group_end:
- \tl_set:Nn \exp_not:N #1
- {
- \if_int_compare:w \l_@@_balance_int < 0 \exp_stop_f:
- \prg_replicate:nn { - \l_@@_balance_int }
- { { \if_false: } \fi: }
- \fi:
- \l_@@_internal_a_tl
- \if_int_compare:w \l_@@_balance_int > 0 \exp_stop_f:
- \prg_replicate:nn { \l_@@_balance_int }
- { \if_false: { \fi: } }
- \fi:
- }
+ \__kernel_msg_error:nnxxx { regex } { result-unbalanced }
+ { replacing } { \int_use:N \l_@@_added_begin_int }
+ { \int_use:N \l_@@_added_end_int }
+ }
+ \group_end:
+ \tl_set_eq:NN #1 \g_@@_internal_tl
+ }
+\cs_new_protected:Npn \@@_group_end_replace_try:
+ {
+ \tex_afterassignment:D \@@_group_end_replace_check:w
+ \__kernel_tl_gset:Nx \g_@@_internal_tl
+ {
+ \prg_replicate:nn { \l_@@_added_begin_int } { { \if_false: } \fi: }
+ \l_@@_internal_a_tl
+ \prg_replicate:nn { \l_@@_added_end_int } { \if_false: { \fi: } }
+ \if_false: { \fi: }
+ }
+ }
+\cs_new_protected:Npn \@@_group_end_replace_check:w
+ {
+ \exp_after:wN \@@_group_end_replace_check:n
+ \exp_after:wN { \if_false: } \fi:
+ }
+\cs_new_protected:Npn \@@_group_end_replace_check:n #1
+ {
+ \tl_if_empty:nF {#1}
+ {
+ \int_incr:N \l_@@_added_begin_int
+ \int_incr:N \l_@@_added_end_int
+ \@@_group_end_replace_try:
}
}
% \end{macrocode}
@@ -7551,6 +7719,7 @@
%^^A recursion condition
%^^A (?(DEFINE)... define subpattern for reference
%^^A (?(assert)... assertion condition
+%^^A (?(?=..)..|..) positive/negative look ahead/behind condition
%^^A (*ACCEPT) force successful match
%^^A (*FAIL) force backtrack; synonym (*F)
%^^A (*COMMIT) overall failure, no advance of starting point
@@ -7567,8 +7736,10 @@
%^^A + possessive quantifiers
%^^A (?>...) atomic, non-capturing group
%^^A (?#....) comment (not nestable)
-%^^A (?JmsUx) options (duplicate names; multiline; single line;
-%^^A ungreedy; extended)
+%^^A (?Jms-UxX) options (duplicate names; multiline; single line;
+%^^A unset what follows; ungreedy; extended;
+%^^A error on bad escapes)
+%^^A (?i:...|...) convenient shorthand for (?:(?i)...|...)
%^^A (*NO_START_OPT) no start-match optimization (PCRE_NO_START_OPTIMIZE)
%^^A (*UTF8) set UTF-8 mode (PCRE_UTF8)
%^^A (*UCP) set PCRE_UCP (use Unicode properties for \d etc)
diff --git a/macros/latex/contrib/l3kernel/l3seq.dtx b/macros/latex/contrib/l3kernel/l3seq.dtx
index 18e954d9e1..a8bd4d97e6 100644
--- a/macros/latex/contrib/l3kernel/l3seq.dtx
+++ b/macros/latex/contrib/l3kernel/l3seq.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -1979,10 +1979,11 @@
%
% \begin{macro}{\seq_map_function:NN, \seq_map_function:cN}
% \UnitTested
-% \begin{macro}[rEXP]{\@@_map_function:NNn}
+% \begin{macro}[rEXP]{\@@_map_function:Nw}
% The idea here is to apply the code of |#2| to each item in the
% sequence without altering the definition of \cs{@@_item:n}. The
-% argument delimited by \cs{@@_item:n} is almost always empty, except
+% even-numbered arguments of \cs{@@_map_function:Nw} delimited by
+% \cs{@@_item:n} are almost always empty, except
% at the end of the loop where it is \cs{prg_break:}. This allows to
% break the loop without needing to do a (relatively-expensive) quark
% test.
@@ -1993,13 +1994,21 @@
\exp_after:wN \@@_map_function:Nw
\exp_after:wN #2
#1
- \prg_break: \@@_item:n { } \prg_break_point:
+ \prg_break:
+ \@@_item:n { } \@@_item:n { } \@@_item:n { } \@@_item:n { }
+ \prg_break_point:
\prg_break_point:Nn \seq_map_break: { }
}
-\cs_new:Npn \@@_map_function:Nw #1#2 \@@_item:n #3
+\cs_new:Npn \@@_map_function:Nw #1
+ #2 \@@_item:n #3
+ #4 \@@_item:n #5
+ #6 \@@_item:n #7
+ #8 \@@_item:n #9
{
- #2
- #1 {#3}
+ #2 #1 {#3}
+ #4 #1 {#5}
+ #6 #1 {#7}
+ #8 #1 {#9}
\@@_map_function:Nw #1
}
\cs_generate_variant:Nn \seq_map_function:NN { c }
@@ -2068,14 +2077,22 @@
{
\exp_last_unbraced:Nno
\use_i:nn { \@@_map_tokens:nw {#2} } #1
- \prg_break: \@@_item:n { } \prg_break_point:
+ \prg_break:
+ \@@_item:n { } \@@_item:n { } \@@_item:n { } \@@_item:n { }
+ \prg_break_point:
\prg_break_point:Nn \seq_map_break: { }
}
\cs_generate_variant:Nn \seq_map_tokens:Nn { c }
-\cs_new:Npn \@@_map_tokens:nw #1#2 \@@_item:n #3
+\cs_new:Npn \@@_map_tokens:nw #1
+ #2 \@@_item:n #3
+ #4 \@@_item:n #5
+ #6 \@@_item:n #7
+ #8 \@@_item:n #9
{
- #2
- \use:n {#1} {#3}
+ #2 \use:n {#1} {#3}
+ #4 \use:n {#1} {#5}
+ #6 \use:n {#1} {#7}
+ #8 \use:n {#1} {#9}
\@@_map_tokens:nw {#1}
}
% \end{macrocode}
diff --git a/macros/latex/contrib/l3kernel/l3skip.dtx b/macros/latex/contrib/l3kernel/l3skip.dtx
index fa2b011f99..0e8636b440 100644
--- a/macros/latex/contrib/l3kernel/l3skip.dtx
+++ b/macros/latex/contrib/l3kernel/l3skip.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -1129,7 +1129,7 @@
\cs_new_protected:Npn \dim_const:Nn #1#2
{
\dim_new:N #1
- \tex_global:D #1 ~ \dim_eval:n {#2} \scan_stop:
+ \tex_global:D #1 = \dim_eval:n {#2} \scan_stop:
}
\cs_generate_variant:Nn \dim_const:Nn { c }
% \end{macrocode}
@@ -1139,11 +1139,12 @@
% \begin{macro}{\dim_gzero:N, \dim_gzero:c}
% Reset the register to zero. Using \cs{c_zero_skip} deals with the
% case where the variable passed is incorrectly a skip (for example a
-% \LaTeXe{} length).
+% \LaTeXe{} length). Besides, these functions are then simply copied
+% for \cs{skip_zero:N} and related functions.
% \begin{macrocode}
-\cs_new_protected:Npn \dim_zero:N #1 { #1 \c_zero_skip }
+\cs_new_protected:Npn \dim_zero:N #1 { #1 = \c_zero_skip }
\cs_new_protected:Npn \dim_gzero:N #1
- { \tex_global:D #1 \c_zero_skip }
+ { \tex_global:D #1 = \c_zero_skip }
\cs_generate_variant:Nn \dim_zero:N { c }
\cs_generate_variant:Nn \dim_gzero:N { c }
% \end{macrocode}
@@ -1184,9 +1185,9 @@
% length).
% \begin{macrocode}
\cs_new_protected:Npn \dim_set:Nn #1#2
- { #1 ~ \@@_eval:w #2 \@@_eval_end: \scan_stop: }
+ { #1 = \@@_eval:w #2 \@@_eval_end: \scan_stop: }
\cs_new_protected:Npn \dim_gset:Nn #1#2
- { \tex_global:D #1 ~ \@@_eval:w #2 \@@_eval_end: \scan_stop: }
+ { \tex_global:D #1 = \@@_eval:w #2 \@@_eval_end: \scan_stop: }
\cs_generate_variant:Nn \dim_set:Nn { c }
\cs_generate_variant:Nn \dim_gset:Nn { c }
% \end{macrocode}
@@ -1213,27 +1214,27 @@
% \begin{macro}{\dim_gadd:Nn, \dim_gadd:cn}
% \begin{macro}{\dim_sub:Nn, \dim_sub:cn}
% \begin{macro}{\dim_gsub:Nn, \dim_gsub:cn}
-% Using |by| here deals with the (incorrect) case |\dimen123|.
+% Using |by| here would slow things down just to detect nonsensical
+% cases such as passing |\dimen 123| as the first argument.
% Using \cs{scan_stop:} deals with skip variables. Since
% debugging checks that the variable is correctly local/global, the
% global versions cannot be defined as \cs{tex_global:D} followed by
-% the local versions. The debugging code is inserted by
-% \cs{@@_tmp:w}.
+% the local versions.
% \begin{macrocode}
\cs_new_protected:Npn \dim_add:Nn #1#2
- { \tex_advance:D #1 by \@@_eval:w #2 \@@_eval_end: \scan_stop: }
+ { \tex_advance:D #1 \@@_eval:w #2 \@@_eval_end: \scan_stop: }
\cs_new_protected:Npn \dim_gadd:Nn #1#2
{
- \tex_global:D \tex_advance:D #1 by
+ \tex_global:D \tex_advance:D #1
\@@_eval:w #2 \@@_eval_end: \scan_stop:
}
\cs_generate_variant:Nn \dim_add:Nn { c }
\cs_generate_variant:Nn \dim_gadd:Nn { c }
\cs_new_protected:Npn \dim_sub:Nn #1#2
- { \tex_advance:D #1 by - \@@_eval:w #2 \@@_eval_end: \scan_stop: }
+ { \tex_advance:D #1 - \@@_eval:w #2 \@@_eval_end: \scan_stop: }
\cs_new_protected:Npn \dim_gsub:Nn #1#2
{
- \tex_global:D \tex_advance:D #1 by
+ \tex_global:D \tex_advance:D #1
-\@@_eval:w #2 \@@_eval_end: \scan_stop:
}
\cs_generate_variant:Nn \dim_sub:Nn { c }
@@ -1642,13 +1643,9 @@
% \end{macro}
%
% \begin{macro}{\dim_use:N, \dim_use:c}
-% Accessing a \meta{dim}.
+% Accessing a \meta{dim}. We hand-code the |c| variant for some speed gain.
% \begin{macrocode}
\cs_new_eq:NN \dim_use:N \tex_the:D
-% \end{macrocode}
-% We hand-code this for some speed gain:
-% \begin{macrocode}
-%\cs_generate_variant:Nn \dim_use:N { c }
\cs_new:Npn \dim_use:c #1 { \tex_the:D \cs:w #1 \cs_end: }
% \end{macrocode}
% \end{macro}
@@ -1673,7 +1670,7 @@
##1 . ##2 \tl_to_str:n { pt }
}
{
- \int_compare:nNnTF {#2} > { 0 }
+ \int_compare:nNnTF {#2} > \c_zero_int
{ #1 . #2 }
{ #1 }
}
@@ -1808,7 +1805,7 @@
\cs_new_protected:Npn \skip_const:Nn #1#2
{
\skip_new:N #1
- \tex_global:D #1 ~ \skip_eval:n {#2} \scan_stop:
+ \tex_global:D #1 = \skip_eval:n {#2} \scan_stop:
}
\cs_generate_variant:Nn \skip_const:Nn { c }
% \end{macrocode}
@@ -1818,8 +1815,8 @@
% \begin{macro}{\skip_gzero:N, \skip_gzero:c}
% Reset the register to zero.
% \begin{macrocode}
-\cs_new_protected:Npn \skip_zero:N #1 { #1 \c_zero_skip }
-\cs_new_protected:Npn \skip_gzero:N #1 { \tex_global:D #1 \c_zero_skip }
+\cs_new_eq:NN \skip_zero:N \dim_zero:N
+\cs_new_eq:NN \skip_gzero:N \dim_gzero:N
\cs_generate_variant:Nn \skip_zero:N { c }
\cs_generate_variant:Nn \skip_gzero:N { c }
% \end{macrocode}
@@ -1856,9 +1853,9 @@
% Much the same as for dimensions.
% \begin{macrocode}
\cs_new_protected:Npn \skip_set:Nn #1#2
- { #1 ~ \tex_glueexpr:D #2 \scan_stop: }
+ { #1 = \tex_glueexpr:D #2 \scan_stop: }
\cs_new_protected:Npn \skip_gset:Nn #1#2
- { \tex_global:D #1 ~ \tex_glueexpr:D #2 \scan_stop: }
+ { \tex_global:D #1 = \tex_glueexpr:D #2 \scan_stop: }
\cs_generate_variant:Nn \skip_set:Nn { c }
\cs_generate_variant:Nn \skip_gset:Nn { c }
% \end{macrocode}
@@ -1886,15 +1883,15 @@
% Using |by| here deals with the (incorrect) case |\skip123|.
% \begin{macrocode}
\cs_new_protected:Npn \skip_add:Nn #1#2
- { \tex_advance:D #1 by \tex_glueexpr:D #2 \scan_stop: }
+ { \tex_advance:D #1 \tex_glueexpr:D #2 \scan_stop: }
\cs_new_protected:Npn \skip_gadd:Nn #1#2
- { \tex_global:D \tex_advance:D #1 by \tex_glueexpr:D #2 \scan_stop: }
+ { \tex_global:D \tex_advance:D #1 \tex_glueexpr:D #2 \scan_stop: }
\cs_generate_variant:Nn \skip_add:Nn { c }
\cs_generate_variant:Nn \skip_gadd:Nn { c }
\cs_new_protected:Npn \skip_sub:Nn #1#2
- { \tex_advance:D #1 by - \tex_glueexpr:D #2 \scan_stop: }
+ { \tex_advance:D #1 - \tex_glueexpr:D #2 \scan_stop: }
\cs_new_protected:Npn \skip_gsub:Nn #1#2
- { \tex_global:D \tex_advance:D #1 by - \tex_glueexpr:D #2 \scan_stop: }
+ { \tex_global:D \tex_advance:D #1 - \tex_glueexpr:D #2 \scan_stop: }
\cs_generate_variant:Nn \skip_sub:Nn { c }
\cs_generate_variant:Nn \skip_gsub:Nn { c }
% \end{macrocode}
@@ -1911,7 +1908,7 @@
% \begin{macrocode}
\prg_new_conditional:Npnn \skip_if_eq:nn #1#2 { p , T , F , TF }
{
- \str_if_eq:eeTF { \skip_eval:n { #1 } } { \skip_eval:n { #2 } }
+ \str_if_eq:eeTF { \skip_eval:n {#1} } { \skip_eval:n {#2} }
{ \prg_return_true: }
{ \prg_return_false: }
}
@@ -1956,9 +1953,8 @@
% \begin{macro}{\skip_use:N, \skip_use:c}
% Accessing a \meta{skip}.
% \begin{macrocode}
-\cs_new_eq:NN \skip_use:N \tex_the:D
-%\cs_generate_variant:Nn \skip_use:N { c }
-\cs_new:Npn \skip_use:c #1 { \tex_the:D \cs:w #1 \cs_end: }
+\cs_new_eq:NN \skip_use:N \dim_use:N
+\cs_new_eq:NN \skip_use:c \dim_use:c
% \end{macrocode}
% \end{macro}
%
@@ -2055,7 +2051,7 @@
\cs_new_protected:Npn \muskip_const:Nn #1#2
{
\muskip_new:N #1
- \tex_global:D #1 ~ \muskip_eval:n {#2} \scan_stop:
+ \tex_global:D #1 = \muskip_eval:n {#2} \scan_stop:
}
\cs_generate_variant:Nn \muskip_const:Nn { c }
% \end{macrocode}
@@ -2066,9 +2062,9 @@
% Reset the register to zero.
% \begin{macrocode}
\cs_new_protected:Npn \muskip_zero:N #1
- { #1 \c_zero_muskip }
+ { #1 = \c_zero_muskip }
\cs_new_protected:Npn \muskip_gzero:N #1
- { \tex_global:D #1 \c_zero_muskip }
+ { \tex_global:D #1 = \c_zero_muskip }
\cs_generate_variant:Nn \muskip_zero:N { c }
\cs_generate_variant:Nn \muskip_gzero:N { c }
% \end{macrocode}
@@ -2108,9 +2104,9 @@
% This should be pretty familiar.
% \begin{macrocode}
\cs_new_protected:Npn \muskip_set:Nn #1#2
- { #1 ~ \tex_muexpr:D #2 \scan_stop: }
+ { #1 = \tex_muexpr:D #2 \scan_stop: }
\cs_new_protected:Npn \muskip_gset:Nn #1#2
- { \tex_global:D #1 ~ \tex_muexpr:D #2 \scan_stop: }
+ { \tex_global:D #1 = \tex_muexpr:D #2 \scan_stop: }
\cs_generate_variant:Nn \muskip_set:Nn { c }
\cs_generate_variant:Nn \muskip_gset:Nn { c }
% \end{macrocode}
@@ -2144,15 +2140,15 @@
% Using |by| here deals with the (incorrect) case |\muskip123|.
% \begin{macrocode}
\cs_new_protected:Npn \muskip_add:Nn #1#2
- { \tex_advance:D #1 by \tex_muexpr:D #2 \scan_stop: }
+ { \tex_advance:D #1 \tex_muexpr:D #2 \scan_stop: }
\cs_new_protected:Npn \muskip_gadd:Nn #1#2
- { \tex_global:D \tex_advance:D #1 by \tex_muexpr:D #2 \scan_stop: }
+ { \tex_global:D \tex_advance:D #1 \tex_muexpr:D #2 \scan_stop: }
\cs_generate_variant:Nn \muskip_add:Nn { c }
\cs_generate_variant:Nn \muskip_gadd:Nn { c }
\cs_new_protected:Npn \muskip_sub:Nn #1#2
- { \tex_advance:D #1 by - \tex_muexpr:D #2 \scan_stop: }
+ { \tex_advance:D #1 - \tex_muexpr:D #2 \scan_stop: }
\cs_new_protected:Npn \muskip_gsub:Nn #1#2
- { \tex_global:D \tex_advance:D #1 by - \tex_muexpr:D #2 \scan_stop: }
+ { \tex_global:D \tex_advance:D #1 - \tex_muexpr:D #2 \scan_stop: }
\cs_generate_variant:Nn \muskip_sub:Nn { c }
\cs_generate_variant:Nn \muskip_gsub:Nn { c }
% \end{macrocode}
@@ -2174,8 +2170,8 @@
% \begin{macro}{\muskip_use:N, \muskip_use:c}
% Accessing a \meta{muskip}.
% \begin{macrocode}
-\cs_new_eq:NN \muskip_use:N \tex_the:D
-\cs_generate_variant:Nn \muskip_use:N { c }
+\cs_new_eq:NN \muskip_use:N \dim_use:N
+\cs_new_eq:NN \muskip_use:c \dim_use:c
% \end{macrocode}
% \end{macro}
%
diff --git a/macros/latex/contrib/l3kernel/l3sort.dtx b/macros/latex/contrib/l3kernel/l3sort.dtx
index 46ed7ca906..1f05797ebd 100644
--- a/macros/latex/contrib/l3kernel/l3sort.dtx
+++ b/macros/latex/contrib/l3kernel/l3sort.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3str-convert.dtx b/macros/latex/contrib/l3kernel/l3str-convert.dtx
index c9ce040eee..1fe62d128c 100644
--- a/macros/latex/contrib/l3kernel/l3str-convert.dtx
+++ b/macros/latex/contrib/l3kernel/l3str-convert.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -824,7 +824,7 @@
\file_if_exist:nTF { l3str-#2- \l_@@_internal_tl .def }
{
\group_begin:
- \@@_load_catcodes:
+ \cctab_select:N \c_code_cctab
\file_input:n { l3str-#2- \l_@@_internal_tl .def }
\group_end:
}
@@ -880,32 +880,6 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\@@_load_catcodes:}
-% Since encoding files may be loaded at arbitrary places in a \TeX{}
-% document, including within verbatim mode, we set the catcodes of all
-% characters appearing in any encoding definition file.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_load_catcodes:
- {
- \char_set_catcode_escape:N \\
- \char_set_catcode_group_begin:N \{
- \char_set_catcode_group_end:N \}
- \char_set_catcode_math_toggle:N \$
- \char_set_catcode_alignment:N \&
- \char_set_catcode_parameter:N \#
- \char_set_catcode_math_superscript:N \^
- \char_set_catcode_ignore:N \ %
- \char_set_catcode_space:N \~
- \tl_map_function:nN { abcdefghijklmnopqrstuvwxyz_:ABCDEFILNPSTUX }
- \char_set_catcode_letter:N
- \tl_map_function:nN { 0123456789"'?*+-.(),`!/<>[];= }
- \char_set_catcode_other:N
- \char_set_catcode_comment:N \%
- \int_set:Nn \tex_endlinechar:D {32}
- }
-% \end{macrocode}
-% \end{macro}
-%
% \subsubsection{Byte unescape and escape}
%
% Strings of bytes may need to be stored in auxiliary files in safe
@@ -2589,7 +2563,7 @@
\exp_after:wN \@@_decode_utf_xxxii_end:w
\fi:
#1#2#3#4 \s_@@
- \if_int_compare:w \@@_tmp:w #1#4 > 0 \exp_stop_f:
+ \if_int_compare:w \@@_tmp:w #1#4 > \c_zero_int
\flag_raise:n { str_overflow }
\flag_raise:n { str_error }
\int_use:N \c_@@_replacement_char_int
diff --git a/macros/latex/contrib/l3kernel/l3str.dtx b/macros/latex/contrib/l3kernel/l3str.dtx
index aecd6d3c0d..6b6acc0336 100644
--- a/macros/latex/contrib/l3kernel/l3str.dtx
+++ b/macros/latex/contrib/l3kernel/l3str.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -401,6 +401,34 @@
% not be used within this string.
% \end{function}
%
+% \begin{function}[EXP, pTF, added = 2021-05-17]{\str_compare:nNn, \str_compare:eNe}
+% \begin{syntax}
+% \cs{str_compare_p:nNn} \Arg{tl_1} \meta{relation} \Arg{tl_2}
+% \cs{str_compare:nNnTF} \Arg{tl_1} \meta{relation} \Arg{tl_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Compares the two \meta{token lists} on a character by character
+% basis (namely after converting them to strings) in a lexicographic
+% order according to the character codes of the characters. The
+% \meta{relation} can be |<|, |=|, or~|>| and the test is
+% \texttt{true} under the following conditions:
+% \begin{itemize}
+% \item for |<|, if the first string is earlier than the second in lexicographic order;
+% \item for |=|, if the two strings have exactly the same characters;
+% \item for |>|, if the first string is later than the second in lexicographic order.
+% \end{itemize}
+% Thus for example the following is logically \texttt{true}:
+% \begin{verbatim}
+% \str_compare_p:nNn { ab } < { abc }
+% \end{verbatim}
+% \begin{texnote}
+% This is a wrapper around the \TeX{} primitive
+% \cs[index=pdfstrcmp]{(pdf)strcmp}. It is meant for programming
+% and not for sorting textual contents, as it simply considers
+% character codes and not more elaborate considerations of grapheme
+% clusters, locale, etc.
+% \end{texnote}
+% \end{function}
+%
% \section{Mapping over strings}
%
% All mappings are done at the current group level, \emph{i.e.}~any
@@ -1109,6 +1137,25 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}[pTF, EXP]{\str_compare:nNn, \str_compare:eNe}
+% Simply rely on \cs{@@_if_eq:nn}, which expands to |-1|, |0|
+% or~|1|. The |ee| version is created directly because it is more efficient.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \str_compare:nNn #1#2#3 { p , T , F , TF }
+ {
+ \if_int_compare:w
+ \@@_if_eq:nn { \exp_not:n {#1} } { \exp_not:n {#3} }
+ #2 \c_zero_int
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+\prg_new_conditional:Npnn \str_compare:eNe #1#2#3 { p , T , F , TF }
+ {
+ \if_int_compare:w \@@_if_eq:nn {#1} {#3} #2 \c_zero_int
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macro}[pTF, EXP]
% {
% \str_if_eq:nn, \str_if_eq:Vn, \str_if_eq:on, \str_if_eq:nV,
@@ -1124,14 +1171,14 @@
{
\if_int_compare:w
\@@_if_eq:nn { \exp_not:n {#1} } { \exp_not:n {#2} }
- = 0 \exp_stop_f:
+ = \c_zero_int
\prg_return_true: \else: \prg_return_false: \fi:
}
\prg_generate_conditional_variant:Nnn \str_if_eq:nn
{ V , v , o , nV , no , VV , nv } { p , T , F , TF }
\prg_new_conditional:Npnn \str_if_eq:ee #1#2 { p , T , F , TF }
{
- \if_int_compare:w \@@_if_eq:nn {#1} {#2} = 0 \exp_stop_f:
+ \if_int_compare:w \@@_if_eq:nn {#1} {#2} = \c_zero_int
\prg_return_true: \else: \prg_return_false: \fi:
}
% \end{macrocode}
@@ -1146,7 +1193,7 @@
{
\if_int_compare:w
\@@_if_eq:nn { \tl_to_str:N #1 } { \tl_to_str:N #2 }
- = 0 \exp_stop_f: \prg_return_true: \else: \prg_return_false: \fi:
+ = \c_zero_int \prg_return_true: \else: \prg_return_false: \fi:
}
\prg_generate_conditional_variant:Nnn \str_if_eq:NN
{ c , Nc , cc } { T , F , TF , p }
@@ -1620,7 +1667,7 @@
{
\int_eval:n
{
- \if_int_compare:w #1 < 0 \exp_stop_f:
+ \if_int_compare:w #1 < \c_zero_int
\if_int_compare:w #1 < -#2 \exp_stop_f:
0
\else:
@@ -1673,7 +1720,7 @@
\cs_new:Npn \@@_collect_end:wn #1 ;
{
\exp_after:wN \@@_collect_end:nnnnnnnnw
- \if_case:w \if_int_compare:w #1 > 0 \exp_stop_f:
+ \if_case:w \if_int_compare:w #1 > \c_zero_int
#1 \else: 0 \fi: \exp_stop_f:
\or: \or: \or: \or: \or: \or: \fi:
}
diff --git a/macros/latex/contrib/l3kernel/l3styleguide.pdf b/macros/latex/contrib/l3kernel/l3styleguide.pdf
index de7203d202..d7ded8c0bd 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 375691e3a2..7a2f830ba0 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 2021-05-11}
+\date{Released 2021-05-25}
\begin{document}
diff --git a/macros/latex/contrib/l3kernel/l3syntax-changes.pdf b/macros/latex/contrib/l3kernel/l3syntax-changes.pdf
index 397508a83c..59bcdb0f4b 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 834a27a6e1..c3c0a0d07a 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 2021-05-11}
+\date{Released 2021-05-25}
\newcommand{\TF}{\textit{(TF)}}
diff --git a/macros/latex/contrib/l3kernel/l3sys.dtx b/macros/latex/contrib/l3kernel/l3sys.dtx
index 6399f57f31..40bb7db644 100644
--- a/macros/latex/contrib/l3kernel/l3sys.dtx
+++ b/macros/latex/contrib/l3kernel/l3sys.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -121,6 +121,17 @@
% \tn{fmtname}).
% \end{variable}
%
+% \begin{function}[added = 2020-09-24, EXP]{\sys_timer:}
+% \begin{syntax}
+% \cs{sys_timer:}
+% \end{syntax}
+% Expands to the current value of the engine's timer clock, a
+% non-negative integer. This function is only defined for engines with
+% timer support. This command measures not just CPU time but
+% real time (including time waiting for user input). The unit are
+% scaled seconds ($2^{-16}$ seconds).
+% \end{function}
+%
% \section{Output format}
%
% \begin{function}[added = 2015-09-19, EXP, pTF]
@@ -863,6 +874,53 @@ end
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}[EXP]{\sys_timer:, \@@_elapsedtime:}
+% \begin{macro}[EXP, pTF]{\sys_if_timer_exist:}
+% In \LuaTeX{}, create a pseudo-primitve, otherwise try to
+% locate the real primitive. The elapsed time will be
+% available if this succeeds.
+% \begin{macrocode}
+%</tex>
+%<*lua>
+ local gettimeofday = os.gettimeofday
+ local epoch = gettimeofday() - os.clock()
+ local write = tex.write
+ local tointeger = math.tointeger
+ luacmd('@@_elapsedtime:', function()
+ write(tointeger((gettimeofday() - epoch)*65536 // 1))
+ end, 'global')
+%</lua>
+%<*tex>
+\sys_if_engine_luatex:TF
+ {
+ \cs_new:Npn \sys_timer:
+ { \@@_elapsedtime: }
+ }
+ {
+ \cs_if_exist:NTF \tex_elapsedtime:D
+ {
+ \cs_new:Npn \sys_timer:
+ { \int_value:w \tex_elapsedtime:D }
+ }
+ {
+ \__kernel_msg_new:nnnn { kernel } { no-elapsed-time }
+ { No~clock~detected~for~#1. }
+ { The~current~engine~provides~no~way~to~access~the~system~time. }
+ \cs_new:Npn \sys_timer:
+ {
+ \int_value:w
+ \__kernel_msg_expandable_error:nnn { kernel } { no-elapsed-time }
+ { \sys_timer: }
+ \c_zero_int
+ }
+ }
+ }
+\@@_const:nn { sys_if_timer_exist }
+ { \cs_if_exist_p:N \tex_elapsedtime:D || \cs_if_exist_p:N \@@_elapsedtime: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
% \subsubsection{Access to the shell}
%
% \begin{variable}{\c_sys_shell_escape_int}
diff --git a/macros/latex/contrib/l3kernel/l3term-glossary.pdf b/macros/latex/contrib/l3kernel/l3term-glossary.pdf
index 667db28a6c..cf45c8fe9f 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 253dc77e19..942a911d2d 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 2021-05-11}
+\date{Released 2021-05-25}
\newcommand{\TF}{\textit{(TF)}}
diff --git a/macros/latex/contrib/l3kernel/l3text-case.dtx b/macros/latex/contrib/l3kernel/l3text-case.dtx
index 3fb6816d12..37a00c889d 100644
--- a/macros/latex/contrib/l3kernel/l3text-case.dtx
+++ b/macros/latex/contrib/l3kernel/l3text-case.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3text-purify.dtx b/macros/latex/contrib/l3kernel/l3text-purify.dtx
index 54fa33d04e..96dfcf4c16 100644
--- a/macros/latex/contrib/l3kernel/l3text-purify.dtx
+++ b/macros/latex/contrib/l3kernel/l3text-purify.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/l3text.dtx b/macros/latex/contrib/l3kernel/l3text.dtx
index 58e87ba0e3..19f98b3f44 100644
--- a/macros/latex/contrib/l3kernel/l3text.dtx
+++ b/macros/latex/contrib/l3kernel/l3text.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -955,7 +955,7 @@
}
\cs_new:Npn \@@_expand_testopt:N #1
{
- \str_if_eq:nnTF {#1} { \@protected@testopt }
+ \token_if_eq_meaning:NNTF #1 \@protected@testopt
{ \@@_expand_testopt:NNn }
{ \@@_expand_encoding:N #1 }
}
diff --git a/macros/latex/contrib/l3kernel/l3tl-analysis.dtx b/macros/latex/contrib/l3kernel/l3tl-analysis.dtx
index 05f32c25fe..3580c370f1 100644
--- a/macros/latex/contrib/l3kernel/l3tl-analysis.dtx
+++ b/macros/latex/contrib/l3kernel/l3tl-analysis.dtx
@@ -44,7 +44,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -75,11 +75,16 @@
% In addition, there is a debugging function \cs{tl_analysis_show:n},
% very similar to the \cs[no-index]{ShowTokens} macro from the \pkg{ted} package.
%
-% \begin{function}[added = 2018-04-09]{\tl_analysis_show:N, \tl_analysis_show:n}
+% \begin{function}[added = 2021-05-11]
+% {
+% \tl_analysis_show:N, \tl_analysis_show:n,
+% \tl_analysis_log:N, \tl_analysis_log:n
+% }
% \begin{syntax}
% \cs{tl_analysis_show:n} \Arg{token list}
+% \cs{tl_analysis_log:n} \Arg{token list}
% \end{syntax}
-% Displays to the terminal the detailed decomposition of the
+% Displays to the terminal (or log) the detailed decomposition of the
% \meta{token list} into tokens, showing the category code of each
% character token, the meaning of control sequences and active
% characters, and the value of registers.
@@ -687,7 +692,7 @@
plus \l_@@_analysis_type_int sp \scan_stop:
\int_incr:N \l_@@_analysis_index_int
\int_zero:N \l_@@_analysis_normal_int
- \if_int_compare:w \l_@@_analysis_nesting_int = -1 \exp_stop_f:
+ \if_int_compare:w \l_@@_analysis_nesting_int = - \c_one_int
\cs_set_eq:NN \@@_analysis_a_loop:w \scan_stop:
\fi:
}
@@ -733,7 +738,7 @@
}
\cs_new_protected:Npn \@@_analysis_a_cs:ww #1; #2;
{
- \if_int_compare:w #1 > 0 \exp_stop_f:
+ \if_int_compare:w #1 > \c_zero_int
\tex_skip:D \l_@@_analysis_index_int
= \int_eval:n { \l_@@_analysis_normal_int + 1 } sp \exp_stop_f:
\tex_advance:D \l_@@_analysis_index_int #1 \exp_stop_f:
@@ -792,7 +797,7 @@
% \begin{macrocode}
\cs_new:Npn \@@_analysis_b_normals:ww #1;
{
- \if_int_compare:w #1 = 0 \exp_stop_f:
+ \if_int_compare:w #1 = \c_zero_int
\@@_analysis_b_special:w
\fi:
\@@_analysis_b_normal:wwN #1;
@@ -863,7 +868,7 @@
{
\exp_after:wN \@@_analysis_b_normals:ww
\int_value:w \int_eval:w
- \if_int_compare:w #1 = 0 \exp_stop_f:
+ \if_int_compare:w #1 = \c_zero_int
#3
\else:
\tex_skip:D \int_eval:n { #4 + #1 } \exp_stop_f:
@@ -978,26 +983,39 @@
%
% \subsection{Showing the results}
%
-% \begin{macro}{\tl_analysis_show:N, \tl_analysis_show:n}
+% \begin{macro}{\tl_analysis_show:N, \tl_analysis_log:N, \@@_analysis_show:NNN}
% Add to \cs{@@_analysis:n} a third pass to display tokens to the terminal.
% If the token list variable is not defined, throw the same error
% as \cs{tl_show:N} by simply calling that function.
% \begin{macrocode}
-\cs_new_protected:Npn \tl_analysis_show:N #1
+\cs_new_protected:Npn \tl_analysis_show:N
+ { \@@_analysis_show:NNN \__kernel_msg_show:nnxxxx \tl_show:N }
+\cs_new_protected:Npn \tl_analysis_log:N
+ { \@@_analysis_show:NNN \__kernel_msg_log:nnxxxx \tl_log:N }
+\cs_new_protected:Npn \@@_analysis_show:NNN #1#2#3
{
- \tl_if_exist:NTF #1
+ \tl_if_exist:NTF #3
{
- \exp_args:No \@@_analysis:n {#1}
- \__kernel_msg_show:nnxxxx { tl } { show-analysis }
- { \token_to_str:N #1 } { \@@_analysis_show: } { } { }
+ \exp_args:No \@@_analysis:n {#3}
+ #1 { tl } { show-analysis }
+ { \token_to_str:N #3 } { \@@_analysis_show: } { } { }
}
- { \tl_show:N #1 }
+ { #2 #3 }
}
-\cs_new_protected:Npn \tl_analysis_show:n #1
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_analysis_show:n, \tl_analysis_log:n, \@@_analysis_show:Nn}
+% No existence test needed here.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_analysis_show:n
+ { \@@_analysis_show:Nn \__kernel_msg_show:nnxxxx }
+\cs_new_protected:Npn \tl_analysis_log:n
+ { \@@_analysis_show:Nn \__kernel_msg_log:nnxxxx }
+\cs_new_protected:Npn \@@_analysis_show:Nn #1#2
{
- \@@_analysis:n {#1}
- \__kernel_msg_show:nnxxxx { tl } { show-analysis }
- { } { \@@_analysis_show: } { } { }
+ \@@_analysis:n {#2}
+ #1 { tl } { show-analysis } { } { \@@_analysis_show: } { } { }
}
% \end{macrocode}
% \end{macro}
@@ -1021,7 +1039,7 @@
{
\use_none:n #2
\iow_newline: > \use:nn { ~ } { ~ }
- \if_int_compare:w "#2 = 0 \exp_stop_f:
+ \if_int_compare:w "#2 = \c_zero_int
\exp_after:wN \@@_analysis_show_cs:n
\else:
\if_int_compare:w "#2 = 13 \exp_stop_f:
@@ -1206,10 +1224,10 @@
\cs_new_protected:Npn \@@_peek_analysis_test:
{
\if_int_odd:w
- \if_catcode:w \exp_not:N \l_peek_token { 0 \exp_stop_f: \fi:
- \if_catcode:w \exp_not:N \l_peek_token } 0 \exp_stop_f: \fi:
- \if_meaning:w \l_peek_token \c_space_token 0 \exp_stop_f: \fi:
- 1 \exp_stop_f:
+ \if_catcode:w \exp_not:N \l_peek_token { \c_zero_int \fi:
+ \if_catcode:w \exp_not:N \l_peek_token } \c_zero_int \fi:
+ \if_meaning:w \l_peek_token \c_space_token \c_zero_int \fi:
+ \c_one_int
\exp_after:wN \exp_after:wN
\exp_after:wN \@@_peek_analysis_normal:N
\exp_after:wN \exp_not:N
diff --git a/macros/latex/contrib/l3kernel/l3tl.dtx b/macros/latex/contrib/l3kernel/l3tl.dtx
index fb2a14b6f0..01e7964a1d 100644
--- a/macros/latex/contrib/l3kernel/l3tl.dtx
+++ b/macros/latex/contrib/l3kernel/l3tl.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -350,6 +350,11 @@
% Otherwise, spaces (and tabs) are retained at both ends of the
% single-line string, as if it appeared in the middle of a line
% read from a file.
+%
+% Contrarily to the \tn{scantokens} primitive, \cs{tl_rescan:nn}
+% tokenizes the whole string in the same category code regime rather
+% than one token at a time, so that directives such as \tn{verb}
+% that rely on changing category codes will not function properly.
% \end{texnote}
% \end{function}
%
@@ -1317,9 +1322,9 @@
% Error checking is sorted out by the parent function.
% \begin{macrocode}
\cs_new_protected:Npn \tl_clear:N #1
- { \tl_set_eq:NN #1 \c_empty_tl }
+ { \tex_let:D #1 = ~ \c_empty_tl }
\cs_new_protected:Npn \tl_gclear:N #1
- { \tl_gset_eq:NN #1 \c_empty_tl }
+ { \tex_global:D \tex_let:D #1 ~ \c_empty_tl }
\cs_generate_variant:Nn \tl_clear:N { c }
\cs_generate_variant:Nn \tl_gclear:N { c }
% \end{macrocode}
@@ -1344,10 +1349,13 @@
% \begin{macro}{\tl_set_eq:NN, \tl_set_eq:Nc, \tl_set_eq:cN, \tl_set_eq:cc}
% \begin{macro}{\tl_gset_eq:NN, \tl_gset_eq:Nc, \tl_gset_eq:cN, \tl_gset_eq:cc}
% For setting token list variables equal to each other. To allow for
-% patching, the arguments have to be explicit.
+% patching, the arguments have to be explicit. In addition this
+% ensures that a braced second argument will not cause problems.
% \begin{macrocode}
-\cs_new_protected:Npn \tl_set_eq:NN #1#2 { \cs_set_eq:NN #1 #2 }
-\cs_new_protected:Npn \tl_gset_eq:NN #1#2 { \cs_gset_eq:NN #1 #2 }
+\cs_new_protected:Npn \tl_set_eq:NN #1#2
+ { \tex_let:D #1 = ~ #2 }
+\cs_new_protected:Npn \tl_gset_eq:NN #1#2
+ { \tex_global:D \tex_let:D #1 = ~ #2 }
\cs_generate_variant:Nn \tl_set_eq:NN { cN, Nc, cc }
\cs_generate_variant:Nn \tl_gset_eq:NN { cN, Nc, cc }
% \end{macrocode}
@@ -1404,14 +1412,9 @@
% created the old-fashioned way.
% \begin{macrocode}
\group_begin:
-\tex_lccode:D `A = `-
-\tex_lccode:D `N = `N
-\tex_lccode:D `V = `V
-\tex_lowercase:D
- {
- \group_end:
- \tl_const:Nn \c_novalue_tl { ANoValue- }
- }
+\tex_catcode:D `- = 11 ~
+\tl_const:Nx \c_novalue_tl { - NoValue \token_to_str:N - }
+\group_end:
% \end{macrocode}
% \end{variable}
%
@@ -2304,22 +2307,27 @@
%
% \begin{macro}[pTF, EXP]{\tl_if_novalue:n}
% \begin{macro}[EXP]{\@@_if_novalue:w}
-% Tests for |-NoValue-|: this is similar to \cs{tl_if_in:nn} but set
-% up to be expandable and to check the value exactly. The question
-% mark prevents the auxiliary from losing braces.
+% Tests whether |##1| matches |-NoValue-| exactly (with suitable
+% catcodes): this is similar to \cs{quark_if_nil:nTF}. The first
+% argument of \cs{@@_if_novalue:w} is empty if and only if |##1|
+% starts with |-NoValue-|, while the second argument is empty if |##1|
+% is exactly |-NoValue-| or if it has a question mark just following
+% |-NoValue-|. In this second case, however, the material after the
+% first |?!| remains and makes the emptyness test return
+% \texttt{false}.
% \begin{macrocode}
\cs_set_protected:Npn \@@_tmp:w #1
{
\prg_new_conditional:Npnn \tl_if_novalue:n ##1
{ p , T , F , TF }
{
- \str_if_eq:onTF
- { \@@_if_novalue:w ? ##1 { } #1 }
- { ? { } #1 }
- { \prg_return_true: }
- { \prg_return_false: }
+ \@@_if_empty_if:o { \@@_if_novalue:w {} ##1 {} ? ! #1 ? ? ! }
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
}
- \cs_new:Npn \@@_if_novalue:w ##1 #1 {##1}
+ \cs_new:Npn \@@_if_novalue:w ##1 #1 ##2 ? ##3 ? ! { ##1 ##2 }
}
\exp_args:No \@@_tmp:w { \c_novalue_tl }
% \end{macrocode}
@@ -2460,37 +2468,56 @@
%
% \subsection{Mapping over token lists}
%
-% \begin{macro}{\tl_map_function:nN}
-% \begin{macro}{\tl_map_function:NN, \tl_map_function:cN}
-% \begin{macro}{\@@_map_function:Nn}
-% Expandable loop macro for token lists. These have the advantage of not
-% needing to test if the argument is empty, because if it is, the stop
-% marker is read immediately and the loop terminated.
+% \begin{macro}
+% {
+% \tl_map_function:nN, \tl_map_function:NN, \tl_map_function:cN,
+% \@@_map_function:Nnnnnnnnn, \@@_map_function_end:w,
+% \@@_use_none_delimit_by_s_stop:w
+% }
+% Expandable loop macro for token lists. We use the internal scan
+% mark \cs{s_@@_stop} (defined later), which is not allowed to show up
+% in the token list |#1| since it is internal to \pkg{l3tl}. This
+% allows us a very fast test of whether some \meta{item} is the
+% end-marker \cs{s_@@_stop}, namely call
+% \cs{@@_use_none_delimit_by_s_stop:w} \meta{item} \meta{function}
+% \cs{s_@@_stop}, which calls \meta{function} if the \meta{item} is
+% the end-marker. To speed up the loop even more, only test one out
+% of eight items, and once we hit one of the eight end-markers,
+% go more slowly through the last few items of the list using
+% \cs{@@_map_function_end:w}.
% \begin{macrocode}
\cs_new:Npn \tl_map_function:nN #1#2
{
- \@@_map_function:Nn #2 #1
- \q_@@_recursion_tail
+ \@@_map_function:Nnnnnnnnn #2 #1
+ \s_@@_stop \s_@@_stop \s_@@_stop \s_@@_stop
+ \s_@@_stop \s_@@_stop \s_@@_stop \s_@@_stop
\prg_break_point:Nn \tl_map_break: { }
}
\cs_new:Npn \tl_map_function:NN
{ \exp_args:No \tl_map_function:nN }
-\cs_new:Npn \@@_map_function:Nn #1#2
+\cs_generate_variant:Nn \tl_map_function:NN { c }
+\cs_new:Npn \@@_map_function:Nnnnnnnnn #1#2#3#4#5#6#7#8#9
{
- \@@_if_recursion_tail_break:nN {#2} \tl_map_break:
- #1 {#2} \@@_map_function:Nn #1
+ \@@_use_none_delimit_by_s_stop:w
+ #9 \@@_map_function_end:w \s_@@_stop
+ #1 {#2} #1 {#3} #1 {#4} #1 {#5} #1 {#6} #1 {#7} #1 {#8} #1 {#9}
+ \@@_map_function:Nnnnnnnnn #1
}
-\cs_generate_variant:Nn \tl_map_function:NN { c }
+\cs_new:Npn \@@_map_function_end:w \s_@@_stop #1#2
+ {
+ \@@_use_none_delimit_by_s_stop:w #2 \tl_map_break: \s_@@_stop
+ #1 {#2}
+ \@@_map_function_end:w \s_@@_stop
+ }
+\cs_new:Npn \@@_use_none_delimit_by_s_stop:w #1 \s_@@_stop { }
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\tl_map_inline:nn}
% \begin{macro}{\tl_map_inline:Nn, \tl_map_inline:cn}
% The inline functions are straight forward by now. We use a little
% trick with the counter \cs{g__kernel_prg_map_int} to make
-% them nestable. We can also make use of \cs{@@_map_function:Nn}
+% them nestable. We can also make use of \cs{@@_map_function:Nnnnnnnnn}
% from before.
% \begin{macrocode}
\cs_new_protected:Npn \tl_map_inline:nn #1#2
@@ -2498,9 +2525,11 @@
\int_gincr:N \g__kernel_prg_map_int
\cs_gset_protected:cpn
{ @@_map_ \int_use:N \g__kernel_prg_map_int :w } ##1 {#2}
- \exp_args:Nc \@@_map_function:Nn
+ \exp_args:Nc \@@_map_function:Nnnnnnnnn
{ @@_map_ \int_use:N \g__kernel_prg_map_int :w }
- #1 \q_@@_recursion_tail
+ #1
+ \s_@@_stop \s_@@_stop \s_@@_stop \s_@@_stop
+ \s_@@_stop \s_@@_stop \s_@@_stop \s_@@_stop
\prg_break_point:Nn \tl_map_break:
{ \int_gdecr:N \g__kernel_prg_map_int }
}
@@ -2511,54 +2540,54 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\tl_map_tokens:nn}
-% \begin{macro}{\tl_map_tokens:Nn, \tl_map_tokens:cn}
-% \begin{macro}{\@@_map_tokens:nn}
+% \begin{macro}
+% {
+% \tl_map_tokens:nn, \tl_map_tokens:Nn, \tl_map_tokens:cn,
+% \@@_map_tokens:nnnnnnnnn, \@@_map_tokens_end:w
+% }
% Much like the function mapping.
% \begin{macrocode}
\cs_new:Npn \tl_map_tokens:nn #1#2
{
- \@@_map_tokens:nn {#2} #1
- \q_@@_recursion_tail
+ \@@_map_tokens:nnnnnnnnn {#2} #1
+ \s_@@_stop \s_@@_stop \s_@@_stop \s_@@_stop
+ \s_@@_stop \s_@@_stop \s_@@_stop \s_@@_stop
\prg_break_point:Nn \tl_map_break: { }
}
\cs_new:Npn \tl_map_tokens:Nn
{ \exp_args:No \tl_map_tokens:nn }
\cs_generate_variant:Nn \tl_map_tokens:Nn { c }
-\cs_new:Npn \@@_map_tokens:nn #1#2
+\cs_new:Npn \@@_map_tokens:nnnnnnnnn #1#2#3#4#5#6#7#8#9
{
- \@@_if_recursion_tail_break:nN {#2} \tl_map_break:
- \use:n {#1} {#2}
- \@@_map_tokens:nn {#1}
+ \@@_use_none_delimit_by_s_stop:w
+ #9 \@@_map_tokens_end:w \s_@@_stop
+ \use:n {#1} {#2} \use:n {#1} {#3} \use:n {#1} {#4} \use:n {#1} {#5}
+ \use:n {#1} {#6} \use:n {#1} {#7} \use:n {#1} {#8} \use:n {#1} {#9}
+ \@@_map_tokens:nnnnnnnnn {#1}
+ }
+\cs_new:Npn \@@_map_tokens_end:w \s_@@_stop \use:n #1#2
+ {
+ \@@_use_none_delimit_by_s_stop:w #2 \tl_map_break: \s_@@_stop
+ #1 {#2}
+ \@@_map_tokens_end:w \s_@@_stop
}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
%
% \begin{macro}{\tl_map_variable:nNn}
% \begin{macro}{\tl_map_variable:NNn, \tl_map_variable:cNn}
% \begin{macro}{\@@_map_variable:Nnn}
-% \cs{tl_map_variable:nNn} \meta{token list} \meta{tl~var}
-% \meta{action} assigns \meta{tl~var} to each element and executes
+% \cs{tl_map_variable:nNn} \Arg{token list} \meta{tl~var}
+% \Arg{action} assigns \meta{tl~var} to each element and executes
% \meta{action}. The assignment to \meta{tl~var} is done after the
% quark test so that this variable does not get set to a quark.
% \begin{macrocode}
\cs_new_protected:Npn \tl_map_variable:nNn #1#2#3
- {
- \@@_map_variable:Nnn #2 {#3} #1
- \q_@@_recursion_tail
- \prg_break_point:Nn \tl_map_break: { }
- }
+ { \tl_map_tokens:nn {#1} { \@@_map_variable:Nnn #2 {#3} } }
+\cs_new_protected:Npn \@@_map_variable:Nnn #1#2#3
+ { \tl_set:Nn #1 {#3} #2 }
\cs_new_protected:Npn \tl_map_variable:NNn
{ \exp_args:No \tl_map_variable:nNn }
-\cs_new_protected:Npn \@@_map_variable:Nnn #1#2#3
- {
- \@@_if_recursion_tail_break:nN {#3} \tl_map_break:
- \tl_set:Nn #1 {#3}
- \use:n {#2}
- \@@_map_variable:Nnn #1 {#2}
- }
\cs_generate_variant:Nn \tl_map_variable:NNn { c }
% \end{macrocode}
% \end{macro}
@@ -3439,7 +3468,7 @@
}
\cs_new:Npn \@@_range_skip:w #1 ; #2
{
- \if_int_compare:w #1 > 0 \exp_stop_f:
+ \if_int_compare:w #1 > \c_zero_int
\exp_after:wN \@@_range_skip:w
\int_value:w \int_eval:n { #1 - 1 } \exp_after:wN ;
\else:
@@ -3499,7 +3528,7 @@
{
\int_eval:n
{
- \if_int_compare:w #1 < 0 \exp_stop_f:
+ \if_int_compare:w #1 < \c_zero_int
\if_int_compare:w #1 < -#2 \exp_stop_f:
0
\else:
diff --git a/macros/latex/contrib/l3kernel/l3token.dtx b/macros/latex/contrib/l3kernel/l3token.dtx
index ce65d87061..5a5ecf5b3c 100644
--- a/macros/latex/contrib/l3kernel/l3token.dtx
+++ b/macros/latex/contrib/l3kernel/l3token.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
@@ -1580,7 +1580,7 @@
\cs_new:Npn \@@_generate_aux:w #1 ; #2 ;
{
\if_int_compare:w #2 = 10 \exp_stop_f:
- \if_int_compare:w #1 = 0 \exp_stop_f:
+ \if_int_compare:w #1 = \c_zero_int
\__kernel_msg_expandable_error:nn { char } { null-space }
\else:
\__kernel_msg_expandable_error:nn { char } { space }
@@ -1595,7 +1595,7 @@
{ invalid-catcode }
\else:
\if_int_odd:w 0
- \if_int_compare:w #1 < 0 \exp_stop_f: 1 \fi:
+ \if_int_compare:w #1 < \c_zero_int 1 \fi:
\if_int_compare:w #1 > \c_max_char_int 1 \fi: \exp_stop_f:
\__kernel_msg_expandable_error:nn { char }
{ out-of-range }
@@ -3143,10 +3143,10 @@ end
\cs_new_protected:Npn \@@_execute_branches_N_type:
{
\if_int_odd:w
- \if_catcode:w \exp_not:N \l_peek_token { 0 \exp_stop_f: \fi:
- \if_catcode:w \exp_not:N \l_peek_token } 0 \exp_stop_f: \fi:
- \if_meaning:w \l_peek_token \c_space_token 0 \exp_stop_f: \fi:
- 1 \exp_stop_f:
+ \if_catcode:w \exp_not:N \l_peek_token { \c_zero_int \fi:
+ \if_catcode:w \exp_not:N \l_peek_token } \c_zero_int \fi:
+ \if_meaning:w \l_peek_token \c_space_token \c_zero_int \fi:
+ \c_one_int
\exp_after:wN \@@_N_type:w
\token_to_meaning:N \l_peek_token
\s_@@_mark \@@_N_type_aux:nnw
diff --git a/macros/latex/contrib/l3kernel/l3unicode.dtx b/macros/latex/contrib/l3kernel/l3unicode.dtx
index 0d2a3bedbc..ddab156267 100644
--- a/macros/latex/contrib/l3kernel/l3unicode.dtx
+++ b/macros/latex/contrib/l3kernel/l3unicode.dtx
@@ -43,7 +43,7 @@
% }^^A
% }
%
-% \date{Released 2021-05-11}
+% \date{Released 2021-05-25}
%
% \maketitle
%
diff --git a/macros/latex/contrib/l3kernel/source3.pdf b/macros/latex/contrib/l3kernel/source3.pdf
index b962910210..fbe699ec01 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 05de34a9e4..bd969b556f 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 2021-05-11}
+\date{Released 2021-05-25}
\pagenumbering{roman}
\maketitle