[latex3-commits] [git/LaTeX3-latex3-latex2e] main: Update l3kernel to 2021-11-22 (23766691)

Joseph Wright joseph.wright at morningstar2.co.uk
Mon Nov 22 16:07:17 CET 2021


Repository : https://github.com/latex3/latex2e
On branch  : main
Link       : https://github.com/latex3/latex2e/commit/2376669195563bcff9d1848305c00e69e75e6bfc

>---------------------------------------------------------------

commit 2376669195563bcff9d1848305c00e69e75e6bfc
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date:   Mon Nov 22 15:06:28 2021 +0000

    Update l3kernel to 2021-11-22


>---------------------------------------------------------------

2376669195563bcff9d1848305c00e69e75e6bfc
 texmf/tex/latex/l3kernel/expl3-code.tex    | 463 +++++++++++++++++------------
 texmf/tex/latex/l3kernel/expl3-generic.tex |   2 +-
 texmf/tex/latex/l3kernel/expl3.ltx         |   2 +-
 texmf/tex/latex/l3kernel/expl3.lua         | 260 ++++++++++++++--
 texmf/tex/latex/l3kernel/expl3.sty         |   2 +-
 5 files changed, 509 insertions(+), 220 deletions(-)

diff --git a/texmf/tex/latex/l3kernel/expl3-code.tex b/texmf/tex/latex/l3kernel/expl3-code.tex
index acd75465..9bbbaa1d 100644
--- a/texmf/tex/latex/l3kernel/expl3-code.tex
+++ b/texmf/tex/latex/l3kernel/expl3-code.tex
@@ -24,7 +24,7 @@
 %% l3file.dtx  (with options: `package')
 %% l3skip.dtx  (with options: `package')
 %% l3keys.dtx  (with options: `package')
-%% l3intarray.dtx  (with options: `package')
+%% l3intarray.dtx  (with options: `package,tex')
 %% l3fp.dtx  (with options: `package')
 %% l3fp-aux.dtx  (with options: `package')
 %% l3fp-traps.dtx  (with options: `package')
@@ -70,7 +70,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2021-11-12}%
+\def\ExplFileDate{2021-11-22}%
 \begingroup
   \def\next{\endgroup}%
   \expandafter\ifx\csname PackageError\endcsname\relax
@@ -158,10 +158,7 @@
     \expandafter\ifx\csname newcatcodetable\endcsname\relax
       \input{ltluatex}%
     \fi
-    \begingroup\edef\ignored{%
-      \expandafter\noexpand\csname prg_return_true:\endcsname
-      \expandafter\noexpand\csname prg_return_false:\endcsname
-    }\endgroup
+    \ifdefined\newluabytecode\newluabytecode\@expl at luadata@bytecode\fi
     \directlua{require("expl3")}%
     \ifnum 0%
       \directlua{
@@ -13091,29 +13088,19 @@
   \cs_new:Npn \__keys_define_code:w #1 \c_colon_str #2 \s__keys_stop
     { \tl_if_empty:nTF {#2} }
 \cs_new_protected:Npn \__keys_bool_set:Nn #1#2
-  {
-    \bool_if_exist:NF #1 { \bool_new:N #1 }
-    \__keys_choice_make:
-    \__keys_cmd_set:nx { \l_keys_path_str / true }
-      { \exp_not:c { bool_ #2 set_true:N } \exp_not:N #1 }
-    \__keys_cmd_set:nx { \l_keys_path_str / false }
-      { \exp_not:c { bool_ #2 set_false:N } \exp_not:N #1 }
-    \__keys_cmd_set:nn { \l_keys_path_str / unknown }
-      {
-        \msg_error:nnx { keys } { boolean-values-only }
-          \l_keys_key_str
-      }
-    \__keys_default_set:n { true }
-  }
+  { \__keys_bool_set:Nnnn #1 {#2} { true } { false } }
 \cs_generate_variant:Nn \__keys_bool_set:Nn { c }
 \cs_new_protected:Npn \__keys_bool_set_inverse:Nn #1#2
+  { \__keys_bool_set:Nnnn #1 {#2} { false } { true } }
+\cs_generate_variant:Nn \__keys_bool_set_inverse:Nn { c }
+\cs_new_protected:Npn \__keys_bool_set:Nnnn #1#2#3#4
   {
     \bool_if_exist:NF #1 { \bool_new:N #1 }
     \__keys_choice_make:
     \__keys_cmd_set:nx { \l_keys_path_str / true }
-      { \exp_not:c { bool_ #2 set_false:N } \exp_not:N #1 }
+      { \exp_not:c { bool_ #2 set_ #3 :N } \exp_not:N #1 }
     \__keys_cmd_set:nx { \l_keys_path_str / false }
-      { \exp_not:c { bool_ #2 set_true:N } \exp_not:N #1 }
+      { \exp_not:c { bool_ #2 set_ #4 :N } \exp_not:N #1 }
     \__keys_cmd_set:nn { \l_keys_path_str / unknown }
       {
         \msg_error:nnx { keys } { boolean-values-only }
@@ -13121,7 +13108,7 @@
       }
     \__keys_default_set:n { true }
   }
-\cs_generate_variant:Nn \__keys_bool_set_inverse:Nn { c }
+\cs_generate_variant:Nn \__keys_bool_set:Nn { c }
 \cs_new_protected:Npn \__keys_choice_make:
   { \__keys_choice_make:N \__keys_choice_find:n }
 \cs_new_protected:Npn \__keys_multichoice_make:
@@ -13228,6 +13215,24 @@
           { \__keys_execute:nn \l_keys_path_str {#1} }
       }
   }
+\cs_new_protected:Npn \__keys_legacy_if_set:nn #1#2
+  { \__keys_legacy_if_set:nnnn {#1} {#2} { true } { false } }
+\cs_new_protected:Npn \__keys_legacy_if_set_inverse:nn #1#2
+  { \__keys_legacy_if_set:nnnn {#1} {#2} { false } { true } }
+\cs_new_protected:Npn \__keys_legacy_if_set:nnnn #1#2#3#4
+  {
+    \__keys_choice_make:
+    \__keys_cmd_set:nx { \l_keys_path_str / true }
+      { \exp_not:c { legacy_if_#2  set_ #3 :n } { \exp_not:n {#1} } }
+    \__keys_cmd_set:nx { \l_keys_path_str / false }
+      { \exp_not:c { legacy_if_#2  set_ #4 :n } { \exp_not:n {#1} } }
+    \__keys_cmd_set:nn { \l_keys_path_str / unknown }
+      {
+        \msg_error:nnx { keys } { boolean-values-only }
+          \l_keys_key_str
+      }
+    \__keys_default_set:n { true }
+  }
 \cs_new_protected:Npn \__keys_meta_make:n #1
   {
     \__keys_cmd_set:Vo \l_keys_path_str
@@ -13420,6 +13425,14 @@
   { \__keys_variable_set_required:NnnN #1 { int } { g } n }
 \cs_new_protected:cpn { \c__keys_props_root_str .int_gset:c } #1
   { \__keys_variable_set_required:cnnN {#1} { int } { g } n }
+\cs_new_protected:cpn { \c__keys_props_root_str .legacy_if_set:n } #1
+  { \__keys_legacy_if_set:nn {#1} { } }
+\cs_new_protected:cpn { \c__keys_props_root_str .legacy_if_gset:n } #1
+  { \__keys_legacy_if_set:nn {#1} { g } }
+\cs_new_protected:cpn { \c__keys_props_root_str .legacy_if_set_inverse:n } #1
+  { \__keys_legacy_if_set_inverse:nn {#1} { } }
+\cs_new_protected:cpn { \c__keys_props_root_str .legacy_if_gset_inverse:n } #1
+  { \__keys_legacy_if_set_inverse:nn {#1} { g } }
 \cs_new_protected:cpn { \c__keys_props_root_str .meta:n } #1
   { \__keys_meta_make:n {#1} }
 \cs_new_protected:cpn { \c__keys_props_root_str .meta:nn } #1
@@ -14032,193 +14045,269 @@
 \prop_gput:Nnn \g_msg_module_name_prop { keys } { LaTeX3 }
 \prop_gput:Nnn \g_msg_module_type_prop { keys } { }
 %% File: l3intarray.dtx
-\cs_new_eq:NN \__intarray_entry:w \tex_fontdimen:D
-\cs_new_eq:NN \__intarray_count:w \tex_hyphenchar:D
-\int_new:N \l__intarray_loop_int
-\dim_const:Nn \c__intarray_sp_dim { 1 sp }
-\int_new:N \g__intarray_font_int
 \msg_new:nnn { kernel } { negative-array-size }
   { Size~of~array~may~not~be~negative:~#1 }
-\cs_new_protected:Npn \__intarray_new:N #1
-  {
-    \__kernel_chk_if_free_cs:N #1
-    \int_gincr:N \g__intarray_font_int
-    \tex_global:D \tex_font:D #1
-      = cmr10~at~ \g__intarray_font_int \c__intarray_sp_dim \scan_stop:
-    \int_step_inline:nn { 8 }
-      { \__kernel_intarray_gset:Nnn #1 {##1} \c_zero_int }
-  }
-\cs_new_protected:Npn \intarray_new:Nn #1#2
+\int_new:N \l__intarray_loop_int
+\cs_if_exist:NTF \__intarray_gset_count:Nw
   {
-    \__intarray_new:N #1
-    \__intarray_count:w #1 = \int_eval:n {#2} \scan_stop:
-    \int_compare:nNnT { \intarray_count:N #1 } < 0
+    \int_new:N \g__intarray_table_int
+    \int_new:N \l__intarray_bad_index_int
+    \cs_new_protected:Npn \__intarray_new:N #1
       {
-        \msg_error:nnx { kernel } { negative-array-size }
-          { \intarray_count:N #1 }
+        \__kernel_chk_if_free_cs:N #1
+        \int_gincr:N \g__intarray_table_int
+        \cs_gset_nopar:Npx #1 { \__intarray:w \int_use:N \g__intarray_table_int \c_space_tl }
       }
-    \int_compare:nNnT { \intarray_count:N #1 } > 0
-      { \__kernel_intarray_gset:Nnn #1 { \intarray_count:N #1 } { 0 } }
-  }
-\cs_generate_variant:Nn \intarray_new:Nn { c }
-\cs_new:Npn \intarray_count:N #1 { \int_value:w \__intarray_count:w #1 }
-\cs_generate_variant:Nn \intarray_count:N { c }
-\cs_new:Npn \__intarray_signed_max_dim:n #1
-  { \int_value:w \int_compare:nNnT {#1} < 0 { - } \c_max_dim }
-\cs_new:Npn \__intarray_bounds:NNnTF #1#2#3
-  {
-    \if_int_compare:w 1 > #3 \exp_stop_f:
-      \__intarray_bounds_error:NNnw #1 #2 {#3}
-    \else:
-      \if_int_compare:w #3 > \intarray_count:N #2 \exp_stop_f:
-        \__intarray_bounds_error:NNnw #1 #2 {#3}
-      \fi:
-    \fi:
-    \use_i:nn
-  }
-\cs_new:Npn \__intarray_bounds_error:NNnw #1#2#3#4 \use_i:nn #5#6
-  {
-    #4
-    #1 { kernel } { out-of-bounds }
-      { \token_to_str:N #2 } {#3} { \intarray_count:N #2 }
-    #6
-  }
-\cs_new_protected:Npn \__kernel_intarray_gset:Nnn #1#2#3
-  { \__intarray_entry:w #2 #1 #3 \c__intarray_sp_dim }
-\cs_new_protected:Npn \intarray_gset:Nnn #1#2#3
-  {
-    \exp_after:wN \__intarray_gset:Nww
-    \exp_after:wN #1
-    \int_value:w \int_eval:n {#2} \exp_after:wN ;
-    \int_value:w \int_eval:n {#3} ;
-  }
-\cs_generate_variant:Nn \intarray_gset:Nnn { c }
-\cs_new_protected:Npn \__intarray_gset:Nww #1#2 ; #3 ;
-  {
-    \__intarray_bounds:NNnTF \msg_error:nnxxx #1 {#2}
+    \cs_new_protected:Npn \intarray_new:Nn #1#2
       {
-        \__intarray_gset_overflow_test:nw {#3}
-        \__kernel_intarray_gset:Nnn #1 {#2} {#3}
+        \__intarray_new:N #1
+        \__intarray_gset_count:Nw #1 \int_eval:n {#2} \scan_stop:
+        \int_compare:nNnT { \intarray_count:N #1 } < 0
+          {
+            \msg_error:nnx { kernel } { negative-array-size }
+              { \intarray_count:N #1 }
+          }
       }
-      { }
-  }
-\cs_if_exist:NTF \tex_ifabsnum:D
-  {
-    \cs_new_protected:Npn \__intarray_gset_overflow_test:nw #1
+    \cs_generate_variant:Nn \intarray_new:Nn { c }
+    \cs_generate_variant:Nn \intarray_count:N { c }
+    \cs_new_protected:Npn \__kernel_intarray_gset:Nnn #1#2#3
+      { \__intarray_gset:w #2 #1 #3 \scan_stop: }
+    \cs_new_protected:Npn \intarray_gset:Nnn #1#2#3
       {
-        \tex_ifabsnum:D #1 > \c_max_dim
-          \exp_after:wN \__intarray_gset_overflow:NNnn
-        \fi:
+        \__intarray_gset:wF \int_eval:n {#2} #1 \int_eval:n{#3}
+          {
+            \msg_error:nnxxx { kernel } { out-of-bounds }
+              { \token_to_str:N #1 } { \int_use:N \l__intarray_bad_index_int } { \intarray_count:N #1 }
+          }
+      }
+    \cs_generate_variant:Nn \intarray_gset:Nnn { c }
+    \cs_generate_variant:Nn \intarray_gzero:N { c }
+    \cs_new:Npn \__kernel_intarray_item:Nn #1#2
+      { \__intarray_item:w #2 #1 }
+    \cs_new:Npn \intarray_item:Nn #1#2
+      {
+        \__intarray_item:wF \int_eval:n {#2} #1
+          {
+            \msg_expandable_error:nnfff { kernel } { out-of-bounds }
+              { \token_to_str:N #1 } { \int_use:N \l__intarray_bad_index_int } { \intarray_count:N #1 }
+            0
+          }
+      }
+    \cs_generate_variant:Nn \intarray_item:Nn { c }
+    \cs_new:Npn \intarray_rand_item:N #1
+      { \intarray_item:Nn #1 { \int_rand:n { \intarray_count:N #1 } } }
+    \cs_generate_variant:Nn \intarray_rand_item:N { c }
+    \cs_new_protected:Npn \intarray_const_from_clist:Nn #1#2
+      {
+        \__intarray_new:N #1
+        \int_zero:N \l__intarray_loop_int
+        \clist_map_inline:nn {#2}
+          {
+            \int_incr:N \l__intarray_loop_int
+            \__kernel_intarray_gset:Nnn #1 \l__intarray_loop_int { \int_eval:n {##1} } }
       }
+    \cs_generate_variant:Nn \intarray_const_from_clist:Nn { c }
+    \cs_new:Npn \intarray_to_clist:N #1 { \__intarray_to_clist:Nn #1 { , } }
+    \cs_generate_variant:Nn \intarray_to_clist:N { c }
+    \cs_new:Npn \__kernel_intarray_range_to_clist:Nnn #1#2#3
+      {
+        \__intarray_range_to_clist:w #1
+        \int_eval:n {#2} ~ \int_eval:n {#3} ~
+      }
+    \cs_new_protected:Npn \__kernel_intarray_gset_range_from_clist:Nnn #1#2#3
+      {
+        \__intarray_gset_range:w \int_eval:w #2 #1 #3 , , \scan_stop:
+      }
+    \cs_new_protected:Npn \__intarray_gset_overflow_test:nw #1
+    {
+    }
   }
   {
-    \cs_new_protected:Npn \__intarray_gset_overflow_test:nw #1
+    \cs_new_eq:NN \__intarray_entry:w \tex_fontdimen:D
+    \cs_new_eq:NN \__intarray_count:w \tex_hyphenchar:D
+    \dim_const:Nn \c__intarray_sp_dim { 1 sp }
+    \int_new:N \g__intarray_font_int
+    \cs_new_protected:Npn \__intarray_new:N #1
       {
-        \if_int_compare:w \int_abs:n {#1} > \c_max_dim
-          \exp_after:wN \__intarray_gset_overflow:NNnn
+        \__kernel_chk_if_free_cs:N #1
+        \int_gincr:N \g__intarray_font_int
+        \tex_global:D \tex_font:D #1
+          = cmr10~at~ \g__intarray_font_int \c__intarray_sp_dim \scan_stop:
+        \int_step_inline:nn { 8 }
+          { \__kernel_intarray_gset:Nnn #1 {##1} \c_zero_int }
+      }
+    \cs_new_protected:Npn \intarray_new:Nn #1#2
+      {
+        \__intarray_new:N #1
+        \__intarray_count:w #1 = \int_eval:n {#2} \scan_stop:
+        \int_compare:nNnT { \intarray_count:N #1 } < 0
+          {
+            \msg_error:nnx { kernel } { negative-array-size }
+              { \intarray_count:N #1 }
+          }
+        \int_compare:nNnT { \intarray_count:N #1 } > 0
+          { \__kernel_intarray_gset:Nnn #1 { \intarray_count:N #1 } { 0 } }
+      }
+    \cs_generate_variant:Nn \intarray_new:Nn { c }
+    \cs_new:Npn \intarray_count:N #1 { \int_value:w \__intarray_count:w #1 }
+    \cs_generate_variant:Nn \intarray_count:N { c }
+    \cs_new:Npn \__intarray_signed_max_dim:n #1
+      { \int_value:w \int_compare:nNnT {#1} < 0 { - } \c_max_dim }
+    \cs_new:Npn \__intarray_bounds:NNnTF #1#2#3
+      {
+        \if_int_compare:w 1 > #3 \exp_stop_f:
+          \__intarray_bounds_error:NNnw #1 #2 {#3}
+        \else:
+          \if_int_compare:w #3 > \intarray_count:N #2 \exp_stop_f:
+            \__intarray_bounds_error:NNnw #1 #2 {#3}
+          \fi:
         \fi:
+        \use_i:nn
       }
-  }
-\cs_new_protected:Npn \__intarray_gset_overflow:NNnn #1#2#3#4
-  {
-    \msg_error:nnxxxx { kernel } { overflow }
-      { \token_to_str:N #2 } {#3} {#4} {  \__intarray_signed_max_dim:n {#4} }
-    #1 #2 {#3} { \__intarray_signed_max_dim:n {#4} }
-  }
-\cs_new_protected:Npn \intarray_gzero:N #1
-  {
-    \int_zero:N \l__intarray_loop_int
-    \prg_replicate:nn { \intarray_count:N #1 }
+    \cs_new:Npn \__intarray_bounds_error:NNnw #1#2#3#4 \use_i:nn #5#6
+      {
+        #4
+        #1 { kernel } { out-of-bounds }
+          { \token_to_str:N #2 } {#3} { \intarray_count:N #2 }
+        #6
+      }
+    \cs_new_protected:Npn \__kernel_intarray_gset:Nnn #1#2#3
+      { \__intarray_entry:w #2 #1 #3 \c__intarray_sp_dim }
+    \cs_new_protected:Npn \intarray_gset:Nnn #1#2#3
+      {
+        \exp_after:wN \__intarray_gset:Nww
+        \exp_after:wN #1
+        \int_value:w \int_eval:n {#2} \exp_after:wN ;
+        \int_value:w \int_eval:n {#3} ;
+      }
+    \cs_generate_variant:Nn \intarray_gset:Nnn { c }
+    \cs_new_protected:Npn \__intarray_gset:Nww #1#2 ; #3 ;
+      {
+        \__intarray_bounds:NNnTF \msg_error:nnxxx #1 {#2}
+          {
+            \__intarray_gset_overflow_test:nw {#3}
+            \__kernel_intarray_gset:Nnn #1 {#2} {#3}
+          }
+          { }
+      }
+    \cs_if_exist:NTF \tex_ifabsnum:D
+      {
+        \cs_new_protected:Npn \__intarray_gset_overflow_test:nw #1
+          {
+            \tex_ifabsnum:D #1 > \c_max_dim
+              \exp_after:wN \__intarray_gset_overflow:NNnn
+            \fi:
+          }
+      }
+      {
+        \cs_new_protected:Npn \__intarray_gset_overflow_test:nw #1
+          {
+            \if_int_compare:w \int_abs:n {#1} > \c_max_dim
+              \exp_after:wN \__intarray_gset_overflow:NNnn
+            \fi:
+          }
+      }
+    \cs_new_protected:Npn \__intarray_gset_overflow:NNnn #1#2#3#4
+      {
+        \msg_error:nnxxxx { kernel } { overflow }
+          { \token_to_str:N #2 } {#3} {#4} {  \__intarray_signed_max_dim:n {#4} }
+        #1 #2 {#3} { \__intarray_signed_max_dim:n {#4} }
+      }
+    \cs_new_protected:Npn \intarray_gzero:N #1
+      {
+        \int_zero:N \l__intarray_loop_int
+        \prg_replicate:nn { \intarray_count:N #1 }
+          {
+            \int_incr:N \l__intarray_loop_int
+            \__intarray_entry:w \l__intarray_loop_int #1 \c_zero_dim
+          }
+      }
+    \cs_generate_variant:Nn \intarray_gzero:N { c }
+    \cs_new:Npn \__kernel_intarray_item:Nn #1#2
+      { \int_value:w \__intarray_entry:w #2 #1 }
+    \cs_new:Npn \intarray_item:Nn #1#2
+      {
+        \exp_after:wN \__intarray_item:Nw
+        \exp_after:wN #1
+        \int_value:w \int_eval:n {#2} ;
+      }
+    \cs_generate_variant:Nn \intarray_item:Nn { c }
+    \cs_new:Npn \__intarray_item:Nw #1#2 ;
+      {
+        \__intarray_bounds:NNnTF \msg_expandable_error:nnfff #1 {#2}
+          { \__kernel_intarray_item:Nn #1 {#2} }
+          { 0 }
+      }
+    \cs_new:Npn \intarray_rand_item:N #1
+      { \intarray_item:Nn #1 { \int_rand:n { \intarray_count:N #1 } } }
+    \cs_generate_variant:Nn \intarray_rand_item:N { c }
+    \cs_new_protected:Npn \intarray_const_from_clist:Nn #1#2
+      {
+        \__intarray_new:N #1
+        \int_zero:N \l__intarray_loop_int
+        \clist_map_inline:nn {#2}
+          { \exp_args:Nf \__intarray_const_from_clist:nN { \int_eval:n {##1} } #1 }
+        \__intarray_count:w #1 \l__intarray_loop_int
+      }
+    \cs_generate_variant:Nn \intarray_const_from_clist:Nn { c }
+    \cs_new_protected:Npn \__intarray_const_from_clist:nN #1#2
       {
         \int_incr:N \l__intarray_loop_int
-        \__intarray_entry:w \l__intarray_loop_int #1 \c_zero_dim
+        \__intarray_gset_overflow_test:nw {#1}
+        \__kernel_intarray_gset:Nnn #2 \l__intarray_loop_int {#1}
       }
-  }
-\cs_generate_variant:Nn \intarray_gzero:N { c }
-\cs_new:Npn \__kernel_intarray_item:Nn #1#2
-  { \int_value:w \__intarray_entry:w #2 #1 }
-\cs_new:Npn \intarray_item:Nn #1#2
-  {
-    \exp_after:wN \__intarray_item:Nw
-    \exp_after:wN #1
-    \int_value:w \int_eval:n {#2} ;
-  }
-\cs_generate_variant:Nn \intarray_item:Nn { c }
-\cs_new:Npn \__intarray_item:Nw #1#2 ;
-  {
-    \__intarray_bounds:NNnTF \msg_expandable_error:nnfff #1 {#2}
-      { \__kernel_intarray_item:Nn #1 {#2} }
-      { 0 }
-  }
-\cs_new:Npn \intarray_rand_item:N #1
-  { \intarray_item:Nn #1 { \int_rand:n { \intarray_count:N #1 } } }
-\cs_generate_variant:Nn \intarray_rand_item:N { c }
-\cs_new_protected:Npn \intarray_const_from_clist:Nn #1#2
-  {
-    \__intarray_new:N #1
-    \int_zero:N \l__intarray_loop_int
-    \clist_map_inline:nn {#2}
-      { \exp_args:Nf \__intarray_const_from_clist:nN { \int_eval:n {##1} } #1 }
-    \__intarray_count:w #1 \l__intarray_loop_int
-  }
-\cs_generate_variant:Nn \intarray_const_from_clist:Nn { c }
-\cs_new_protected:Npn \__intarray_const_from_clist:nN #1#2
-  {
-    \int_incr:N \l__intarray_loop_int
-    \__intarray_gset_overflow_test:nw {#1}
-    \__kernel_intarray_gset:Nnn #2 \l__intarray_loop_int {#1}
-  }
-\cs_new:Npn \intarray_to_clist:N #1 { \__intarray_to_clist:Nn #1 { , } }
-\cs_generate_variant:Nn \intarray_to_clist:N { c }
-\cs_new:Npn \__intarray_to_clist:Nn #1#2
-  {
-    \int_compare:nNnF { \intarray_count:N #1 } = \c_zero_int
+    \cs_new:Npn \intarray_to_clist:N #1 { \__intarray_to_clist:Nn #1 { , } }
+    \cs_generate_variant:Nn \intarray_to_clist:N { c }
+    \cs_new:Npn \__intarray_to_clist:Nn #1#2
+      {
+        \int_compare:nNnF { \intarray_count:N #1 } = \c_zero_int
+          {
+            \exp_last_unbraced:Nf \use_none:n
+              { \__intarray_to_clist:w 1 ; #1 {#2} \prg_break_point: }
+          }
+      }
+    \cs_new:Npn \__intarray_to_clist:w #1 ; #2#3
+      {
+        \if_int_compare:w #1 > \__intarray_count:w #2
+          \prg_break:n
+        \fi:
+        #3 \__kernel_intarray_item:Nn #2 {#1}
+        \exp_after:wN \__intarray_to_clist:w
+        \int_value:w \int_eval:w #1 + \c_one_int ; #2 {#3}
+      }
+    \cs_new:Npn \__kernel_intarray_range_to_clist:Nnn #1#2#3
       {
         \exp_last_unbraced:Nf \use_none:n
-          { \__intarray_to_clist:w 1 ; #1 {#2} \prg_break_point: }
+          {
+            \exp_after:wN \__intarray_range_to_clist:ww
+            \int_value:w \int_eval:w #2 \exp_after:wN ;
+            \int_value:w \int_eval:w #3 ;
+            #1 \prg_break_point:
+          }
       }
-  }
-\cs_new:Npn \__intarray_to_clist:w #1 ; #2#3
-  {
-    \if_int_compare:w #1 > \__intarray_count:w #2
-      \prg_break:n
-    \fi:
-    #3 \__kernel_intarray_item:Nn #2 {#1}
-    \exp_after:wN \__intarray_to_clist:w
-    \int_value:w \int_eval:w #1 + \c_one_int ; #2 {#3}
-  }
-\cs_new:Npn \__kernel_intarray_range_to_clist:Nnn #1#2#3
-  {
-    \exp_last_unbraced:Nf \use_none:n
+    \cs_new:Npn \__intarray_range_to_clist:ww #1 ; #2 ; #3
       {
+        \if_int_compare:w #1 > #2 \exp_stop_f:
+          \prg_break:n
+        \fi:
+        , \__kernel_intarray_item:Nn #3 {#1}
         \exp_after:wN \__intarray_range_to_clist:ww
-        \int_value:w \int_eval:w #2 \exp_after:wN ;
-        \int_value:w \int_eval:w #3 ;
-        #1 \prg_break_point:
+        \int_value:w \int_eval:w #1 + \c_one_int ; #2 ; #3
+      }
+    \cs_new_protected:Npn \__kernel_intarray_gset_range_from_clist:Nnn #1#2#3
+      {
+        \int_set:Nn \l__intarray_loop_int {#2}
+        \__intarray_gset_range:Nw #1 #3 , , \prg_break_point:
+      }
+    \cs_new_protected:Npn \__intarray_gset_range:Nw #1 #2 ,
+      {
+        \if_catcode:w \scan_stop: \tl_to_str:n {#2} \scan_stop:
+          \prg_break:n
+        \fi:
+        \__kernel_intarray_gset:Nnn #1 \l__intarray_loop_int {#2}
+        \int_incr:N \l__intarray_loop_int
+        \__intarray_gset_range:Nw #1
       }
-  }
-\cs_new:Npn \__intarray_range_to_clist:ww #1 ; #2 ; #3
-  {
-    \if_int_compare:w #1 > #2 \exp_stop_f:
-      \prg_break:n
-    \fi:
-    , \__kernel_intarray_item:Nn #3 {#1}
-    \exp_after:wN \__intarray_range_to_clist:ww
-    \int_value:w \int_eval:w #1 + \c_one_int ; #2 ; #3
-  }
-\cs_new_protected:Npn \__kernel_intarray_gset_range_from_clist:Nnn #1#2#3
-  {
-    \int_set:Nn \l__intarray_loop_int {#2}
-    \__intarray_gset_range:Nw #1 #3 , , \prg_break_point:
-  }
-\cs_new_protected:Npn \__intarray_gset_range:Nw #1 #2 ,
-  {
-    \if_catcode:w \scan_stop: \tl_to_str:n {#2} \scan_stop:
-      \prg_break:n
-    \fi:
-    \__kernel_intarray_gset:Nnn #1 \l__intarray_loop_int {#2}
-    \int_incr:N \l__intarray_loop_int
-    \__intarray_gset_range:Nw #1
   }
 \cs_new_protected:Npn \intarray_show:N { \__intarray_show:NN \msg_show:nnxxxx }
 \cs_generate_variant:Nn \intarray_show:N { c }
diff --git a/texmf/tex/latex/l3kernel/expl3-generic.tex b/texmf/tex/latex/l3kernel/expl3-generic.tex
index 3e0a8141..12f6e530 100644
--- a/texmf/tex/latex/l3kernel/expl3-generic.tex
+++ b/texmf/tex/latex/l3kernel/expl3-generic.tex
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2021-11-12}%
+\def\ExplFileDate{2021-11-22}%
 \let\ExplLoaderFileDate\ExplFileDate
 \begingroup
   \catcode`\_=11
diff --git a/texmf/tex/latex/l3kernel/expl3.ltx b/texmf/tex/latex/l3kernel/expl3.ltx
index b581aa5d..9c5d9531 100644
--- a/texmf/tex/latex/l3kernel/expl3.ltx
+++ b/texmf/tex/latex/l3kernel/expl3.ltx
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2021-11-12}%
+\def\ExplFileDate{2021-11-22}%
 \let\ExplLoaderFileDate\ExplFileDate
 \begingroup
   \catcode`\_=11
diff --git a/texmf/tex/latex/l3kernel/expl3.lua b/texmf/tex/latex/l3kernel/expl3.lua
index 9eed3547..befb32e5 100644
--- a/texmf/tex/latex/l3kernel/expl3.lua
+++ b/texmf/tex/latex/l3kernel/expl3.lua
@@ -8,6 +8,7 @@
 -- l3names.dtx  (with options: `package,lua')
 -- l3sys.dtx  (with options: `package,lua')
 -- l3token.dtx  (with options: `package,lua')
+-- l3intarray.dtx  (with options: `package,lua')
 -- 
 -- Copyright (C) 1990-2021 The LaTeX Project
 -- 
@@ -56,9 +57,37 @@ local scan_int     = token.scan_int or token.scan_integer
 local scan_string  = token.scan_string
 local scan_keyword = token.scan_keyword
 local put_next     = token.put_next
+local token_create = token.create
+local token_create_safe
+do
+  local is_defined = token.is_defined
+  local set_char   = token.set_char
+  local runtoks    = tex.runtoks
+  local let_token  = token_create'let'
+
+  function token_create_safe(s)
+    local orig_token = token_create(s)
+    if is_defined(s, true) then
+      return orig_token
+    end
+    set_char(s, 0)
+    local new_token = token_create(s)
+    runtoks(function()
+      put_next(let_token, new_token, orig_token)
+    end)
+    return new_token
+  end
+end
 
-local true_tok     = token.create'prg_return_true:'
-local false_tok    = token.create'prg_return_false:'
+local true_tok     = token_create_safe'prg_return_true:'
+local false_tok    = token_create_safe'prg_return_false:'
+local command_id   = token.command_id
+if not command_id and tokens and tokens.commands then
+  local id_map = tokens.commands
+  function command_id(name)
+    return id_map[name]
+  end
+end
 local function deprecated(table, name, func)
   table[name] = function(...)
     write_nl(format("Calling deprecated Lua function %s", name))
@@ -226,9 +255,8 @@ deprecated(l3kernel, "shellescape", function(cmd)
   end
 end)
 local luacmd do
-  local token_create = token.create
   local set_lua = token.set_lua
-  local undefined_cs = token.command_id'undefined_cs'
+  local undefined_cs = command_id'undefined_cs'
 
   if not context and not luatexbase then require'ltluatex' end
   if luatexbase then
@@ -249,7 +277,7 @@ local luacmd do
     local register = context.functions.register
     local functions = context.functions.known
     function luacmd(name, func, ...)
-      local tok = token.create(name)
+      local tok = token_create(name)
       if tok.command == undefined_cs then
         token.set_lua(name, register(func), ...)
       else
@@ -258,6 +286,44 @@ local luacmd do
     end
   end
 end
+local register_luadata, get_luadata
+
+if luatexbase then
+  local register = token_create'@expl at luadata@bytecode'.index
+  if status.ini_version then
+    local luadata, luadata_order = {}, {}
+
+    function register_luadata(name, func)
+      if luadata[name] then
+        error(format("LaTeX error: data name %q already in use", name))
+      end
+      luadata[name] = func
+      luadata_order[#luadata_order + 1] = func and name
+    end
+    luatexbase.add_to_callback("pre_dump", function()
+      if next(luadata) then
+        local str = "return {"
+        for i=1, #luadata_order do
+          local name = luadata_order[i]
+          str = format('%s[%q]=%s,', str, name, luadata[name]())
+        end
+        lua.bytecode[register] = assert(load(str .. "}"))
+      end
+    end, "ltx.luadata")
+  else
+    local luadata = lua.bytecode[register]
+    if luadata then
+      lua.bytecode[register] = nil
+      luadata = luadata()
+    end
+    function get_luadata(name)
+      if not luadata then return end
+      local data = luadata[name]
+      luadata[name] = nil
+      return data
+    end
+  end
+end
 -- File: l3names.dtx
 local minus_tok = token.new(string.byte'-', 12)
 local zero_tok = token.new(string.byte'0', 12)
@@ -318,17 +384,22 @@ do
   luacmd("__sys_shell_now:e", function()
     shellescape(scan_string())
   end, "global", "protected")
-  local whatsit_id = node.id'whatsit'
-  local latelua_sub = node.subtype'late_lua'
-  local node_new = node.direct.new
-  local setfield = node.direct.setwhatsitfield or node.direct.setfield
+  local new_latelua = nodes and nodes.nuts and nodes.nuts.pool and nodes.nuts.pool.latelua or (function()
+    local whatsit_id = node.id'whatsit'
+    local latelua_sub = node.subtype'late_lua'
+    local node_new = node.direct.new
+    local setfield = node.direct.setwhatsitfield or node.direct.setfield
+    return function(f)
+      local n = node_new(whatsit_id, latelua_sub)
+      setfield(n, 'data', f)
+      return n
+    end
+  end)()
   local node_write = node.direct.write
 
   luacmd("__sys_shell_shipout:e", function()
     local cmd = scan_string()
-    local n = node_new(whatsit_id, latelua_sub)
-    setfield(n, 'data', function() shellescape(cmd) end)
-    node_write(n)
+    node_write(new_latelua(function() shellescape(cmd) end))
   end, "global", "protected")
 end
   local gettimeofday = os.gettimeofday
@@ -344,9 +415,10 @@ do
   local get_command = token.get_command
   local get_index = token.get_index
   local get_mode = token.get_mode or token.get_index
-  local cmd = token.command_id
+  local cmd = command_id
   local set_font = cmd'get_font'
-  local biggest_char = token.biggest_char()
+  local biggest_char = token.biggest_char and token.biggest_char()
+                    or status.getconstants().max_character_code
 
   local mode_below_biggest_char = {}
   local index_not_nil = {}
@@ -355,29 +427,29 @@ do
     [cmd'left_brace'] = true,
     [cmd'right_brace'] = true,
     [cmd'math_shift'] = true,
-    [cmd'mac_param'] = mode_below_biggest_char,
-    [cmd'sup_mark'] = true,
-    [cmd'sub_mark'] = true,
-    [cmd'endv'] = true,
+    [cmd'mac_param' or cmd'parameter'] = mode_below_biggest_char,
+    [cmd'sup_mark' or cmd'superscript'] = true,
+    [cmd'sub_mark' or cmd'subscript'] = true,
+    [cmd'endv' or cmd'ignore'] = true,
     [cmd'spacer'] = true,
     [cmd'letter'] = true,
     [cmd'other_char'] = true,
-    [cmd'tab_mark'] = mode_below_biggest_char,
+    [cmd'tab_mark' or cmd'alignment_tab'] = mode_below_biggest_char,
     [cmd'char_given'] = true,
-    [cmd'math_given'] = true,
-    [cmd'xmath_given'] = true,
+    [cmd'math_given' or 'math_char_given'] = true,
+    [cmd'xmath_given' or 'math_char_xgiven'] = true,
     [cmd'set_font'] = mode_not_null,
     [cmd'undefined_cs'] = true,
     [cmd'call'] = true,
-    [cmd'long_call'] = true,
-    [cmd'outer_call'] = true,
-    [cmd'long_outer_call'] = true,
-    [cmd'assign_glue'] = index_not_nil,
-    [cmd'assign_mu_glue'] = index_not_nil,
-    [cmd'assign_toks'] = index_not_nil,
-    [cmd'assign_int'] = index_not_nil,
-    [cmd'assign_attr'] = true,
-    [cmd'assign_dimen'] = index_not_nil,
+    [cmd'long_call' or cmd'protected_call'] = true,
+    [cmd'outer_call' or cmd'tolerant_call'] = true,
+    [cmd'long_outer_call' or cmd'tolerant_protected_call'] = true,
+    [cmd'assign_glue' or cmd'register_glue'] = index_not_nil,
+    [cmd'assign_mu_glue' or cmd'register_mu_glue'] = index_not_nil,
+    [cmd'assign_toks' or cmd'register_toks'] = index_not_nil,
+    [cmd'assign_int' or cmd'register_int'] = index_not_nil,
+    [cmd'assign_attr' or cmd'register_attribute'] = true,
+    [cmd'assign_dimen' or cmd'register_dimen'] = index_not_nil,
   }
 
   luacmd("__token_if_primitive_lua:N", function()
@@ -396,3 +468,131 @@ do
              and (get_mode(tok) > biggest_char and true_tok or false_tok))
   end, "global")
 end
+-- File: l3intarray.dtx
+luacmd('__intarray:w', function()
+  scan_int()
+  tex.error'LaTeX Error: Isolated intarray ignored'
+end, 'protected', 'global')
+
+local scan_token = token.scan_token
+local put_next = token.put_next
+local intarray_marker = token_create_safe'__intarray:w'
+local use_none = token_create_safe'use_none:n'
+local use_i = token_create_safe'use:n'
+local expand_after_scan_stop = {token_create_safe'exp_after:wN',
+                                token_create_safe'scan_stop:'}
+local comma = token_create(string.byte',')
+local __intarray_table do
+  local tables = get_luadata and get_luadata'__intarray' or {[0] = {}}
+  function __intarray_table()
+    local t = scan_token()
+    if t ~= intarray_marker then
+      put_next(t)
+      tex.error'LaTeX Error: intarray expected'
+      return tables[0]
+    end
+    local i = scan_int()
+    local current_table = tables[i]
+    if current_table then return current_table end
+    current_table = {}
+    tables[i] = current_table
+    return current_table
+  end
+  if register_luadata then
+    register_luadata('__intarray', function()
+      local t = "{[0]={},"
+      for i=1, #tables do
+        t = string.format("%s{%s},", t, table.concat(tables[i], ','))
+      end
+      return t .. "}"
+    end)
+  end
+end
+
+local sprint = tex.sprint
+
+luacmd('__intarray_gset_count:Nw', function()
+  local t = __intarray_table()
+  local n = scan_int()
+  for i=#t+1, n do t[i] = 0 end
+end, 'protected', 'global')
+
+luacmd('intarray_count:N', function()
+  sprint(-2, #__intarray_table())
+end, 'global')
+luacmd('__intarray_gset:wF', function()
+  local i = scan_int()
+  local t = __intarray_table()
+  if t[i] then
+    t[i] = scan_int()
+    put_next(use_none)
+  else
+    tex.count.l__intarray_bad_index_int = i
+    scan_int()
+    put_next(use_i)
+  end
+end, 'protected', 'global')
+
+luacmd('__intarray_gset:w', function()
+  local i = scan_int()
+  local t = __intarray_table()
+  t[i] = scan_int()
+end, 'protected', 'global')
+luacmd('intarray_gzero:N', function()
+  local t = __intarray_table()
+  for i=1, #t do
+    t[i] = 0
+  end
+end, 'global', 'protected')
+luacmd('__intarray_item:wF', function()
+  local i = scan_int()
+  local t = __intarray_table()
+  local item = t[i]
+  if item then
+    put_next(use_none)
+  else
+    tex.l__intarray_bad_index_int = i
+    put_next(use_i)
+  end
+  put_next(expand_after_scan_stop)
+  scan_token()
+  if item then
+    sprint(-2, item)
+  end
+end, 'global')
+
+luacmd('__intarray_item:w', function()
+  local i = scan_int()
+  local t = __intarray_table()
+  sprint(-2, t[i])
+end, 'global')
+local concat = table.concat
+luacmd('__intarray_to_clist:Nn', function()
+  local t = __intarray_table()
+  local sep = token.scan_string()
+  sprint(-2, concat(t, sep))
+end, 'global')
+luacmd('__intarray_range_to_clist:w', function()
+  local t = __intarray_table()
+  local from = scan_int()
+  local to = scan_int()
+  sprint(-2, concat(t, ',', from, to))
+end, 'global')
+luacmd('__intarray_gset_range:w', function()
+  local from = scan_int()
+  local t = __intarray_table()
+  while true do
+    local tok = scan_token()
+    if tok == comma then
+      repeat
+        tok = scan_token()
+      until tok ~= comma
+      break
+    else
+      put_next(tok)
+    end
+    t[from] = scan_int()
+    scan_token()
+    from = from + 1
+  end
+  end, 'global', 'protected')
diff --git a/texmf/tex/latex/l3kernel/expl3.sty b/texmf/tex/latex/l3kernel/expl3.sty
index 068438f5..eb2ccfa7 100644
--- a/texmf/tex/latex/l3kernel/expl3.sty
+++ b/texmf/tex/latex/l3kernel/expl3.sty
@@ -19,7 +19,7 @@
 %% and all files in that bundle must be distributed together.
 %% 
 %% File: expl3.dtx
-\def\ExplFileDate{2021-11-12}%
+\def\ExplFileDate{2021-11-22}%
 \let\ExplLoaderFileDate\ExplFileDate
 \ProvidesPackage{expl3}
   [%





More information about the latex3-commits mailing list.