diff options
author | Karl Berry <karl@freefriends.org> | 2021-05-25 20:48:22 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2021-05-25 20:48:22 +0000 |
commit | 1764edc3b60a2c9fb210ca74b758f3e8e8a53692 (patch) | |
tree | da1842e54bdea33c2b8d434860131cfa08c9444d /Master/texmf-dist/source/latex/l3kernel | |
parent | 4bf5956529386575d89874638bfd567040b9475c (diff) |
l3kernel (25may21)
git-svn-id: svn://tug.org/texlive/trunk@59345 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel')
56 files changed, 1435 insertions, 697 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx b/Master/texmf-dist/source/latex/l3kernel/expl3.dtx index 16632dbd992..8f3af5c3892 100644 --- a/Master/texmf-dist/source/latex/l3kernel/expl3.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx index 47c746ee43f..7fe36b480c0 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx index 40047fe4464..d9b59d5e065 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3bootstrap.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-05-11} +% \date{Released 2021-05-25} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx b/Master/texmf-dist/source/latex/l3kernel/l3box.dtx index 1eb6848d857..f9cef57a962 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3box.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx b/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx index 84fd99a2b09..4cbda2d01b8 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3candidates.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx b/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx index 9a0bc549333..9be46ebd85b 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3cctab.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-05-11} +% \date{Released 2021-05-25} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx index f61fedb4837..147fb466751 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx b/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx index e0cdd606b31..dfeb71e9ec9 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3coffins.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3color.dtx b/Master/texmf-dist/source/latex/l3kernel/l3color.dtx index 9b72bdc466a..8efa83b1abc 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3color.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx b/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx index b7eb9d0215d..1ac920d00ef 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3debug.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx b/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx index 42e7283436d..7e7f6bd37be 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3deprecation.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-05-11} +% \date{Released 2021-05-25} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx b/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx index aa9fce6c58b..d3154c8c9e1 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3doc.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx index fa01fb954e7..62399e23c65 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3docstrip.dtx @@ -63,7 +63,7 @@ % }^^A % } % -% \date{Released 2021-05-11} +% \date{Released 2021-05-25} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx index 163e867881d..949b70c2aa0 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3expan.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-05-11} +% \date{Released 2021-05-25} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx b/Master/texmf-dist/source/latex/l3kernel/l3file.dtx index a89f6540c68..d3f57f9deba 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3file.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx b/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx index 1b8dfa7c7ae..74f3cf439c3 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3flag.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-05-11} +% \date{Released 2021-05-25} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx index 59eb0b65df0..eb4500db358 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-assign.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx index 1811a174755..c98bcf90356 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-aux.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx index 0a5662979dd..1fd4ce1656d 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-basics.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx index 097da442af6..edf99846713 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-convert.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx index 0be0e3f605d..213885a7014 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-expo.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx index 44ae9a5d7d6..d8d10634f91 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-extended.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx index 165d955d7b9..3292b9f11e3 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-logic.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx index dcfa86e2276..7c5f6a6e372 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-parse.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx index 7b854343ed1..d801f89d82b 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-random.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx index 5012e48e9b2..4832e895173 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-round.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx index c4dbfa4d15a..1a376b8edaa 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-traps.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx index 669642d2e8f..0a2c9f86165 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp-trig.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx index 27ee89c0730..3a007cb6a6f 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fp.dtx @@ -49,7 +49,7 @@ % }^^A % } % -% \date{Released 2021-05-11} +% \date{Released 2021-05-25} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx b/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx index a66073e0735..76cd235b623 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3fparray.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-05-11} +% \date{Released 2021-05-25} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx b/Master/texmf-dist/source/latex/l3kernel/l3int.dtx index 5994a193c6c..505afcd9ee4 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3int.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx b/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx index f67e937989b..6f8215023ce 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3intarray.dtx @@ -44,7 +44,7 @@ % }^^A % } % -% \date{Released 2021-05-11} +% \date{Released 2021-05-25} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx b/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx index 428774aa937..51b6fe2a826 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3kernel-functions.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-05-11} +% \date{Released 2021-05-25} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx index 8f5f984c79c..113760c9694 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx b/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx index 05b98fed562..1055137bb69 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3legacy.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx index 35c8df065da..19487b50478 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3luatex.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-05-11} +% \date{Released 2021-05-25} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx index ed2169b94f2..a46d268a484 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3msg.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3names.dtx b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx index 44239f2348e..673bd468c15 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3names.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3names.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-05-11} +% \date{Released 2021-05-25} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx b/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx index 71a0f854697..f3ec7e241df 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3pdf.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-05-11} +% \date{Released 2021-05-25} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx index eedb4f271a3..8539c24ff29 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3prg.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-05-11} +% \date{Released 2021-05-25} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx index 371f894c420..16609f3af80 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx b/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx index 10ccfa74836..ebad07808f1 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3quark.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx b/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx index 4962ca6fa2e..7f384c8d56d 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3regex.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx index 18e954d9e18..a8bd4d97e63 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx b/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx index fa2b011f990..0e8636b4402 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3skip.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx b/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx index 46ed7ca906e..1f05797ebdf 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3sort.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-05-11} +% \date{Released 2021-05-25} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx b/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx index c9ce040eeec..1fe62d128ca 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3str-convert.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3str.dtx b/Master/texmf-dist/source/latex/l3kernel/l3str.dtx index aecd6d3c0d1..6b6acc03364 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3str.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx index 6399f57f318..40bb7db644c 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3sys.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx b/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx index 3fb6816d12e..37a00c889d3 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3text-case.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-05-11} +% \date{Released 2021-05-25} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx b/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx index 54fa33d04e8..96dfcf4c166 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3text-purify.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-05-11} +% \date{Released 2021-05-25} % % \maketitle % diff --git a/Master/texmf-dist/source/latex/l3kernel/l3text.dtx b/Master/texmf-dist/source/latex/l3kernel/l3text.dtx index 58e87ba0e3a..19f98b3f447 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3text.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx index 05f32c25fe5..3580c370f19 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3tl-analysis.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx index fb2a14b6f05..01e7964a1d1 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3token.dtx b/Master/texmf-dist/source/latex/l3kernel/l3token.dtx index ce65d87061b..5a5ecf5b3c3 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3token.dtx +++ b/Master/texmf-dist/source/latex/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/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx b/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx index 0d2a3bedbc8..ddab1562677 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3unicode.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-05-11} +% \date{Released 2021-05-25} % % \maketitle % |