diff options
Diffstat (limited to 'Master/texmf-dist/tex/latex')
-rw-r--r-- | Master/texmf-dist/tex/latex/erw-l3/erw-l3.sty | 1127 |
1 files changed, 662 insertions, 465 deletions
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 18e94e85057..e9fda734166 100644 --- a/Master/texmf-dist/tex/latex/erw-l3/erw-l3.sty +++ b/Master/texmf-dist/tex/latex/erw-l3/erw-l3.sty @@ -5,499 +5,696 @@ %% The original source files were: %% %% erw-l3.dtx (with options: `package') -%% ---------------------------------------------------------------------------- -%% erw-l3 --- Utilities for LaTeX3 programming +%% ----------------------------------------------------------------------------- +%% erw-l3 --- Utilities based on LaTeX3, such as 'merge sort' %% Released under the LaTeX Project Public License v1.3c or later %% See http://www.latex-project.org/lppl.txt %% ---------------------------------------------------------------------------- %% - \NeedsTeXFormat{LaTeX2e}[2020/02/02] - \RequirePackage{etoolbox}[2019/09/21] - \RequirePackage{l3keys2e}[2020/03/06] - \RequirePackage{xparse}[2020/03/06] + \NeedsTeXFormat{LaTeX2e}[2021-06-01] + \RequirePackage{xparse, l3keys2e, xtemplate}[2021-06-01] \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 - } - \exp_args:Nf\erw_tl_map:n - { - \tl_reverse:n{#2} - } -} -\cs_set:Npn \erw_cs_identity:n #1{#1} -\cs_new_protected:Nn \erw_cs_set_inline:Nn -{ - \cs_set:Npn #1 ##1{#2} -} -\cs_generate_variant:Nn \erw_cs_set_inline:Nn {cn} -\cs_new:Nn \erw_cs_gset_inline:Nn -{ - \cs_gset:Npn #1 ##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 -{ - \exp_args:No \use:c{\erw_csint_name:n{#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 -{ - \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_new:Nn \erw_csint_names_braced:nnn -{ - \int_step_function:nnnN { #1 }{ #2 }{ #3 } \erw_csint_names_braced:n - % TODO \tl_range_braced:nnn? -} -\cs_new:Nn \erw_csint_names_braced:n {{\erw_csint_name:n{#1}}} -\cs_new:Nn \erw_csint_names_braced: -{ - \erw_csint_names_braced:nnn{1}{1}{\g__erw_csint_int} -} -\cs_new_protected:Nn \erw_csint_reset: -{ - \int_zero:N \g__erw_csint_int - \tl_set:Nn \__erw_csint_ext_tl{}%^^A TODO remove? -} -\cs_set:Npn \__erw_int_range:nnn #1 #2 #3 -{ - \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}} + {erw-l3} % Package name + {2022-01-28} % Release date + {4.2} % Release version + {erw-l3 --- Utilities based on LaTeX3, such as 'merge sort' } % Description +\cs_generate_variant:Nn\int_compare_p:nNn{eNe} +\cs_generate_variant:Nn\int_eval:n{e} +\cs_generate_variant:Nn\prg_new_conditional:Nnn{c} +\cs_generate_variant:Nn\prg_replicate:nn{e} +\cs_generate_variant:Nn\regex_gset:Nn{c} +\cs_generate_variant:Nn\regex_log:N{c} +\cs_generate_variant:Nn\regex_match:NnTF{c} +\cs_generate_variant:Nn\tl_to_str:n{e} +\cs_generate_variant:Nn\prop_put:Nnn{Nne} +\msg_new:nnnn{__erw}{text}{text~is~not~loaded}{load~amsmath} +\cs_new:Npn \__erw_text:n #1 +{\cs_if_exist:NTF\text{\text{#1}}{\msg_error:nn{__erw}{text}}} +\cs_new:Npn\__erw_empty:w #1 \q_recursion_stop {\c_empty_tl} +\cs_new_protected:Nn\erw_keys_set:n{ \keys_set:nn{__erw}{#1} } +\cs_new_protected:Nn\erw_keys_set:nn{ \keys_set:nn{__erw / #1}{#2} } +\cs_generate_variant:Nn\erw_apply:Nw{c} +\cs_new:Npn \erw_identity:n#1{#1} +\cs_new:Npn \erw_int_incr:n#1{\int_eval:n{#1+1}} +\cs_new:Npn \erw_swap:nn#1#2{#2#1} +\cs_generate_variant:Nn \erw_swap:nn{e} +\cs_new:Npn \erw_name_signature_cs:N #1 +{ \exp_last_unbraced:Ne + \__erw_name_signature_cs:nnn{\cs_split_function:N#1}} +\cs_new:Nn \__erw_name_signature_cs:nnn{{#1}{#2}} +\msg_new:nnn{erw}{quark-only-tail} +{requires~tail;~got~'#1';~\msg_line_context:} +\cs_new:Npn +\erw_all_q:w +#1 +\q_recursion_stop +{% + \erw_remove_last_q:w#1\q_recursion_stop + \erw_last_q:w#1\q_recursion_stop +} +\cs_new:Npn +\erw_remove_first_q:w +#1 % <tokenlist ending with recursion tail> +\q_recursion_stop +{\quark_if_recursion_tail_stop:n{#1} + \__erw_remove_first_q:nw#1\q_recursion_stop} +\cs_new:Npn +\__erw_remove_first_q:nw +#1 % <head> +#2 % <rest> +\q_recursion_stop +{\erw_remove_last_q:w#2\q_recursion_stop + \erw_last_q:w#2\q_recursion_stop} +\cs_new:Npn +\erw_first_q:w +#1 +\q_recursion_stop +{% + \quark_if_recursion_tail_stop:n{#1} + \__erw_first_q:enw{ \tl_if_head_is_group_p:n{#1}}#1\q_recursion_stop } +\cs_new:Npn +\__erw_first_q:nnw +#1 % <head is group> +#2 % <head> +#3 % <rest> +\q_recursion_stop +{% + \bool_if:nTF{#1}{{#2}}{#2} +} +\cs_generate_variant:Nn\__erw_first_q:nnw{e} +\cs_new:Npn +\erw_remove_last_q:w #1 \q_recursion_stop +{% + \quark_if_recursion_tail_stop:n{#1} + \__erw_remove_last_q:ew{\tl_if_head_is_group_p:n{#1}}#1\q_recursion_stop } +\cs_new:Npn +\__erw_remove_last_q:nw +#1 % <head is group> +#2 % <tokenlist> +\q_recursion_stop +{ \__erw_remove_last_q:nnw{#1}#2\q_recursion_stop } +\cs_generate_variant:Nn\__erw_remove_last_q:nw{e} +\cs_new:Npn +\__erw_remove_last_q:nnw +#1 % <head is group> +#2 % <head> +#3 % <rest> +\q_recursion_stop +{% + \quark_if_recursion_tail_stop:n{#3} + \bool_if:nTF{#1}{{#2}}{#2} + \__erw_remove_last_q:ew {\tl_if_head_is_group_p:n{#3}} #3 \q_recursion_stop +} +\cs_generate_variant:Nn\__erw_remove_last_q:nnw{e} +\cs_new:Npn +\erw_last_q:w #1 \q_recursion_stop +{\quark_if_recursion_tail_stop:n{#1} + \__erw_last_q:ew{\tl_if_head_is_group_p:n{#1}}#1\q_recursion_stop} +\cs_new:Npn +\__erw_last_q:nw +#1 % <head is group> +#2 % <tokenlist> +\q_recursion_stop +{ \__erw_last_q:nnw{#1}#2\q_recursion_stop } +\cs_generate_variant:Nn\__erw_last_q:nw{e} +\cs_new:Npn +\__erw_last_q:nnw +#1 % <head is group> +#2 % <head> +#3 % <rest> +\q_recursion_stop +{% + \quark_if_recursion_tail_stop_do:nn{#3}{ \bool_if:nTF{#1}{{#2}}{#2} } + \__erw_last_q:ew {\tl_if_head_is_group_p:n{#3}} #3 \q_recursion_stop +} +\cs_generate_variant:Nn\__erw_last_q:nnw{e} +\msg_new:nnn{__erw}{predicate-empty} +{empty~expression~in~predicate} +\prg_new_conditional:Npnn +\erw_and_tl:nn +#1 % <predicate expression> +#2 % <tokens> +{p} +{%^^A + \__erw_and_tl:nw {#1}#2 \q_recursion_tail\q_recursion_stop +} +\cs_new:Npn +\__erw_and_tl:nw +#1 % <predicate expression> +#2 % <value> +\q_recursion_stop +{% + \quark_if_recursion_tail_stop_do:nn{#2} + { \prg_return_true: } + \__erw_and_tl:nnw + {#1} % <predicate expression> + #2 % <value> + \q_recursion_stop +} +\cs_new:Npn +\__erw_and_tl:nnw +#1 % <predicate expression> +#2 % <value> +#3 % <rest> +\q_recursion_stop +{% + \bool_if:nTF + {#1{#2}} + {\__erw_and_tl:nw{#1}#3\q_recursion_stop} + { \prg_return_false: } +} +\cs_new:Npn \__erw_new_compare_p:nnn +#1 % <name> +#2 % <signature> +#3 % <code> +{% + \prg_new_conditional:cnn{#1:#2} + {p} + {% + \bool_if:nTF {#3} + {\prg_return_true:} + {\prg_return_false:} } } -\cs_new:Nn \erw_int_range:nn -{ - \__erw_int_range:nnn {{#1}}{#1}{#2} -} -\cs_new:Nn \erw_int_range:n -{ - \__erw_int_range:nnn {}{0}{#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 -{ - \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_new_protected:Npn \erw_lambda:nnn #1 #2 #3 -{ - \exp_args:NNx - #1 \__erw_lambda_expression - {#2} - {#3} - \__erw_lambda_expression -} -\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_protected:Nn \__erw_function:nn - { - #1 #2 {##1}{##2} - } - \prop_map_function:NN #3 \__erw_function:nn -} -\cs_new_protected:Nn \erw_prop_to_clist:Nn -{ - \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_prop_to_clist:Nn { c } -\cs_new_protected:Nn \erw_prop_map_item:NNN -{ - \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_new_protected:Nn\erw_prop_keyval_parse:NNNn -{ - \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} - } -} -\keys_define:nn{__erw} -{ - 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_new_protected:Nn\erw_option:n -{ - \keys_set:nn{__erw}{#1} -} -\tl_new:N \g__erw_seq_fold_item_tl -\cs_new_protected:Nn\__erw_seq_put_right_clist:Nn -{ - \cs_set_protected:Nn \__erw_function:n - { - \seq_put_right:Nn #1{##1} +\keys_define:nn{ __erw } +{ + new_compare_p.code:n = {\__erw_new_compare_p:nnn#1} +} +\erw_keys_set:n +{% + new_compare_p = + {erw_compare} % <name> + {nNnNn} + { \__erw_compare:eecN{ #2{#3} }{ #2{#5} }{ #1:nNn }#4 } +} +\cs_new:Npn +\__erw_compare:nnNN +#1 % <first> +#2 % <second> +#3 % <predicate> +#4 % <operator> +{ #3{ #1 }#4{ #2 } } +\cs_generate_variant:Nn\__erw_compare:nnNN{eec} +\erw_keys_set:n +{% + new_compare_p = + {erw_int_incr} + {nn} + {\exp_args:Ne + \int_compare_p:nNn{ \int_eval:n{#1+1} } = {#2} } +} +\cs_new:Npn\__erw_keyval_key:w #1 = #2 \q_recursion_stop{#1} +\cs_new:Npn\__erw_keyval_value:w #1 = #2 \q_recursion_stop{#2} +\cs_new:Npn \erw_keyval_key:n#1{\__erw_keyval_key:w #1 \q_recursion_stop} +\cs_new:Npn \erw_keyval_value:n#1{\__erw_keyval_value:w #1 \q_recursion_stop} +\cs_new:Npn \erw_keyval:nn#1#2{ #1 = #2 } +\erw_keys_set:n +{ + new_compare_p = {erw_key_compare} + {nNn}{ \erw_compare_p:nNnNn + {int_compare_p}\erw_keyval_key:n{#1}#2{#3} }, + new_compare_p = {erw_key_compare} + {n}{ \erw_compare_recurse_p:nnNN{#1} + {int_compare_p}\erw_keyval_key:n< } +} +\cs_new:Npn +\erw_remove_first:n +#1 % <tokenlist> +{\erw_remove_first_q:w#1\q_recursion_tail\q_recursion_stop} +\cs_generate_variant:Nn\erw_remove_first:n{e} +\cs_new:Npn +\erw_remove_last:n +#1 % <tokenlist> +{\erw_remove_last_q:w#1\q_recursion_tail\q_recursion_stop} +\cs_generate_variant:Nn\erw_remove_last:n{e} +\cs_new:Npn +\erw_first:n +#1 +{\erw_first_q:w#1\q_recursion_tail\q_recursion_stop} +\cs_generate_variant:Nn\erw_first:n{e} +\cs_new:Npn +\erw_last:n +#1 % <tokenlist> +{\erw_last_q:w#1\q_recursion_tail\q_recursion_stop} +\cs_generate_variant:Nn\erw_last:n{e} +\cs_new:Npn +\erw_adjacent_insert:nn +#1 % <list> +#2 % <separator> +{% + \erw_first:n{#1} + \erw_swap:en + { \erw_remove_first:n{#1} } + {% + \__erw_adjacent_insert:nw + {#2} % <separator> } - \keyval_parse:NNn - \__erw_function:n - \erw_keyval_keyonly:nn - {#2} -} -\cs_generate_variant:Nn \__erw_seq_put_right_clist:Nn { c } -\cs_new_protected:Nn\__erw_seq_put_right_prop:NNn -{ - \__erw_seq_put_right_clist:Nn #1 - {\erw_prop_to_clist:Nn #2 {#3}} -} -\cs_generate_variant:Nn \__erw_seq_put_right_prop:NNn { cc } -\cs_new_protected:Nn\erw_seq_put_right_clist:Nn -{ - \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_generate_variant:Nn \erw_seq_put_right_clist:Nn { c } -\cs_new_protected:Nn\erw_seq_put_right_prop:NNn -{ - \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_generate_variant:Nn \erw_seq_put_right_prop:NNn { cc } -\cs_new_protected:Nn \erw_seq_fold:NN -{ - \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_generate_variant:Nn \erw_seq_fold:NN {cN} -\cs_new:Nn \erw_seq_use:Nn -{ - \exp_last_unbraced:NNf - \seq_use:Nnnn #1 - \erw_tl_separators:n{#2} -} -\cs_new:Nn \__erw_sys_date_dec: -{ - \int_eval:n - { - \c_sys_year_int * 10000 - +\c_sys_month_int * 100 - +\c_sys_day_int * 1 + \q_recursion_tail + \q_recursion_stop +} +\cs_generate_variant:Nn\erw_adjacent_insert:nn{e} +\cs_new:Npn +\__erw_adjacent_insert:nw +#1 % <separator> +#2 % <rest> +\q_recursion_stop +{% + \quark_if_recursion_tail_stop:n{#2} + \__erw_adjacent_insert:new {#1}{\tl_if_head_is_group_p:n{#2}}#2 \q_recursion_stop +} +\cs_new:Npn +\__erw_adjacent_insert:nnw +#1 % <separator> +#2 % <head is group> +#3 % <head> +#4 % <rest> +\q_recursion_stop +{% + #1\bool_if:nTF{#2}{{#3}}{#3} + \__erw_adjacent_insert:nw{#1}#4\q_recursion_stop +} +\cs_generate_variant:Nn\__erw_adjacent_insert:nnw{ne} +\cs_new:Npn +\erw_clist_tl:nn +#1 % <bool> +#2 % <list> +{ \erw_clist_tl:nnw {#1} #2 \q_recursion_tail\q_recursion_stop } +\cs_new:Npn +\erw_clist_tl:nnw #1 #2\q_recursion_stop +{\quark_if_recursion_tail_stop:n{#2} + \erw_clist_tl:nenw {#1} + {\tl_if_head_is_group_p:n{#2}} #2 \q_recursion_stop} +\cs_generate_variant:Nn\erw_clist_tl:nnw{ne} +\cs_new:Npn +\erw_clist_tl:nnnw +#1 % <bool> +#2 % <head is group> +#3 % <head> +#4 % <rest> +\q_recursion_stop +{ + \quark_if_recursion_tail_stop_do:nn{#4} + {% + \bool_if:nTF + {\bool_lazy_and_p:nn{#1}{#2}} + {{#3}}{#3} } -} -\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: -{ - \int_eval:n - { - \c_sys_hour_int * 100 - +\c_sys_minute_int * 1 + \bool_if:nTF{\bool_lazy_and_p:nn{#1}{#2}} + {{#3}}{#3}, + \erw_clist_tl:nnw {#1} #4 \q_recursion_stop +} +\cs_generate_variant:Nn\erw_clist_tl:nnnw{ne} +\prg_new_conditional:Npnn +\erw_if_in_clist:nn +#1 % <value> +#2 % <clist> +{p} +{ \__erw_clist_if_in:nw {#1} #2, \q_recursion_tail \q_recursion_stop } +\cs_new:Npn +\__erw_clist_if_in:nw #1 #2 \q_recursion_stop +{% + \quark_if_recursion_tail_stop:n{#2} + \__erw_clist_if_in:nnw {#1} #2 \q_recursion_stop +} +\cs_new:Nn +\__erw_clist_if_in:nn +{\__erw_clist_if_in:nw{#1} #2 \q_recursion_stop} +\cs_new:Npn +\__erw_clist_if_in:nnw #1 #2, #3 \q_recursion_stop +{% + \quark_if_recursion_tail_stop_do:nn{#3} + {% + \str_if_eq:nnTF{#1}{#2} + {\prg_return_true:}{\prg_return_false:} } -} -\cs_new:Nn\__erw_sys_time_hex:{\int_to_hex:n{\__erw_sys_time_dec:}} -\cs_new:Nn\__erw_sys_datetime_base:n -{ - \int_case:nnTF{#1} - { - {10}{dec} - {16}{hex} + \str_if_eq:nnTF{#1}{#2} + {\prg_return_true:} + {\__erw_clist_if_in:nw {#1} #3 \q_recursion_stop} + \__erw_empty:w\q_recursion_stop +} +\cs_new:Npn +\erw_split_even:n +#1 % <tokenlist> +{% + \tl_if_empty:nF{#1} + {% + \exp_last_unbraced:Ne + \__erw_split_even:nnnw + {% + {\__erw_split_even_threshold:n{#1}} % <count> + {\tl_if_head_is_group_p:n{#1}} % <head is group> + } + #1 % <tokenlist> + \q_recursion_tail + \q_recursion_stop } - {\c_empty_tl} - {\msg_error:nnn{__erw}{timestamp / base}{\__erw_sys_datetime_base:n{#1}}} } -\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 -{ - \str_case:nnTF{#1} - { - {date}{date} - {time}{time} - {datetime}{datetime} +\cs_generate_variant:Nn\erw_split_even:n{e} +\cs_new:Npn +\__erw_split_even_threshold:n +#1 % <tokenlist> +{\exp_args:Ne + \int_div_round:nn{\tl_count:n{#1}}{2}} +\cs_new:Npn +\__erw_split_even:nnnw +#1 % <threshold> +#2 % <head is group> +#3 % <head> +#4 % <rest> +\q_recursion_stop +{% + \quark_if_recursion_tail_stop_do:nn{#4} + { { \bool_if:nTF{#2}{{#3}}{#3} }{} } + \exp_last_unbraced:Ne + \__erw_split_even:nnnnw + {% + {1} % <left size> + { \tl_if_head_is_group_p:n{#4} } + {#1} % <threshold count> + { \bool_if:nTF{#2}{{#3}}{#3} } % <left list> } - {\c_empty_tl} - {\msg_error:nnn{__erw}{ timestamp / period }{\__erw_sys_datetime_period: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_tl_join:nn - {\c_sys_jobname_str} - {\g__erw_sys_timestamp_delim_str} -} -\cs_new:Nn\__erw_sys_jobnametimestamp:nn -{ - \erw_tl_join:nn - {\__erw_sys_jobnametimestamp_prefix:} - {\erw_sys_timestamp:nn{#1}{#2}} -} -\cs_new:Nn\__erw_sys_jobnametimestamp: -{ - \erw_tl_join:nn - {\__erw_sys_jobnametimestamp_prefix:} - {\erw_sys_timestamp:} -} -\cs_new:Nn\__erw_sys_timestamp:nn -{ - \exp_args:No - \use:c{__erw_sys_\__erw_sys_datetime_period:n{#1}_\__erw_sys_datetime_base:n{#2}:} -} -\cs_new_protected:Nn \__erw_sys_set_delim:nn -{ - \use:c{tl_gset:N#1} - \g__erw_sys_timestamp_delim_str{#2} -} -\keys_define:nn{__erw} -{ - 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_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: -{ - \use:N \g__erw_sys_timestamp_delim_str -} -\cs_new:Nn\erw_sys_timestamp:nn -{ - \__erw_sys_timestamp:nn{#1}{#2} -} -\cs_new:Nn\erw_sys_timestamp: -{ - \__erw_sys_timestamp:nn{datetime}{16} -} -\tl_new:N \g__erw_tl_compose_tl -\cs_new_protected:Nn \g__erw_tl_function:n -{ - \msg_error:nnn - {erw} - {notset} - {\g__erw_tl_function:n} -} -\cs_set_protected:Nn \__erw_tl_map:nn -{ - \quark_if_recursion_tail_stop:n{#1} - \g__erw_tl_function:n{#1} \__erw_tl_map:nn{#2} -} -\cs_set_protected:Nn \__erw_tl_map_thread_at:Nnn -{ - #1 - {\exp_args:Nf\tl_item:nn {#3} {#2} } -} -\cs_set_protected:Nn \__erw_tl_map_thread_at:Nnnn -{ - #1 - {\exp_args:Nf\tl_item:nn {#3} {#2} } - {\exp_args:Nf\tl_item:nn {#4} {#2} } -} -\cs_set_protected:Nn \__erw_tl_map_thread_at: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} } -} -\cs_set_protected:Nn \__erw_tl_map_thread_at:Nnnnnn -{ - #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_new:Nn \__erw_tl_separators:nn -{ - \int_case:nnTF {#1} - { - {1} - { \prg_replicate:nn{ 3 }{#2} } - {2} + #4 % <right list> + \q_recursion_stop +} +\cs_new:Npn +\__erw_split_even:nnnnw +#1 % <left size> +#2 % <right head is group> +#3 % <threshold count> +#4 % <left list> +#5 % <right head> +#6 % <right rest> +\q_recursion_stop +{% + \bool_if:nTF + { \int_compare_p:nNn {#1}<{#3} } + {% + \exp_last_unbraced:Ne + \__erw_split_even:nnnnw { - { \use_ii:nn #2 } - { \use_i:nn #2 } - { \use_i:nn #2 \use_ii:nn #2 } + { \int_eval:n{#1+1} } % <left size> + { \tl_if_head_is_group_p:n{#6} } % <right head is group> + {#3} % <threshold count> + {#4\bool_if:nTF{#2}{{#5}}{#5}} % <left list> } - {3}{#2} + #6 + \q_recursion_stop } - { \c_empty_tl } - { - \msg_error:nnnn { __erw } - { separ } - { \__erw_tl_separators:nn } - {#2} + {% + {#4} + {% + \bool_if:nTF{#2}{{#5}}{#5} + \erw_remove_last_q:w#6\q_recursion_stop\erw_last_q:w#6\q_recursion_stop} } } -\cs_generate_variant:Nn \__erw_tl_separators:nn { e } -\cs_new:Nn \erw_tl_append_item:nn -{ - {#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} - } -} -\cs_generate_variant:Nn \erw_tl_fold:NN {cN} -\cs_new:Nn \erw_tl_gset_function:N -{ - \erw_cs_gset_eq:NN \g__erw_tl_function:n #1 -} -\cs_new:Nn \erw_tl_gset_function:n -{ - \erw_cs_gset_inline:Nn \g__erw_tl_function:n {#1} -} -\cs_new:Nn \erw_tl_last_item:n -{ - \exp_args:Nof \tl_item:nn +\cs_new:Npn +\erw_thread_sort:nnNn +#1 % <first sorted list> +#2 % <second sorted list> +#3 % <compare predicate name> +#4 % <compare operator> +{% + \__erw_thread_sort:nNnnn + {#3} % <compare predicate name> + #4 % <compare operator> + {\c_empty_tl} % <accum> {#1} - { - \tl_count:n{#1} - } -} -\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 -{ - \__erw_tl_map:nn#1\q_recursion_tail\q_recursion_stop\q_recursion_tail\q_recursion_stop -} -\cs_new_protected:Nn \erw_tl_map:Nn -{ - \cs_set_eq:NN \g__erw_tl_function:n #1 - \erw_tl_map:n{#2} -} -\cs_new_protected:Nn \erw_tl_map_inline:nn -{ - \erw_cs_set_inline:Nn \g__erw_tl_function:n {#1} - \erw_tl_map:n{#2} -} -\cs_new:Nn \erw_tl_repeat:nn -{ - \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} + {#2} } -\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 +\cs_generate_variant:Nn\erw_thread_sort:nnNn{ee} +\cs_new:Npn +\__erw_thread_sort:nNnnn +#1 % <compare predicate name> +#2 % <compare operator> +#3 % <sorted> +#4 % <first> +#5 % <second> +{% + \__erw_thread_sort:nNnww + {#1} % <compare predicate name> + {#2} % <compare operator> + {#3} % <sorted> + #4 \q_recursion_tail% <first> + \q_stop + #5 \q_recursion_tail% <second> + \q_recursion_stop +} +\cs_generate_variant:Nn\__erw_thread_sort:nNnnn{nNeee} +\cs_new:Npn +\__erw_thread_sort:nNnww +#1 % <compare predicate name> +#2 % <compare operator> +#3 % <sorted> +#4 % <first> +\q_stop +#5 % <second> +\q_recursion_stop +{% + \quark_if_recursion_tail_stop_do:nn{#4} + { #3 \erw_all_q:w #5 \q_recursion_stop } + \quark_if_recursion_tail_stop_do:nn{#5} + { #3 \erw_all_q:w #4 \q_recursion_stop } + \__erw_thread_sort:nNneeww + {#1}#2{#3} + { \tl_if_head_is_group_p:n{#4} } + { \tl_if_head_is_group_p:n{#5} } + #4\q_stop + #5\q_recursion_stop +} +\cs_new:Npn +\__erw_thread_sort:nNnnnww +#1 % <compare predicate name> +#2 % <compare operator> +#3 % <sorted> +#4 % <head is begin> +#5 % <head is begin> +#6 % <first head> +#7 % <first rest> +\q_stop +#8 % <second head> +#9 % <second rest> +\q_recursion_stop +{% + \bool_if:nTF + { \use:c{#1:nNn}{#6}#2{#8} } + {% + \__erw_thread_sort:nNeee + {#1} + #2 + {#3\bool_if:nTF{#4}{{#6}}{#6}} + {\erw_all_q:w#7\q_recursion_stop} + {\bool_if:nTF{#5}{{#8}}{#8}\erw_all_q:w#9\q_recursion_stop} } - { - \msg_error:nnn{__erw} - {generic} - {erw_tl_map_thread_at:~count~of~#3~not~withing~1~to~4} + {% + \__erw_thread_sort:nNeee + {#1} + #2 + {#3\bool_if:nTF{#5}{{#8}}{#8}} + {\bool_if:nTF{#4}{{#6}}{#6}\erw_all_q:w#7\q_recursion_stop} + {\erw_all_q:w#9\q_recursion_stop} } } -\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} +\cs_generate_variant:Nn\__erw_thread_sort:nNnnnww{nNnee} +\cs_new:Npn +\erw_merge_sort:nNn +#1 % <compare predicate name> +#2 % <compare operator> +#3 % <unsorted list> +{% + \tl_if_empty:nF{#3} + {% + \__erw_sort_merge:enNw + {\tl_if_head_is_group_p:n{#3}} % <head is group> + {#1} % <compare predicate name> + #2 % <compare operator> + #3 % <unsorted list> + \q_recursion_tail + \q_recursion_stop } } -\cs_new:Nn \erw_tl_separators:n -{ - \__erw_tl_separators:en{ \tl_count:n{#1} }{#1} -} +\cs_generate_variant:Nn\erw_merge_sort:nNn{nNe} +\cs_new:Npn +\__erw_sort_merge:nnNw +#1 % <head is group> +#2 % <compare predicate name> +#3 % <compare operator> +#4 % <unsorted list head> +#5 % <unsorted list rest> +\q_recursion_stop +{% + \quark_if_recursion_tail_stop_do:nn{#5} + { \bool_if:nTF{#1}{{#4}}{#4} } + \exp_last_unbraced:Ne + \__erw_sort_merge:nnnN + {% + \erw_split_even:e + {% + \bool_if:nTF{#1}{{#4}}{#4} + \erw_all_q:w#5\q_recursion_stop + } + } % {<first sorted list>}{<second sorted list>} + {#2} % <compare predicate name> + #3 % <compare operator> + \__erw_empty:w \q_recursion_stop +} +\cs_generate_variant:Nn\__erw_sort_merge:nnNw{e} +\cs_new:Npn +\__erw_sort_merge:nnnN +#1 % <left unsorted list> +#2 % <right unsorted list> +#3 % <compare predicate name> +#4 % <compare operator> +{% + \erw_thread_sort:eeNn + {% + \__erw_sort_merge:enNw + {\tl_if_head_is_group_p:n{#1}} + {#3} % <compare predicate name> + #4 % <compare operator> + #1 % <unsorted list> + \q_recursion_tail + \q_recursion_stop + } % <first sorted list> + {% + \__erw_sort_merge:enNw + {\tl_if_head_is_group_p:n{#2}} + {#3} % <compare predicate name> + #4 % <compare operator> + #2 % <unsorted list> + \q_recursion_tail + \q_recursion_stop + } % <second sorted list> + {#3} % <compare predicate name> + #4 % <operator> +} +\msg_new:nnn{__erw}{tokenlist-incr} +{expecting~an~ascending~tokenlist~got~#1~followed~by~#2} +\cs_new:Npn +\__erw_filter_uniq:nnw +#1 % <compare predicate> +#2 % <greatest> +#3 % <tokenlist> +\q_recursion_stop +{ % + \quark_if_recursion_tail_stop:n{#3} + \__erw_filter_uniq_aux:nnw{#1}{#2}#3\q_recursion_stop} +\cs_new:Npn +\__erw_filter_uniq_aux:nw +#1 % <compare predicate> +#2 % <tokenlist head> +#3 % <tokenlist rest> +\q_recursion_stop +{% + {#2} + \__erw_filter_uniq:nnw + {#1} % <compare predicate> + {#2} #3 % <tokenlist> + \q_recursion_stop } +\cs_new:Npn +\__erw_filter_uniq_aux:nnw +#1 % <compare predicate> +#2 % <last> +#3 % <head token> +#4 % <rest token> +\q_recursion_stop +{ % + \bool_if:nTF{\use:c{#1:nNn}{#3}<{#2}} + {\msg_error:nnnn{__erw}{tokenlist-incr}{#2}{#3}} + {% + \bool_if:nF + {\use:c{#1:nNn}{#3}={#2}} +{\tl_if_single_token:nTF{#3}{#3}{{#3}}} +} +\quark_if_recursion_tail_stop:n{#4} +\__erw_filter_uniq:nnw{#1}{#3}#4\q_recursion_stop } +\cs_new:Npn +\__erw_filter_uniq:nw +#1 % <compare predicate> +#2 % <tokenlist> +{% + \quark_if_recursion_tail_stop_do:nn{#2}{\c_empty_tl} + \__erw_filter_uniq_aux:nw {#1}#2 \q_recursion_stop} +\cs_new:Npn +\erw_filter_uniq:nn +#1 % <compare predicate> +#2 % <tokenlist> +{% + \__erw_filter_uniq_aux:nw + {#1} % <compare predicate> + #2 + \q_recursion_tail % <head token> + \q_recursion_stop} +\cs_new:Npn +\erw_filter_uniq:n +#1 % <ascending integers> +{ \erw_filter_uniq:nn{int_compare_p}{#1} } +\cs_generate_variant:Nn\erw_filter_uniq:nn{ne} +\keys_define:nn{__erw} +{ clist_map_inline.code:n = \__erw_map_inline_clist:nnn#1 } +\cs_new_protected:Npn +\__erw_map_inline_clist:nnn +#1 % <clist> +#2 % <signature> +#3 % <code> +{ + \cs_new_protected:cn + {__erw_do:#2}{#3} + \clist_map_inline:nn + {#1} + {\use:c{__erw_do:#2}##1} +} +\cs_new:Npn +\erw_parameter:n +#1 %^^A <arity> +{## #1} +\cs_new:Npn +\__erw_parameter_aux:nn +#1 % <finish> +#2 % <start> +{ \int_step_function:nnN {#2}{#1}\erw_parameter:n} +\cs_new:Npn +\erw_parameter:nn +#1 % <start> +#2 % <count> +{% + \exp_args:Ne + \__erw_parameter_aux:nn + {\int_eval:n{#1+#2-1}}{#1}} +\cs_new:Npn +\erw_argument:nn +#1 % <position> +#2 % <signature> +{\__erw_argument:nw{#1}#2\q_recursion_tail\q_recursion_stop} +\cs_new:Npn +\__erw_argument_unit:nn +#1 % <position> +#2 % <n|N> +{\use:c{__erw_argument_#2:w} #1 \q_recursion_stop} +\cs_new:Npn\__erw_argument_n:w #1 \q_recursion_stop{{## #1}} +\cs_new:Npn\__erw_argument_N:w #1 \q_recursion_stop{## #1} +\cs_new:Npn +\__erw_argument:nw +#1 % <position> +#2 % <signature list> +\q_recursion_stop +{ \quark_if_recursion_tail_stop:n{#2} + \__erw_argument:nnw{#1}#2\q_recursion_stop } +\cs_new:Npn +\__erw_argument:nnw +#1 % <position> +#2 % <n|N> +#3 % <signature rest> +\q_recursion_stop +{% + \__erw_argument_unit:nn{#1}{#2} + \exp_args:Ne + \__erw_argument:nw + {\erw_int_incr:n{#1}}#3\q_recursion_stop } +\ProcessKeysOptions{__erw} \ExplSyntaxOff %% -%% Copyright (C) 2018-2020 by Erwann Rogard +%% Copyright (C) 2020-2022 by Erwann Rogard %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License (LPPL), either |