summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3keys.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3keys.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3keys.dtx287
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}