%% %% This is file `clistmap.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% clistmap.dtx (with options: `package') %% ---------------------------------------------------------------------------- %% clistmap --- Partition a comma separated list, map differentiatedly across %% components %% Released under the LaTeX Project Public License v1.3c or later %% See http://www.latex-project.org/lppl.txt %% ---------------------------------------------------------------------------- %% \NeedsTeXFormat{LaTeX2e}[2021-06-01] \RequirePackage{xparse, xtemplate, l3keys2e}[2021-06-01] \RequirePackage{erw-l3}[2022-01-28] \ProvidesExplPackage {clistmap} %^^A Package name {2022-01-29} %^^A Release date {1.2} %^^A Release version {Partition a comma separated list, %^^A Description map differentiatedly across components} \cs_generate_variant:Nn\str_if_eq:nnTF{e} \cs_generate_variant:Nn\tl_to_str:n{e} \cs_generate_variant:Nn\prop_gput:Nnn{Nee} \cs_generate_variant:Nn\erw_parameter:n{e} \cs_generate_variant:Nn\erw_argument:nn{ne} \cs_generate_variant:Nn\erw_parameter:nn{ne} \cs_generate_variant:Nn\erw_clist_tl:nn{ne} \cs_new:Npn\__clistmap_empty:w#1\q_recursion_stop{} \clist_new:N\__clistmap_helper_clist \cs_new_protected:Nn \clistmap_keys_set:n{ \keys_set:nn{ __clistmap }{ #1 } } \prop_new:N\__clistmap_info_clist_prop \cs_new_protected:Npn \__clistmap_info_clist_put:nn #1 % #2 % {\prop_gput:Nnn\__clistmap_info_clist_prop{#1}{#2}} \cs_new_protected:Npn \clistmap_info_clist:nn #1 % #2 % {\clist_map_inline:cn{\prop_item:Nn\__clistmap_info_clist_prop{#1}}{#2}} \prop_new:N\__clistmap_info_prop_prop \cs_new_protected:Npn \__clistmap_info_prop_put:nn #1 % #2 % {\prop_gput:Nnn\__clistmap_info_prop_prop{#1}{#2}} \cs_new:Nn \__clistmap_brace:nn{{{#1}{#2}}} \cs_new:Npn \clistmap_info_prop:n #1 % { \prop_map_function:cN {\prop_item:Nn\__clistmap_info_prop_prop{#1}}\__clistmap_brace:nn } \cs_new:Npn \clistmap_info_prop:nn #1 % #2 % { \prop_map_inline:cn {\prop_item:Nn\__clistmap_info_prop_prop{#1}}{#2} } \cs_new:Nn \__clistmap_group_if:nn {\bool_if:nTF{#2}{{#1}}{#1}} \cs_generate_variant:Nn\__clistmap_group_if:nn{e} \cs_new:Nn \__clistmap_head_clist:n {% \exp_args:Ne \tl_head:n { \clist_map_function:nN{#1}\__clistmap_head_clist_aux:n } } \cs_new:Nn \__clistmap_head_clist_aux:n{#1} \cs_new:Npn \__clistmap_rule_name:n #1 % {rule_#1} \cs_new:Npn \__clistmap_instance_name:nn #1 % #2 % {instance_#1_#2} \cs_new:Npn \__clistmap_instance_name:nnn #1 % #2 % #3 % {\__clistmap_instance_name:nn{#1_#2}{#3}} \cs_new:Npn \__clistmap_instance_signature:n #1 % {n#1w} \cs_new:Npn \__clistmap_c:n #1 % {__clistmap_#1} \cs_generate_variant:Nn\__clistmap_c:n{e} \cs_new:Npn \__clistmap_c:nn #1 % #2 % {\__clistmap_c:n{#1:#2}} \cs_generate_variant:Nn\__clistmap_c:nn{e, ee} \cs_new:Npn \__clistmap_bound_cs_c:nn #1 % #2 % {#1:#2n} \cs_new:Npn \__clistmap_rule_c:n #1 % {% \__clistmap_c:en {\__clistmap_rule_name:n{#1}} {nnnnnnnn} } \cs_new:Npn \__clistmap_instance_c:nn #1 % #2 % { \__clistmap_c:e { \__clistmap_instance_name:nn{#1}{#2} } } \cs_generate_variant:Nn\__clistmap_instance_c:nn{e} \cs_new:Npn \__clistmap_instance_c:nnn #1 % #2 % #3 % {% \__clistmap_c:ee { \__clistmap_instance_name:nn{#1}{#2} } { \__clistmap_instance_signature:n{#3} } } \cs_generate_variant:Nn\__clistmap_instance_c:nnn{e, nne} \cs_new:Npn \__clistmap_instance_c_this:nnnn #1 % #2 % #3 % #4 % { \__clistmap_instance_c:enn {\__clistmap_rule_link:nn{#1}{#2}}{#3}{#4} } \cs_new:Npn \__clistmap_rule_link:nn #1 % #2 % {#1_#2} \cs_new:Npn \__clistmap_rule_link:n #1 % <{rule{1}}...> {% \__clistmap_rule_link:w#1\q_recursion_tail\q_recursion_stop } \cs_generate_variant:Nn\__clistmap_rule_link:n{e} \cs_new:Npn \__clistmap_rule_link:w #1 \q_recursion_stop {% \quark_if_recursion_tail_stop:n{#1} \__clistmap_rule_link:nw #1 \q_recursion_stop} \cs_new:Npn \__clistmap_rule_link:nw #1 % #2 % <{rule{1}}...> \q_recursion_stop {% \quark_if_recursion_tail_stop_do:nn{#2}{#1} \__clistmap_rule_link:nnw{#1}#2\q_recursion_stop} \cs_generate_variant:Nn\__clistmap_rule_link:nw{e} \cs_new:Npn \__clistmap_rule_link:nnw #1 % #2 % #3 % <{rule{2}}...> \q_recursion_stop {% \__clistmap_rule_link:ew {% \__clistmap_rule_link:nn {#1} % {#2} % } % #3 % <{rule{1}}...> \q_recursion_stop } \cs_new_protected:Nn \__clistmap_inline_set_exp_nnnot:Nn {\cs_set:Nn#1 {\exp_not:n {\exp_not:n {\exp_not:n{#2}}}}} \cs_generate_variant:Nn\__clistmap_inline_set_exp_nnnot:Nn{c} \cs_new:Nn\__clistmap_inline_c:n{__clistmap_#1:n} \cs_new:Nn\__clistmap_inline_use:n {%^^A BUG \use:c{\__clistmap_inline_c:n{#1}}} \cs_new_protected:Nn \__clistmap_inline_set_exp_nnnot:nn {\__clistmap_inline_set_exp_nnnot:cn {\__clistmap_inline_c:n{#1}}{#2}} \msg_new:nnn{__clistmap} {inline-empty-N} {instance~signature~must~be~empty~or~N;~got~'#1'} \msg_new:nnn{__clistmap} {inline-empty-args} {instance~signature=empty;~so~should~args=#1} \msg_new:nnn{__clistmap}{key} {no~match~for~#1~in~instance~or~instance~sequence} \msg_new:nnn{__clistmap}{signature-mismatch} {instance~signature~must~be~#1;~instances:~#2} \cs_new_protected:Npn \clistmap_inline:nnn #1 % #2 % #3 % {%^^A \bool_if:nTF { \__clistmap_instance_signature_p:nn{#2}{N} } {%^^A \__clistmap_inline_set_exp_nnnot:nn{a}{#3} \clistmap:nnn {#1} % {#2} % {\__clistmap_a:n} } {%^^A \bool_if:nTF { \__clistmap_instance_signature_p:nn{#2}{} } {%^^A \tl_if_empty:nTF {#3} {%^^A \clistmap:nnn {#1} % {#2} % {} } {%^^A \msg_error:nnnn{__clistmap} {inline-empty-args} {#3} } } {%^^A \msg_error:nnnn{__clistmap} {inline-empty-N} {#2} } } } \cs_new:Npn \clistmap:nnn #1 % #2 % #3 % {% \__clistmap_eval:nenn {#2} % ,... {\tl_if_head_is_group_p:n{#1}} % {#3} % {#1} % } \cs_generate_variant:Nn\clistmap:nnn{e,f,x} \cs_new:Npn \__clistmap_eval:nnnn #1 % ,... #2 % #3 % #4 % {% \exp_args:Ne \__clistmap_eval_aux:nnnn {\__clistmap_instance_expand:n{#1}} {#2} % {#3} % {#4} % } \cs_new:Npn \__clistmap_eval_aux:nnnn #1 % ,... #2 % #3 % #4 % {% \__clistmap_eval:nnnw {#2} % {#3} % {#4} % #1 % ,... , \q_recursion_tail \q_recursion_stop } \cs_generate_variant:Nn\__clistmap_eval:nnnn{ ne } \cs_new:Npn \__clistmap_eval:nnnw #1 % #2 % #3 % #4 % \q_recursion_stop {% \quark_if_recursion_tail_stop:n{#4} \__clistmap_eval:nnnnw {#1} % {#2} % {#3} % #4 % \q_recursion_stop } \cs_new:Npn \__clistmap_eval:nnnnw #1 % #2 % #3 % #4 % , #5 % \q_recursion_stop {% \exp_last_unbraced:Ne \__clistmap_eval:nnnnnn { \__clistmap_instance_get:n{#4} } {#1}{#2}{#3} \__clistmap_eval:nnnw {#1} % {#2} % {#3} % #5 % \q_recursion_stop } \cs_new:Npn \__clistmap_eval:nnnnnn #1 % #2 % #3 % #4 % #5 % #6 % {% \exp_args:Ne \clistmap_use_w:nnnn { \__clistmap_rule_sequence_name:n{#1} } % {#2} % {#3} % {#4} % #5 #6, \q_recursion_tail\q_recursion_stop } \msg_new:nnn{__clistmap} {chain}{unknown~chain~tag~#1} \cs_new_protected:Npn \__clistmap_append:NNN #1 % #2 % <\__clistmap_append(?:_inline):nnn> #3 % <\clistmap(?_inline):nnnn> {%^^A #1 #2 {%^^A \clistmap:nnn{##1}{##2}{##3} #3{##1} } } \__clistmap_append:NNN \cs_new:Nn \__clistmap_append:nnn \clistmap:nnnn \__clistmap_append:NNN \cs_new_protected:Nn \__clistmap_append_inline:nnn \clistmap_inline:nnnn \cs_new_protected:Npn \__clistmap_nest:NNN #1 % #2 % <\__clistmap_nest(?:_inline):nnn> #3 % <\clistmap(?_inline):nnnn> {%^^A #1 #2 {%^^A \exp_args:Ne #3{ \clistmap:nnn{##1}{##2}{##3} } } } \__clistmap_nest:NNN \cs_new:Nn \__clistmap_nest:nnn \clistmap:nnnn \__clistmap_nest:NNN \cs_new_protected:Nn \__clistmap_nest_inline:nnn \clistmap_inline:nnnn \cs_new_protected:Npn \__clistmap_join:NNNN #1 % #2 % <\__clistmap_join(?:_inline):nnnn> #3 % <\__clistmap_join(?:_inline):nnn> #4 % <\clistmap(?_inline):nnnn> {%^^A #1 #2 { #4{##1,##2}{##3}{##4} } #1 #3 { #2{\clistmap:nnn{##1}{##2}{##3}} } } \__clistmap_join:NNNN \cs_new:Nn \__clistmap_join:nnnn \__clistmap_join:nnn \clistmap:nnnn \__clistmap_join:NNNN \cs_new_protected:Nn \__clistmap_join_inline:nnnn \__clistmap_join_inline:nnn \clistmap_inline:nnnn \cs_new_protected:Npn \__clistmap_chain:NNNNN #1 % #2 % <__clistmap_chain(?:_inline):nnnn> #3 % <__clistmap_append(?:_inline):nnn> #4 % <__clistmap_nest(?:_inline):nnn> #5 % <__clistmap_join(?:_inline):nnn> {%^^A #1 #2 {%^^A \str_case:nnTF {##4} {%^^A {end} { \clistmap:nnn{##1}{##2}{##3} } {append} { #3{##1}{##2}{##3} } {nest} { #4{##1}{##2}{##3} } {join} { #5{##1}{##2}{##3} } } {} { \msg_error:nnn{__clistmap}{chain}{##4} } } } \__clistmap_chain:NNNNN \cs_new:Nn \clistmap:nnnn \__clistmap_append:nnn \__clistmap_nest:nnn \__clistmap_join:nnn \__clistmap_chain:NNNNN \cs_new_protected:Nn \__clistmap_inline_aux:nnnn \__clistmap_append_inline:nnn \__clistmap_nest_inline:nnn \__clistmap_join_inline:nnn \cs_new_protected:Npn \clistmap_inline:nnnn #1 % #2 % #3 % #4 % {%^^A \bool_if:nTF { \__clistmap_instance_signature_p:nn{#2}{N} } {%^^A \__clistmap_inline_set_exp_nnnot:nn{a}{#3} \__clistmap_inline_aux:nnnn{#1}{#2}{\__clistmap_a:n}{#4} } { \__clistmap_inline_aux:nnnn{#1}{#2}{}{#4} } } \cs_new:Npn \clistmap_use_w_group:nnnnnn #1 % #2 % #3 % #4 % #5 % #6 % {% \clistmap_use_w:nnnn {#1}{#2}{#3} {#4}#5{#6} } \cs_new:Npn \clistmap_use_w:nnnn #1 % #2 % #3 % #4 % {% \use:c{ \__clistmap_instance_c:nnn{#1}{#2}{#3} }{#4} } \cs_generate_variant:Nn\clistmap_use_w:nnnn{nnne} \cs_new:Npn \clistmap_use_w:nnnnn #1 % #2 % #3 % #4 % #5 % {% \use:c{% \__clistmap_instance_c_this:nnnn {#1} % {#2} % {#3} % {#4} % }{#5} } \cs_generate_variant:Nn\clistmap_use_w:nnnnn{nnnne} \cs_new:Npn \clistmap_bound_cs_group:nnnnn #1 % #2 % #3 % #4 % #5 % {\__clistmap_bound_cs:nnne{#1}{#2}{#4}{\bool_if:nTF{#3}{{#5}}{#5}}} \cs_generate_variant:Nn\clistmap_bound_cs_use_group:nnnnn{nnenn} \cs_new:Npn \__clistmap_bound_cs:nnnn #1 % #2 % #3 % #4 % { \use:c{\__clistmap_bound_cs_c:nn{#1}{#2}}#3{#4} } \cs_generate_variant:Nn\__clistmap_bound_cs:nnnn{nnne} \keys_define:nn{ __clistmap } { rule.code:n = \__clistmap_rule:nn#1 } \prop_new:N\__clistmap_rule_clist \__clistmap_info_clist_put:nn{rule}{__clistmap_rule_clist} \cs_new_protected:Npn \__clistmap_rule:nn #1 % #2 % {% \clist_gput_right:Nn\__clistmap_rule_clist{#1} \exp_args:Nno \cs_new_protected:cn { \__clistmap_rule_c:n{#1} } {% \__clistmap_rule_apply:nnnnnnnn {#1} % {} {#2} % {} {##1} % {##2} % {##3} % {{##4}{##5}{##6}} % % ^^A % ^^A {##7} % {##8} % #2 % #3 % #4 % #5 % #6 % {}{}{} #7 % #8 % {% \__clistmap_rule_apply:ennnnnn {\__clistmap_instance_c_this:nnnn{#1}{#3}{#4}{#5}} {#2}#6{#7}{#8} } \cs_new_protected:Npn \__clistmap_rule_apply:nnnnnnn #1 % #2 % #3 % #4 % #5 % #6 % #7 % {% \cs_if_exist:cF{#1} {%^^A \cs_new:cpn{#1} #3#7#5, #6\q_recursion_stop % {#2} } } \cs_generate_variant:Nn\__clistmap_rule_apply:nnnnnnn{e} \cs_new:Nn \__clistmap_quark_if_recursion_tail_stop:nn {\quark_if_recursion_tail_stop:n{#1#2}} \cs_generate_variant:Nn\__clistmap_quark_if_recursion_tail_stop:nn{e} \keys_define:nn{ __clistmap } {% rule_if_rest_is_tail_eval_else.code:n = {\__clistmap_rule_if_rest_is_tail_eval_else:nn#1} } \cs_new_protected:Npn \__clistmap_rule_if_rest_is_tail_eval_else:nn #1 % #2 % {% % ^^A ##1 % % ^^A ##2 % % ^^A ##3 % % ^^A ##4 % % ^^A ##5 % % ^^A ##6 % % ^^A ##7 % % ^^A ##8 % \clistmap_keys_set:n {% rule = {if_rest_is_tail_eval_else_#1} {% \quark_if_recursion_tail_stop_do:nn{##7} {% \clistmap_bound_cs_group:nnnnn {##2} % {##3} % {##4} % {##5} % {##6} % } #2 } } } \keys_define:nn { __clistmap } { rule_if_empty_stop_else.code:n = {\__clistmap_rule_if_empty_stop_else:nn#1} } \cs_new_protected:Npn \__clistmap_rule_if_empty_stop_else:nn #1 % #2 % {% % ^^A ##1 % % ^^A ##2 % % ^^A ##3 % % ^^A ##4 % % ^^A ##5 % % ^^A ##6 % % ^^A ##7 % % ^^A ##8 % \clistmap_keys_set:n {% rule = {if_empty_stop_else_#1} {% \__clistmap_quark_if_recursion_tail_stop:en {\bool_if:nTF{##4}{{##6}}{##6}}{##7} #2 } } } \cs_new_protected:Npn \__clistmap_instantiate:nnnn #1 % #2 % #3 % #4 % {% \exp_args:Ne \__clistmap_instantiate:nnnnn {\tl_count:n{#4}} % {#1} % {#2} % {#3} % {#4} % } \cs_new_protected:Npn \__clistmap_instantiate:nnnnn #1 % #2 % #3 % #4 % #5 % {%^^A \__clistmap_instantiate:eeeeennn { \erw_parameter:n{ 1 } } % { \erw_parameter:ne{2}{ #1 } } % { \erw_parameter:e{ \int_eval:n{#1+2} } } % { \erw_parameter:e{ \int_eval:n{#1+3} } } % { \erw_argument:ne{2}{ #5 } } % { #2 } % { #3 } % { #4 } % { #5 } % } \cs_new:Npn \__clistmap_instantiate:nnnnnnnn #1 % #2 % #3 % #4 % #5 % #6 % #7 % #8 % #9 % {% \use:c{ \__clistmap_rule_c:n{#6} } {#7} % {#8} % {#9} % {#1} % {#2} % {#3} % {#4} % {#2} % } \cs_generate_variant:Nn\__clistmap_instantiate:nnnnnnnn{eeeee} \cs_new:Npn \__clistmap_rule_sequence_name:n #1 % {% \__clistmap_rule_link:e {\__clistmap_rule_sequence_get:n{#1}{null}} } \keys_define:nn{__clistmap} { rule_sequence.code:n = \__clistmap_rule_sequence_from_keyval:n{#1} } \prop_new:N\__clistmap_rule_sequence_prop \__clistmap_info_prop_put:nn{rule_sequence}{__clistmap_rule_sequence_prop} \cs_new_protected:Npn \__clistmap_rule_sequence_from_keyval:n #1 % {% \prop_set_from_keyval:Nn \__clistmap_rule_sequence_prop{#1} } \cs_new:Npn \__clistmap_rule_sequence_get:n #1 % {% \exp_args:Ne \__clistmap_rule_sequence_aux:n {% \prop_item:Nn \__clistmap_rule_sequence_prop{#1} } } \cs_new:Npn \__clistmap_rule_sequence_aux:n #1 % {% \prop_if_in:NnTF \__clistmap_rule_sequence_prop {#1} {\__clistmap_rule_sequence_get:n{#1}} {#1} } \prg_new_conditional:Npnn \clistmap_instance:n #1 {p} {\prop_if_in:NnTF \__clistmap_instance_prop{#1} {\prg_return_true:} {\prg_return_false:} } \msg_new:nnn{__clistmap}{instance-not}{#1~is~not~an~instance} \msg_new:nnn{__clistmap}{key-conflict}{key~#1~already~exists~in~prop~#2} \prop_new:N\__clistmap_instance_prop \__clistmap_info_prop_put:nn{instance}{__clistmap_instance_prop} \cs_new_protected:Npn \__clistmap_instance_put:nnnn #1 % #2 % #3 % #4 % {% \prop_gput:Nnn \__clistmap_instance_prop{#1} { {#2}{#3}{#4} } } \cs_new:Npn \__clistmap_instance_get:n #1 % { \prop_item:Nn\__clistmap_instance_prop{#1} } \cs_new:Nn \clistmap_signature:n {%^^A \bool_if:nTF { \clistmap_instance_p:n{#1} } { \__clistmap_instance_signature_get:n{#1} } { \msg_error:nnn{__clistmap}{instance-not}{#1} } } \cs_new:Npn \__clistmap_instance_signature_get:n #1 % {\exp_last_unbraced:Ne\use_iii:nnn {\__clistmap_instance_get:n{#1}}} \cs_new:Npn \__clistmap_instance_expand:n #1 %^^A {%^^A \__clistmap_instance_expand:w #1, \q_recursion_tail \q_recursion_stop } \cs_new:Npn \__clistmap_instance_expand:w #1 %^^A ,#2 \q_recursion_stop { \quark_if_recursion_tail_stop:n{#1#2} \__clistmap_instance_expand:nw#1, #2\q_recursion_stop } \cs_new:Npn \__clistmap_instance_expand:nw #1 % , #2 % \q_recursion_stop { \bool_if:nTF {\clistmap_instance_sequence_p:n{#1}} {%^^A \exp_args:Ne \__clistmap_instance_expand:n { \__clistmap_instance_sequence_get:n{#1} } } {% \bool_if:nTF {\clistmap_instance_p:n{#1}} {#1} {\msg_error:nnn{__clistmap}{neither-inst-seq}{#1}} } \quark_if_recursion_tail_stop:n{#2},%^^A comma \__clistmap_instance_expand:nw#2\q_recursion_stop } \msg_new:nnn{__clistmap}{neither-inst-seq} {#1~is~neither~an~instance~nor~a~sequence} \prg_new_conditional:Npnn \__clistmap_instance_signature:nn #1 % #2 % {p} {%^^A \bool_if:nTF { \exp_args:Ne \__clistmap_instance_signature_aux_p:nn {%^^A \exp_args:Ne \clist_map_function:nN { \__clistmap_instance_expand:n{#1} } \clistmap_signature:n } {#2} } {\prg_return_true:} {\prg_return_false:} } \prg_new_conditional:Npnn \__clistmap_instance_signature_aux:nn #1 % #2 % {p} {% \tl_if_empty:nTF {#1} {%^^A \tl_if_empty:nTF{#2} {\prg_return_true:} {\prg_return_false:} } {%^^A \bool_if:nTF {%^^A \erw_and_tl_p:nn { \str_if_eq_p:nn{#2} } { #1 } } {\prg_return_true:} {\prg_return_false:} } } \keys_define:nn{ __clistmap } {%^^A instance_sequence.code:n = {%^^A \clist_map_function:nN{#1} \__clistmap_instance_sequence_put:n } } \prg_new_conditional:Npnn \clistmap_instance_sequence:n #1 {p} {% \prop_if_in:NnTF \__clistmap_instance_sequence_prop{#1} {\prg_return_true:} {\prg_return_false:} } \prop_new:N \__clistmap_instance_sequence_prop \__clistmap_info_prop_put:nn{instance_sequence}{__clistmap_instance_sequence_prop} \cs_new:Nn\__clistmap_first_braced:nn{{#1}} \cs_new:Nn\__clistmap_instance_sequence_keys: {% \prop_map_function:NN \__clistmap_instance_sequence_prop \__clistmap_first_braced:nn } \cs_new_protected:Npn \__clistmap_instance_sequence_put:n #1 % <{signature}{prefix key}{prefix key{1},...}> { \__clistmap_instance_sequence_put:nnn#1 } \cs_new:Npn \__clistmap_instance_sequence_value:nn #1 % #2 % {% \exp_args:Nne \erw_clist_tl:nn{\c_false_bool} {%^^A \clist_map_tokens:nn {#2} { \__clistmap_instance_sequence_value_aux:nn{#1} } } } \cs_new:Nn \__clistmap_instance_sequence_value_aux:nn {{\clistmap_instance_key:nn{#2}{#1}}} \cs_new_protected:Npn \__clistmap_instance_sequence_put:nnn #1 % #2 % #3 % ,... {%^^A \exp_args:Nee \__clistmap_instance_sequence_put:nn { \clistmap_instance_key:nn{#2}{#1} } { \__clistmap_instance_sequence_value:nn{#1}{#3} } } \cs_new_protected:Npn \__clistmap_instance_sequence_put:nn #1 % #2 % ,... {% \prop_if_in:NnTF \__clistmap_instance_prop{#1} {\msg_error:nnnn{__clistmap}{key-conflict}{#1}{instance}} {% \prop_gput:Nnn \__clistmap_instance_sequence_prop{#1} { #2 } } } \cs_new:Nn \clistmap_instance_sequence:n {\__clistmap_instance_sequence_get:n{#1}} \cs_new:Npn \__clistmap_instance_sequence_get:n #1 % {\prop_item:Nn\__clistmap_instance_sequence_prop{#1}} \keys_define:nn{__clistmap} { instance.code:n = \clist_map_function:nN{#1} \__clistmap_instance:n } \cs_new_protected:Npn \__clistmap_instance:n #1 % {}{key prefix}{}{} { \__clistmap_instance:nnnn#1 } \cs_new_protected:Npn \__clistmap_instance:nnnn #1 % #2 % #3 % #4 % {% \exp_args:Ne \__clistmap_instance_aux:nnnn { \clistmap_instance_key:nn{#2}{#1} } {#3}{#4}{#1} } \cs_new:Npn \clistmap_instance_key:nn #1 % #2 % {#1:#2} \cs_new_protected:Npn \__clistmap_instance_aux:nnnn #1 % #2 % #3 % #4 % {% \__clistmap_instance_put:nnnn{#1}{#2}{#3}{#4} \__clistmap_instance_using_key:nnn{#2}{#3}{#4} } \cs_new_protected:Npn \__clistmap_instance_using_key:nnn #1 % #2 % #3 % {% \__clistmap_instance_using_list:enn { \__clistmap_rule_sequence_get:n{#1}{null} } % <{rule{1}}...> {#2} % {#3}% } \cs_new_protected:Npn \__clistmap_instance_using_list:nnn #1 % <{rule{1}}{rule{2}}...> #2 % #3 % {% \exp_last_unbraced:Ne \__clistmap_instance_backward:nnnnn {% { \tl_count:n{#3} } % \erw_last:n{#1} % { \erw_remove_first:e{\tl_reverse:n{#1}} } % <{rule{n-1}}{rule{n-2}}...> } { #2 } % { #3 } % } \cs_generate_variant:Nn\__clistmap_instance_using_list:nnn{enn} \msg_new:nnn{__clistmap}{null} {clistmap~expects~'null'~as~the~last~rule;~got~'#1'} \cs_new_protected:Npn \__clistmap_instance_backward:nnnnn #1 % #2 % #3 % <{rule{n-1}}{rule{n-2}}...> #4 % #5 % {% \str_case:nnTF{#2} { {null}{} } {% \__clistmap_instance_backward:nnnw {#2} % {#4} % {#5} % #3\q_recursion_tail % <{rule{n}}{rule{n-1}}...> \q_recursion_stop } {% \msg_error:nnn{__clistmap} {null} {#2} } } \cs_generate_variant:Nn\__clistmap_instance_backward:nnnnn{eee} \cs_new_protected:Npn \__clistmap_instance_backward:nnnw #1 % #2 % #3 % #4 % <{rule{n}}{rule{n-1}}...> \q_recursion_stop {% \quark_if_recursion_tail_stop:n{#4} \__clistmap_instance_backward:nnnnw {#1} % {#2} % {#3} % #4 % % <{rule{n-1}}...> \q_recursion_stop } \cs_generate_variant:Nn\__clistmap_instance_backward:nnnw{e} \cs_new_protected:Npn \__clistmap_instance_backward:nnnnw #1 % #2 % #3 % #4 % #5 % <{rule{n-1}}...> \q_recursion_stop {% \__clistmap_instantiate:nnnn {#4} % {#1} % {#2} % {#3} % \__clistmap_instance_backward:ennw {\__clistmap_rule_link:nn{#4}{#1}} % {#2} % {#3} % #5 % <{rule{n}}...> \q_recursion_stop } \msg_new:nnn{__clistmap}{tail}{expects~tail;~got~'#1'} \clistmap_keys_set:n {% rule = {if_rest_is_tail_stop_else_eval_recurse} {% \quark_if_recursion_tail_stop:n{#7} \clistmap_bound_cs_group:nnnnn {#2} % {#3} % {#4} % {#5} % {#6} % \clistmap_use_w:nnnne {if_rest_is_tail_stop_else_eval_recurse} % {#1} % {#2} % {#3} % {\tl_if_head_is_group_p:n{#7}}#5#7\q_recursion_stop % }, rule = {if_rest_is_tail_stop_else_forward_rest} {% \quark_if_recursion_tail_stop:n{#7} \clistmap_use_w:nnne {#1}{#2}{#3} {\tl_if_head_is_group_p:n{#7}}#5#7\q_recursion_stop }, rule_if_empty_stop_else = {error} {% \msg_error:nnn{__clistmap}{tail}{#6#7} \__clistmap_empty:w{}\q_recursion_stop }, rule_if_empty_stop_else = {forward_head} {% \bool_if:nTF{#4} {% \clistmap_use_w_group:nnnnnn{#1}{#2}{#3}{#4}{#5}{#6} ,\q_recursion_tail\q_recursion_stop } {% \clistmap_use_w:nnnn{#1}{#2}{#3} {#4}#5#6,\q_recursion_tail\q_recursion_stop } }, rule_if_empty_stop_else = {forward_rest} {% \clistmap_use_w:nnne {#1}{#2}{#3} {\tl_if_head_is_group_p:n{#7}}#5#7\q_recursion_stop }, rule_if_empty_stop_else = {forward_all} {% \bool_if:nTF{#4} {% \clistmap_use_w_group:nnnnnn{#1}{#2}{#3}{#4}{#5}{#6}, #7\q_recursion_stop } {% \clistmap_use_w:nnnn {#1}{#2}{#3}{#4}#5#6, #7\q_recursion_stop } }, rule_if_rest_is_tail_eval_else = {error} {% \msg_error:nnn{__clistmap}{tail}{#6} \__clistmap_empty:w\q_recursion_stop }, rule_if_rest_is_tail_eval_else = {stop} {% \__clistmap_empty:w{}\q_recursion_stop }, rule_if_rest_is_tail_eval_else = {recurse} {% \clistmap_use_w:nnnne {if_rest_is_tail_eval_else_recurse} % {#1} % {#2} % {#3} % {\tl_if_head_is_group_p:n{#7}} % #5 % #7 % \q_recursion_stop } } \clistmap_keys_set:n {% rule_sequence = {% first = { {if_empty_stop_else_forward_head} {if_rest_is_tail_eval_else_error} }, middle = { {if_empty_stop_else_forward_all} {if_rest_is_tail_stop_else_forward_rest} {if_rest_is_tail_stop_else_eval_recurse} }, last = { {if_empty_stop_else_forward_all} {if_rest_is_tail_stop_else_forward_rest} {if_rest_is_tail_eval_else_recurse} }, serial_second = { {if_empty_stop_else_forward_all} {if_rest_is_tail_stop_else_forward_rest} {if_rest_is_tail_eval_else_stop} }, serial_last = { {if_empty_stop_else_forward_all} {if_rest_is_tail_stop_else_forward_rest} {if_rest_is_tail_stop_else_forward_rest} {if_rest_is_tail_eval_else_recurse} } } } \msg_new:nnnn{__clistmap}{text}{text~is~not~loaded}{amsmath} \cs_new:Nn\__clistmap_unbrace_aux:n{#1} \erw_keys_set:n { clist_map_inline = {% {Nn}{apply}{#1{#2}}, {Nn}{math}{\ensuremath{#1{#2}}}, {Nn}{comma_map}{,\clist_map_function:nN#2#1}, {Nn}{comma}{,#1{#2}}, {Nn}{serial_math}{\text{,~}\ensuremath{#1{#2}}}, {Nn}{serial_math_and}{\text{,~and~}\ensuremath{#1{#2}}}, {Nn}{map}{\clist_map_function:nN#2#1}, {Nn}{noindent}{\noindent}, {n}{apply}{#1}, {n}{math}{\ensuremath{#1}}, {n}{comma_math}{,\ensuremath{#1}}, {n}{newline}{\\#1}, {n}{comma_unbrace}{,\__clistmap_unbrace_aux:n#1}, {n}{comma}{,#1}, {n}{noindent}{\noindent}, {n}{serial_and}{,~and~#1}, {n}{serial_math_and}{\text{,~and~}\ensuremath{#1}}, {n}{serial_math}{\text{,~}\ensuremath{#1}}, {n}{serial}{,~#1}, {n}{unbrace}{\__clistmap_unbrace_aux:n#1} } {nnn} { \clist_gput_right:Nn\__clistmap_helper_clist{#2:#1} \cs_new:cn{__clistmap_#2:#1}{#3} } } \clistmap_keys_set:n { instance = { {N}{first_apply}{first}{__clistmap_apply}, {N}{first_map}{first}{__clistmap_map}, {N}{first_math}{first}{__clistmap_math}, {N}{first_noindent}{first}{__clistmap_noindent}, {N}{last_apply}{last}{__clistmap_apply}, {N}{last_comma_map}{last}{__clistmap_comma_map}, {N}{last_comma_math}{last}{__clistmap_comma_math}, {N}{last_comma}{last}{__clistmap_comma}, {N}{serial_last}{serial_last}{__clistmap_comma}, {N}{serial_second}{serial_second}{__clistmap_comma}, {N}{middle_apply}{middle}{__clistmap_apply}, {N}{middle_comma_map}{middle}{__clistmap_comma_map}, {N}{middle_comma_math}{middle}{__clistmap_comma_math}, {N}{middle_comma}{middle}{__clistmap_comma}, {N}{serial_last_math_and}{serial_last}{__clistmap_serial_math_and}, {N}{serial_middle_math}{middle}{__clistmap_serial_math}, {N}{serial_second_math_and}{serial_second}{__clistmap_serial_math_and}, {}{first_apply}{first}{__clistmap_apply}, {}{first_math}{first}{__clistmap_math}, {}{first_noindent}{first}{__clistmap_noindent}, {}{first_unbrace}{first}{__clistmap_unbrace}, {}{last_apply}{last}{__clistmap_apply}, {}{last_comma_math}{last}{__clistmap_comma_math}, {}{last_comma_unbrace}{last}{__clistmap_comma_unbrace}, {}{last_comma}{last}{__clistmap_comma}, {}{last_newline}{last}{__clistmap_newline}, {}{last_unbrace}{last}{__clistmap_unbrace}, {}{middle_apply}{middle}{__clistmap_apply}, {}{middle_comma_math}{middle}{__clistmap_comma_math}, {}{middle_comma_unbrace}{middle}{__clistmap_comma_unbrace}, {}{middle_comma}{middle}{__clistmap_comma}, {}{middle_newline}{middle}{__clistmap_newline}, {}{middle_unbrace}{middle}{__clistmap_unbrace}, {}{serial_last_and}{serial_last}{__clistmap_serial_and}, {}{serial_last_math_and}{serial_last}{__clistmap_serial_math_and}, {}{serial_middle_math}{middle}{__clistmap_serial_math}, {}{serial_middle}{middle}{__clistmap_serial}, {}{serial_second_and}{serial_second}{__clistmap_serial_and}, {}{serial_second_math_and}{serial_second}{__clistmap_serial_math_and}, } } \clistmap_keys_set:n {% instance_sequence = { {N}{apply}{first_apply, rest_apply}, {N}{comma_map}{first_map, rest_comma_map}, {N}{comma_math}{first_math, rest_comma_math}, {N}{comma}{first_apply, rest_comma}, {N}{rest_apply}{middle_apply, last_apply}, {N}{rest_comma_map}{middle_comma_map, last_comma_map}, {N}{rest_comma_math}{middle_comma_math, last_comma_math}, {N}{rest_comma}{middle_comma, last_comma}, {N}{serial_and}{first_apply, serial_rest_and}, {N}{serial_math_and}{first_math, serial_rest_math_and}, {N}{serial_rest_and}{serial_middle, serial_second_and, serial_last_and}, %^^A {N} {serial_rest_math_and} {serial_middle_math, serial_second_math_and, serial_last_math_and} %^^A , {}{apply}{first_apply, rest_apply}, {}{comma_math}{first_math, rest_comma_math}, {}{newline}{first_apply, rest_newline}, {}{comma_unbrace}{first_unbrace, rest_comma_unbrace}, {}{comma}{first_apply, rest_comma}, {}{rest_apply}{middle_apply, last_apply}, {}{rest_comma_math}{middle_comma_math, last_comma_math}, {}{rest_newline}{middle_newline, last_newline}, {}{rest_comma_unbrace}{middle_comma_unbrace, last_comma_unbrace}, {}{rest_comma}{middle_comma, last_comma}, {}{rest_unbrace}{middle_unbrace, last_unbrace}, {}{serial_and}{first_apply, serial_rest_and}, {}{serial_math_and}{first_apply, serial_rest_math_and}, {}{unbrace}{first_unbrace, rest_unbrace}, % ^^A {}{serial_rest_and} {serial_middle, serial_second_and, serial_last_and} % ^^A , % ^^A {}{serial_rest_math_and} {serial_middle_math, serial_second_math_and, serial_last_math_and} % ^^A } } \ProcessKeysOptions{__clistmap} \ExplSyntaxOff %% %% Copyright (C) 2022 by Erwann Rogard %% %% This work may be distributed and/or modified under the %% conditions of the LaTeX Project Public License (LPPL), either %% version 1.3c of this license or (at your option) any later %% version. The latest version of this license is in the file: %% %% http://www.latex-project.org/lppl.txt %% %% This work is "maintained" (as per LPPL maintenance status) by %% Erwann Rogard. %% %% This work consists of the file clistmap.dtx and the derived files: %% clistmap.sty, and clistmap.pdf. %% %% %% End of file `clistmap.sty'.