%%
%% 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 110 2009-06-12 21:27:24Z josephwright $
  {Key management for LaTeX3}
\ProvidesExplPackage
  {\filename}{\filedate}{\fileversion}{\filedescription}
\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
\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
  }
  \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 {
  \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
  }
  \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_bool_set_aux:N {
  \keys_choice_make:
  \cs_if_exist:NF #1 {
    \bool_new:N #1
  }
  \keys_default_set:n { true }
}
\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_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: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: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}
  }{
    \msg_error:nnx { keys } { property~unknown }
      { \l_keys_key_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 }
    }
  }{
    \intexpr_compare:nTF {
      \exp_args:Nc \cs_get_arg_count_from_signature:N
        { \l_keys_key_tl }  = \c_one
    } {
      \keys_tmp:w {#1}
    }{
      \keys_tmp:w #1
    }
  }
}
\cs_new_nopar:Nn \keys_execute: {
  \keys_execute_aux:nn { \l_keys_path_tl } {
    \keys_execute_unknown:
  }
}
\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_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_property_find_aux:n {
  \keys_property_find_aux:w #1 \q_stop
}
\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
  }{
    \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: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_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 {
      \msg_error:nnx { keys }  { key~value~required }
        { \l_keys_path_tl }
    }{
      \keys_set_elt_aux:
    }
  }{
    \keys_set_elt_aux:
  }
}
\cs_new_nopar:Nn \keys_set_elt_aux: {
  \keys_if_value_requirement:nTF { forbidden } {
    \bool_if:NTF \l_keys_no_value_bool {
      \keys_execute:
    }{
      \msg_error:nnxx { keys} { key~value~forbidden }
        { \l_keys_path_tl }
        { \toks_use:N \l_keys_value_toks }
    }
  }{
    \keys_execute:
  }
}
\cs_new_nopar:Nn \keys_show:nn {
  \cs_show:c { \c_keys_root_tl #1 / \tl_to_str:n {#2} .cmd:w }
}
\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_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_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}
  }
}
\keys_property_new:nn { .choice: } {
  \keys_choice_make:
}
\keys_property_new:nn { .code:n } {
  \keys_cmd_set:nNn { \l_keys_path_tl } 1 {#1}
}
\keys_property_new:nn { .code:Nn } {
  \keys_cmd_set:nNn { \l_keys_path_tl } #1 {#2}
}
\keys_property_new:nn { .code:x } {
  \keys_cmd_set:nNx { \l_keys_path_tl } 1 {#1}
}
\keys_property_new:nn { .code:Nx } {
  \keys_cmd_set:nNx { \l_keys_path_tl } #1 {#2}
}
\keys_property_new:nn { .default:n } {
  \keys_default_set:n  {#1}
}
\keys_property_new:nn { .default:V } {
  \keys_default_set:V #1
}
\keys_property_new:nn { .generate_choices:nn } {
  \keys_choices_generate:nx {#1} { \exp_not:n {#2} }
}
\keys_property_new:nn { .generate_choices:nx } {
  \keys_choices_generate:nx {#1} {#2}
}
\keys_property_new:nn { .set:N } {
  \keys_variable_set:NN n #1
}
\keys_property_new:nn { .set_x:N } {
  \keys_variable_set:NN x #1
}
\keys_property_new:nn { .set_bool:N } {
  \keys_bool_set:N #1
}
\keys_property_new:nn { .set_bool_inverse:N } {
  \keys_bool_set_inverse:N #1
}
\keys_property_new:nn { .value_forbidden: } {
  \keys_value_requirement:n { forbidden }
}
\keys_property_new:nn { .value_required: } {
  \keys_value_requirement:n { required }
}
\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
%%   Joseph Wright <joseph.wright@morningstar2.co.uk>
%% 
%% 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'.
