diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3keys.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3keys.dtx | 161 |
1 files changed, 89 insertions, 72 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx index 9919abfd869..54155d6d4e4 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2024-01-04} +% \date{Released 2024-01-22} % % \maketitle % @@ -109,8 +109,8 @@ % Key names may contain any tokens, as they are handled internally % using \cs{tl_to_str:n}. As discussed in % 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 +% |/| is reserved for sub-division of keys into different subsets. +% Functions and variables are \emph{not} expanded when creating % key names, and so % \begin{verbatim} % \tl_set:Nn \l_mymodule_tmp_tl { key } @@ -323,9 +323,15 @@ % \begin{syntax} % \meta{key} .groups:n = \Arg{groups} % \end{syntax} -% Defines \meta{key} as belonging to the \meta{groups} declared. Groups +% Defines \meta{key} as belonging to the \meta{groups} (a +% comma-separated list). Groups % provide a \enquote{secondary axis} for selectively setting keys, and are % described in Section~\ref{sec:l3keys:selective}. +% \begin{texnote} +% The \meta{groups} argument is turned into a string then +% interpreted as a comma-separated list, so group names cannot +% contain commas nor start or end with a space character. +% \end{texnote} % \end{function} % % \begin{function}[added = 2016-11-22]{.inherit:n} @@ -334,7 +340,7 @@ % \end{syntax} % Specifies that the \meta{key} path should inherit the keys listed % as any of the \meta{parents} (a comma list), which can be a module -% or a subgroup. For example, after setting +% or a sub-division thereof. For example, after setting % \begin{verbatim} % \keys_define:nn { foo } { test .code:n = \tl_show:n {#1} } % \keys_define:nn { } { bar .inherit:n = foo } @@ -541,21 +547,21 @@ % \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 +% them into several subsets for a given module. This can be achieved % either by adding a sub-division to the module name: % \begin{verbatim} -% \keys_define:nn { mymodule / subgroup } +% \keys_define:nn { mymodule / subset } % { key .code:n = code } % \end{verbatim} % or to the key name: % \begin{verbatim} % \keys_define:nn { mymodule } -% { subgroup / key .code:n = code } +% { subset / key .code:n = code } % \end{verbatim} % As illustrated, the best choice of token for sub-dividing keys in % this way is |/|. This is because of the method that is % used to represent keys internally. Both of the above code fragments -% set the same key, which has full name \texttt{mymodule/subgroup/key}. +% set the same key, which has full name \texttt{mymodule/subset/key}. % % As illustrated in the next section, this subdivision is % particularly relevant to making multiple choices. @@ -856,29 +862,29 @@ % 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, updated = 2019-01-29] +% \begin{function}[added = 2024-01-10] % { -% \keys_set_filter:nnn, \keys_set_filter:nnV, -% \keys_set_filter:nnv, \keys_set_filter:nno, -% \keys_set_filter:nnnN, \keys_set_filter:nnVN, -% \keys_set_filter:nnvN, \keys_set_filter:nnoN, -% \keys_set_filter:nnnnN, \keys_set_filter:nnVnN, -% \keys_set_filter:nnvnN, \keys_set_filter:nnonN, +% \keys_set_exclude_groups:nnn, \keys_set_exclude_groups:nnV, +% \keys_set_exclude_groups:nnv, \keys_set_exclude_groups:nno, +% \keys_set_exclude_groups:nnnN, \keys_set_exclude_groups:nnVN, +% \keys_set_exclude_groups:nnvN, \keys_set_exclude_groups:nnoN, +% \keys_set_exclude_groups:nnnnN, \keys_set_exclude_groups:nnVnN, +% \keys_set_exclude_groups:nnvnN, \keys_set_exclude_groups:nnonN, % } % \begin{syntax} -% \cs{keys_set_filter:nnn} \Arg{module} \Arg{groups} \Arg{keyval list} -% \cs{keys_set_filter:nnnN} \Arg{module} \Arg{groups} \Arg{keyval list} \meta{tl} -% \cs{keys_set_filter:nnnnN} \Arg{module} \Arg{groups} \Arg{keyval list} \meta{root} \meta{tl} +% \cs{keys_set_exclude_groups:nnn} \Arg{module} \Arg{groups} \Arg{keyval list} +% \cs{keys_set_exclude_groups:nnnN} \Arg{module} \Arg{groups} \Arg{keyval list} \meta{tl} +% \cs{keys_set_exclude_groups:nnnnN} \Arg{module} \Arg{groups} \Arg{keyval list} \meta{root} \meta{tl} % \end{syntax} -% Activates key filtering in an \enquote{opt-out} sense: keys assigned to any -% of the \meta{groups} specified are ignored. The \meta{groups} are +% Sets keys by excluding those in the specificied \meta{groups}. +% The \meta{groups} are % given as a comma-separated list. Unknown keys are not assigned to any % group and are thus always set. The key--value pairs for each % key which is filtered out are 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. +% list}). The \cs{keys_set_exclude_groups:nnn} version skips this stage. % -% Use of \cs{keys_set_filter:nnnN} can be nested, with the correct residual +% Use of \cs{keys_set_exclude_groups:nnnN} can be nested, with the correct residual % \meta{keyval list} returned at each stage. In the version which takes % a \meta{root} argument, the key list is returned relative to that point % in the key tree. In the cases without a \meta{root} argument, only @@ -1662,7 +1668,7 @@ % \end{variable} % % \begin{variable}{\l_@@_selective_bool, \l_@@_filtered_bool} -% Two flags for using key groups: one to indicate that \enquote{selective} +% Two booleans 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} @@ -1755,6 +1761,21 @@ % \end{macrocode} % \end{macro} % +% \begin{macro}{\@@_cs_undefine:c} +% Local version of \cs{cs_undefine:c} to avoid sprinkling +% \cs{tex_undefined:D} everywhere. +% \begin{macrocode} +\cs_new_protected:Npn \@@_cs_undefine:c #1 + { + \if_cs_exist:w #1 \cs_end: + \else: + \use_i:nnnn + \fi: + \cs_set_eq:cN {#1} \tex_undefined:D + } +% \end{macrocode} +% \end{macro} +% % \subsection{The key defining mechanism} % % \begin{macro}{\keys_define:nn, \keys_define:ne, \keys_define:nx} @@ -2061,9 +2082,8 @@ { \tl_if_empty:nTF {#1} { - \cs_set_eq:cN + \@@_cs_undefine:c { \c_@@_default_root_str \l_keys_path_str } - \tex_undefined:D } { \cs_set_nopar:cpe @@ -2084,11 +2104,11 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_groups_set:n #1 { - \clist_set:Nn \l_@@_groups_clist {#1} + \clist_set:Ne \l_@@_groups_clist { \tl_to_str:n {#1} } \clist_if_empty:NTF \l_@@_groups_clist { - \cs_set_eq:cN { \c_@@_groups_root_str \l_keys_path_str } - \tex_undefined:D + \@@_cs_undefine:c + { \c_@@_groups_root_str \l_keys_path_str } } { \cs_set_eq:cN { \c_@@_groups_root_str \l_keys_path_str } @@ -2222,9 +2242,8 @@ \clist_map_inline:nn { code , default , groups , inherit , type , check } { - \cs_set_eq:cN + \@@_cs_undefine:c { \tl_use:c { c_@@_ ##1 _root_str } \l_keys_path_str } - \tex_undefined:D } } % \end{macrocode} @@ -2254,9 +2273,8 @@ { \c_@@_check_root_str \l_keys_path_str } { @@_check_ #1 : } { - \cs_set_eq:cN + \@@_cs_undefine:c { \c_@@_check_root_str \l_keys_path_str } - \tex_undefined:D } } } @@ -2831,7 +2849,7 @@ % \keys_set_known:no % } % \begin{macro}{\@@_set_known:nnn} -% Setting known keys simply means setting the appropriate flag, then +% Setting known keys simply means setting the appropriate boolean, then % running the standard code. To allow for nested setting, any existing % value of \cs{l_@@_unused_clist} is saved on the stack and reset % afterwards. Note that for speed/simplicity reasons we use a \texttt{tl} @@ -2853,8 +2871,8 @@ { \clist_clear:N \l_@@_unused_clist \@@_set_known:nnn {#2} {#3} {#4} - \__kernel_tl_set:Ne #5 { \exp_not:o \l_@@_unused_clist } - \__kernel_tl_set:Ne \l_@@_unused_clist { \exp_not:n {#1} } + \__kernel_tl_set:Nx #5 { \exp_not:o \l_@@_unused_clist } + \__kernel_tl_set:Nx \l_@@_unused_clist { \exp_not:n {#1} } } \cs_new_protected:Npn \keys_set_known:nn #1#2 { \@@_set_known:nnn \q_@@_no_value {#1} {#2} } @@ -2887,21 +2905,21 @@ % % \begin{macro} % { -% \keys_set_filter:nnnN, \keys_set_filter:nnVN, \keys_set_filter:nnvN, -% \keys_set_filter:nnoN +% \keys_set_exclude_groups:nnnN, \keys_set_exclude_groups:nnVN, +% \keys_set_exclude_groups:nnvN, \keys_set_exclude_groups:nnoN % } % \begin{macro} % { -% \keys_set_filter:nnnnN, \keys_set_filter:nnVnN, -% \keys_set_filter:nnvnN, \keys_set_filter:nnonN +% \keys_set_exclude_groups:nnnnN, \keys_set_exclude_groups:nnVnN, +% \keys_set_exclude_groups:nnvnN, \keys_set_exclude_groups:nnonN % } -% \begin{macro}{\@@_set_filter:nnnnnN} +% \begin{macro}{\@@_set_exclude_groups:nnnnnN} % \begin{macro} % { -% \keys_set_filter:nnn, \keys_set_filter:nnV, \keys_set_filter:nnv, -% \keys_set_filter:nno +% \keys_set_exclude_groups:nnn, \keys_set_exclude_groups:nnV, +% \keys_set_exclude_groups:nnv, \keys_set_exclude_groups:nno % } -% \begin{macro}{\@@_set_filter:nnnn} +% \begin{macro}{\@@_set_exclude_groups:nnnn} % \begin{macro} % { % \keys_set_groups:nnn, \keys_set_groups:nnV, \keys_set_groups:nnv, @@ -2909,35 +2927,35 @@ % } % \begin{macro}{\@@_set_selective:nnn} % \begin{macro}{\@@_set_selective:nnnn} -% The idea of setting keys in a selective manner again uses flags +% The idea of setting keys in a selective manner again uses booleans % wrapped around the basic code. The comments on \cs{keys_set_known:nnN} % also apply here. We have a bit more shuffling to do to keep everything % nestable. % \begin{macrocode} -\cs_new_protected:Npn \keys_set_filter:nnnN #1#2#3#4 +\cs_new_protected:Npn \keys_set_exclude_groups:nnnN #1#2#3#4 { - \exp_args:No \@@_set_filter:nnnnnN + \exp_args:No \@@_set_exclude_groups:nnnnnN \l_@@_unused_clist \q_@@_no_value {#1} {#2} {#3} #4 } -\cs_generate_variant:Nn \keys_set_filter:nnnN { nnV , nnv , nno } -\cs_new_protected:Npn \keys_set_filter:nnnnN #1#2#3#4#5 +\cs_generate_variant:Nn \keys_set_exclude_groups:nnnN { nnV , nnv , nno } +\cs_new_protected:Npn \keys_set_exclude_groups:nnnnN #1#2#3#4#5 { - \exp_args:No \@@_set_filter:nnnnnN + \exp_args:No \@@_set_exclude_groups:nnnnnN \l_@@_unused_clist {#4} {#1} {#2} {#3} #5 } -\cs_generate_variant:Nn \keys_set_filter:nnnnN { nnV , nnv , nno } -\cs_new_protected:Npn \@@_set_filter:nnnnnN #1#2#3#4#5#6 +\cs_generate_variant:Nn \keys_set_exclude_groups:nnnnN { nnV , nnv , nno } +\cs_new_protected:Npn \@@_set_exclude_groups:nnnnnN #1#2#3#4#5#6 { \clist_clear:N \l_@@_unused_clist - \@@_set_filter:nnnn {#2} {#3} {#4} {#5} - \__kernel_tl_set:Ne #6 { \exp_not:o \l_@@_unused_clist } - \__kernel_tl_set:Ne \l_@@_unused_clist { \exp_not:n {#1} } + \@@_set_exclude_groups:nnnn {#2} {#3} {#4} {#5} + \__kernel_tl_set:Nx #6 { \exp_not:o \l_@@_unused_clist } + \__kernel_tl_set:Nx \l_@@_unused_clist { \exp_not:n {#1} } } -\cs_new_protected:Npn \keys_set_filter:nnn #1#2#3 - {\@@_set_filter:nnnn \q_@@_no_value {#1} {#2} {#3} } -\cs_generate_variant:Nn \keys_set_filter:nnn { nnV , nnv , nno } -\cs_new_protected:Npn \@@_set_filter:nnnn #1#2#3#4 +\cs_new_protected:Npn \keys_set_exclude_groups:nnn #1#2#3 + {\@@_set_exclude_groups:nnnn \q_@@_no_value {#1} {#2} {#3} } +\cs_generate_variant:Nn \keys_set_exclude_groups:nnn { nnV , nnv , nno } +\cs_new_protected:Npn \@@_set_exclude_groups:nnnn #1#2#3#4 { \use:e { @@ -2981,7 +2999,8 @@ { \exp_args:No \@@_set_selective:nnnn \l_@@_selective_seq } \cs_new_protected:Npn \@@_set_selective:nnnn #1#2#3#4 { - \seq_set_from_clist:Nn \l_@@_selective_seq {#3} + \exp_args:NNe \seq_set_from_clist:Nn + \l_@@_selective_seq { \tl_to_str:n {#3} } \@@_set:nn {#2} {#4} \tl_set:Nn \l_@@_selective_seq {#1} } @@ -3044,7 +3063,7 @@ % \begin{macrocode} \cs_new_protected:Npn \@@_set_keyval:nnn #1#2#3 { - \__kernel_tl_set:Ne \l_keys_path_str + \__kernel_tl_set:Nx \l_keys_path_str { \tl_if_blank:nF {#1} { #1 / } @@ -3118,23 +3137,21 @@ % 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. -% We cannot replace the clist mapping by \cs{clist_if_in:NnTF} because -% catcodes may not be the same; they cannot be normalized easily in the -% clist because of the remote possibility that some items need braces -% if they involve commas or leading/trailing spaces. +% It is safe to use \cs{clist_if_in:NnTF} because +% both \cs{l_@@_selective_seq} and \cs{l_@@_groups_clist} contain the +% groups as strings, without leading/trailing spaces in any item, +% since the \pkg{l3clist} functions were applied to the result of +% applying \cs{tl_to_str:n}. % \begin{macrocode} \cs_new_protected:Npn \@@_check_groups: { \bool_set_false:N \l_@@_tmp_bool \seq_map_inline:Nn \l_@@_selective_seq { - \clist_map_inline:Nn \l_@@_groups_clist + \clist_if_in:NnT \l_@@_groups_clist {##1} { - \str_if_eq:nnT {##1} {####1} - { - \bool_set_true:N \l_@@_tmp_bool - \clist_map_break:n \seq_map_break: - } + \bool_set_true:N \l_@@_tmp_bool + \seq_map_break: } } \bool_if:NTF \l_@@_tmp_bool @@ -3325,7 +3342,7 @@ } \cs_new_protected:Npn \@@_store_unused_aux: { - \__kernel_tl_set:Ne \l_@@_relative_tl + \__kernel_tl_set:Nx \l_@@_relative_tl { \exp_args:No \@@_trim_spaces:n \l_@@_relative_tl } \use:e { |