%% %% This is file `keys3.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% keys3.dtx (with options: `package') %% --------------------------------------------------------------- %% The keys3 package --- Key management for LaTeX3 %% Maintained by Joseph Wright %% E-mail: joseph.wright@morningstar2.co.uk %% Released under the LaTeX Project Public License v1.3c or later %% See http://www.latex-project.org/lppl.txt %% --------------------------------------------------------------- %% %% EXPERIMENTAL CODE %% %% Do not distribute this file without also distributing the %% source files specified above. %% %% Do not distribute a modified version of this file. %% \RequirePackage{expl3} \GetIdInfo$Id: keys3.dtx 101 2009-06-10 12:16:20Z 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 \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 } } \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 } } \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: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 } } \cs_new_nopar:Nn \keys_check_exists:NN { \cs_if_exist:NF #1 { #2 #1 } } \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_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_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_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 } }{ \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: } } } \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} }{ \keys_if_cmd_exist:nTF { \l_keys_current_path_tl / unknown } { \keys_use_cmd:n { \l_keys_current_path_tl / unknown } }{ \keys_error:n { unknown~key } } } } \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:Nn \keys_value_elt:nn { \bool_set_false:N \l_keys_no_value_bool \keys_process_elt:nn {#1} {#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:Nn \keys_path_add:N { \exp_after:wN \keys_path_add: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 }{ \keys_path_add_aux:w } } \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: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 } { \bool_if:NTF \l_keys_no_value_bool { \keys_error:n { value~required } }{ \keys_process_elt_aux: } }{ \keys_process_elt_aux: } } \cs_new:Nn \keys_process_elt_aux: { \keys_if_value:nTF { forbidden } { \bool_if:NTF \l_keys_no_value_bool { \keys_find_code_full: }{ \keys_error:nn { value~forbidden } { \toks_use:N \l_keys_current_value_toks } } }{ \keys_find_code_full: } } \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_set:NN { \keys_parse_list:n { \c_keys_properties_path_tl /.code:n = { #1 #2 {##1} } } } \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: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_undefine:n { \cs_set_eq:cN { \c_keys_cs_prefix_tl #1 } \c_undefined } \cs_new_nopar:Nn \keys_use:n { \use:c { \c_keys_cs_prefix_tl #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 } } \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} } } \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 } } \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_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_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_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_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_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_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_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_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_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_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 } } } %% %% Copyright (C) 2008-2009 by %% Joseph Wright %% %% It 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 %% Joseph Wright. %% %% This work consists of the file keys3.dtx %% and the derived files keys3.pdf, %% keys3.sty and %% keys3.ins. %% %% %% End of file `keys3.sty'.