summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/l3kernel/l3keys.sty
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2011-08-29 00:08:58 +0000
committerKarl Berry <karl@freefriends.org>2011-08-29 00:08:58 +0000
commit62ea3c38421c330e364e1b53c366715efe3c7554 (patch)
treef323abbf0bd2346b481fc35187c6ec2d50ce2d1a /Master/texmf-dist/tex/latex/l3kernel/l3keys.sty
parent0a90bbc7d05e8e767bb8992e0ed6180206ae2bc7 (diff)
l3kernel 2678 (28aug11)
git-svn-id: svn://tug.org/texlive/trunk@23738 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/l3kernel/l3keys.sty')
-rw-r--r--Master/texmf-dist/tex/latex/l3kernel/l3keys.sty245
1 files changed, 237 insertions, 8 deletions
diff --git a/Master/texmf-dist/tex/latex/l3kernel/l3keys.sty b/Master/texmf-dist/tex/latex/l3kernel/l3keys.sty
index 749a5791777..434ba050077 100644
--- a/Master/texmf-dist/tex/latex/l3kernel/l3keys.sty
+++ b/Master/texmf-dist/tex/latex/l3kernel/l3keys.sty
@@ -46,11 +46,134 @@
%%
%% -----------------------------------------------------------------------
\RequirePackage{l3names}
-\GetIdInfo$Id: l3keys.dtx 2568 2011-08-14 05:03:32Z bruno $
+\GetIdInfo$Id: l3keys.dtx 2677 2011-08-28 06:54:22Z joseph $
{L3 Experimental key-value interfaces}
\ProvidesExplPackage
{\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
\package_check_loaded_expl:
+\int_new:N \g_keyval_level_int
+\tl_new:N \l_keyval_key_tl
+\tl_new:N \l_keyval_value_tl
+\tl_new:N \l_keyval_sanitise_tl
+\tl_new:N \l_keyval_parse_tl
+\group_begin:
+ \char_set_catcode_active:n { `\= }
+ \char_set_catcode_active:n { `\, }
+ \char_set_lccode:nn { `\8 } { `\= }
+ \char_set_lccode:nn { `\9 } { `\, }
+\tl_to_lowercase:n
+ {
+ \group_end:
+ \cs_new_protected:Npn \keyval_parse:n #1
+ {
+ \group_begin:
+ \tl_clear:N \l_keyval_sanitise_tl
+ \tl_set:Nn \l_keyval_sanitise_tl {#1}
+ \tl_replace_all:Nnn \l_keyval_sanitise_tl { = } { 8 }
+ \tl_replace_all:Nnn \l_keyval_sanitise_tl { , } { 9 }
+ \tl_clear:N \l_keyval_parse_tl
+ \exp_after:wN \keyval_parse_elt:w \exp_after:wN
+ \q_no_value \l_keyval_sanitise_tl 9 \q_nil 9
+ \exp_after:wN \group_end:
+ \l_keyval_parse_tl
+ }
+ }
+\cs_new_protected:Npn \keyval_parse_elt:w #1 ,
+ {
+ \tl_if_blank:oTF { \use_none:n #1 }
+ { \keyval_parse_elt:w \q_no_value }
+ {
+ \quark_if_nil:oF { \use_ii:nn #1 }
+ {
+ \keyval_split_key_value:w #1 = = \q_stop
+ \keyval_parse_elt:w \q_no_value
+ }
+ }
+ }
+\cs_new_protected:Npn \keyval_split_key_value:w #1 = #2 \q_stop
+ {
+ \keyval_split_key:w #1 \q_stop
+ \str_if_eq:nnTF {#2} { = }
+ {
+ \tl_put_right:Nx \l_keyval_parse_tl
+ {
+ \exp_not:c
+ { keyval_key_no_value_elt_ \int_use:N \g_keyval_level_int :n }
+ { \exp_not:o \l_keyval_key_tl }
+ }
+ }
+ {
+ \keyval_split_key_value_aux:wTF #2 \q_no_value \q_stop
+ { \keyval_split_value:w \q_nil #2 }
+ { \msg_kernel_error:nn { keyval } { misplaced-equals-sign } }
+ }
+ }
+\cs_new:Npn \keyval_split_key_value_aux:wTF #1 = #2#3 \q_stop
+ { \tl_if_head_eq_meaning:nNTF {#3} \q_no_value }
+\group_begin:
+ \char_set_catcode_math_toggle:n { `\Q }
+ \cs_new_protected:Npn \keyval_split_key:w #1 \q_stop
+ {
+ \exp_args:NNf \tl_set:Nn \l_keyval_key_tl
+ {
+ \exp_after:wN \keyval_remove_spaces:w \exp_after:wN
+ \exp_not:N \use_none:n #1 Q ~ Q
+ }
+ \tl_set:Nx \l_keyval_key_tl
+ { \exp_after:wN \keyval_split_key_aux:w \l_keyval_key_tl \q_stop }
+ }
+ \cs_gset:Npn \keyval_split_key_aux:w #1 \q_stop { \exp_not:n {#1} }
+ \cs_gset:Npn \keyval_remove_spaces:w #1 ~ Q
+ { \keyval_remove_spaces_aux:w #1 Q }
+ \cs_gset:Npn \keyval_remove_spaces_aux:w #1 Q #2 {#1}
+\group_end:
+\cs_new_protected:Npn \keyval_split_value:w #1 = =
+ {
+ \tl_put_right:Nx \l_keyval_parse_tl
+ {
+ \exp_not:c
+ { keyval_key_value_elt_ \int_use:N \g_keyval_level_int :nn }
+ { \exp_not:o \l_keyval_key_tl }
+ }
+ \tl_set:Nx \l_keyval_value_tl
+ { \exp_not:o { \use_none:nnn #1 \q_nil \q_nil } }
+ \tl_if_empty:NTF \l_keyval_value_tl
+ { \tl_put_right:Nn \l_keyval_parse_tl { { } } }
+ {
+ \quark_if_nil:NTF \l_keyval_value_tl
+ {
+ \tl_put_right:Nx \l_keyval_parse_tl
+ { { \exp_not:o { \use_ii:nnn #1 \q_nil } } }
+ }
+ { \keyval_split_value_aux:w #1 \q_stop }
+ }
+ }
+\group_begin:
+ \char_set_catcode_math_toggle:n { `\Q }
+ \cs_new_protected:Npn \keyval_split_value_aux:w \q_nil #1 \q_stop
+ {
+ \exp_args:NNf \tl_set:Nn \l_keyval_value_tl
+ { \keyval_remove_spaces:w \exp_not:N #1 Q ~ Q }
+ \tl_put_right:Nx \l_keyval_parse_tl
+ { { \exp_not:o \l_keyval_value_tl } }
+ }
+\group_end:
+\cs_new_protected:Npn \keyval_parse:NNn #1#2#3
+ {
+ \int_gincr:N \g_keyval_level_int
+ \cs_gset_eq:cN
+ { keyval_key_no_value_elt_ \int_use:N \g_keyval_level_int :n } #1
+ \cs_gset_eq:cN
+ { keyval_key_value_elt_ \int_use:N \g_keyval_level_int :nn } #2
+ \keyval_parse:n {#3}
+ \int_gdecr:N \g_keyval_level_int
+ }
+\msg_kernel_new:nnnn { keyval } { misplaced-equals-sign }
+ { Misplaced~equals~sign~in~key-value~input~\msg_line_number: }
+ {
+ LaTeX~is~attempting~to~parse~some~key-value~input~but~found~
+ two~equals~signs~not~separated~by~a~comma.
+ }
\tl_const:Nn \c_keys_code_root_tl { key~code~>~ }
\tl_const:Nn \c_keys_vars_root_tl { key~var~>~ }
\tl_const:Nn \c_keys_props_root_tl { key~prop~>~ }
@@ -63,6 +186,7 @@
\bool_new:N \l_keys_no_value_bool
\tl_new:N \l_keys_path_tl
\tl_new:N \l_keys_property_tl
+\tl_new:N \l_keys_unknown_clist
\tl_new:N \l_keys_value_tl
\cs_new_protected:Npn \keys_define:nn
{ \keys_define_aux:onn \l_keys_module_tl }
@@ -141,6 +265,21 @@
}
\keys_default_set:n { true }
}
+\cs_new_nopar:Npn \keys_bool_set_inverse:NN #1#2
+ {
+ \cs_if_exist:NF #1 { \bool_new:N #1 }
+ \keys_choice_make:
+ \keys_cmd_set:nx { \l_keys_path_tl / true }
+ { \exp_not:c { bool_ #2 set_false:N } \exp_not:N #1 }
+ \keys_cmd_set:nx { \l_keys_path_tl / false }
+ { \exp_not:c { bool_ #2 set_true:N } \exp_not:N #1 }
+ \keys_cmd_set:nn { \l_keys_path_tl / unknown }
+ {
+ \msg_kernel_error:nnx { keys } { boolean-values-only }
+ { \l_keys_key_tl }
+ }
+ \keys_default_set:n { true }
+ }
\cs_new_protected_nopar:Npn \keys_choice_make:
{
\keys_cmd_set:nn { \l_keys_path_tl }
@@ -151,6 +290,22 @@
{ \l_keys_path_tl } {##1}
}
}
+\cs_new_protected:Npn \keys_choices_make:nn #1#2
+ {
+ \keys_choice_make:
+ \int_zero:N \l_keys_choice_int
+ \clist_map_inline:nn {#1}
+ {
+ \keys_cmd_set:nx { \l_keys_path_tl / ##1 }
+ {
+ \tl_set:Nn \exp_not:N \l_keys_choice_tl {##1}
+ \int_set:Nn \exp_not:N \l_keys_choice_int
+ { \int_use:N \l_keys_choice_int }
+ \exp_not:n {#2}
+ }
+ \int_incr:N \l_keys_choice_int
+ }
+ }
\cs_new_protected:Npn \keys_choices_generate:n #1
{
\cs_if_exist:cTF
@@ -169,8 +324,8 @@
{
\keys_cmd_set:nx { \l_keys_path_tl / #1 }
{
- \exp_not:n { \tl_set:Nn \l_keys_choice_tl } {#1}
- \exp_not:n { \int_set:Nn \l_keys_choice_int }
+ \tl_set:Nn \exp_not:N \l_keys_choice_tl {#1}
+ \int_set:Nn \exp_not:N \l_keys_choice_int
{ \int_use:N \l_keys_choice_int }
\exp_not:v
{ \c_keys_vars_root_tl \l_keys_path_tl .choice~code }
@@ -210,13 +365,41 @@
\cs_new_protected_nopar:Npn \keys_meta_make:n #1
{
\exp_args:NNo \keys_cmd_set:nn \l_keys_path_tl
- { \exp_after:wN \keys_set:nn \exp_after:wN { \l_keys_module_tl } {#1} }
+ { \exp_after:wN \keys_set:nn \exp_after:wN { \l_keys_module_tl } {#1} }
}
\cs_new_protected_nopar:Npn \keys_meta_make:x #1
{
\keys_cmd_set:nx { \l_keys_path_tl }
{ \exp_not:N \keys_set:nn { \l_keys_module_tl } {#1} }
}
+\cs_new_nopar:Npn \keys_multichoice_find:n #1
+ { \clist_map_function:nN {#1} \keys_choice_find:n }
+\cs_new_protected_nopar:Npn \keys_multichoice_make:
+ {
+ \keys_cmd_set:nn { \l_keys_path_tl }
+ { \keys_multichoice_find:n {##1} }
+ \keys_cmd_set:nn { \l_keys_path_tl / unknown }
+ {
+ \msg_kernel_error:nnxx { keys } { choice-unknown }
+ { \l_keys_path_tl } {##1}
+ }
+ }
+\cs_new_protected:Npn \keys_multichoices_make:nn #1#2
+ {
+ \keys_multichoice_make:
+ \int_zero:N \l_keys_choice_int
+ \clist_map_inline:nn {#1}
+ {
+ \keys_cmd_set:nx { \l_keys_path_tl / ##1 }
+ {
+ \tl_set:Nn \exp_not:N \l_keys_choice_tl {##1}
+ \int_set:Nn \exp_not:N \l_keys_choice_int
+ { \int_use:N \l_keys_choice_int }
+ \exp_not:n {#2}
+ }
+ \int_incr:N \l_keys_choice_int
+ }
+ }
\cs_new_protected_nopar:Npn \keys_value_requirement:n #1
{
\tl_set_eq:cc
@@ -237,8 +420,14 @@
{ \keys_bool_set:NN #1 { } }
\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .bool_gset:N } #1
{ \keys_bool_set:NN #1 g }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .bool_set_inverse:N } #1
+ { \keys_bool_set_inverse:NN #1 { } }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .bool_gset_inverse:N } #1
+ { \keys_bool_set_inverse:NN #1 g }
\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .choice: }
{ \keys_choice_make: }
+\cs_new_protected:cpn { \c_keys_props_root_tl .choices:nn } #1
+ { \keys_choices_make:nn #1 }
\cs_new_protected:cpn { \c_keys_props_root_tl .code:n } #1
{ \keys_cmd_set:nn { \l_keys_path_tl } {#1} }
\cs_new_protected:cpn { \c_keys_props_root_tl .code:x } #1
@@ -281,6 +470,10 @@
{ \keys_meta_make:n {#1} }
\cs_new_protected:cpn { \c_keys_props_root_tl .meta:x } #1
{ \keys_meta_make:x {#1} }
+\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .multichoice: }
+ { \keys_multichoice_make: }
+\cs_new_protected:cpn { \c_keys_props_root_tl .multichoices:nn } #1
+ { \keys_multichoices_make:nn #1 }
\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .skip_set:N } #1
{ \keys_variable_set:NnN #1 { skip } n }
\cs_new_protected_nopar:cpn { \c_keys_props_root_tl .skip_set:c } #1
@@ -319,6 +512,20 @@
}
\cs_generate_variant:Nn \keys_set:nn { nV , nv , no }
\cs_generate_variant:Nn \keys_set_aux:nnn { o }
+\cs_new_protected:Npn \keys_set_known:nnN
+ { \keys_set_known_aux:onnN { \l_keys_module_tl } }
+\cs_new_protected:Npn \keys_set_known_aux:nnnN #1#2#3#4
+ {
+ \tl_set:Nn \l_keys_module_tl {#2}
+ \clist_clear:N \l_keys_unknown_clist
+ \cs_set_eq:NN \keys_execute_unknown: \keys_execute_unknown_alt:
+ \keyval_parse:NNn \keys_set_elt:n \keys_set_elt:nn {#3}
+ \cs_set_eq:NN \keys_execute_unknown: \keys_execute_unknown_std:
+ \tl_set:Nn \l_keys_module_tl {#1}
+ \clist_set_eq:NN #4 \l_keys_unknown_clist
+ }
+\cs_generate_variant:Nn \keys_set_known:nnN { nV , nv , no }
+\cs_generate_variant:Nn \keys_set_known_aux:nnnN { o }
\cs_new_protected_nopar:Npn \keys_set_elt:n #1
{
\bool_set_true:N \l_keys_no_value_bool
@@ -363,8 +570,11 @@
{
\quark_if_no_value:cF { \c_keys_vars_root_tl \l_keys_path_tl .default }
{
- \tl_set_eq:Nc \l_keys_value_tl
- { \c_keys_vars_root_tl \l_keys_path_tl .default }
+ \cs_if_exist:cT { \c_keys_vars_root_tl \l_keys_path_tl .default }
+ {
+ \tl_set_eq:Nc \l_keys_value_tl
+ { \c_keys_vars_root_tl \l_keys_path_tl .default }
+ }
}
}
}
@@ -385,6 +595,16 @@
{ \l_keys_path_tl } { \l_keys_module_tl }
}
}
+\cs_new_eq:NN \keys_execute_unknown_std: \keys_execute_unknown:
+\cs_new_nopar:Npn \keys_execute_unknown_alt:
+ {
+ \clist_put_right:Nx \l_keys_unknown_clist
+ {
+ \exp_not:o \l_keys_key_tl
+ \bool_if:NF \l_keys_no_value_bool
+ { = { \exp_not:o \l_keys_value_tl } }
+ }
+ }
\cs_new_nopar:Npn \keys_execute:nn #1#2
{
\cs_if_exist:cTF { \c_keys_code_root_tl #1 }
@@ -402,8 +622,14 @@
\prg_new_conditional:Npnn \keys_if_exist:nn #1#2 { p , T , F , TF }
{
\cs_if_exist:cTF { \c_keys_code_root_tl #1 / #2 }
- { \prg_return_true:}
- { \prg_return_false:}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
+\prg_new_conditional:Npnn \keys_if_choice_exist:nnn #1#2#3 { p , T , F , TF }
+ {
+ \cs_if_exist:cTF { \c_keys_code_root_tl #1 / #2 / #3 }
+ { \prg_return_true: }
+ { \prg_return_false: }
}
\cs_new_nopar:Npn \keys_show:nn #1#2
{ \cs_show:c { \c_keys_code_root_tl #1 / \tl_to_str:n {#2} } }
@@ -470,6 +696,9 @@
The~key~'#1'~must~have~a~value.\\
No~value~was~present:~the~key~will~be~ignored.
}
+\cs_new_eq:NN \KV_process_space_removal_sanitize:NNn \keyval_parse:NNn
+\cs_new_eq:NN \KV_process_space_removal_no_sanitize:NNn \keyval_parse:NNn
+\cs_new_eq:NN \KV_process_no_space_removal_no_sanitize:NNn \keyval_parse:NNn
%%
%%
%% End of file `l3keys.sty'.