diff options
author | Karl Berry <karl@freefriends.org> | 2009-06-14 18:00:54 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2009-06-14 18:00:54 +0000 |
commit | d88fd922cc82efa8efbbc59d5dfc3830567abb9b (patch) | |
tree | 6f455fe1f9b19d923c5a70ba81c1c14f4662fe75 /Master/texmf-dist/tex | |
parent | b9d7958e66727425075266e52ba598759a3edecc (diff) |
keys3 110 (12jun09)
git-svn-id: svn://tug.org/texlive/trunk@13738 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex')
-rw-r--r-- | Master/texmf-dist/tex/latex/keys3/keys3.sty | 860 |
1 files changed, 290 insertions, 570 deletions
diff --git a/Master/texmf-dist/tex/latex/keys3/keys3.sty b/Master/texmf-dist/tex/latex/keys3/keys3.sty index 140e038463e..d6881765f8d 100644 --- a/Master/texmf-dist/tex/latex/keys3/keys3.sty +++ b/Master/texmf-dist/tex/latex/keys3/keys3.sty @@ -21,647 +21,367 @@ %% Do not distribute a modified version of this file. %% \RequirePackage{expl3} -\GetIdInfo$Id: keys3.dtx 101 2009-06-10 12:16:20Z josephwright $ +\GetIdInfo$Id: keys3.dtx 110 2009-06-12 21:27:24Z josephwright $ {Key management for LaTeX3} \ProvidesExplPackage {\filename}{\filedate}{\fileversion}{\filedescription} -\tl_new:cn { c_keys_0_empty_tl } {} -\tl_new:cn { c_keys_1_empty_tl } { {} } -\tl_new:cn { c_keys_2_empty_tl } { {} {} } -\tl_new:cn { c_keys_3_empty_tl } { {} {} {} } -\tl_new:cn { c_keys_4_empty_tl } { {} {} {} {} } -\tl_new:cn { c_keys_5_empty_tl } { {} {} {} {} {} } -\tl_new:cn { c_keys_6_empty_tl } { {} {} {} {} {} {} } -\tl_new:cn { c_keys_7_empty_tl } { {} {} {} {} {} {} {} } -\tl_new:cn { c_keys_8_empty_tl } { {} {} {} {} {} {} {} {} } -\tl_new:cn { c_keys_9_empty_tl } { {} {} {} {} {} {} {} {} {} } -\tl_new:Nn \c_keys_cs_prefix_tl { keys-root } -\tl_new:Nn \c_keys_errors_path_tl { /keys/errors } -\tl_new:Nn \c_keys_properties_path_tl { /keys/properties } -\tl_new:Nn \c_keys_utilities_path_tl { /keys } -\tl_new:Nn \c_keys_root_tl { / } -\tl_new:N \l_keys_choice_code_tl -\tl_new:N \l_keys_current_choice_tl -\int_new:N \l_keys_current_choice_int -\tl_new:N \l_keys_current_key_full_tl -\tl_new:N \l_keys_current_default_tl -\tl_new:N \l_keys_current_module_tl -\tl_new:N \l_keys_current_path_tl -\tl_new:N \l_keys_default_path_tl -\tl_set_eq:NN \l_keys_default_path_tl \c_keys_root_tl -\tl_new:N \l_keys_choice_path_tl -\toks_new:N \l_keys_current_value_toks +\tl_new:Nn \c_keys_root_tl { keys~>~ } +\tl_new:Nn \c_keys_properties_root_tl { keys_properties } +\tl_new:Nn \c_keys_value_forbidden_tl { forbidden } +\tl_new:Nn \c_keys_value_required_tl { required } +\int_new:N \l_keys_choice_int +\tl_new:N \l_keys_choice_tl +\tl_new:N \l_keys_key_tl +\tl_new:N \l_keys_path_tl +\tl_new:N \l_keys_module_tl \bool_new:N \l_keys_no_value_bool -\bool_new:N \l_keys_success_bool -\tl_new:N \l_keys_tmpa_tl -\cs_new:Nn \keys_manage:n { - \cs_set_eq:NN \keys_parse:n \KV_parse_space_removal_sanitize:n - \tl_clear:N \l_keys_current_module_tl - \keys_manage_internal:n {#1} -} -\cs_new:Nn \keys_manage_quick:n { - \cs_set_eq:NN \keys_parse:n \KV_parse_no_space_removal_no_sanitize:n - \tl_clear:N \l_keys_current_module_tl - \keys_manage_internal:n {#1} -} -\cs_new:Nn \keys_manage_internal:n { - \keys_manage_aux:Vn \l_keys_default_path_tl {#1} -} -\cs_new:Nn \keys_manage_aux:nn { - \tl_set_eq:NN \l_keys_default_path_tl \c_keys_root_tl - \keys_parse_list:n {#2} - \tl_set:Nn \l_keys_default_path_tl {#1} -} -\cs_generate_variant:Nn \keys_manage_aux:nn { Vn } -\cs_new:Nn \keys_manage:nn { - \cs_set_eq:NN \keys_parse:n \KV_parse_space_removal_sanitize:n - \keys_manage_aux:Vnn \l_keys_default_path_tl {#1} {#2} -} -\cs_new:Nn \keys_manage_quick:nn { - \cs_set_eq:NN \keys_parse:n \KV_parse_space_no_removal_no_sanitize:n - \keys_manage_aux:Vnn \l_keys_default_path_tl {#1} {#2} -} -\cs_new:Nn \keys_manage_aux:nnn { - \tl_set:Nn \l_keys_default_path_tl {#2} - \tl_clear:N \l_keys_current_module_tl - \keys_parse_list:n {#3} - \tl_set:Nn \l_keys_default_path_tl {#1} -} -\cs_generate_variant:Nn \keys_manage_aux:nnn { Vnn } -\cs_new_nopar:Nn \keys_bool_new:n { - \bool_new:c { \c_keys_cs_prefix_tl #1 } - \bool_set_true:c { \c_keys_cs_prefix_tl #1 } -} -\cs_new_nopar:Nn \keys_bool_set:nN { - \keys_parse_list:n { - \c_keys_properties_path_tl /.code:n = { - \cs_if_exist:cTF { bool_ #1 _ ##1 :N } { - \use:c { bool_ #1 _ ##1 :N } #2 - }{ - \keys_error:nn { Boolean~expected } {##1} - } - }, - \l_keys_current_path_tl /.default:n = true +\toks_new:N \l_keys_value_toks +\cs_new_nopar:Nn \keys_bool_set:N { + \keys_cmd_set:nNx { \l_keys_path_tl / true } 1 { + \exp_not:c { bool_ \keys_variable_get_scope:N #1 set_true:N } + \exp_not:N #1 } -} -\cs_new_nopar:Nn \keys_bool_set:nnn { - \keys_parse_list:n { - \c_keys_properties_path_tl /.code:x = { - \exp_not:N \cs_if_exist:cTF { bool_ #1 _ ##1 :c } { - \exp_not:N \use:c { bool_ #1 _ ##1 :c } - { #2 \l_keys_current_module_tl #3 _bool } - }{ - \keys_error:nn { Boolean~expected } {##1} - } - }, - \l_keys_current_path_tl /.default:n = true + \keys_cmd_set:nNx { \l_keys_path_tl / false } 1 { + \exp_not:N \use:c + { bool_ \keys_variable_get_scope:N #1 set_false:N } + \exp_not:N #1 } + \keys_bool_set_aux:N #1 } -\cs_new_nopar:Nn \keys_bool_set_inverse:n { - \tl_if_eq:nnTF {#1} { true } { false } { true } -} -\cs_new_nopar:Nn \keys_bool_set_inverse:nN { - \keys_parse_list:n { - \c_keys_properties_path_tl /.code:n = { - \cs_if_exist:cTF { bool_ #1 _ ##1 :N } { - \use:c { bool_ #1 _ \keys_bool_set_inverse:n {##1} :N } #2 - }{ - \keys_error:nn { Boolean~expected } {##1} - } - }, - \l_keys_current_path_tl /.default:n = true +\cs_new_nopar:Nn \keys_bool_set_inverse:N { + \keys_cmd_set:nNx { \l_keys_path_tl / true } 1 { + \exp_not:c { bool_ \keys_variable_get_scope:N #1 set_false:N } + \exp_not:N #1 } -} -\cs_new_nopar:Nn \keys_bool_set_inverse:nnn { - \keys_parse_list:n { - \c_keys_properties_path_tl /.code:x = { - \exp_not:N \cs_if_exist:cTF { bool_ #1 _ ##1 :c } { - \exp_not:N \use:c { - bool_ #1 _ \exp_not:N \keys_bool_set_inverse:n {##1} :c - } { #2 \l_keys_current_module_tl #3 _bool } - }{ - \keys_error:nn { Boolean~expected } {##1} - } - }, - \l_keys_current_path_tl /.default:n = true + \keys_cmd_set:nNx { \l_keys_path_tl / false } 1 { + \exp_not:c { bool_ \keys_variable_get_scope:N #1 set_true:N } + \exp_not:N #1 } + \keys_bool_set_aux:N #1 } -\cs_new_nopar:Nn \keys_check_exists:NN { +\cs_new_nopar:Nn \keys_bool_set_aux:N { + \keys_choice_make: \cs_if_exist:NF #1 { - #2 #1 + \bool_new:N #1 } + \keys_default_set:n { true } } -\cs_generate_variant:Nn \keys_check_exists:NN { cN } -\cs_new:Nn \keys_choices_create:Nnn { - \tl_set_eq:NN \l_keys_choice_path_tl \l_keys_current_path_tl - \int_zero:N \l_keys_current_choice_int - \use:c { keys_choices_create_aux: #1 } {#3} - \clist_map_function:nN {#2} \keys_choice_create:n - \keys_manage_internal:n { \l_keys_choice_path_tl /.expects_choice: } -} -\cs_new:Nn \keys_choices_create_aux:n { - \tl_set:Nn \l_keys_choice_code_tl { \exp_not:n {#1} } -} -\cs_new:Nn \keys_choices_create_aux:x { - \tl_set:Nn \l_keys_choice_code_tl {#1} -} -\cs_new_nopar:Nn \keys_choice_create:n { - \int_incr:N \l_keys_current_choice_int - \keys_parse_list:n { - \l_keys_choice_path_tl / #1 /.code:x = { - \exp_not:n { \int_set:Nn \l_keys_current_choice_int } - { \int_use:N \l_keys_current_choice_int } - \exp_not:n { \tl_set:Nn \l_keys_current_choice_tl } {#1} - \l_keys_choice_code_tl - } +\cs_new_nopar:Nn \keys_choice_find:n { + \keys_execute_aux:nn { \l_keys_path_tl / #1 } { + \keys_execute_aux:nn { \l_keys_path_tl / unknown } { } } } -\cs_new_nopar:Nn \keys_clear_properties:n { - \keys_undefine:n { #1 /._cmd:w } - \keys_undefine:n { #1 /._default_tl } - \keys_undefine:n { #1 /._forbidden_bool } - \keys_undefine:n { #1 /._num_args_tl } - \keys_undefine:n { #1 /._required_bool } +\cs_new_nopar:Nn \keys_choice_make: { + \keys_cmd_set:nNn { \l_keys_path_tl } 1 { + \keys_choice_find:n {##1} + } + \keys_cmd_set:nNn { \l_keys_path_tl / unknown } 1 { + \msg_error:nnxx { keys } { choice~unknown } + { \l_keys_path_tl } {##1} + } } -\cs_new_nopar:Nn \keys_default_add: { - \bool_if:NT \l_keys_no_value_bool { - \keys_if_exist:nT - { \l_keys_current_key_full_tl /._default_tl } { - \keys_toks_set:Nn \l_keys_current_value_toks - { \l_keys_current_key_full_tl /._default_tl } - \bool_set_false:N \l_keys_no_value_bool +\cs_new:Nn \keys_choices_generate:nx { + \keys_choice_make: + \int_zero:N \l_keys_choice_int + \cs_set_nopar:Nn \keys_choices_generate_aux:n { + \int_incr:N \l_keys_choice_int + \keys_cmd_set:nNx { \l_keys_path_tl / ##1 } 1 { + \exp_not:n { \tl_set:Nn \l_keys_choice_tl } {##1} + \exp_not:n { \int_set:Nn \l_keys_choice_int } + { \int_use:N \l_keys_choice_int } + #2 } } + \clist_map_function:nN {#1} \keys_choices_generate_aux:n +} +\cs_new_nopar:Nn \keys_choices_generate_aux:n { } +\cs_new:Nn \keys_cmd_set:nNn { + \keys_cmd_set_aux:nN {#1} #2 + \cs_generate_from_arg_count:cNnn { \c_keys_root_tl #1 .cmd:w } + \cs_set:Npn #2 {#3} +} +\cs_new:Nn \keys_cmd_set:nNx { + \keys_cmd_set_aux:nN {#1} #2 + \cs_generate_from_arg_count:cNnn { \c_keys_root_tl #1 .cmd:w } + \cs_set:Npx #2 {#3} +} +\cs_new_nopar:Nn \keys_cmd_set_aux:nN { + \keys_property_undefine:n { #1 .default_tl } + \num_set:cn { \c_keys_root_tl #1 .args_num } {#2} + \tl_set:cn { \c_keys_root_tl #1 .req_tl } { } +} +\cs_new:Nn \keys_default_set:n { + \tl_set:cn { \c_keys_root_tl \l_keys_path_tl .default_tl } {#1} +} +\cs_generate_variant:Nn \keys_default_set:n { V } +\cs_new:Nn \keys_define:nn { + \tl_set:Nn \l_keys_module_tl {#1} + \cs_set_eq:NN \KV_key_no_value_elt:n \keys_define_elt:n + \cs_set_eq:NN \KV_key_value_elt:nn \keys_define_elt:nn + \KV_parse_no_space_removal_no_sanitize:n {#2} +} +\cs_new:Nn \keys_define_elt:n { + \bool_set_true:N \l_keys_no_value_bool + \keys_define_elt_aux:nn {#1} { } } -\cs_new_nopar:Nn \keys_find_code_full: { - \keys_if_cmd_exist:nTF { \l_keys_current_key_full_tl } { - \keys_use_cmd:n { \l_keys_current_key_full_tl } +\cs_new:Nn \keys_define_elt:nn { + \bool_set_false:N \l_keys_no_value_bool + \keys_define_elt_aux:nn {#1} {#2} +} +\cs_new:Nn \keys_define_elt_aux:nn { + \keys_property_find:n {#1} + \cs_set_eq:Nc \keys_tmp:w + { \c_keys_properties_root_tl \l_keys_key_tl } + \cs_if_exist:NTF \keys_tmp:w { + \keys_define_key:n {#2} }{ - \keys_if_exist:nTF { \l_keys_current_key_full_tl } { - \bool_if:NTF \l_keys_no_value_bool { - \keys_use:n { \l_keys_current_key_full_tl } - }{ - \keys_store:nx { \l_keys_current_key_full_tl } - { \toks_use:N \l_keys_current_value_toks } - } - }{ - \keys_find_code_name: - } + \msg_error:nnx { keys } { property~unknown } + { \l_keys_key_tl } } } -\cs_new_nopar:Nn \keys_find_code_name: { - \keys_separate_path: - \keys_if_cmd_exist:nTF - { \c_keys_properties_path_tl / \l_keys_current_key_name_tl } { - \keys_use_cmd:n - {\c_keys_properties_path_tl / \l_keys_current_key_name_tl} +\cs_new:Nn \keys_define_key:n { + \bool_if:NTF \l_keys_no_value_bool { + \intexpr_compare:nTF { + \exp_args:Nc \cs_get_arg_count_from_signature:N + { \l_keys_key_tl } = \c_zero + } { + \keys_tmp:w + }{ + \msg_error:nnx { keys } { property~value~required } + { \l_keys_key_tl } + } }{ - \keys_if_cmd_exist:nTF - { \l_keys_current_path_tl / unknown } { - \keys_use_cmd:n { \l_keys_current_path_tl / unknown } + \intexpr_compare:nTF { + \exp_args:Nc \cs_get_arg_count_from_signature:N + { \l_keys_key_tl } = \c_one + } { + \keys_tmp:w {#1} }{ - \keys_error:n { unknown~key } + \keys_tmp:w #1 } } } -\prg_new_conditional:Nnn \keys_if_cmd_exist:n {TF,T,F} { - \if_cs_exist:w \c_keys_cs_prefix_tl #1 /._cmd:w \cs_end: - \prg_return_true: - \else: - \prg_return_false: - \fi: -} -\prg_new_conditional:Nnn \keys_if_exist:n {TF,T,F} { - \if_cs_exist:w \c_keys_cs_prefix_tl #1 \cs_end: - \prg_return_true: - \else: - \prg_return_false: - \fi: -} -\prg_new_conditional:Nnn \keys_if_value:n {TF,T,F} { - \if_cs_exist:w - \c_keys_cs_prefix_tl \l_keys_current_key_full_tl /._ #1 _bool - \cs_end: - \prg_return_true: - \else: - \prg_return_false: - \fi: -} -\cs_new:Nn \keys_no_value_elt:n { - \bool_set_true:N \l_keys_no_value_bool - \keys_process_elt:nn {#1} { } +\cs_new_nopar:Nn \keys_execute: { + \keys_execute_aux:nn { \l_keys_path_tl } { + \keys_execute_unknown: + } } -\cs_new:Nn \keys_value_elt:nn { - \bool_set_false:N \l_keys_no_value_bool - \keys_process_elt:nn {#1} {#2} +\cs_new_nopar:Nn \keys_execute_unknown: { + \keys_execute_aux:nn { \l_keys_module_tl / unknown } { + \msg_error:nnx { keys } { key~unknown } { \l_keys_path_tl } + } +} +\cs_new_nopar:Nn \keys_execute_aux:nn { + \cs_set_eq:Nc \keys_tmp:w { \c_keys_root_tl #1 .cmd:w } + \cs_if_exist:NTF \keys_tmp:w { + \intexpr_compare:nTF { + \num_use:c { \c_keys_root_tl #1 .args_num } = \c_one + } { + \exp_args:NV \keys_tmp:w \l_keys_value_toks + }{ + \exp_after:wN \keys_tmp:w \toks_use:N \l_keys_value_toks + } + }{ + #2 + } } -\cs_new:Nn \keys_parse:n { \ERROR } -\cs_new:Nn \keys_parse_list:n { - \cs_set_eq:NN \KV_key_value_elt:nn \keys_value_elt:nn - \cs_set_eq:NN \KV_key_no_value_elt:n \keys_no_value_elt:n - \keys_parse:n {#1} +\cs_new_nopar:Npn \keys_if_value_requirement:nTF #1 { + \tl_if_eq:ccTF { c_keys_value_ #1 _tl } { + \c_keys_root_tl \l_keys_path_tl .req_tl + } +} +\cs_new_nopar:Nn \keys_property_find:n { + \tl_set:Nx \l_keys_path_tl { \l_keys_module_tl / } + \tl_if_in:nnTF {#1} {.} { + \keys_property_find_aux:n {#1} + }{ + \msg_error:nnx { keys } { no~property } { #1 } + } } -\cs_new_nopar:Nn \keys_path_add:N { - \exp_after:wN \keys_path_add:w #1 \q_stop +\cs_new_nopar:Nn \keys_property_find_aux:n { + \keys_property_find_aux:w #1 \q_stop } -\cs_new_nopar:Npn \keys_path_add:w { - \exp_after:wN \peek_meaning:NTF \c_keys_root_tl { - \use_none_delimit_by_q_stop:w +\cs_new_nopar:Npn \keys_property_find_aux:w #1 . #2 \q_stop { + \tl_if_in:nnTF {#2} {.} { + \tl_set:Nx \l_keys_path_tl { \l_keys_path_tl . #1 } + \keys_property_find_aux:w #2 \q_stop }{ - \keys_path_add_aux:w + \tl_set:Nx \l_keys_path_tl { \l_keys_path_tl \tl_to_str:n {#1} } + \tl_set:Nn \l_keys_key_tl { . #2 } } } -\cs_new_nopar:Npn \keys_path_add_aux:w #1 \q_stop { - \tl_set:Nx \l_keys_current_key_full_tl {\l_keys_default_path_tl #1} +\cs_new_nopar:Nn \keys_property_new:nn { + \cs_new:cn { \c_keys_properties_root_tl #1 } {#2} +} +\cs_new_nopar:Nn \keys_property_undefine:n { + \cs_set_eq:cN { \c_keys_root_tl #1 } \c_undefined +} +\cs_new:Nn \keys_set:nn { + \tl_set:Nn \l_keys_module_tl {#1} + \cs_set_eq:NN \KV_key_no_value_elt:n \keys_set_elt:n + \cs_set_eq:NN \KV_key_value_elt:nn \keys_set_elt:nn + \KV_parse_space_removal_sanitize:n {#2} +} +\cs_new:Nn \keys_set_elt:n { + \bool_set_true:N \l_keys_no_value_bool + \keys_set_elt_aux:nn {#1} { } +} +\cs_new:Nn \keys_set_elt:nn { + \bool_set_false:N \l_keys_no_value_bool + \keys_set_elt_aux:nn {#1} {#2} } -\cs_new:Nn \keys_process_elt:nn { - \tl_set:Nx \l_keys_current_key_full_tl {#1} - \toks_set:Nn \l_keys_current_value_toks {#2} - \keys_path_add:N \l_keys_current_key_full_tl - \keys_default_add: - \keys_if_value:nTF { required } { +\cs_new:Nn \keys_set_elt_aux:nn { + \tl_set:Nx \l_keys_key_tl { \tl_to_str:n {#1} } + \tl_set:Nx \l_keys_path_tl { \l_keys_module_tl / \l_keys_key_tl } + \keys_value_or_default:n {#2} + \keys_if_value_requirement:nTF { required } { \bool_if:NTF \l_keys_no_value_bool { - \keys_error:n { value~required } + \msg_error:nnx { keys } { key~value~required } + { \l_keys_path_tl } }{ - \keys_process_elt_aux: + \keys_set_elt_aux: } }{ - \keys_process_elt_aux: + \keys_set_elt_aux: } } -\cs_new:Nn \keys_process_elt_aux: { - \keys_if_value:nTF { forbidden } { +\cs_new_nopar:Nn \keys_set_elt_aux: { + \keys_if_value_requirement:nTF { forbidden } { \bool_if:NTF \l_keys_no_value_bool { - \keys_find_code_full: + \keys_execute: }{ - \keys_error:nn { value~forbidden } - { \toks_use:N \l_keys_current_value_toks } + \msg_error:nnxx { keys} { key~value~forbidden } + { \l_keys_path_tl } + { \toks_use:N \l_keys_value_toks } } }{ - \keys_find_code_full: + \keys_execute: } } -\cs_new_nopar:Nn \keys_separate_path: { - \tl_clear:N \l_keys_current_path_tl - \exp_after:wN \keys_separate_path:w \l_keys_current_key_full_tl - / \q_stop -} -\cs_new_nopar:Npn \keys_separate_path:w / #1 / #2 \q_stop { - \tl_if_empty:nTF {#2} { - \tl_set:Nn \l_keys_current_key_name_tl {#1} - }{ - \tl_put_right:Nn \l_keys_current_path_tl { / #1 } - \keys_separate_path:w /#2 \q_stop - } +\cs_new_nopar:Nn \keys_show:nn { + \cs_show:c { \c_keys_root_tl #1 / \tl_to_str:n {#2} .cmd:w } } -\cs_new_nopar:Nn \keys_set:NN { - \keys_parse_list:n { - \c_keys_properties_path_tl /.code:n = { - #1 #2 {##1} +\cs_new:Npn \keys_tmp:w {} +\cs_new:Nn \keys_value_or_default:n { + \toks_set:Nn \l_keys_value_toks {#1} + \bool_if:NT \l_keys_no_value_bool { + \cs_if_exist:cT { \c_keys_root_tl \l_keys_path_tl .default_tl } { + \toks_set:Nv \l_keys_value_toks { + \c_keys_root_tl \l_keys_path_tl .default_tl + } } } } -\cs_new_nopar:Nn \keys_set:Nnn { - \keys_parse_list:n { - \c_keys_properties_path_tl /.code:x = { - \exp_not:N #1 { #2 \l_keys_current_module_tl #3 } {##1} +\cs_new_nopar:Nn \keys_value_requirement:n { + \tl_set_eq:cc { \c_keys_root_tl \l_keys_path_tl .req_tl } + { c_keys_value_ #1 _tl } +} +\cs_new_nopar:Nn \keys_variable_get_scope:N { + \tl_if_eq:xxT { \token_to_str:N g } + { \keys_variable_get_scope_aux:N #1 } + { g } +} +\cs_new_nopar:Nn \keys_variable_get_scope_aux:N { + \exp_last_unbraced:NNo \use_i:nn \use_i_delimit_by_q_stop:nw + \token_to_str:N #1 \q_stop +} +\group_begin: + \char_set_lccode:nn {`\&} {`\_} + \char_make_other:N \& +\tl_to_lowercase:n { + \group_end: + \cs_new_nopar:Nn \keys_variable_get_type:N { + \exp_after:wN \keys_variable_get_type_aux:w + \token_to_str:N #1 & \q_nil \q_stop + } + \cs_new_nopar:Npn \keys_variable_get_type_aux:w #1 & #2 \q_stop { + \quark_if_nil:nTF {#2} { + #1 + }{ + \keys_variable_get_type_aux:w #2 \q_stop } } } -\cs_new:Nn \keys_set_cmd:nn { - \keys_clear_properties:n {#1} - \cs_set:cpn { \c_keys_cs_prefix_tl #1 /._cmd:w } ##1 {#2} -} -\cs_new:Nn \keys_set_cmd:nx { - \keys_clear_properties:n {#1} - \cs_set:cpx { \c_keys_cs_prefix_tl #1 /._cmd:w } ##1 {#2} -} -\cs_new:Nn \keys_set_cmd:nNn { - \keys_clear_properties:n {#1} - \cs_generate_from_arg_count:cNnn { \c_keys_cs_prefix_tl #1 /._cmd:w } - \cs_set:Npn #2 {#3} - \keys_store:nn { #1 /._num_args_tl} {#2} -} -\cs_new:Nn \keys_set_cmd:nNx { - \keys_clear_properties:n {#1} - \cs_generate_from_arg_count:cNnn { \c_keys_cs_prefix_tl #1 /._cmd:w } - \cs_set:Npx #2 {#3} - \keys_store:nn { #1 /._num_args_tl} {#2} -} -\cs_new:Nn \keys_store:nn { - \tl_set:cn { \c_keys_cs_prefix_tl #1 } {#2} -} -\cs_new:Nn \keys_store:nx { - \tl_set:cx { \c_keys_cs_prefix_tl #1 } {#2} -} -\cs_new_nopar:Nn \keys_toks_set:Nn { - \exp_args:NNv \toks_set:Nn #1 { \c_keys_cs_prefix_tl #2 } -} -\cs_new_nopar:Nn \keys_try: { - \bool_set_false:N \l_keys_success_bool - \keys_if_cmd_exist:nT { \l_keys_current_path_tl } { - \bool_set_true:N \l_keys_success_bool - \bool_if:NT \l_keys_no_value_bool { - \keys_if_exist:nT - { \l_keys_current_path_tl /._default_tl } { - \keys_toks_set:Nn \l_keys_current_value_toks - { \l_keys_current_path_tl /._default_tl } - } - } - \cs_set_eq:NN \l_keys_current_key_full_tl \l_keys_current_path_tl - \keys_use_cmd:n { \l_keys_current_path_tl } +\cs_new_nopar:Nn \keys_variable_set:NN { + \cs_if_exist:NF #2 { + \use:c { \keys_variable_get_type:N #2 _new:N } #2 + } + \keys_cmd_set:nNx { \l_keys_path_tl } 1 { + \exp_not:c { + \keys_variable_get_type:N #2 _ + \keys_variable_get_scope:N #2 set:N #1 + } \exp_not:N #2 {##1} } } -\cs_new_nopar:Nn \keys_undefine:n { - \cs_set_eq:cN { \c_keys_cs_prefix_tl #1 } \c_undefined +\keys_property_new:nn { .choice: } { + \keys_choice_make: } -\cs_new_nopar:Nn \keys_use:n { - \use:c { \c_keys_cs_prefix_tl #1 } +\keys_property_new:nn { .code:n } { + \keys_cmd_set:nNn { \l_keys_path_tl } 1 {#1} } -\cs_new_nopar:Nn \keys_use_cmd:n { - \exp_args:Nno \keys_use_cmd:nn {#1} - { \toks_use:N \l_keys_current_value_toks } +\keys_property_new:nn { .code:Nn } { + \keys_cmd_set:nNn { \l_keys_path_tl } #1 {#2} } -\cs_new_nopar:Nn \keys_use_cmd:nn { - \keys_if_exist:nTF { #1 /._num_args_tl } { - \keys_use_cmd_aux:nn {#1} {#2} - }{ - \keys_use:n {#1/._cmd:w} {#2} - } +\keys_property_new:nn { .code:x } { + \keys_cmd_set:nNx { \l_keys_path_tl } 1 {#1} } -\cs_new_nopar:Nn \keys_use_cmd_aux:nn { - \tl_if_empty:nTF {#2} { - \cs_set:Npn \keys_use_cmd_aux:w { - \keys_use:n { #1 /._cmd:w } - } - \exp_after:wN \exp_after:wN \exp_after:wN \keys_use_cmd_aux:w - \cs:w - c_keys_ \keys_use:n { #1 /._num_args_tl } _empty_tl - \cs_end: - }{ - \keys_use:n { #1 /._cmd:w } #2 - } +\keys_property_new:nn { .code:Nx } { + \keys_cmd_set:nNx { \l_keys_path_tl } #1 {#2} } -\cs_new_nopar:Npn \keys_msg_new:nn #1 { - \msg_new:nnn { keys } {#1} -} -\cs_new_protected_nopar:Nn \keys_error:nn { - \msg_error:nnxx { keys } {#1} { \l_keys_current_key_full_tl } {#2} -} -\cs_new_protected_nopar:Nn \keys_error:n { - \msg_error:nnx { keys } {#1} { \l_keys_current_key_full_tl } -} -\keys_msg_new:nn - { unknown~key } - {The key `#1' is unknown and is being ignored.} -\keys_msg_new:nn - { value~required } - {The key `#1' requires a value\\% - and is being ignored.} -\keys_msg_new:nn - { value~forbidden } - {The key `#1' cannot taken a value:\\% - the given input `#2' is being ignored.} -\keys_msg_new:nn - { Boolean~expected } - {Key `#1' takes the Boolean values\\% - `true' and `false'~only.\\% - The given value `#2' is being ignored.} -\keys_msg_new:nn - { not_boolean } - {Key `#1' is not a Boolean key: you cannot create a complement.} -\keys_msg_new:nn - { unknown~choice } - {Choice `#2' unknown for key `#1':\\% - the key is being ignored.} -\keys_set_cmd:nn { \c_keys_properties_path_tl /.code:n } { - \keys_set_cmd:nn { \l_keys_current_path_tl } {#1} -} -\keys_set_cmd:nNn { \c_keys_properties_path_tl /.code:Nn } 2 { - \keys_set_cmd:nNn { \l_keys_current_path_tl } #1 {#2} -} -\keys_manage_quick:n { - \c_keys_errors_path_tl /unknown/.code:n = { - \keys_error:n { unknown~key } - } +\keys_property_new:nn { .default:n } { + \keys_default_set:n {#1} } -\keys_manage_quick:n { - \c_keys_properties_path_tl /.code:x/.code:n = { - \keys_set_cmd:nx { \l_keys_current_path_tl } {#1} - }, - \c_keys_properties_path_tl /.code:Nx/.code:Nn = 2 { - \keys_set_cmd:nNx { \l_keys_current_path_tl } {#1} {#2} - } +\keys_property_new:nn { .default:V } { + \keys_default_set:V #1 } -\keys_manage_quick:n { - \c_keys_properties_path_tl /.cd:/.code:n = { - \tl_set:Nx \l_keys_default_path_tl { \l_keys_current_path_tl / } - } +\keys_property_new:nn { .generate_choices:nn } { + \keys_choices_generate:nx {#1} { \exp_not:n {#2} } } -\keys_manage_quick:n { - \c_keys_properties_path_tl /.value_required:/.code:n = { - \keys_bool_new:n { \l_keys_current_path_tl /._required_bool } - \keys_undefine:n { \l_keys_current_path_tl /._forbidden_bool } - }, - \c_keys_properties_path_tl /.value_forbidden:/.code:n = { - \keys_bool_new:n { \l_keys_current_path_tl /._forbidden_bool } - \keys_undefine:n { \l_keys_current_path_tl /._required_bool } - } +\keys_property_new:nn { .generate_choices:nx } { + \keys_choices_generate:nx {#1} {#2} } -\keys_manage_quick:n { - \c_keys_properties_path_tl /.default:n/.code:n = { - \keys_store:nn { \l_keys_current_path_tl /._default_tl } {#1} - \keys_undefine:n { \l_keys_current_path_tl /._required_bool } - } +\keys_property_new:nn { .set:N } { + \keys_variable_set:NN n #1 } -\keys_manage_quick:n { - \c_keys_properties_path_tl /.tl_set:N/.code:n = { - \keys_check_exists:NN #1 \tl_new:N - \keys_set:NN \tl_set:Nn #1 - }, - \c_keys_properties_path_tl /.tl_set_x:N/.code:n = { - \keys_check_exists:NN #1 \tl_new:N - \keys_set:NN \tl_set:Nx #1 - }, - \c_keys_properties_path_tl /.tl_gset:N/.code:n = { - \keys_check_exists:NN #1 \tl_new:N - \keys_set:NN \tl_gset:Nn #1 - }, - \c_keys_properties_path_tl /.tl_gset_x:N/.code:n = { - \keys_check_exists:NN #1 \tl_new:N - \keys_set:NN \tl_gset:Nx #1 - } +\keys_property_new:nn { .set_x:N } { + \keys_variable_set:NN x #1 } -\keys_manage_quick:n { - \c_keys_properties_path_tl /.int_set:N/.code:n = { - \keys_check_exists:NN #1 \int_new:N - \keys_set:NN \int_set:Nn #1 - }, - \c_keys_properties_path_tl /.int_gset:N/.code:n = { - \keys_check_exists:NN #1 \int_new:N - \keys_set:NN \int_gset:Nn #1 - }, - \c_keys_properties_path_tl /.skip_set:N/.code:n = { - \keys_check_exists:NN #1 \skip_new:N - \keys_set:NN \skip_set:Nn #1 - }, - \c_keys_properties_path_tl /.skip_gset:N/.code:n = { - \keys_check_exists:NN #1 \skip_new:N - \keys_set:NN \skip_gset:Nn #1 - }, - \c_keys_properties_path_tl /.toks_set:N/.code:n = { - \keys_check_exists:NN #1 \toks_new:N - \keys_set:NN \toks_set:Nn #1 - }, - \c_keys_properties_path_tl /.toks_gset:N/.code:n = { - \keys_check_exists:NN #1 \toks_new:N - \keys_set:NN \toks_gset:Nn #1 - } +\keys_property_new:nn { .set_bool:N } { + \keys_bool_set:N #1 } -\keys_manage_quick:n { - \c_keys_utilities_path_tl /current_module:n/.code:n = { - \tl_if_empty:nTF {#1} { - \tl_clear:N \l_keys_current_module_tl - }{ - \tl_set:Nn \l_keys_current_module_tl { #1 _ } - } - } +\keys_property_new:nn { .set_bool_inverse:N } { + \keys_bool_set_inverse:N #1 } -\keys_manage_quick:n { - \c_keys_properties_path_tl /.tl_set:n/.code:n = { - \keys_check_exists:cN { l_ #1 _tl } \tl_new:N - \keys_set:Nnn \tl_set:cn { l_ } { #1 _tl } - }, - \c_keys_properties_path_tl /.tl_set_x:n/.code:n = { - \keys_check_exists:cN { l_ #1 _tl } \tl_new:N - \keys_set:Nnn \tl_set:cx { l_ } { #1 _tl } - }, - \c_keys_properties_path_tl /.tl_gset:n/.code:n = { - \keys_check_exists:cN { g_ #1 _tl } \tl_new:N - \keys_set:Nnn \tl_gset:cn { g_ } { #1 _tl } - }, - \c_keys_properties_path_tl /.tl_gset_x:n/.code:n = { - \keys_check_exists:cN { g_ #1 _tl } \tl_new:N - \keys_set:Nnn \tl_gset:cx { g_ } { #1 _tl } - }, - \c_keys_properties_path_tl /.int_set:n/.code:n = { - \keys_check_exists:cN { l_ #1 _int } \int_new:N - \keys_set:Nnn \int_set:cn { l_ } { #1 _int } - }, - \c_keys_properties_path_tl /.int_gset:n/.code:n = { - \keys_check_exists:cN { g_ #1 _int } \int_new:N - \keys_set:Nnn \int_gset:cn { g_ } { #1 _int } - }, - \c_keys_properties_path_tl /.skip_set:n/.code:n = { - \keys_check_exists:cN { l_ #1 _skip } \skip_new:N - \keys_set:Nnn \skip_set:cn { l_ } { #1 _skip } - }, - \c_keys_properties_path_tl /.skip_gset:n/.code:n = { - \keys_check_exists:cN { g_ #1 _skip } \skip_new:N - \keys_set:Nnn \skip_gset:cn { g_ } { #1 _skip } - }, - \c_keys_properties_path_tl /.toks_set:n/.code:n = { - \keys_check_exists:cN { g_ #1 _toks } \toks_new:N - \keys_set:Nnn \toks_set:cn { l_ } { #1 _toks } - }, - \c_keys_properties_path_tl /.toks_gset:n/.code:n = { - \keys_check_exists:cN { g_ #1 _toks } \toks_new:N - \keys_set:Nnn \toks_gset:cn { g_ } { #1 _toks } - }, -} -\keys_manage_quick:n { - \c_keys_properties_path_tl /.bool_set:N/.code:n = { - \keys_bool_set:nN { set } #1 - }, - \c_keys_properties_path_tl /.bool_gset:N/.code:n = { - \keys_bool_set:nN { gset } #1 - }, - \c_keys_properties_path_tl /.bool_set:n/.code:n = { - \keys_bool_set:nnn { set } { l_ } { #1 } - }, - \c_keys_properties_path_tl /.bool_gset:n/.code:n = { - \keys_bool_set:nnn { gset } { g_ } { #1 } - }, -} -\keys_manage_quick:n { - \c_keys_properties_path_tl /.bool_set_inverse:N/.code:n = { - \keys_bool_set_inverse:nN { set } #1 - }, - \c_keys_properties_path_tl /.bool_gset_inverse:N/.code:n = { - \keys_bool_set_inverse:nN { gset } #1 - }, - \c_keys_properties_path_tl /.bool_set_inverse:n/.code:n = { - \keys_bool_set_inverse:nnn { set } { l_ } { #1 } - }, - \c_keys_properties_path_tl /.bool_gset_inverse:n/.code:n = { - \keys_bool_set_inverse:nnn { gset } { g_ } { #1 } - }, -} -\keys_manage_quick:n { - \c_keys_properties_path_tl /.expects_choice:/.code:n = { - \keys_manage_internal:n { - \l_keys_current_path_tl /.cd:, - .code:n = { - \tl_set:Nn \l_keys_current_choice_tl {##1} - \int_zero:N \l_keys_current_choice_int - \exp_args:No \keys_parse_list:n - { \l_keys_current_key_full_tl / ##1 } - }, - unknown/.code:n = { - \keys_error:nn { unknown~choice } - { \l_keys_current_key_name_tl } - } - } - }, -} -\keys_manage_quick:n { - \c_keys_properties_path_tl /.create_choices:nn/.code:Nn = 2 { - \keys_choices_create:Nnn n {#1} {#2} - }, - \c_keys_properties_path_tl /.create_choices:nx/.code:Nn = 2 { - \keys_choices_create:Nnn x {#1} {#2} - }, -} -\keys_manage_quick:n { - \c_keys_properties_path_tl /.use_keys:n/.code:n = { - \keys_manage_internal:n { - \l_keys_current_path_tl /.code:n = { \keys_parse_list:n {#1} } - } - }, - \c_keys_properties_path_tl /.use_keys:x/.code:n = { - \keys_manage_internal:n { - \l_keys_current_path_tl /.code:x = { - \exp_not:N \keys_parse_list:n {#1} - } - } - }, - \c_keys_properties_path_tl /.use_keys:Nn/.code:Nn = 2 { - \keys_manage_internal:n { - \l_keys_current_path_tl /.code:Nn = #1 { \keys_parse_list:n {#2} } - } - }, - \c_keys_properties_path_tl /.use_keys:Nx/.code:Nn = 2 { - \keys_manage_internal:n { - \l_keys_current_path_tl /.code:Nx = - #1 { \exp_not:N \keys_parse_list:n {#2} } - } - } +\keys_property_new:nn { .value_forbidden: } { + \keys_value_requirement:n { forbidden } } -\keys_manage_quick:n { - \c_keys_properties_path_tl /.try:n/.code:n = { \keys_try: }, - \c_keys_properties_path_tl /.retry:n/.code:n = { - \bool_if:NF \l_keys_success_bool { \keys_try: } - } +\keys_property_new:nn { .value_required: } { + \keys_value_requirement:n { required } } -\keys_manage_quick:n { - \c_keys_properties_path_tl /.show_code:/.code:n = { - \cs_show:c { - \c_keys_cs_prefix_tl \l_keys_current_path_tl /._cmd:w - } - }, - \c_keys_properties_path_tl /.show_key:/.code:n = { - \cs_show:c { \c_keys_cs_prefix_tl \l_keys_current_path_tl } - } +\msg_new:nnn { keys } { choice~unknown } {% + Choice `#2' unknown for key `#1':\\% + the key is being ignored.% +} +\msg_new:nnn { keys } { key~unknown } {% + The key `#1' is unknown and is being ignored.% +} +\msg_new:nnn { keys } { key~value~forbidden }{% + The key `#1' cannot taken a value:\\% + the given input `#2' is being ignored.% +} +\msg_new:nnn { keys } { key~value~required } {% + The key `#1' requires a value\\% + and is being ignored.% +} +\msg_new:nnn { keys } { no~property } {% + No property given in definition of key `#1'.% +} +\msg_new:nnn { keys } { property~unknown } {% + The key property `#1' is unknown.% +} +\msg_new:nnn { keys } { property~value~required } {% + The property `#1' requires a value\\% + and is being ignored.% } %% %% Copyright (C) 2008-2009 by |