summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2013-07-28 21:53:53 +0000
committerKarl Berry <karl@freefriends.org>2013-07-28 21:53:53 +0000
commit476ef285597d50560f829ffd64532d75d937d06a (patch)
tree5c652f3fb3c6e7458bb762f660a005e2f77c3f80 /Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
parent9cad0f5f2f5f3df83a79cca1d848bf3a5feef241 (diff)
latex3 (28jul13)
git-svn-id: svn://tug.org/texlive/trunk@31299 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3keys.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3keys.dtx480
1 files changed, 350 insertions, 130 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
index 3ad30990c73..e5c80030f7e 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
@@ -35,7 +35,7 @@
%
%<*driver|package>
\RequirePackage{l3bootstrap}
-\GetIdInfo$Id: l3keys.dtx 4544 2013-07-12 07:14:52Z joseph $
+\GetIdInfo$Id: l3keys.dtx 4581 2013-07-28 08:38:50Z joseph $
{L3 Experimental key-value interfaces}
%</driver|package>
%<*driver>
@@ -122,7 +122,7 @@
%
% Key names may contain any tokens, as they are handled internally
% using \cs{tl_to_str:n}. As will be discussed in
-% section~\ref{sec:subdivision}, it is suggested that the character
+% section~\ref{sec:l3keys:subdivision}, it is suggested that the character
% |/| is reserved for sub-division of keys into logical
% groups. Functions and variables are \emph{not} expanded when creating
% key names, and so
@@ -281,6 +281,16 @@
% (which must a floating point expression). If the variable does not exist,
% it will be created globally at the point that the key is set up.
% \end{function}
+%
+% \begin{function}[added = 2013-07-14]
+% {.groups:n}
+% \begin{syntax}
+% \meta{key} .groups:n = \meta{groups}
+% \end{syntax}
+% Defines \meta{key} as belonging to the \meta{groups} declared. Groups
+% provide a \enquote{secondary axis} for selectively setting keys, and are
+% described in Section~\ref{sec:l3keys:selective}.
+% \end{function}
%
% \begin{function}[updated = 2013-07-09]
% {.initial:n, .initial:V, .initial:o, .initial:x}
@@ -391,7 +401,7 @@
% \end{function}
%
% \section{Sub-dividing keys}
-% \label{sec:subdivision}
+% \label{sec:l3keys:subdivision}
%
% When creating large numbers of keys, it may be desirable to divide
% them into several sub-groups for a given module. This can be achieved
@@ -612,10 +622,12 @@
% \begin{function}[added = 2011-08-23]
% {
% \keys_set_known:nnN, \keys_set_known:nVN,
-% \keys_set_known:nvN, \keys_set_known:noN
+% \keys_set_known:nvN, \keys_set_known:noN,
+% \keys_set_known:nn, \keys_set_known:nV,
+% \keys_set_known:nv, \keys_set_known:no
% }
% \begin{syntax}
-% \cs{keys_set_known:nn} \Arg{module} \Arg{keyval list} \meta{tl}
+% \cs{keys_set_known:nnN} \Arg{module} \Arg{keyval list} \meta{tl}
% \end{syntax}
% In some cases, the desired behavior is to simply ignore unknown keys,
% collecting up information on these for later processing. The
@@ -624,7 +636,81 @@
% are not processed further by the parser.
% The key--value pairs for each \emph{unknown} key name will be
% stored in the \meta{tl} in a comma-separated form (\emph{i.e.}~an edited
-% version of the \meta{keyval list}).
+% version of the \meta{keyval list}). The \cs{keys_set_known:nn} version skips
+% this stage.
+% \end{function}
+%
+% \section{Selective key setting}
+% \label{sec:l3keys:selective}
+%
+% In some cases it may be useful to be able to select only some keys for
+% setting, even though these keys have the same path. For example, with
+% a set of keys defined using
+% \begin{verbatim}
+% \keys define:nn { mymodule }
+% {
+% key-one .code:n = { \my_func:n {#1} } ,
+% key-two .tl_set:N = \l_my_a_tl ,
+% key-three .tl_set:N = \l_my_b_tl ,
+% key-four .fp_set:N = \l_my_a_fp ,
+% }
+% \end{verbatim}
+% the use of \cs{keys_set:nn} will attempt to set all four keys. However, in
+% some contexts it may only be sensible to set some keys, or to control the
+% order of setting. To do this, keys may be assigned to \emph{groups}:
+% arbitrary sets which are independent of the key tree. Thus modifying the
+% example to read
+% \begin{verbatim}
+% \keys define:nn { mymodule }
+% {
+% key-one .code:n = { \my_func:n {#1} } ,
+% key-one .groups:n = { first } ,
+% key-two .tl_set:N = \l_my_a_tl ,
+% key-two .groups:n = { first } ,
+% key-three .tl_set:N = \l_my_b_tl ,
+% key-three .groups:n = { second } ,
+% key-four .fp_set:N = \l_my_a_fp ,
+% }
+% \end{verbatim}
+% will assign \texttt{key-one} and \texttt{key-two} to group \texttt{first},
+% \texttt{key-three} to group \texttt{second}, while \texttt{key-four} is
+% not assigned to a group.
+%
+% Selective key setting may be achieved either by selecting one or more
+% groups to be made \enquote{active}, or by marking one or more groups to
+% be ignored in key setting.
+%
+% \begin{function}[added = 2013-07-14]
+% {
+% \keys_set_filter:nnnN, \keys_set_filter:nnVN,
+% \keys_set_filter:nnvN, \keys_set_filter:nnoN,
+% \keys_set_filter:nnn, \keys_set_filter:nnV,
+% \keys_set_filter:nnv, \keys_set_filter:nno
+% }
+% \begin{syntax}
+% \cs{keys_set_filter:nnnN} \Arg{module} \Arg{groups} \Arg{keyval list} \meta{tl}
+% \end{syntax}
+% Actives key filtering in an \enquote{opt-out} sense: keys assigned to any
+% of the \meta{groups} specified will be ignored. The \meta{groups} are
+% given as a comma-separated list. Unknown keys are not assigned to any
+% group and will thus always be set. The key--value pairs for each
+% key which is filtered out will be stored in the \meta{tl} in a
+% comma-separated form (\emph{i.e.}~an edited version of the \meta{keyval
+% list}). The \cs{keys_set_filter:nnn} version skips this stage.
+% \end{function}
+%
+% \begin{function}[added = 2013-07-14]
+% {
+% \keys_set_groups:nnn, \keys_set_groups:nnV,
+% \keys_set_groups:nnv, \keys_set_groups:nno
+% }
+% \begin{syntax}
+% \cs{keys_set_groups:nnn} \Arg{module} \Arg{groups} \Arg{keyval list}
+% \end{syntax}
+% Actives key filtering in an \enquote{opt-in} sense: only keys assigned to
+% one or more of the \meta{groups} specified will be set. The \meta{groups} are
+% given as a comma-separated list. Unknown keys are not assigned to any
+% group and will thus never be set.
% \end{function}
%
% \section{Utility functions for keys}
@@ -968,11 +1054,11 @@
%<@@=keys>
% \end{macrocode}
%
-% \begin{variable}{\c_@@_code_root_tl, \c_@@_vars_root_tl}
+% \begin{variable}{\c_@@_code_root_tl, \c_@@_info_root_tl}
% The prefixes for the code and variables of the keys themselves.
% \begin{macrocode}
\tl_const:Nn \c_@@_code_root_tl { key~code~>~ }
-\tl_const:Nn \c_@@_vars_root_tl { key~var~>~ }
+\tl_const:Nn \c_@@_info_root_tl { key~info~>~ }
% \end{macrocode}
% \end{variable}
%
@@ -983,14 +1069,6 @@
% \end{macrocode}
% \end{variable}
%
-% \begin{variable}{\c_@@_value_forbidden_tl, \c_@@_value_required_tl}
-% Two marker token lists.
-% \begin{macrocode}
-\tl_const:Nn \c_@@_value_forbidden_tl { forbidden }
-\tl_const:Nn \c_@@_value_required_tl { required }
-% \end{macrocode}
-% \end{variable}
-%
% \begin{variable}{\l_keys_choice_int, \l_keys_choice_tl}
% Publicly accessible data on which choice is being used when several
% are generated as a set.
@@ -999,6 +1077,15 @@
\tl_new:N \l_keys_choice_tl
% \end{macrocode}
% \end{variable}
+%
+% \begin{variable}{\l_@@_groups_clist}
+% Used for storing and recovering the list of groups which apply to a key:
+% set as a comma list but at one point we have to use this for a token
+% list recovery.
+% \begin{macrocode}
+\clist_new:N \l_@@_groups_clist
+% \end{macrocode}
+% \end{variable}
%
% \begin{variable}{\l_keys_key_tl}
% The name of a key itself: needed when setting keys.
@@ -1021,6 +1108,13 @@
\bool_new:N \l_@@_no_value_bool
% \end{macrocode}
% \end{variable}
+%
+% \begin{variable}{\l_@@_only_known_bool}
+% Used to track if only \enquote{known} keys are being set.
+% \begin{macrocode}
+\bool_new:N \l_@@_only_known_bool
+% \end{macrocode}
+% \end{variable}
%
% \begin{variable}{\l_keys_path_tl}
% The \enquote{path} of the current key is stored here: this is
@@ -1037,11 +1131,28 @@
\tl_new:N \l_@@_property_tl
% \end{macrocode}
% \end{variable}
+%
+% \begin{variable}{\l_@@_selective_bool, \l_@@_filtered_bool}
+% Two flags for using key groups: one to indicate that \enquote{selective}
+% setting is active, a second to specify which type (\enquote{opt-in}
+% or \enquote{opt-out}).
+% \begin{macrocode}
+\bool_new:N \l_@@_selective_bool
+\bool_new:N \l_@@_filtered_bool
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_@@_selective_seq}
+% The list of key groups being filtered in or out during selective setting.
+% \begin{macrocode}
+\seq_new:N \l_@@_selective_seq
+% \end{macrocode}
+% \end{variable}
%
-% \begin{variable}{\l_@@_unknown_clist}
-% Used when setting only known keys to store those left over.
+% \begin{variable}{\l_@@_unused_clist}
+% Used when setting only some keys to store those left over.
% \begin{macrocode}
-\tl_new:N \l_@@_unknown_clist
+\tl_new:N \l_@@_unused_clist
% \end{macrocode}
% \end{variable}
%
@@ -1051,6 +1162,13 @@
\tl_new:N \l_keys_value_tl
% \end{macrocode}
% \end{variable}
+%
+% \begin{variable}{\l_@@_tmp_bool}
+% Scratch space.
+% \begin{macrocode}
+\bool_new:N \l_@@_tmp_bool
+% \end{macrocode}
+% \end{variable}
%
% \subsection{The key defining mechanism}
%
@@ -1259,31 +1377,43 @@
%
% \begin{macro}[int]
% {\@@_cmd_set:nn, \@@_cmd_set:nx, \@@_cmd_set:Vn, \@@_cmd_set:Vo}
-% \begin{macro}[aux]{\@@_cmd_set:n}
% Creating a new command means tidying up the properties and then making
% the internal function which actually does the work.
% \begin{macrocode}
\cs_new_protected:Npn \@@_cmd_set:nn #1#2
{
- \@@_cmd_set:n {#1}
+ \prop_clear_new:c { \c_@@_info_root_tl #1 }
\cs_set:cpn { \c_@@_code_root_tl #1 } ##1 {#2}
}
\cs_generate_variant:Nn \@@_cmd_set:nn { nx , Vn , Vo }
-\cs_new_protected:Npn \@@_cmd_set:n #1
- {
- \tl_clear_new:c { \c_@@_vars_root_tl #1 .default }
- \tl_set:cn { \c_@@_vars_root_tl #1 .default } { \q_no_value }
- \tl_clear_new:c { \c_@@_vars_root_tl #1 .req }
- }
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
% \begin{macro}[int]{\@@_default_set:n}
% Setting a default value is easy.
% \begin{macrocode}
\cs_new_protected:Npn \@@_default_set:n #1
- { \tl_set:cn { \c_@@_vars_root_tl \l_keys_path_tl .default } {#1} }
+ {
+ \prop_if_exist:cT { \c_@@_info_root_tl \l_keys_path_tl }
+ { \prop_put:cnn { \c_@@_info_root_tl \l_keys_path_tl } { default } {#1} }
+ }
+% \end{macrocode}
+% \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.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_groups_set:n #1
+ {
+ \prop_if_exist:cT { \c_@@_info_root_tl \l_keys_path_tl }
+ {
+ \clist_set:Nn \l_@@_groups_clist {#1}
+ \prop_put:cnV { \c_@@_info_root_tl \l_keys_path_tl }
+ { groups } \l_@@_groups_clist
+ }
+ }
% \end{macrocode}
% \end{macro}
%
@@ -1359,13 +1489,16 @@
%
% \begin{macro}[int]{\@@_value_requirement:n}
% Values can be required or forbidden by having the appropriate marker
-% set.
+% set. First, both the required and forbidden ones are clear, just in case!
% \begin{macrocode}
\cs_new_protected:Npn \@@_value_requirement:n #1
{
- \tl_set_eq:cc
- { \c_@@_vars_root_tl \l_keys_path_tl .req }
- { c_@@_value_ #1 _tl }
+ \prop_if_exist:cT { \c_@@_info_root_tl \l_keys_path_tl }
+ {
+ \prop_remove:cn { \c_@@_info_root_tl \l_keys_path_tl } { required }
+ \prop_remove:cn { \c_@@_info_root_tl \l_keys_path_tl } { forbidden }
+ \prop_put:cnn { \c_@@_info_root_tl \l_keys_path_tl } {#1} { true }
+ }
}
% \end{macrocode}
% \end{macro}
@@ -1522,6 +1655,14 @@
% \end{macrocode}
% \end{macro}
% \end{macro}
+%
+% \begin{macro}{.groups:n}
+% A single property to create groups of keys.
+% \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_tl .groups:n } #1
+ { \@@_groups_set:n {#1} }
+% \end{macrocode}
+% \end{macro}
%
% \begin{macro}{.initial:n, .initial:V, .initial:o, .initial:x}
% The standard hand-off approach.
@@ -1656,7 +1797,7 @@
% \begin{macro}[aux]{\@@_set:nnn, \@@_set:onn}
% A simple wrapper again.
% \begin{macrocode}
-\cs_new_protected:Npn \keys_set:nn
+\cs_new_protected_nopar:Npn \keys_set:nn
{ \@@_set:onn { \l_@@_module_tl } }
\cs_new_protected:Npn \@@_set:nnn #1#2#3
{
@@ -1675,28 +1816,83 @@
% \keys_set_known:nnN, \keys_set_known:nVN,
% \keys_set_known:nvN, \keys_set_known:noN
% }
-% \begin{macro}[aux]{\@@_set_known:nnnN, \@@_set_known:onnN}
+% \begin{macro}
+% {
+% \keys_set_known:nn, \keys_set_known:nV,
+% \keys_set_known:nv, \keys_set_known:no
+% }
+% Setting known keys simply means setting the appropriate flag, then
+% running the standard code.
% \begin{macrocode}
-\cs_new_protected:Npn \keys_set_known:nnN
- { \@@_set_known:onnN { \l_@@_module_tl } }
-\cs_new_protected:Npn \@@_set_known:nnnN #1#2#3#4
+\cs_new_protected:Npn \keys_set_known:nnN #1#2#3
{
- \tl_set:Nx \l_@@_module_tl { \tl_to_str:n {#2} }
- \clist_clear:N \l_@@_unknown_clist
- \cs_set_eq:NN \@@_execute_unknown: \@@_execute_unknown_alt:
- \keyval_parse:NNn \@@_set_elt:n \@@_set_elt:nn {#3}
- \cs_set_eq:NN \@@_execute_unknown: \@@_execute_unknown_std:
- \tl_set:Nn \l_@@_module_tl {#1}
- \cs_set_eq:NN #4 \l_@@_unknown_clist
+ \clist_clear:N \l_@@_unused_clist
+ \keys_set_known:nn {#1} {#2}
+ \tl_set:Nx #3 { \exp_not:o { \l_@@_unused_clist } }
}
\cs_generate_variant:Nn \keys_set_known:nnN { nV , nv , no }
-\cs_generate_variant:Nn \@@_set_known:nnnN { o }
+\cs_new_protected:Npn \keys_set_known:nn #1#2
+ {
+ \bool_set_true:N \l_@@_only_known_bool
+ \keys_set:nn {#1} {#2}
+ \bool_set_false:N \l_@@_only_known_bool
+ }
+\cs_generate_variant:Nn \keys_set_known:nn { nV , nv , no }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \keys_set_filter:nnnN, \keys_set_filter:nnVN, \keys_set_filter:nnvN
+% \keys_set_filter:nnoN
+% }
+% \begin{macro}
+% {
+% \keys_set_filter:nnn, \keys_set_filter:nnV, \keys_set_filter:nnv
+% \keys_set_filter:nno
+% }
+% \begin{macro}
+% {
+% \keys_set_groups:nnn, \keys_set_groups:nnV, \keys_set_groups:nnv
+% \keys_set_groups:nno
+% }
+% The idea of setting keys in a selective manner again uses flags
+% wrapped around the basic code.
+% \begin{macrocode}
+\cs_new_protected:Npn \keys_set_filter:nnnN #1#2#3#4
+ {
+ \clist_clear:N \l_@@_unused_clist
+ \keys_set_filter:nnn {#1} {#2} {#3}
+ \tl_set:Nx #4 { \exp_not:o { \l_@@_unused_clist } }
+ }
+\cs_generate_variant:Nn \keys_set_filter:nnnN { nnV , nnv , nno }
+\cs_new_protected:Npn \keys_set_filter:nnn #1#2#3
+ {
+ \bool_set_true:N \l_@@_selective_bool
+ \bool_set_true:N \l_@@_filtered_bool
+ \seq_set_from_clist:Nn \l_@@_selective_seq {#2}
+ \keys_set:nn {#1} {#3}
+ \bool_set_false:N \l_@@_selective_bool
+ }
+\cs_generate_variant:Nn \keys_set_filter:nnn { nnV , nnv , nno }
+\cs_new_protected:Npn \keys_set_groups:nnn #1#2#3
+ {
+ \bool_set_true:N \l_@@_selective_bool
+ \bool_set_false:N \l_@@_filtered_bool
+ \seq_set_from_clist:Nn \l_@@_selective_seq {#2}
+ \keys_set:nn {#1} {#3}
+ \bool_set_false:N \l_@@_selective_bool
+ }
+\cs_generate_variant:Nn \keys_set_groups:nnn { nnV , nnv , nno }
% \end{macrocode}
% \end{macro}
% \end{macro}
+% \end{macro}
%
% \begin{macro}[int]{\@@_set_elt:n, \@@_set_elt:nn}
% \begin{macro}[aux]{\@@_set_elt_aux:nn}
+% \begin{macro}[aux]{\@@_set_elt_aux:, \@@_set_elt_selective:}
% A shared system once again. First, set the current path and add a
% default if needed. There are then checks to see if the a value is
% required or forbidden. If everything passes, move on to execute the
@@ -1717,6 +1913,12 @@
\tl_set:Nx \l_keys_key_tl { \tl_to_str:n {#1} }
\tl_set:Nx \l_keys_path_tl { \l_@@_module_tl / \l_keys_key_tl }
\@@_value_or_default:n {#2}
+ \bool_if:NTF \l_@@_selective_bool
+ { \@@_set_elt_selective: }
+ { \@@_set_elt_aux: }
+ }
+\cs_new_protected_nopar:Npn \@@_set_elt_aux:
+ {
\bool_if:nTF
{
\@@_if_value_p:n { required } &&
@@ -1740,6 +1942,64 @@
}
}
% \end{macrocode}
+% If selective setting is active, there are a number of possible sub-cases
+% to consider. The key name may not be known at all or if it is, it may not
+% have any groups assigned. There is then the question of whether the
+% selection is opt-in or opt-out.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_set_elt_selective:
+ {
+ \prop_if_exist:cTF { \c_@@_info_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
+ { \@@_set_elt_aux: }
+ { \@@_store_unused: }
+ }
+ }
+ {
+ \bool_if:NTF \l_@@_filtered_bool
+ { \@@_set_elt_aux: }
+ { \@@_store_unused: }
+ }
+ }
+% \end{macrocode}
+% In the case where selective setting requires a comparison of the list
+% of groups which apply to a key with the list of those which have been
+% set active. That requires two mappings, and again a different outcome
+% depending on whether opt-in or opt-out is set.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \@@_check_groups:
+ {
+ \bool_set_false:N \l_@@_tmp_bool
+ \seq_map_inline:Nn \l_@@_selective_seq
+ {
+ \clist_map_inline:Nn \l_@@_groups_clist
+ {
+ \str_if_eq:nnT {##1} {####1}
+ {
+ \bool_set_true:N \l_@@_tmp_bool
+ \clist_map_break:n { \seq_map_break: }
+ }
+ }
+ }
+ \bool_if:NTF \l_@@_tmp_bool
+ {
+ \bool_if:NTF \l_@@_filtered_bool
+ { \@@_store_unused: }
+ { \@@_set_elt_aux: }
+ }
+ {
+ \bool_if:NTF \l_@@_filtered_bool
+ { \@@_set_elt_aux: }
+ { \@@_store_unused: }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
% \end{macro}
% \end{macro}
%
@@ -1749,18 +2009,13 @@
% \begin{macrocode}
\cs_new_protected:Npn \@@_value_or_default:n #1
{
- \tl_set:Nn \l_keys_value_tl {#1}
- \bool_if:NT \l_@@_no_value_bool
+ \bool_if:NTF \l_@@_no_value_bool
{
- \quark_if_no_value:cF { \c_@@_vars_root_tl \l_keys_path_tl .default }
- {
- \cs_if_exist:cT { \c_@@_vars_root_tl \l_keys_path_tl .default }
- {
- \tl_set_eq:Nc \l_keys_value_tl
- { \c_@@_vars_root_tl \l_keys_path_tl .default }
- }
- }
+ \prop_get:cnNF { \c_@@_info_root_tl \l_keys_path_tl }
+ { default } \l_keys_value_tl
+ { \tl_clear:N \l_keys_value_tl }
}
+ { \tl_set:Nn \l_keys_value_tl {#1} }
}
% \end{macrocode}
% \end{macro}
@@ -1771,44 +2026,39 @@
% \begin{macrocode}
\prg_new_conditional:Npnn \@@_if_value:n #1 { p }
{
- \tl_if_eq:ccTF { c_@@_value_ #1 _tl }
- { \c_@@_vars_root_tl \l_keys_path_tl .req }
- { \prg_return_true: }
+ \prop_if_exist:cTF { \c_@@_info_root_tl \l_keys_path_tl }
+ {
+ \prop_if_in:cnTF { \c_@@_info_root_tl \l_keys_path_tl } {#1}
+ { \prg_return_true: }
+ { \prg_return_false: }
+ }
{ \prg_return_false: }
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[int]{\@@_execute:}
-% \begin{macro}[aux]
-% {
-% \@@_execute_unknown:,
-% \@@_execute_unknown_std:,
-% \@@_execute_unknown_alt:
-% }
+% \begin{macro}[aux]{\@@_execute_unknown:}
% \begin{macro}[aux, EXP]{\@@_execute:nn}
+% \begin{macro}[aux]{\@@_store_unused:}
% Actually executing a key is done in two parts. First, look for the
% key itself, then look for the \texttt{unknown} key with the same
-% path. If both of these fail, complain.
+% path. If both of these fail, complain. What exactly happens if a key
+% is unknown depends on whether unknown keys are being skipped or if
+% an error should be raised.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \@@_execute:
{ \@@_execute:nn { \l_keys_path_tl } { \@@_execute_unknown: } }
\cs_new_protected_nopar:Npn \@@_execute_unknown:
{
- \@@_execute:nn { \l_@@_module_tl / unknown }
- {
- \__msg_kernel_error:nnxx { kernel } { key-unknown }
- { \l_keys_path_tl } { \l_@@_module_tl }
- }
- }
-\cs_new_eq:NN \@@_execute_unknown_std: \@@_execute_unknown:
-\cs_new_protected_nopar:Npn \@@_execute_unknown_alt:
- {
- \clist_put_right:Nx \l_@@_unknown_clist
+ \bool_if:NTF \l_@@_only_known_bool
+ { \@@_store_unused: }
{
- \exp_not:o \l_keys_key_tl
- \bool_if:NF \l_@@_no_value_bool
- { = { \exp_not:o \l_keys_value_tl } }
+ \@@_execute:nn { \l_@@_module_tl / unknown }
+ {
+ \__msg_kernel_error:nnxx { kernel } { key-unknown }
+ { \l_keys_path_tl } { \l_@@_module_tl }
+ }
}
}
\cs_new:Npn \@@_execute:nn #1#2
@@ -1820,10 +2070,20 @@
}
{#2}
}
+\cs_new_protected_nopar:Npn \@@_store_unused:
+ {
+ \clist_put_right:Nx \l_@@_unused_clist
+ {
+ \exp_not:o \l_keys_key_tl
+ \bool_if:NF \l_@@_no_value_bool
+ { = { \exp_not:o \l_keys_value_tl } }
+ }
+ }
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
%
% \begin{macro}[int, EXP]{\@@_choice_find:n}
% Executing a choice has two parts. First, try the choice given, then
@@ -1934,46 +2194,34 @@
% \end{macrocode}
%
% \subsection{Deprecated functions}
-%
-% Deprecated on 2013-07-09.
%
% \begin{macro}[int]{\@@_choice_code_store:n, \@@_choice_code_store:x}
-% The code for making multiple choices is stored in a token list.
+% \begin{macro}{.choice_code:n, .choice_code:x}
+% \begin{macro}[int]{\@@_choices_generate:n}
+% \begin{macro}[aux]{\@@_choices_generate_aux:n}
+% \begin{macro}{.generate_choices:n}
+% Deprecated on 2013-07-09.
% \begin{macrocode}
\cs_new_protected:Npn \@@_choice_code_store:n #1
{
\cs_if_exist:cF
- { \c_@@_vars_root_tl \l_keys_path_tl .choice~code }
+ { \c_@@_info_root_tl \l_keys_path_tl .choice~code }
{
\tl_new:c
- { \c_@@_vars_root_tl \l_keys_path_tl .choice~code }
+ { \c_@@_info_root_tl \l_keys_path_tl .choice~code }
}
- \tl_set:cn { \c_@@_vars_root_tl \l_keys_path_tl .choice~code }
+ \tl_set:cn { \c_@@_info_root_tl \l_keys_path_tl .choice~code }
{#1}
}
\cs_generate_variant:Nn \@@_choice_code_store:n { x }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{.choice_code:n, .choice_code:x}
-% Storing the code for choices
-% \begin{macrocode}
\cs_new_protected:cpn { \c_@@_props_root_tl .choice_code:n } #1
{ \@@_choice_code_store:n {#1} }
\cs_new_protected:cpn { \c_@@_props_root_tl .choice_code:x } #1
{ \@@_choice_code_store:x {#1} }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[int]{\@@_choices_generate:n}
-% \begin{macro}[aux]{\@@_choices_generate_aux:n}
-% Creating multiple-choices means setting up the \enquote{indicator}
-% code, then applying whatever the user wanted.
-% \begin{macrocode}
\cs_new_protected:Npn \@@_choices_generate:n #1
{
\cs_if_exist:cTF
- { \c_@@_vars_root_tl \l_keys_path_tl .choice~code }
+ { \c_@@_info_root_tl \l_keys_path_tl .choice~code }
{
\@@_choice_make:
\int_zero:N \l_keys_choice_int
@@ -1993,7 +2241,7 @@
\int_set:Nn \exp_not:N \l_keys_choice_int
{ \int_use:N \l_keys_choice_int }
\exp_not:v
- { \c_@@_vars_root_tl \l_keys_path_tl .choice~code }
+ { \c_@@_info_root_tl \l_keys_path_tl .choice~code }
}
}
\__msg_kernel_new:nnnn { kernel } { generate-choices-before-code }
@@ -2003,42 +2251,14 @@
Before~using~.generate_choices:n~the~code~should~be~defined~
with~'.choice_code:n'~or~'.choice_code:x'.
}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{.generate_choices:n}
-% Making choices is easy.
-% \begin{macrocode}
\cs_new_protected:cpn { \c_@@_props_root_tl .generate_choices:n } #1
{ \@@_choices_generate:n {#1} }
% \end{macrocode}
% \end{macro}
-%
-% Deprecated on 2011-05-27, for removal by 2011-08-31.
-%
-% \begin{macro}{\KV_process_space_removal_sanitize:NNn}
-% \begin{macro}{\KV_process_space_removal_no_sanitize:NNn}
-% \begin{macro}{\KV_process_no_space_removal_no_sanitize:NNn}
-% There is just one function for this now.
-% \begin{macrocode}
-%<*deprecated>
-\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
-%</deprecated>
-% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
-%
-% Internal material for removal by 2012-12-31.
-%
-% \begin{macrocode}
-%<*deprecated>
-\cs_new_eq:NN \c_keys_code_root_tl \c__keys_code_root_tl
-%</deprecated>
-% \end{macrocode}
+% \end{macro}
%
% \begin{macrocode}
%</initex|package>