From 886a160757f8fa328e5a5e95c6796d72780e831b Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 22 Nov 2021 21:19:01 +0000 Subject: l3kernel (22nov21) git-svn-id: svn://tug.org/texlive/trunk@61121 c570f23f-e606-0410-a88d-b1316a301751 --- .../texmf-dist/tex/latex/l3kernel/expl3-code.tex | 463 ++++++++++++--------- .../tex/latex/l3kernel/expl3-generic.tex | 2 +- Master/texmf-dist/tex/latex/l3kernel/expl3.ltx | 2 +- Master/texmf-dist/tex/latex/l3kernel/expl3.lua | 260 ++++++++++-- Master/texmf-dist/tex/latex/l3kernel/expl3.sty | 2 +- 5 files changed, 509 insertions(+), 220 deletions(-) (limited to 'Master/texmf-dist/tex/latex/l3kernel') diff --git a/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex b/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex index acd7546557c..9bbbaa1dc45 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex +++ b/Master/texmf-dist/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@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/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex b/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex index 3e0a8141cb7..12f6e53070f 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex +++ b/Master/texmf-dist/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/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx b/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx index b581aa5d546..9c5d9531678 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/expl3.ltx +++ b/Master/texmf-dist/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/Master/texmf-dist/tex/latex/l3kernel/expl3.lua b/Master/texmf-dist/tex/latex/l3kernel/expl3.lua index 9eed3547cf9..befb32e536c 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/expl3.lua +++ b/Master/texmf-dist/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@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/Master/texmf-dist/tex/latex/l3kernel/expl3.sty b/Master/texmf-dist/tex/latex/l3kernel/expl3.sty index 068438f51d7..eb2ccfa77a1 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/expl3.sty +++ b/Master/texmf-dist/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} [% -- cgit v1.2.3