From 56d8ecd6f0302bfcfee027a368d5f2b12e88bf8f Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Thu, 4 Jun 2020 21:07:37 +0000 Subject: erw-l3 (4jun20) git-svn-id: svn://tug.org/texlive/trunk@55414 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/tex/latex/erw-l3/erw-l3.sty | 642 +++++++++++++++----------- 1 file changed, 377 insertions(+), 265 deletions(-) (limited to 'Master/texmf-dist/tex/latex/erw-l3') diff --git a/Master/texmf-dist/tex/latex/erw-l3/erw-l3.sty b/Master/texmf-dist/tex/latex/erw-l3/erw-l3.sty index ba4182d0e1d..18e94e85057 100644 --- a/Master/texmf-dist/tex/latex/erw-l3/erw-l3.sty +++ b/Master/texmf-dist/tex/latex/erw-l3/erw-l3.sty @@ -5,385 +5,499 @@ %% The original source files were: %% %% erw-l3.dtx (with options: `package') -%% ---------------------------------------------------------------- -%% erw-l3 Utilities built around expl3 +%% ---------------------------------------------------------------------------- +%% erw-l3 --- Utilities for LaTeX3 programming %% Released under the LaTeX Project Public License v1.3c or later %% See http://www.latex-project.org/lppl.txt -%% ---------------------------------------------------------------- +%% ---------------------------------------------------------------------------- %% -\RequirePackage{expl3}[2018/06/01] -\RequirePackage{xparse}[2018/02/01] -\RequirePackage{l3keys2e} -\ProvidesExplPackage - {erw-l3} % Package name - {2020/02/05} % Release date - {0.1.6} % Release version - {Utilities built around expl3} % Description -\NeedsTeXFormat{LaTeX2e} -\ExplSyntaxOn -\msg_new:nnn{erw}{generic}{#1} -\cs_set:Npn \erw_compose:NnV - #1 % method - #2 % funs - #3 % var -{ - \erw_fold_set_par:n{Nf} - \erw_fold_apply_par:n{Nf} - \erw_cs_set_inline:Nn \__erw_map:n + \NeedsTeXFormat{LaTeX2e}[2020/02/02] + \RequirePackage{etoolbox}[2019/09/21] + \RequirePackage{l3keys2e}[2020/03/06] + \RequirePackage{xparse}[2020/03/06] + \ProvidesExplPackage + {erw-l3} % Package name + {2020/06/04} % Release date + {3.1} % Release version + {erw-l3 --- Utilities for LaTeX3 programming } % Description +\cs_new:Nn \__erw_cs_name:N +{ + \exp_last_unbraced:Nf \use_i:nnn {\cs_split_function:N #1} +} +\cs_new:Nn \erw_cs_compose:NnN +{ + \erw_cs_set_inline:Nn \g__erw_tl_function:n { - #1{##1}#3 + #1{##1}#3 } - \exp_args:Nf\erw_map:n + \exp_args:Nf\erw_tl_map:n { - \tl_reverse:n{#2} + \tl_reverse:n{#2} } } -\cs_set:Npn \erw_compose:nV #1 #2 +\cs_set:Npn \erw_cs_identity:n #1{#1} +\cs_new_protected:Nn \erw_cs_set_inline:Nn { - \erw_compose:NnV \erw_fold:NV {#1} #2 + \cs_set:Npn #1 ##1{#2} } -\cs_set:Npn \erw_compose_c:nV #1 #2 +\cs_generate_variant:Nn \erw_cs_set_inline:Nn {cn} +\cs_new:Nn \erw_cs_gset_inline:Nn { - \erw_compose:NnV \erw_fold:cV {#1} #2 + \cs_gset:Npn #1 ##1{#2} } -\tl_new:N \__erw_compose_tl -\cs_set:Npn \erw_compose:nn #1 #2 +\cs_generate_variant:Nn \erw_cs_gset_inline:Nn {cn} +\int_new:N \g__erw_csint_int +\cs_new:Nn \__erw_csint_name: {\erw_csint_name:n{\g__erw_csint_int}} +\cs_new:Nn \erw_csint:nn { - \tl_set:Nn \__erw_compose_tl {#2} - \erw_compose:nV{#1}\__erw_compose_tl - \__erw_compose_tl + \exp_args:No \use:c{\erw_csint_name:n{#1}}{#2} } -\cs_set:Npn \erw_compose_c:nn #1 #2 +\cs_new:Nn \erw_csint_name:n {__erw_csint_\int_to_alph:n{#1}:n} +\cs_new_protected:Nn \erw_csint_new:n { - \tl_set:Nn \__erw_compose_tl {#2} - \erw_compose_c:nV{#1}\__erw_compose_tl - \__erw_compose_tl + \int_incr:N \g__erw_csint_int + \exp_args:No + \erw_cs_set_inline:cn{\__erw_csint_name:} + { + \token_if_cs:NTF + {#1} + {#1{##1}} + {#1} + } } -\cs_set:Npn \erw_compose_seq:nV #1 #2 +\cs_new:Nn \erw_csint_names_braced:nnn { - \erw_compose:NnV \erw_fold_seq:NV {#1} #2 + \int_step_function:nnnN { #1 }{ #2 }{ #3 } \erw_csint_names_braced:n + % TODO \tl_range_braced:nnn? } -\cs_set:Npn \erw_compose_seq_c:nV - #1 % funs - #2 % seq +\cs_new:Nn \erw_csint_names_braced:n {{\erw_csint_name:n{#1}}} +\cs_new:Nn \erw_csint_names_braced: { - \erw_compose:NnV \erw_fold_seq:cV {#1} #2 + \erw_csint_names_braced:nnn{1}{1}{\g__erw_csint_int} } -\cs_set:Npn \erw_compose_vers:nV #1 #2 +\cs_new_protected:Nn \erw_csint_reset: { - \msg_error:nnn{erw}{generic}{erw_compose_vers:nV~yet-to~be~implemented} + \int_zero:N \g__erw_csint_int + \tl_set:Nn \__erw_csint_ext_tl{}%^^A TODO remove? } -\cs_set:Npn \erw_compose_seq_vers:nV #1 #2 +\cs_set:Npn \__erw_int_range:nnn #1 #2 #3 { - \msg_error:nnn{erw}{generic}{erw_compose_vers:nV~yet-to~be~implemented} + \int_compare:nNnTF + { + \int_eval:n{#2+1} + }>{#3} + { + {#1} + } + { + \__erw_int_range:nnn + { + \exp_args:Nx\erw_tl_append_item:nn{#1} + { + \int_eval:n{#2+1} + } + } + {\int_eval:n{#2+1}} + {#3} + } } -\cs_set:Npn \erw_compose_vers:nn #1 #2 +\cs_new:Nn \erw_int_range:nn { - \erw_numbrd_cs_reset:{} - \tl_map_function:nN{#1}\erw_numbrd_cs_new:n - \exp_last_unbraced:Nx - \erw_compose_c:nn - {{\erw_numbrd_cs_names_braced:{}}} - {#2} + \__erw_int_range:nnn {{#1}}{#1}{#2} } -\cs_set:Npn \erw_accum:nn #1 #2 +\cs_new:Nn \erw_int_range:n { - {#1{#2}} + \__erw_int_range:nnn {}{0}{#1} } -\cs_set:Npn \__erw_cs_name:N #1 +\cs_new:Nn \erw_keyval_error:Nn{\msg_error:nnnnn{__erw}{keyval/n}{\erw_keyval_error:Nn}{#1}{#2}} +\cs_new:Nn \erw_keyval_error:Nnn{\msg_error:nnnnnn{__erw}{keyval/nn}{\erw_keyval_error:Nnn}{#1}{#2}{#3}} +\cs_new_protected:Nn\erw_keyval_parse:NNNn { - \exp_last_unbraced:Nf \use_i:nnn {\cs_split_function:N #1} + \cs_set_protected:Nn \__erw_keyval_function:n {#2 #1{##1}} + \cs_set_protected:Nn \__erw_keyval_function:nn {#3 #1{##1}{##2}} + \keyval_parse:NNn + \__erw_keyval_function:n + \__erw_keyval_function:nn + {#4} } -\cs_set:Npn \erw_apply:Nn - #1 % fun - #2 % tl +\cs_new_protected:Npn \erw_lambda:nnn #1 #2 #3 { - #1{#2} + \exp_args:NNx + #1 \__erw_lambda_expression + {#2} + {#3} + \__erw_lambda_expression } -\cs_generate_variant:Nn \erw_apply:Nn {No, Nf, Nx, c} -\cs_set:Npn \erw_cs_set_eq:NN #1 #2 +\msg_new:nnn{__erw}{generic}{#1} +\msg_new:nnn{__erw}{keyval/nn}{#1#2{#3}{#4};~encountered~key=val~where~only~key~required} +\msg_new:nnn{__erw}{keyval/n}{#1#2{#3};~encountered~key~~where~only~key=val~required} +\msg_new:nnn{__erw}{separ}{#1~expects~1~to~3~items,~#2} +\msg_new:nnn{__erw}{timestamp / base}{Calling~#1,~arg~must~be~'dec|hex'} +\msg_new:nnn{__erw}{timestamp / period}{Calling~#1,~arg~must~be~'date|time|datetime'} +\msg_new:nnn{erw}{notset}{#1~not~set} +\cs_new_protected:Nn \__erw_prop_map_item:NNN { - \cs_set:Npn #1 ##1{#2{##1}} + \cs_set_protected:Nn \__erw_function:nn + { + #1 #2 {##1}{##2} + } + \prop_map_function:NN #3 \__erw_function:nn } -\cs_generate_variant:Nn \erw_cs_set_eq:NN {cN} -\cs_set:Npn \erw_cs_gset_eq:NN #1 #2 +\cs_new_protected:Nn \erw_prop_to_clist:Nn { - \cs_gset:Npn #1 ##1{#2{##1}} + \cs_set:Nn \__erw_keyval_function:n {,\prop_item:Nn#1{##1}} + \exp_args:Nf + \tl_tail:n + { + \keyval_parse:NNn + \__erw_keyval_function:n + \erw_keyval_error:Nnn + {#2} + } } -\cs_generate_variant:Nn \erw_cs_gset_eq:NN {cN} -\cs_set:Npn \erw_cs_set_inline:Nn #1 #2 +\cs_generate_variant:Nn \erw_prop_to_clist:Nn { c } +\cs_new_protected:Nn \erw_prop_map_item:NNN { - \cs_set:Npn #1 ##1{#2} + \prop_if_exist:NTF #2 + {\__erw_prop_map_item:NNN #1#2#3} + { + \prop_new:N #2 + \erw_prop_map_item:NNN #1#2#3 + } } -\cs_generate_variant:Nn \erw_cs_set_inline:Nn {cn} -\cs_set:Npn \erw_cs_gset_inline:Nn #1 #2 +\cs_new_protected:Nn\erw_prop_keyval_parse:NNNn { - \cs_gset:Npn #1 ##1{#2} + \prop_if_exist:NTF#1 + {\erw_keyval_parse:NNNn #1#2#3{#4}} + { + \prop_new:N #1 + \erw_prop_keyval_parse:NNNn#1#2#3{#4} + } } -\cs_generate_variant:Nn \erw_cs_gset_inline:Nn {cn} -\tl_set:Nn \__erw_fold_set_par_tl{\c_novalue_tl} -\tl_set:Nn \__erw_fold_apply_par_tl{\c_novalue_tl} -\cs_set:Npn \erw_fold_set_par:n #1 +\keys_define:nn{__erw} { - \tl_set:Nn \__erw_fold_set_par_tl{#1} + tl/fold_set_par.tl_gset:N = \g__erw_tl_fold_set_par_tl, + tl/fold_set_par.value_required:n = true, + tl/fold_set_par.default:n = {Nf}, + tl/fold_set_par.initial:n = {Nf}, + tl/fold_apply_par.tl_gset:N = \g__erw_tl_fold_apply_par_tl, + tl/fold_apply_par.value_required:n = true, + tl/fold_apply_par.default:n = {Nf}, + tl/fold_apply_par.initial:n = {Nf} } -\cs_set:Npn \erw_fold_apply_par:n #1 +\cs_new_protected:Nn\erw_option:n { - \tl_set:Nn \__erw_fold_apply_par_tl{#1} + \keys_set:nn{__erw}{#1} } -\cs_set:Npn \erw_fold:NV - #1 % fun - #2 % var +\tl_new:N \g__erw_seq_fold_item_tl +\cs_new_protected:Nn\__erw_seq_put_right_clist:Nn { - \use:c{tl_set:\__erw_fold_set_par_tl} - #2 - {\use:c{erw_apply:\__erw_fold_apply_par_tl}{#1}{#2}} + \cs_set_protected:Nn \__erw_function:n + { + \seq_put_right:Nn #1{##1} + } + \keyval_parse:NNn + \__erw_function:n + \erw_keyval_keyonly:nn + {#2} } -\cs_generate_variant:Nn \erw_fold:NV {cV} -\tl_new:N \__erw_fold_seq_item_tl -\cs_set:Npn \erw_fold_seq:NV - #1 % fun - #2 % seq +\cs_generate_variant:Nn \__erw_seq_put_right_clist:Nn { c } +\cs_new_protected:Nn\__erw_seq_put_right_prop:NNn { - \seq_get_right:NN #2 \__erw_fold_seq_item_tl - \erw_fold:NV #1 \__erw_fold_seq_item_tl - \seq_put_right:No #2 {\__erw_fold_seq_item_tl} + \__erw_seq_put_right_clist:Nn #1 + {\erw_prop_to_clist:Nn #2 {#3}} } -\cs_generate_variant:Nn \erw_fold_seq:NV {cV} -\cs_set:Npn \erw_identity:n #1{#1} -\prg_set_conditional:Npnn \erw_is_matrix:n #1 { p, TF } +\cs_generate_variant:Nn \__erw_seq_put_right_prop:NNn { cc } +\cs_new_protected:Nn\erw_seq_put_right_clist:Nn { - \erw_gset_map_inline:n{==\tl_count:n{##1}} - \int_compare:nTF - { - \exp_args:Nf\tl_count:n{\tl_head:n{#1}} - \exp_args:Nf \erw_map:n - { - \tl_tail:n{#1} - } - } - {\prg_return_true:} - {\prg_return_false:} + \seq_if_exist:NTF#1 + {\__erw_seq_put_right_clist:Nn#1{#2}} + {\seq_new:N#1\erw_seq_put_right_clist:Nn#1{#2}} } -\cs_set:Npn \erw_last_item:n #1 +\cs_generate_variant:Nn \erw_seq_put_right_clist:Nn { c } +\cs_new_protected:Nn\erw_seq_put_right_prop:NNn { - \exp_args:Nof \tl_item:nn - {#1} - { - \tl_count:n{#1} - } + \seq_if_exist:NTF#1 + {\__erw_seq_put_right_prop:NNn#1#2{#3}} + {\seq_new:N#1\erw_seq_put_right_prop:NNn#1#2{#3}} } -\cs_set:Npn \erw_merge:nn #1 #2 +\cs_generate_variant:Nn \erw_seq_put_right_prop:NNn { cc } +\cs_new_protected:Nn \erw_seq_fold:NN { - {#1#2} + \seq_get_right:NN #2 \g__erw_seq_fold_item_tl + \erw_tl_fold:NN #1 \g__erw_seq_fold_item_tl + \seq_put_right:No #2 {\g__erw_seq_fold_item_tl} } -\cs_set:Npn \erw_repeat:nn #1 #2 +\cs_generate_variant:Nn \erw_seq_fold:NN {cN} +\cs_new:Nn \erw_seq_use:Nn { - \int_step_inline:nnnn{1}{1}{#1}{#2} + \exp_last_unbraced:NNf + \seq_use:Nnnn #1 + \erw_tl_separators:n{#2} } -\cs_set:Npn \erw_split:nnn #1 #2 #3 +\cs_new:Nn \__erw_sys_date_dec: { - \tl_head:n{#1} - \use:c{exp_args:#3} \tl_map_inline:nn - { - \tl_tail:n - { - #1 - } - }{#2##1} + \int_eval:n + { + \c_sys_year_int * 10000 + +\c_sys_month_int * 100 + +\c_sys_day_int * 1 + } } -\cs_set:Npn \erw_split:nn #1 #2 +\cs_new:Nn \__erw_sys_date:N{\int_to_hex:n{\__erw_sys_date_dec:}} +\cs_new:Nn \__erw_sys_date_hex:{\int_to_hex:n{\__erw_sys_date_dec:}} +\cs_new:Nn \__erw_sys_time_dec: { - \erw_split:nnn{#1}{#2}{Nf} + \int_eval:n + { + \c_sys_hour_int * 100 + +\c_sys_minute_int * 1 + } } -\cs_set:Npn \__erw_int_range:nnn #1 #2 #3 +\cs_new:Nn\__erw_sys_time_hex:{\int_to_hex:n{\__erw_sys_time_dec:}} +\cs_new:Nn\__erw_sys_datetime_base:n { - \int_compare:nNnTF - { - \int_eval:n{#2+1} - }>{#3} - { - {#1} - } - { - \__erw_int_range:nnn - { - \exp_args:Nx\erw_accum:nn{#1} - { - \int_eval:n{#2+1} - } - } - {\int_eval:n{#2+1}} - {#3} - } + \int_case:nnTF{#1} + { + {10}{dec} + {16}{hex} + } + {\c_empty_tl} + {\msg_error:nnn{__erw}{timestamp / base}{\__erw_sys_datetime_base:n{#1}}} } -\cs_set:Npn \erw_int_range:nn #1 #2 +\cs_new:Nn\__erw_sys_datetime_join:nn{\erw_tl_join:nnn{#1}{\g__erw_sys_timestamp_delim_str}{#2}} +\cs_new:Nn\__erw_sys_datetime_period:n { - \__erw_int_range:nnn {{#1}}{#1}{#2} + \str_case:nnTF{#1} + { + {date}{date} + {time}{time} + {datetime}{datetime} + } + {\c_empty_tl} + {\msg_error:nnn{__erw}{ timestamp / period }{\__erw_sys_datetime_period:n{#1}}} } -\cs_set:Npn \erw_int_range:n #1 +\cs_new:Nn\__erw_sys_datetime_dec: {\__erw_sys_datetime_join:nn{\__erw_sys_date_dec:}{\__erw_sys_time_dec:}} +\cs_new:Nn\__erw_sys_datetime_hex: {\__erw_sys_datetime_join:nn{\__erw_sys_date_hex:}{\__erw_sys_time_hex:}} +\cs_new:Nn\__erw_sys_jobnametimestamp_prefix: { - \__erw_int_range:nnn {}{0}{#1} + \erw_tl_join:nn + {\c_sys_jobname_str} + {\g__erw_sys_timestamp_delim_str} } -\cs_set:Npn \erw_gset_map:N #1 +\cs_new:Nn\__erw_sys_jobnametimestamp:nn { - \erw_cs_gset_eq:NN \__erw_map:n #1 + \erw_tl_join:nn + {\__erw_sys_jobnametimestamp_prefix:} + {\erw_sys_timestamp:nn{#1}{#2}} } -\cs_set:Npn \erw_gset_map_inline:n #1 +\cs_new:Nn\__erw_sys_jobnametimestamp: { - \erw_cs_gset_inline:Nn \__erw_map:n {#1} + \erw_tl_join:nn + {\__erw_sys_jobnametimestamp_prefix:} + {\erw_sys_timestamp:} } -\cs_set:Npn \erw_map:n #1 +\cs_new:Nn\__erw_sys_timestamp:nn { - \__erw_map:nn#1\q_recursion_tail\q_recursion_stop\q_recursion_tail\q_recursion_stop + \exp_args:No + \use:c{__erw_sys_\__erw_sys_datetime_period:n{#1}_\__erw_sys_datetime_base:n{#2}:} } -\cs_set:Npn \__erw_map:nn #1 #2 +\cs_new_protected:Nn \__erw_sys_set_delim:nn { - \quark_if_recursion_tail_stop:n{#1} - \__erw_map:n{#1} \__erw_map:nn{#2} + \use:c{tl_gset:N#1} + \g__erw_sys_timestamp_delim_str{#2} } -\cs_new:Npn \__erw_map:n #1 +\keys_define:nn{__erw} { - \msg_error:nnn - {erw} - {generic} - {__erw_map:n~not~set} + sys / timestamp_delim .code:n = + { + \exp_last_unbraced:No + \__erw_sys_set_delim:nn{n}{#1} + }, + sys / timestamp_delim .value_required:n = true, + sys / timestamp_delim .default:n = {-}, + sys / timestamp_delim .initial:n = {-} } -\cs_set:Npn \erw_map:Nn - #1 % fun - #2 % tl +\cs_new:Nn\erw_sys_jobnametimestamp:nn{\__erw_sys_jobnametimestamp:nn{#1}{#2}} +\cs_new:Nn\erw_sys_jobnametimestamp:{\__erw_sys_jobnametimestamp:} +\cs_new:Nn\erw_sys_timestamp_delimiter: { - \erw_cs_set_eq:NN \__erw_map:n #1 - \erw_map:n{#2} + \use:N \g__erw_sys_timestamp_delim_str } -\cs_set:Npn \erw_map_inline:nn - #1 % inl - #2 % tl +\cs_new:Nn\erw_sys_timestamp:nn { - \erw_cs_set_inline:Nn \__erw_map:n {#1} - \erw_map:n{#2} + \__erw_sys_timestamp:nn{#1}{#2} } -\cs_set:Npn \erw_apply:Nnn #1 #2 #3 +\cs_new:Nn\erw_sys_timestamp: { - #1{#2}{#3} + \__erw_sys_timestamp:nn{datetime}{16} } -\cs_set:Npn \erw_apply:Nnnn #1 #2 #3 #4 +\tl_new:N \g__erw_tl_compose_tl +\cs_new_protected:Nn \g__erw_tl_function:n { - #1{#2}{#3}{#4} + \msg_error:nnn + {erw} + {notset} + {\g__erw_tl_function:n} } -\cs_set:Npn \erw_apply:Nnnnn #1 #2 #3 #4 #5 +\cs_set_protected:Nn \__erw_tl_map:nn { - #1{#2}{#3}{#4}{#5} + \quark_if_recursion_tail_stop:n{#1} + \g__erw_tl_function:n{#1} \__erw_tl_map:nn{#2} } -\cs_set:Npn \__erw_map_thread_at:Nnn #1 #2 #3 +\cs_set_protected:Nn \__erw_tl_map_thread_at:Nnn { - \erw_apply:Nn #1 - {\exp_args:Nf\tl_item:nn {#3} {#2} } + #1 + {\exp_args:Nf\tl_item:nn {#3} {#2} } } -\cs_set:Npn \__erw_map_thread_at:Nnnn #1 #2 #3 #4 +\cs_set_protected:Nn \__erw_tl_map_thread_at:Nnnn { - \erw_apply:Nnn #1 - {\exp_args:Nf\tl_item:nn {#3} {#2} } - {\exp_args:Nf\tl_item:nn {#4} {#2} } + #1 + {\exp_args:Nf\tl_item:nn {#3} {#2} } + {\exp_args:Nf\tl_item:nn {#4} {#2} } } -\cs_set:Npn \__erw_map_thread_at:Nnnnn #1 #2 #3 #4 #5 +\cs_set_protected:Nn \__erw_tl_map_thread_at:Nnnnn { - \erw_apply:Nnnn #1 - {\exp_args:Nf\tl_item:nn {#3} {#2} } - {\exp_args:Nf\tl_item:nn {#4} {#2} } - {\exp_args:Nf\tl_item:nn {#5} {#2} } + #1 + {\exp_args:Nf\tl_item:nn {#3} {#2} } + {\exp_args:Nf\tl_item:nn {#4} {#2} } + {\exp_args:Nf\tl_item:nn {#5} {#2} } } -\cs_set:Npn \__erw_map_thread_at:Nnnnnn #1 #2 #3 #4 #5 #6 +\cs_set_protected:Nn \__erw_tl_map_thread_at:Nnnnnn { - \erw_apply:Nnnnn #1 - {\exp_args:Nf\tl_item:nn {#3} {#2} } - {\exp_args:Nf\tl_item:nn {#4} {#2} } - {\exp_args:Nf\tl_item:nn {#5} {#2} } - {\exp_args:Nf\tl_item:nn {#6} {#2} } + #1 + {\exp_args:Nf\tl_item:nn {#3} {#2} } + {\exp_args:Nf\tl_item:nn {#4} {#2} } + {\exp_args:Nf\tl_item:nn {#5} {#2} } + {\exp_args:Nf\tl_item:nn {#6} {#2} } } -\cs_set:Npn \erw_map_thread_at:Nnn #1 #2 #3 +\cs_new:Nn \__erw_tl_separators:nn { - \exp_args:Nf\int_case:nnTF - { - \tl_count:n{#3} - } - { - {1}{ \__erw_map_thread_at:Nnn #1{#2}#3 } - {2}{ \__erw_map_thread_at:Nnnn #1{#2}#3 } - {3}{ \__erw_map_thread_at:Nnnnn #1{#2}#3 } - {4}{ \__erw_map_thread_at:Nnnnnn #1{#2}#3 } - } - { - % Do nothing - } + \int_case:nnTF {#1} + { + {1} + { \prg_replicate:nn{ 3 }{#2} } + {2} { - \msg_error:nnn{erw} - {generic} - {erw_map_thread_at:~count~of~#3~not~withing~1~to~4} + { \use_ii:nn #2 } + { \use_i:nn #2 } + { \use_i:nn #2 \use_ii:nn #2 } } + {3}{#2} + } + { \c_empty_tl } + { + \msg_error:nnnn { __erw } + { separ } + { \__erw_tl_separators:nn } + {#2} + } } -\cs_set:Npn \erw_map_thread:Nn #1 #2 +\cs_generate_variant:Nn \__erw_tl_separators:nn { e } +\cs_new:Nn \erw_tl_append_item:nn { - % TODO check that #2 is a matrix - \int_step_inline:nn - { - \exp_args:Nf \tl_count:n{ \tl_head:n{#2} } - } - { - \erw_map_thread_at:Nnn #1 {##1} {#2} - } + {#1{#2}} +} +\cs_new:Nn \erw_tl_fold:NN +{ + \use:c{tl_set:\g__erw_tl_fold_set_par_tl} + #2 + { + \use:c{exp_args:\g__erw_tl_fold_apply_par_tl}{#1}{#2} + } } -\int_new:N \__erw_numbrd_cs_int -\cs_set:Npn \erw_numbrd_cs_name:n #1{__erw_numbrd_cs_\int_to_alph:n{#1}:n} -\cs_set:Npn \erw_numbrd_cs_name_braced:n #1{{\erw_numbrd_cs_name:n{#1}}} -\tl_set:Nn \__erw_numbrd_cs_name_tl {\erw_numbrd_cs_name:n{\__erw_numbrd_cs_int}} -\cs_set:Npn \erw_numbrd_cs:nn #1 #2 +\cs_generate_variant:Nn \erw_tl_fold:NN {cN} +\cs_new:Nn \erw_tl_gset_function:N { - \erw_apply:cn{__erw_numbrd_cs_\int_to_alph:n{#1}:n}{#2} + \erw_cs_gset_eq:NN \g__erw_tl_function:n #1 } -\cs_new_protected:Npn \erw_numbrd_cs_reset: +\cs_new:Nn \erw_tl_gset_function:n { - \int_zero:N \__erw_numbrd_cs_int - \tl_set:Nn \__erw_numbrd_cs_ext_tl{} + \erw_cs_gset_inline:Nn \g__erw_tl_function:n {#1} } -\cs_new_protected:Npn \erw_numbrd_cs_new:n #1 +\cs_new:Nn \erw_tl_last_item:n { - \int_incr:N \__erw_numbrd_cs_int - \erw_cs_set_inline:cn{\__erw_numbrd_cs_name_tl} - { - \token_if_cs:NTF - {#1} - {#1{##1}} - {#1} - } + \exp_args:Nof \tl_item:nn + {#1} + { + \tl_count:n{#1} + } } -\cs_new:Npn \erw_numbrd_cs_names:nnn #1 #2 #3 +\cs_new:Nn \erw_tl_join:nn{#1#2} +\cs_new:Nn \erw_tl_join:nnn{#1#2#3} +\cs_new:Nn \erw_tl_join:nnnn{#1#2#3#4} +\cs_new:Nn \erw_tl_join:nnnnn{#1#2#3#4#5} +\cs_new_protected:Nn \erw_tl_map:n { - \int_step_function:nnnN { #1 }{ #2 }{ #3 } \erw_numbrd_cs_name:n + \__erw_tl_map:nn#1\q_recursion_tail\q_recursion_stop\q_recursion_tail\q_recursion_stop } -\cs_new:Npn \erw_numbrd_cs_names_braced:nnn #1 #2 #3 +\cs_new_protected:Nn \erw_tl_map:Nn { - \int_step_function:nnnN { #1 }{ #2 }{ #3 } \erw_numbrd_cs_name_braced:n - % TODO \tl_range_braced:nnn? + \cs_set_eq:NN \g__erw_tl_function:n #1 + \erw_tl_map:n{#2} } -\cs_new:Npn \erw_numbrd_cs_names_braced: +\cs_new_protected:Nn \erw_tl_map_inline:nn { - \erw_numbrd_cs_names_braced:nnn{1}{1}{\__erw_numbrd_cs_int} + \erw_cs_set_inline:Nn \g__erw_tl_function:n {#1} + \erw_tl_map:n{#2} } -\NewDocumentCommand{\numbrdcsnew}{ s m } +\cs_new:Nn \erw_tl_repeat:nn { - \IfBooleanTF{#1} - {} - { \erw_numbrd_cs_reset:{}} - \tl_map_function:nN {#2}\erw_numbrd_cs_new:n + \int_step_inline:nnnn{1}{1}{#1}{#2} +} +\cs_new:Nn \erw_tl_split:nnn +{ + \tl_head:n{#1} + \use:c{exp_args:#3} \tl_map_inline:nn + { + \tl_tail:n + { + #1 + } + }{#2##1} +} +\cs_new:Nn \erw_tl_split:nn +{ + \erw_tl_split:nnn{#1}{#2}{Nf} +} +\cs_new_protected:Nn \erw_tl_map_thread_at:Nnn +{ + \exp_args:Nf\int_case:nnTF + { + \tl_count:n{#3} + } + { + {1}{ \__erw_tl_map_thread_at:Nnn #1{#2}#3 } + {2}{ \__erw_tl_map_thread_at:Nnnn #1{#2}#3 } + {3}{ \__erw_tl_map_thread_at:Nnnnn #1{#2}#3 } + {4}{ \__erw_tl_map_thread_at:Nnnnnn #1{#2}#3 } + } + { + % Do nothing + } + { + \msg_error:nnn{__erw} + {generic} + {erw_tl_map_thread_at:~count~of~#3~not~withing~1~to~4} + } +} +\cs_new_protected:Nn \erw_tl_map_thread:Nn +{ + \int_step_inline:nn + { + \exp_args:Nf \tl_count:n{ \tl_head:n{#2} } + } + { + \erw_tl_map_thread_at:Nnn #1 {##1} {#2} + } } -\NewDocumentCommand{\numbrdcs}{ m m } +\cs_new:Nn \erw_tl_separators:n { - \erw_numbrd_cs:nn{#1}{#2} + \__erw_tl_separators:en{ \tl_count:n{#1} }{#1} } \ExplSyntaxOff %% -%% Copyright (C) 2018 by Erwann Rogard +%% Copyright (C) 2018-2020 by Erwann Rogard %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License (LPPL), either @@ -395,10 +509,8 @@ %% This work is "maintained" (as per LPPL maintenance status) by %% Erwann Rogard. %% -%% This work consists of the file erw-l3.dtx -%% and the derived files erw-l3.ins, -%% erw-l3.pdf and -%% erw-l3.sty. +%% This work consists of the file erw-l3.dtx and the derived files: +%% erw-l3.sty, and erw-l3.pdf. %% %% %% End of file `erw-l3.sty'. -- cgit v1.2.3