From 1404d03626d57bc9fd3aa74a865f568cd012147d Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Mon, 30 May 2022 20:10:02 +0000 Subject: l3 (30may22) git-svn-id: svn://tug.org/texlive/trunk@63449 c570f23f-e606-0410-a88d-b1316a301751 --- .../texmf-dist/tex/latex/l3kernel/expl3-code.tex | 33 ++- .../tex/latex/l3kernel/expl3-generic.tex | 2 +- Master/texmf-dist/tex/latex/l3kernel/expl3.ltx | 2 +- Master/texmf-dist/tex/latex/l3kernel/expl3.lua | 37 ++++ Master/texmf-dist/tex/latex/l3kernel/expl3.sty | 2 +- .../tex/latex/l3packages/l3keys2e/l3keys2e.sty | 2 +- Master/texmf-dist/tex/latex/l3packages/xfp/xfp.sty | 2 +- .../tex/latex/l3packages/xfrac/xfrac.sty | 3 +- .../tex/latex/l3packages/xparse/xparse.sty | 2 +- .../tex/latex/l3packages/xtemplate/xtemplate.sty | 243 ++++++++++++--------- 10 files changed, 214 insertions(+), 114 deletions(-) (limited to 'Master/texmf-dist/tex/latex') diff --git a/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex b/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex index 08d97cff671..bb26a016778 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex +++ b/Master/texmf-dist/tex/latex/l3kernel/expl3-code.tex @@ -70,7 +70,7 @@ %% and all files in that bundle must be distributed together. %% %% File: expl3.dtx -\def\ExplFileDate{2022-05-04}% +\def\ExplFileDate{2022-05-30}% \begingroup \def\next{\endgroup}% \expandafter\ifx\csname PackageError\endcsname\relax @@ -5022,12 +5022,12 @@ Type H for immediate help}\def~{\errmessage{% \cs_new:Npn \__str_case:nnTF #1#2#3#4 { \__str_case:nw {#1} #2 {#1} { } \s__str_mark {#3} \s__str_mark {#4} \s__str_stop } \cs_generate_variant:Nn \str_case:nn { V , o , nV , nv } +\prg_generate_conditional_variant:Nnn \str_case:nn + { V , o , nV , nv } { T , F , TF } \cs_new_eq:NN \str_case:Nn \str_case:Vn \cs_new_eq:NN \str_case:NnT \str_case:VnT \cs_new_eq:NN \str_case:NnF \str_case:VnF \cs_new_eq:NN \str_case:NnTF \str_case:VnTF -\prg_generate_conditional_variant:Nnn \str_case:nn - { V , o , nV , nv } { T , F , TF } \cs_new:Npn \__str_case:nw #1#2#3 { \str_if_eq:nnTF {#1} {#2} @@ -31504,6 +31504,16 @@ Type H for immediate help}\def~{\errmessage{% { \lua_shipout_e:n { \exp_not:n {#1} } } \cs_new:Npn \lua_escape:e #1 { \__lua_escape:n {#1} } \cs_new:Npn \lua_escape:n #1 { \lua_escape:e { \exp_not:n {#1} } } +\str_new:N \l__lua_err_msg_str +\cs_generate_variant:Nn \msg_error:nnnn { nnnV } +\cs_new_protected:Npn \lua_load_module:n #1 + { + \bool_if:nF { \__lua_load_module_p:n { #1 } } + { + \msg_error:nnnV + { luatex } { module-not-found } { #1 } { \l__lua_err_msg_str } + } + } \sys_if_engine_luatex:F { \clist_map_inline:nn @@ -31519,7 +31529,7 @@ Type H for immediate help}\def~{\errmessage{% } } \clist_map_inline:nn - { \lua_shipout_e:n , \lua_shipout:n } + { \lua_shipout_e:n , \lua_shipout:n, \lua_load_module:n } { \cs_set_protected:Npn #1 ##1 { @@ -31534,6 +31544,19 @@ Type H for immediate help}\def~{\errmessage{% The~feature~you~are~using~is~only~available~ with~the~LuaTeX~engine.~LaTeX3~ignored~'#1'. } + +\msg_new:nnnn { luatex } { module-not-found } + { Lua~module~`#1'~not~found. } + { + The~file~`#1.lua'~could~not~be~found.~Please~ensure~ + that~the~file~was~properly~installed~and~that~the~ + filename~database~is~current. \\ \\ + The~Lua~loader~provided~this~additional~information: \\ + #2 + } + +\prop_gput:Nnn \g_msg_module_name_prop { luatex } { LaTeX3 } +\prop_gput:Nnn \g_msg_module_type_prop { luatex } { } %% File: l3unicode.dtx \ior_new:N \g__char_data_ior \bool_lazy_or:nnTF { \sys_if_engine_luatex_p: } { \sys_if_engine_xetex_p: } @@ -33117,7 +33140,7 @@ Type H for immediate help}\def~{\errmessage{% \cs_new:cpn { __text_change_case_upper_hy-x-yiwn:nnnN } #1#2#3#4 { \__text_change_case_char:nnnN {#1} {#2} {#3} #4 } \cs_new_eq:cc { __text_change_case_title_hy-x-yiwn:nnnN } - { __text_change_case_upper_hy-x-yiwm:nnnN } + { __text_change_case_upper_hy-x-yiwn:nnnN } } \bool_lazy_or:nnT { \sys_if_engine_luatex_p: } diff --git a/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex b/Master/texmf-dist/tex/latex/l3kernel/expl3-generic.tex index fe6d8d57096..5045760ad1d 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{2022-05-04}% +\def\ExplFileDate{2022-05-30}% \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 46d3ff329cf..eb42bb11909 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{2022-05-04}% +\def\ExplFileDate{2022-05-30}% \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 10cec935888..f965f88979c 100644 --- a/Master/texmf-dist/tex/latex/l3kernel/expl3.lua +++ b/Master/texmf-dist/tex/latex/l3kernel/expl3.lua @@ -50,6 +50,9 @@ local cprint = tex.cprint local write = tex.write local write_nl = texio.write_nl local utf8_char = utf8.char +local package_loaded = package.loaded +local package_searchers = package.searchers +local table_concat = table.concat local scan_int = token.scan_int or token.scan_integer local scan_string = token.scan_string @@ -57,6 +60,7 @@ local scan_keyword = token.scan_keyword local put_next = token.put_next local token_create = token.create local token_new = token.new +local set_macro = token.set_macro local token_create_safe do local is_defined = token.is_defined @@ -217,6 +221,39 @@ local luacmd do end end end +local function try_require(name) + if package_loaded[name] then + return true, package_loaded[name] + end + + local failure_details = {} + for _, searcher in ipairs(package_searchers) do + local loader, data = searcher(name) + if type(loader) == 'function' then + package_loaded[name] = loader(name, data) or true + return true, package_loaded[name] + elseif type(loader) == 'string' then + failure_details[#failure_details + 1] = loader + end + end + + return false, table_concat(failure_details, '\n') +end +local char_given = command_id'char_given' +local c_true_bool = token_create(1, char_given) +local c_false_bool = token_create(0, char_given) +local c_str_cctab = token_create('c_str_cctab').mode + +luacmd('__lua_load_module_p:n', function() + local success, result = try_require(scan_string()) + if success then + set_macro(c_str_cctab, 'l__lua_err_msg_str', '') + put_next(c_true_bool) + else + set_macro(c_str_cctab, 'l__lua_err_msg_str', result) + put_next(c_false_bool) + end +end) local register_luadata, get_luadata if luatexbase then diff --git a/Master/texmf-dist/tex/latex/l3kernel/expl3.sty b/Master/texmf-dist/tex/latex/l3kernel/expl3.sty index 67067310390..04df7d9a5f1 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{2022-05-04}% +\def\ExplFileDate{2022-05-30}% \let\ExplLoaderFileDate\ExplFileDate \ProvidesPackage{expl3} [% diff --git a/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty b/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty index 80171d5a50a..31567e5d648 100644 --- a/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty +++ b/Master/texmf-dist/tex/latex/l3packages/l3keys2e/l3keys2e.sty @@ -32,7 +32,7 @@ }% \endinput } -\ProvidesExplPackage{l3keys2e}{2022-01-12}{} +\ProvidesExplPackage{l3keys2e}{2022-05-30}{} {LaTeX2e option processing using LaTeX3 keys} \cs_if_exist:NT \ProcessKeysOptions { \file_input_stop: } diff --git a/Master/texmf-dist/tex/latex/l3packages/xfp/xfp.sty b/Master/texmf-dist/tex/latex/l3packages/xfp/xfp.sty index c611d9ad25d..38bf65a5434 100644 --- a/Master/texmf-dist/tex/latex/l3packages/xfp/xfp.sty +++ b/Master/texmf-dist/tex/latex/l3packages/xfp/xfp.sty @@ -32,7 +32,7 @@ }% \endinput } -\ProvidesExplPackage{xfp}{2022-01-12}{} +\ProvidesExplPackage{xfp}{2022-05-30}{} {L3 Floating point unit} \ProvideExpandableDocumentCommand \fpeval { m } { \fp_eval:n {#1} } \ProvideExpandableDocumentCommand \inteval { m } { \int_eval:n {#1} } diff --git a/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty b/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty index 28d3378f4b2..5d477450e87 100644 --- a/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty +++ b/Master/texmf-dist/tex/latex/l3packages/xfrac/xfrac.sty @@ -34,7 +34,7 @@ \endinput } \RequirePackage{amstext,graphicx,l3keys2e,textcomp,xparse,xtemplate} -\ProvidesExplPackage{xfrac}{2022-01-12}{} +\ProvidesExplPackage{xfrac}{2022-05-30}{} {L3 Experimental split-level fractions} \keys_define:nn { xfrac } { @@ -156,7 +156,6 @@ v-scale = \l__xfrac_vscale_fp } { - \AssignTemplateKeys \mode_if_math:TF { \cs_set_eq:NN \__xfrac_text_or_math:n \text diff --git a/Master/texmf-dist/tex/latex/l3packages/xparse/xparse.sty b/Master/texmf-dist/tex/latex/l3packages/xparse/xparse.sty index e33f73226c5..b57a85d5d27 100644 --- a/Master/texmf-dist/tex/latex/l3packages/xparse/xparse.sty +++ b/Master/texmf-dist/tex/latex/l3packages/xparse/xparse.sty @@ -60,7 +60,7 @@ } } \ExplSyntaxOff -\ProvidesExplPackage{xparse}{2022-01-12}{} +\ProvidesExplPackage{xparse}{2022-05-30}{} {L3 Experimental document command parser} \clist_new:N \l__cmd_options_clist \DeclareOption* { \clist_put_right:NV \l__cmd_options_clist \CurrentOption } diff --git a/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty b/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty index 80d22378628..5350f7b32cd 100644 --- a/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty +++ b/Master/texmf-dist/tex/latex/l3packages/xtemplate/xtemplate.sty @@ -32,8 +32,10 @@ }% \endinput } -\ProvidesExplPackage{xtemplate}{2022-01-12}{} +\ProvidesExplPackage{xtemplate}{2022-05-30}{} {L3 Experimental prototype document functions} +\cs_generate_variant:Nn \keys_define:nn { nx } +\cs_generate_variant:Nn \tl_trim_spaces:n { e } \tl_const:Nn \c__xtemplate_code_root_tl { template~code~>~ } \tl_const:Nn \c__xtemplate_defaults_root_tl { template~defaults~>~ } \tl_const:Nn \c__xtemplate_instances_root_tl { template~instance~>~ } @@ -125,12 +127,6 @@ \cs_generate_variant:Nn \__xtemplate_if_key_value:nT { o } \cs_generate_variant:Nn \__xtemplate_if_key_value:nF { o } \cs_generate_variant:Nn \__xtemplate_if_key_value:nTF { o } -\prg_new_conditional:Npnn \__xtemplate_if_eval_now:n #1 { TF } - { - \str_if_eq:noTF { \EvaluateNow } { \tl_head:w #1 \q_nil \q_stop } - { \prg_return_true: } - { \prg_return_false: } - } \prg_new_conditional:Npnn \__xtemplate_if_instance_exist:nnn #1#2#3 { T, F, TF } { @@ -326,7 +322,6 @@ { \exp_not:N \bool_set_false:N \exp_not:N \l__xtemplate_error_bool \tl_set:Nn \exp_not:N \l__xtemplate_tmp_tl {#1} - \tl_remove_all:Nn \exp_not:N \l__xtemplate_tmp_tl { ~ } \tl_replace_all:Nnn \exp_not:N \l__xtemplate_tmp_tl { : } { \token_to_str:N : } \tl_if_in:onTF \exp_not:N \l__xtemplate_tmp_tl { \token_to_str:N : } { @@ -348,7 +343,10 @@ ##1 \token_to_str:N : ##2 \s__xtemplate_stop { \tl_put_right:Nx \exp_not:N \l__xtemplate_key_name_tl - { \exp_not:N \tl_to_str:n {##1} } + { + \exp_not:N \tl_trim_spaces:e + { \exp_not:N \tl_to_str:n {##1} } + } \tl_if_in:nnTF {##2} { \token_to_str:N : } { \tl_put_right:Nn \exp_not:N \l__xtemplate_key_name_tl @@ -393,34 +391,14 @@ \cs_new:Npn \__xtemplate_split_keytype_arg_aux:n #1 { } \cs_new:Npn \__xtemplate_split_keytype_arg_aux:w #1 \s__xtemplate_stop { } \cs_new_protected:Npn \__xtemplate_store_value_boolean:n #1 - { - \__xtemplate_if_eval_now:nTF {#1} - { - \bool_if:cTF { c_ #1 _bool } - { - \prop_put:Non \l__xtemplate_values_prop \l__xtemplate_key_name_tl - { true } - } - { - \prop_put:Non \l__xtemplate_values_prop \l__xtemplate_key_name_tl - { false } - } - } - { - \prop_put:Non \l__xtemplate_values_prop \l__xtemplate_key_name_tl {#1} - } - } + { \prop_put:Non \l__xtemplate_values_prop \l__xtemplate_key_name_tl {#1} } \cs_new_protected:Npn \__xtemplate_store_value_code:n #1 { \prop_put:Non \l__xtemplate_values_prop \l__xtemplate_key_name_tl {#1} } \cs_new_eq:NN \__xtemplate_store_value_choice:n \__xtemplate_store_value_code:n \cs_new_eq:NN \__xtemplate_store_value_function:n \__xtemplate_store_value_code:n \cs_new_eq:NN \__xtemplate_store_value_instance:n \__xtemplate_store_value_code:n \cs_new_protected:Npn \__xtemplate_store_value_aux:Nn #1#2 - { - \__xtemplate_if_eval_now:nTF {#2} - { \prop_put:NVx \l__xtemplate_values_prop \l__xtemplate_key_name_tl { #1 {#2} } } - { \prop_put:Non \l__xtemplate_values_prop \l__xtemplate_key_name_tl {#2} } - } + { \prop_put:Non \l__xtemplate_values_prop \l__xtemplate_key_name_tl {#2} } \cs_new_protected:Npn \__xtemplate_store_value_integer:n { \__xtemplate_store_value_aux:Nn \int_eval:n } \cs_new_protected:Npn \__xtemplate_store_value_length:n @@ -443,21 +421,30 @@ \__xtemplate_if_keys_exist:nnT {#1} {#2} { \__xtemplate_store_key_implementation:nnn {#1} {#2} {#4} - \cs_generate_from_arg_count:cNnn - { \c__xtemplate_code_root_tl #1 / #2 } - \cs_gset_protected:Npn {#3} {#5} + \regex_match:nnTF { \c { AssignTemplateKeys } } {#5} + { \__xtemplate_declare_template_code:nnn { #1 / #2 } {#3} {#5} } + { + \__xtemplate_declare_template_code:nnn + { #1 / #2 } {#3} { \AssignTemplateKeys #5 } + } } } } } +\cs_new_protected:Npn \__xtemplate_declare_template_code:nnn #1#2#3 + { + \cs_generate_from_arg_count:cNnn + { \c__xtemplate_code_root_tl #1 } + \cs_gset_protected:Npn {#2} {#3} + } \cs_new_protected:Npn \__xtemplate_store_key_implementation:nnn #1#2#3 { \__xtemplate_recover_defaults:n { #1 / #2 } \__xtemplate_recover_restrictions:n { #1 / #2 } \__xtemplate_recover_keytypes:n { #1 / #2 } \prop_clear:N \l__xtemplate_vars_prop - \keyval_parse:NNn - \__xtemplate_parse_vars_elt:n \__xtemplate_parse_vars_elt:nn {#3} + \keyval_parse:nnn + { \__xtemplate_parse_vars_elt:n } { \__xtemplate_parse_vars_elt:nnn { #1 / #2 } } {#3} \__xtemplate_store_vars:n { #1 / #2 } \__xtemplate_store_restrictions:n { #1 / #2 } \prop_map_inline:Nn \l__xtemplate_keytypes_prop @@ -468,93 +455,130 @@ } \cs_new_protected:Npn \__xtemplate_parse_vars_elt:n #1 { \msg_error:nnx { xtemplate } { key-no-variable } {#1} } -\cs_new_protected:Npn \__xtemplate_parse_vars_elt:nn #1#2 +\cs_new_protected:Npn \__xtemplate_parse_vars_elt:nnn #1#2#3 { - \tl_set:Nx \l__xtemplate_key_name_tl { \tl_to_str:n {#1} } - \tl_remove_all:Nn \l__xtemplate_key_name_tl { ~ } + \tl_set:Nx \l__xtemplate_key_name_tl + { \tl_trim_spaces:e { \tl_to_str:n {#2} } } \prop_get:NoNTF \l__xtemplate_keytypes_prop \l__xtemplate_key_name_tl \l__xtemplate_keytype_tl { \__xtemplate_split_keytype_arg:o \l__xtemplate_keytype_tl - \__xtemplate_parse_vars_elt_aux:n {#2} + \__xtemplate_parse_vars_elt_aux:nn {#1} {#3} \prop_remove:NV \l__xtemplate_keytypes_prop \l__xtemplate_key_name_tl } - { \msg_error:nnx { xtemplate } { unknown-key } {#1} } + { \msg_error:nnx { xtemplate } { unknown-key } {#2} } + } +\cs_new_protected:Npn \__xtemplate_parse_vars_elt_aux:nn #1#2 + { + \__xtemplate_parse_vars_elt_aux:nw {#1} #2 global global \s__xtemplate_stop + } +\cs_new_protected:Npn \__xtemplate_parse_vars_elt_aux:nw + #1#2 global #3 global #4 \s__xtemplate_stop + { + \tl_if_blank:nTF {#4} + { \__xtemplate_parse_vars_elt_aux:nnn {#1} { } {#2} } + { + \tl_if_blank:nTF {#2} + { + \exp_args:Nnnx \__xtemplate_parse_vars_elt_aux:nnn + {#1} { global } { \tl_trim_spaces:n {#3} } + } + { \msg_error:nnn { xtemplate } { bad-variable } { #2 global #3 } } + } } -\cs_new_protected:Npn \__xtemplate_parse_vars_elt_aux:n #1 +\cs_new_protected:Npn \__xtemplate_parse_vars_elt_aux:nnn #1#2#3 { - \str_if_eq:onTF \l__xtemplate_keytype_tl { choice } - { \__xtemplate_implement_choices:n {#1} } + \str_case:VnF \l__xtemplate_keytype_tl { - \str_if_eq:onTF \l__xtemplate_keytype_tl { code } + { choice } { \__xtemplate_implement_choices:nn {#1} {#3} } + { code } { + \__xtemplate_parse_vars_elt_key:nn {#1} + { + .cs_ \str_if_eq:nnT {#1} { global } { g } + set_protected:Np = \exp_not:N #3 + } \prop_put:Non \l__xtemplate_vars_prop - \l__xtemplate_key_name_tl {#1} + \l__xtemplate_key_name_tl {#2#3} } + { function } { - \tl_if_single:nTF {#1} + \cs_if_exist:NF #3 + { \cs_new:Npn #3 { } } + \__xtemplate_parse_vars_elt_key:nn {#1} { - \cs_if_exist:NF #1 - { \__xtemplate_create_variable:N #1 } - \prop_put:Non \l__xtemplate_vars_prop - \l__xtemplate_key_name_tl {#1} + .code:n = + { + \exp_not:c + { cs_ \str_if_eq:nnT {#1} { global } { g } seq_eq:NN } + \exp_not:N #3 ####1 + } } + \prop_put:Non \l__xtemplate_vars_prop + \l__xtemplate_key_name_tl {#2#3} + } + { instance } + { + \__xtemplate_parse_vars_elt_key:nn {#1} { - \tl_if_in:nnTF {#1} { global } - { \__xtemplate_parse_vars_elt_aux:w #1 \s__xtemplate_stop } + .code:n = { - \msg_error:nnx { xtemplate } { bad-variable } - { \tl_to_str:n {#1} } + \exp_not:c + { cs_ \str_if_eq:nnT {#1} { global } { g } set:Npn } + \exp_not:N #3 { \UseInstance {####1} } } } + \prop_put:Non \l__xtemplate_vars_prop + \l__xtemplate_key_name_tl {#2#3} } } - } -\cs_new_protected:Npn \__xtemplate_parse_vars_elt_aux:w #1 global #2 \s__xtemplate_stop - { - \tl_if_empty:nTF {#1} { - \tl_if_single:nTF {#2} + \tl_if_single:nTF {#3} { - \cs_if_exist:NF #2 - { \__xtemplate_create_variable:N #2 } + \cs_if_exist:NF #3 + { \use:c { \__xtemplate_map_var_type: _new:N } #3 } + \__xtemplate_parse_vars_elt_key:nn {#1} + { + . \__xtemplate_map_var_type: + _ \str_if_eq:nnT {#1} { global } { g } set:N + = \exp_not:N #3 + } \prop_put:Non \l__xtemplate_vars_prop - \l__xtemplate_key_name_tl { #1 global #2 } + \l__xtemplate_key_name_tl {#2#3} } - { - \msg_error:nnx { xtemplate } { bad-variable } - { \tl_to_str:n { #1 global #2 } } - } - } - { - \msg_error:nnx { xtemplate } { bad-variable } - { \tl_to_str:n { #1 global #2 } } + { \msg_error:nnx { xtemplate } { bad-variable } { #2#3 } } } } -\cs_new_protected:Npn \__xtemplate_create_variable:N #1 +\cs_new_protected:Npn \__xtemplate_parse_vars_elt_key:nn #1#2 + { + \keys_define:nx { template / #1 } + { \l__xtemplate_key_name_tl #2 } + } +\cs_new:Npn \__xtemplate_map_var_type: { - \str_case:onF \l__xtemplate_keytype_tl + \str_case:on \l__xtemplate_keytype_tl { - { boolean } { \bool_new:N #1 } - { commalist } { \clist_new:N #1 } - { function } { \cs_new:Npn #1 { } } - { instance } { \cs_new_protected:Npn #1 { } } - { integer } { \int_new:N #1 } - { length } { \dim_new:N #1 } - { real } { \fp_new:N #1 } - { tokenlist } { \tl_new:N #1 } + { boolean } { bool } + { commalist } { clist } + { integer } { int } + { length } { dim } + { muskip } { muskip } + { real } { fp } + { skip } { skip } + { tokenlist } { tl } } - { \use:c { \l__xtemplate_keytype_tl _ new:N } #1 } } -\cs_new_protected:Npn \__xtemplate_implement_choices:n #1 +\cs_new_protected:Npn \__xtemplate_implement_choices:nn #1#2 { \clist_set:No \l__xtemplate_tmp_clist { \l__xtemplate_keytype_arg_tl } \prop_put:Non \l__xtemplate_vars_prop \l__xtemplate_key_name_tl { } - \keyval_parse:NNn - \__xtemplate_implement_choice_elt:n \__xtemplate_implement_choice_elt:nn - {#1} + \keys_define:nx { template / #1 } { \l__xtemplate_key_name_tl .choice: } + \keyval_parse:nnn + { \__xtemplate_implement_choice_elt:n } + { \__xtemplate_implement_choice_elt:nnn {#1} } + {#2} \prop_get:NoNT \l__xtemplate_values_prop \l__xtemplate_key_name_tl \l__xtemplate_tmp_tl { \__xtemplate_implement_choices_default: } @@ -588,39 +612,49 @@ } } } -\cs_new_protected:Npn \__xtemplate_implement_choice_elt:n #1 +\cs_new_protected:Npn \__xtemplate_implement_choice_elt:nnn #1#2#3 { \clist_if_empty:NTF \l__xtemplate_tmp_clist { - \str_if_eq:nnF {#1} { unknown } + \str_if_eq:nnTF {#2} { unknown } + { \__xtemplate_implement_choice_elt_aux:nnn {#1} {#2} {#3} } { \prop_get:NoN \l__xtemplate_keytypes_prop \l__xtemplate_key_name_tl \l__xtemplate_tmp_tl \__xtemplate_split_keytype_arg:o \l__xtemplate_tmp_tl \msg_error:nnxxx { xtemplate } { unknown-choice } - { \l__xtemplate_key_name_tl } {#1} + { \l__xtemplate_key_name_tl } {#2} { \l__xtemplate_keytype_arg_tl } } } { - \clist_if_in:NnTF \l__xtemplate_tmp_clist {#1} - { \clist_remove_all:Nn \l__xtemplate_tmp_clist {#1} } + \clist_if_in:NnTF \l__xtemplate_tmp_clist {#2} + { + \clist_remove_all:Nn \l__xtemplate_tmp_clist {#2} + \__xtemplate_implement_choice_elt_aux:nnn {#1} {#2} {#3} + } { \prop_get:NoN \l__xtemplate_keytypes_prop \l__xtemplate_key_name_tl \l__xtemplate_tmp_tl \__xtemplate_split_keytype_arg:o \l__xtemplate_tmp_tl \msg_error:nnxxx { xtemplate } { unknown-choice } - { \l__xtemplate_key_name_tl } {#1} + { \l__xtemplate_key_name_tl } {#2} { \l__xtemplate_keytype_arg_tl } } } } -\cs_new_protected:Npn \__xtemplate_implement_choice_elt:nn #1#2 +\cs_new_protected:Npn \__xtemplate_implement_choice_elt_aux:nnn #1#2#3 { - \__xtemplate_implement_choice_elt:n {#1} + \keys_define:nx { template / #1 } + { \l__xtemplate_key_name_tl / #2 .code:n = { \exp_not:n {#3} } } \tl_set:Nx \l__xtemplate_tmp_tl - { \l__xtemplate_key_name_tl \c_space_tl #1 } - \prop_put:Non \l__xtemplate_vars_prop \l__xtemplate_tmp_tl {#2} + { \l__xtemplate_key_name_tl \c_space_tl #2 } + \prop_put:Non \l__xtemplate_vars_prop \l__xtemplate_tmp_tl {#3} + } +\cs_new_protected:Npn \__xtemplate_implement_choice_elt:n #1 + { + \msg_error:nnxxx { xtemplate } { choice-requires-code } + { \l__xtemplate_key_name_tl } {#1} } \cs_new_protected:Npn \__xtemplate_declare_restricted:nnnn #1#2#3#4 { @@ -665,8 +699,8 @@ } \cs_new_protected:Npn \__xtemplate_parse_values_elt:nn #1#2 { - \tl_set:Nx \l__xtemplate_key_name_tl { \tl_to_str:n {#1} } - \tl_remove_all:Nn \l__xtemplate_key_name_tl { ~ } + \tl_set:Nx \l__xtemplate_key_name_tl + { \tl_trim_spaces:e { \tl_to_str:n {#1} } } \prop_get:NoNTF \l__xtemplate_keytypes_prop \l__xtemplate_key_name_tl \l__xtemplate_tmp_tl { @@ -980,8 +1014,7 @@ { \exp_after:wN \__xtemplate_key_to_value_auxi:w \l__xtemplate_value_tl } \cs_new_protected:Npn \__xtemplate_key_to_value_auxi:w \KeyValue #1 { - \tl_set:Nx \l__xtemplate_tmp_tl { \tl_to_str:n {#1} } - \tl_remove_all:Nn \l__xtemplate_key_name_tl { ~ } + \tl_set:Nx \l__xtemplate_tmp_tl { \tl_trim_spaces:e { \tl_to_str:n {#1} } } \prop_get:NoNTF \l__xtemplate_vars_prop \l__xtemplate_tmp_tl @@ -1132,6 +1165,13 @@ each~choice~name~must~have~an~associated~implementation.\\ This~should~be~given~after~a~'='~sign:~LaTeX~did~not~find~one. } +\msg_new:nnnn { xtemplate } { choice-requires-code } + { The~choice~'#2'~for~key~'#1'~requires~an~implementation. } + { + You~should~have~put:\\ + \ \ #1~:~choice~{~#2 = ~} \\ + but~LaTeX~did~not~find~any~. + } \msg_new:nnnn { xtemplate } { duplicate-key-interface } { Key~'#1'~appears~twice~in~interface~definition~\msg_line_context:. } { @@ -1320,10 +1360,11 @@ { \__xtemplate_if_instance_exist:nnnT {#1} { } {#2} } \cs_new:Npn \IfInstanceExistF #1#2 { \__xtemplate_if_instance_exist:nnnF {#1} { } {#2} } -\cs_new_protected:Npn \EvaluateNow #1 {#1} \cs_new_protected:Npn \KeyValue #1 {#1} \cs_new_protected:Npn \AssignTemplateKeys { \__xtemplate_assignments_pop: } +\cs_new_protected:Npn \SetTemplateKeys #1#2#3 + { \keys_set:nn { template / #1 / #2 } {#3} } \cs_new_eq:NN \ShowTemplateKeytypes \ShowTemplateInterface %% %% -- cgit v1.2.3