diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3keys.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3keys.dtx | 287 |
1 files changed, 148 insertions, 139 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx index 0f109a3d695..202cc321018 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx @@ -1,43 +1,30 @@ % \iffalse meta-comment % -%% File: l3keys.dtx Copyright (C) 2006-2016 The LaTeX3 Project -%% -%% 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 file is part of the "l3kernel bundle" (The Work in LPPL) -%% and all files in that bundle must be distributed together. -%% -%% The released version of this bundle is available from CTAN. -%% -%% ----------------------------------------------------------------------- -%% -%% The development version of the bundle can be found at -%% -%% http://www.latex-project.org/svnroot/experimental/trunk/ -%% -%% for those people who are interested. -%% -%%%%%%%%%%% -%% NOTE: %% -%%%%%%%%%%% -%% -%% Snapshots taken from the repository represent work in progress and may -%% not work or may contain conflicting material! We therefore ask -%% people _not_ to put them into distributions, archives, etc. without -%% prior consultation with the LaTeX3 Project. -%% -%% ----------------------------------------------------------------------- +%% File: l3keys.dtx Copyright (C) 2006-2017 The LaTeX3 Project +% +% 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 file is part of the "l3kernel bundle" (The Work in LPPL) +% and all files in that bundle must be distributed together. +% +% ----------------------------------------------------------------------- +% +% The development version of the bundle can be found at +% +% https://github.com/latex3/latex3 +% +% for those people who are interested. % %<*driver> \documentclass[full]{l3doc} %</driver> %<*driver|package> -\GetIdInfo$Id: l3keys.dtx 6711 2016-09-21 07:04:35Z joseph $ +\GetIdInfo$Id: l3keys.dtx 6811 2017-01-01 08:50:54Z joseph $ {L3 Key-value interfaces} %</driver|package> %<*driver> @@ -320,6 +307,26 @@ % described in Section~\ref{sec:l3keys:selective}. % \end{function} % +% \begin{function}[added = 2016-11-22]{.inherit:n} +% \begin{syntax} +% \meta{key} .inherit:n = \Arg{parents} +% \end{syntax} +% Specifies that the \meta{key} path should inherit the keys listed +% as \meta{parents}. For example, with setting +% \begin{verbatim} +% \keys_define:n { foo } { test .code:n = \tl_show:n {#1} } +% \keys_define:n { } { bar .inherit:n = foo } +% \end{verbatim} +% setting +% \begin{verbatim} +% \keys_set:n { bar } { test = a } +% \end{verbatim} +% will be equivalent to +% \begin{verbatim} +% \keys_set:n { foo } { test = a } +% \end{verbatim} +% \end{function} +% % \begin{function}[updated = 2013-07-09] % {.initial:n, .initial:V, .initial:o, .initial:x} % \begin{syntax} @@ -1115,8 +1122,9 @@ % { % \c_@@_code_root_tl , % \c_@@_default_root_tl , -% \c_@@_groups_root_tl, -% \c_@@_info_root_tl , +% \c_@@_groups_root_tl , +% \c_@@_inherit_root_tl , +% \c_@@_type_root_tl , % \c_@@_validate_root_tl % } % Various storage areas for the different data which make up keys. @@ -1124,7 +1132,8 @@ \tl_const:Nn \c_@@_code_root_tl { key~code~>~ } \tl_const:Nn \c_@@_default_root_tl { key~default~>~ } \tl_const:Nn \c_@@_groups_root_tl { key~groups~>~ } -\tl_const:Nn \c_@@_info_root_tl { key~info~>~ } +\tl_const:Nn \c_@@_inherit_root_tl { key~inherit~>~ } +\tl_const:Nn \c_@@_type_root_tl { key~type~>~ } \tl_const:Nn \c_@@_validate_root_tl { key~validate~>~ } % \end{macrocode} % \end{variable} @@ -1316,7 +1325,12 @@ { \str_if_eq:nnTF {#3} { . } { - \tl_set:Nx \l_keys_path_tl { \l_@@_module_tl / #1 } + \tl_set:Nx \l_keys_path_tl + { + \tl_if_empty:NF \l_@@_module_tl + { \l_@@_module_tl / } + #1 + } \tl_set:Nn \l_@@_property_tl { . #2 } } { @@ -1376,35 +1390,6 @@ % % \subsection{Turning properties into actions} % -% \begin{macro}[int]{\@@_ensure_exist:n, \@@_ensure_exist:V} -% Used to make sure that a key implementation and the related property -% list will exist whenever this is required. We cannot use for example -% \cs{prop_clear_new:c} here as that would affect the order in which key -% properties must be set. As key definitions are never global we use -% |\cs_set_protected:cpn| not |\cs_new_protected:cpn| here. For the -% same reason, to avoid issues if the key has been undefined in the -% current scope but exists at a higher level, we do not use \cs{prop_new:c} -% but rather \cs{prop_set_eq:cN}. The function \cs{__chk_log:x} only -% writes to the log file if logging all new functions is active: without -% it keys would not show up (as we are not using \cs[no-index]{..._new}). -% \begin{macrocode} -\cs_new_protected:Npn \@@_ensure_exist:n #1 - { - \prop_if_exist:cF { \c_@@_info_root_tl #1 } - { - \prop_set_eq:cN { \c_@@_info_root_tl #1 } \c_empty_prop - } - - \cs_if_exist:cF { \c_@@_code_root_tl #1 } - { - \__chk_log:x { Defining~key~#1~ \msg_line_context: } - \cs_set_protected:cpn { \c_@@_code_root_tl #1 } ##1 { } - } - } -\cs_generate_variant:Nn \@@_ensure_exist:n { V } -% \end{macrocode} -% \end{macro} -% % \begin{macro}[int]{\@@_bool_set:Nn, \@@_bool_set:cn} % Boolean keys are really just choices, but all done by hand. The % second argument here is the scope: either empty or \texttt{ g } for @@ -1452,13 +1437,10 @@ % \end{macro} % % \begin{macro}[int]{\@@_choice_make:, \@@_multichoice_make:} -% \begin{macro}[int]{\@@_choice_make:N} +% \begin{macro}[aux]{\@@_choice_make:N} % \begin{macro}[aux]{\@@_choice_make_aux:N} -% \begin{macro}[aux]{\@@_parent:n, \@@_parent:o} -% \begin{macro}[aux]{\@@_parent:wn} % To make a choice from a key, two steps: set the code, and set the -% unknown key. There is one point to watch here: choice keys cannot be -% nested! As multichoices and choices are essentially the same bar one +% unknown key. As multichoices and choices are essentially the same bar one % function, the code is given together. % \begin{macrocode} \cs_new_protected:Npn \@@_choice_make: @@ -1467,12 +1449,12 @@ { \@@_choice_make:N \@@_multichoice_find:n } \cs_new_protected:Npn \@@_choice_make:N #1 { - \prop_if_exist:cTF - { \c_@@_info_root_tl \@@_parent:o \l_keys_path_tl } + \cs_if_exist:cTF + { \c_@@_type_root_tl \@@_parent:o \l_keys_path_tl } { - \prop_get:cnNTF - { \c_@@_info_root_tl \@@_parent:o \l_keys_path_tl } - { choice } \l_keys_value_tl + \str_if_eq_x:nnTF + { \exp_not:v { \c_@@_type_root_tl \@@_parent:o \l_keys_path_tl } } + { choice } { \__msg_kernel_error:nnxx { kernel } { nested-choice-key } { \l_keys_path_tl } { \@@_parent:o \l_keys_path_tl } @@ -1483,32 +1465,18 @@ } \cs_new_protected:Npn \@@_choice_make_aux:N #1 { + \cs_set_nopar:cpn { \c_@@_type_root_tl \l_keys_path_tl } { choice } \@@_cmd_set:nn { \l_keys_path_tl } { #1 {##1} } - \prop_put:cnn { \c_@@_info_root_tl \l_keys_path_tl } { choice } - { true } \@@_cmd_set:nn { \l_keys_path_tl / unknown } { \__msg_kernel_error:nnxx { kernel } { key-choice-unknown } { \l_keys_path_tl } {##1} } } -\cs_new:Npn \@@_parent:n #1 - { \@@_parent:wn #1 / / \q_stop { } } -\cs_generate_variant:Nn \@@_parent:n { o } -\cs_new:Npn \@@_parent:wn #1 / #2 / #3 \q_stop #4 - { - \tl_if_blank:nTF {#2} - { \use_none:n #4 } - { - \@@_parent:wn #2 / #3 \q_stop { #4 / #1 } - } - } % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} % % \begin{macro}[int]{\@@_choices_make:nn, \@@_multichoices_make:nn} % \begin{macro}[aux]{\@@_choices_make:Nnn} @@ -1546,7 +1514,8 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_cmd_set:nn #1#2 { - \@@_ensure_exist:V \l_keys_path_tl + \cs_if_exist:cF { \c_@@_code_root_tl #1 } + { \__chk_log:x { Defining~key~#1~\msg_line_context: } } \cs_set_protected:cpn { \c_@@_code_root_tl #1 } ##1 {#2} } \cs_generate_variant:Nn \@@_cmd_set:nn { nx , Vn , Vo } @@ -1575,27 +1544,39 @@ % \end{macro} % % \begin{macro}[int]{\@@_groups_set:n} -% Assigning a key to one or more groups uses comma lists. So that the comma -% list is \enquote{well-behaved} later, the storage is done via a stored -% list here, which does the normalisation. +% Assigning a key to one or more groups uses comma lists. As the list of +% groups only exists if there is anything to do, the setting is done using +% a scratch list. For the usual grouping reasons we use the low-level +% approach to undefining a list. % \begin{macrocode} \cs_new_protected:Npn \@@_groups_set:n #1 { - \@@_ensure_exist:V \l_keys_path_tl \clist_set:Nn \l_@@_groups_clist {#1} \clist_if_empty:NTF \l_@@_groups_clist { - \prop_remove:cn { \c_@@_info_root_tl \l_keys_path_tl } - { groups } + \cs_set_eq:cN { \c_@@_groups_root_tl \l_keys_path_tl } + \tex_undefined:D } { - \prop_put:cnV { \c_@@_info_root_tl \l_keys_path_tl } - { groups } \l_@@_groups_clist + \clist_set_eq:cN { \c_@@_groups_root_tl \l_keys_path_tl } + \l_@@_groups_clist } } % \end{macrocode} % \end{macro} % +% \begin{macro}[int]{\@@_inherit:n} +% Inheritance means ignoring anything already said about the key: +% zap the lot and set up. +% \begin{macrocode} +\cs_new_protected:Npn \@@_inherit:n #1 + { + \@@_undefine: + \cs_set_nopar:cpn { \c_@@_inherit_root_tl \l_keys_path_tl } {#1} + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}[int]{\@@_initialise:n} % A set up for initialisation: just run the code if it exists. % \begin{macrocode} @@ -1631,7 +1612,7 @@ \cs_new_protected:Npn \@@_undefine: { \clist_map_inline:nn - { code , default , groups , info , validate } + { code , default , groups , inherit , type , validate } { \cs_set_eq:cN { \tl_use:c { c_@@_ ##1 _root_tl } \l_keys_path_tl } @@ -1866,6 +1847,14 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{.inherit:n} +% Nothing complex: only one variant at the moment! +% \begin{macrocode} +\cs_new_protected:cpn { \c_@@_props_root_tl .inherit:n } #1 + { \@@_inherit:n {#1} } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{.initial:n, .initial:V, .initial:o, .initial:x} % The standard hand-off approach. % \begin{macrocode} @@ -2143,7 +2132,12 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_set_aux:nnn #1#2#3 { - \tl_set:Nx \l_keys_path_tl { #1 / \@@_remove_spaces:n {#2} } + \tl_set:Nx \l_keys_path_tl + { + \tl_if_blank:nF {#1} + { #1 / } + \@@_remove_spaces:n {#2} + } \tl_clear:N \l_@@_module_tl \exp_after:wN \@@_find_key_module:w \l_keys_path_tl / \q_stop \@@_value_or_default:n {#3} @@ -2174,16 +2168,11 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_set_selective: { - \prop_if_exist:cTF { \c_@@_info_root_tl \l_keys_path_tl } + \cs_if_exist:cTF { \c_@@_groups_root_tl \l_keys_path_tl } { - \prop_get:cnNTF { \c_@@_info_root_tl \l_keys_path_tl } - { groups } \l_@@_groups_clist - { \@@_check_groups: } - { - \bool_if:NTF \l_@@_filtered_bool - { \@@_execute: } - { \@@_store_unused: } - } + \clist_set_eq:Nc \l_@@_groups_clist + { \c_@@_groups_root_tl \l_keys_path_tl } + \@@_check_groups: } { \bool_if:NTF \l_@@_filtered_bool @@ -2274,23 +2263,41 @@ \bool_if:NTF \l_@@_only_known_bool { \@@_store_unused: } { - \cs_if_exist:cTF { \c_@@_code_root_tl \l_@@_module_tl / unknown } + \cs_if_exist:cTF + { \c_@@_inherit_root_tl \@@_parent:o \l_keys_path_tl } { - \cs:w \c_@@_code_root_tl \l_@@_module_tl / unknown \exp_after:wN - \cs_end: \exp_after:wN { \l_keys_value_tl } + \clist_map_inline:cn + { \c_@@_inherit_root_tl \@@_parent:o \l_keys_path_tl } + { + \cs_if_exist:cT + { \c_@@_code_root_tl ##1 / \l_keys_key_tl } + { + \cs:w \c_@@_code_root_tl ##1 / \l_keys_key_tl + \exp_after:wN \cs_end: \exp_after:wN + { \l_keys_value_tl } + \clist_map_break: + } + } } { - \__msg_kernel_error:nnxx { kernel } { key-unknown } - { \l_keys_path_tl } { \l_@@_module_tl } + \cs_if_exist:cTF { \c_@@_code_root_tl \l_@@_module_tl / unknown } + { + \cs:w \c_@@_code_root_tl \l_@@_module_tl / unknown + \exp_after:wN \cs_end: \exp_after:wN { \l_keys_value_tl } + } + { + \__msg_kernel_error:nnxx { kernel } { key-unknown } + { \l_keys_path_tl } { \l_@@_module_tl } + } } - } + } } \cs_new:Npn \@@_execute:nn #1#2 { \cs_if_exist:cTF { \c_@@_code_root_tl #1 } { - \exp_args:Nc \exp_args:No { \c_@@_code_root_tl #1 } - \l_keys_value_tl + \cs:w \c_@@_code_root_tl #1 \exp_after:wN \cs_end: + \exp_after:wN { \l_keys_value_tl } } {#2} } @@ -2328,6 +2335,25 @@ % % \subsection{Utilities} % +% \begin{macro}[EXP, int]{\@@_parent:n, \@@_parent:o} +% \begin{macro}[EXP, aux]{\@@_parent:w} +% Used to strip off the ending part of the key path after the last~|/|. +% \begin{macrocode} +\cs_new:Npn \@@_parent:n #1 + { \@@_parent:w #1 / / \q_stop { } } +\cs_generate_variant:Nn \@@_parent:n { o } +\cs_new:Npn \@@_parent:w #1 / #2 / #3 \q_stop #4 + { + \tl_if_blank:nTF {#2} + { \use_none:n #4 } + { + \@@_parent:w #2 / #3 \q_stop { #4 / #1 } + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macro}[EXP, int]{\@@_remove_spaces:n} % \begin{macro}[EXP, aux]{\@@_remove_spaces:w} % Removes all spaces from the input which is detokenized as a result. @@ -2375,7 +2401,7 @@ % \end{macro} % % \begin{macro}{\keys_show:nn} -% \begin{macro}[aux]{\@@_show:NN} +% \begin{macro}[aux]{\@@_show:N} % To show a key, test for its existence to issue the correct message % (same message, but with a |t| or |f| argument, then build the % control sequences which contain the code and other information @@ -2389,9 +2415,8 @@ { \__msg_show_pre:nnxxxx { LaTeX / kernel } { show-key } { \@@_remove_spaces:n { #1 / #2 } } { t } { } { } - \exp_args:Ncc \@@_show:NN + \exp_args:Nc \@@_show:N { \c_@@_code_root_tl \@@_remove_spaces:n { #1 / #2 } } - { \c_@@_info_root_tl \@@_remove_spaces:n { #1 / #2 } } } { \__msg_show_pre:nnxxxx { LaTeX / kernel } { show-key } @@ -2399,7 +2424,7 @@ \__msg_show_wrap:n { } } } -\cs_new_protected:Npn \@@_show:NN #1#2 +\cs_new_protected:Npn \@@_show:N #1 { \use:x { @@ -2407,8 +2432,6 @@ { \exp_not:N \__msg_show_item_unbraced:nn { code } { \token_get_replacement_spec:N #1 } - \exp_not:n - { \prop_map_function:NN #2 \__msg_show_item_unbraced:nn } } } } @@ -2491,20 +2514,6 @@ } % \end{macrocode} % -% \subsection{Deprecated functions} -% -% \begin{macro}[deprecated = 2017]{.value_forbidden:} -% \begin{macro}{.value_required:} -% Deprecated 2015-07-14. -% \begin{macrocode} -\cs_new_protected:cpn { \c_@@_props_root_tl .value_forbidden: } - { \@@_value_requirement:nn { forbidden } { true } } -\cs_new_protected:cpn { \c_@@_props_root_tl .value_required: } - { \@@_value_requirement:nn { required } { true } } -% \end{macrocode} -% \end{macro} -% \end{macro} -% % \begin{macrocode} %</initex|package> % \end{macrocode} |