[latex3-commits] [git/LaTeX3-latex3-latex3] main: Add support for validity scope for keys (#1028) (70d15cd69)

GitHub noreply at github.com
Mon Jan 10 18:30:19 CET 2022


Repository : https://github.com/latex3/latex3
On branch  : main
Link       : https://github.com/latex3/latex3/commit/70d15cd6946ba1650e97c75ae3d68a929368b0de

>---------------------------------------------------------------

commit 70d15cd6946ba1650e97c75ae3d68a929368b0de
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date:   Mon Jan 10 17:30:19 2022 +0000

    Add support for validity scope for keys (#1028)


>---------------------------------------------------------------

70d15cd6946ba1650e97c75ae3d68a929368b0de
 l3kernel/CHANGELOG.md            |   1 +
 l3kernel/l3clist.dtx             |  20 +++++--
 l3kernel/l3keys.dtx              | 123 ++++++++++++++++++++++++++++++++++++++-
 l3kernel/testfiles/m3keys007.lvt |  56 ++++++++++++++++++
 l3kernel/testfiles/m3keys007.tlg |  45 ++++++++++++++
 5 files changed, 239 insertions(+), 6 deletions(-)

diff --git a/l3kernel/CHANGELOG.md b/l3kernel/CHANGELOG.md
index ef2c26764..0d3b525de 100644
--- a/l3kernel/CHANGELOG.md
+++ b/l3kernel/CHANGELOG.md
@@ -9,6 +9,7 @@ this project uses date-based 'snapshot' version identifiers.
 
 ### Added
 - `\prop_to_keyval:N`
+- Support for validity scope for keys
 
 ### Changed
 - Allow indirect conversions between colorspaces though fallback models
diff --git a/l3kernel/l3clist.dtx b/l3kernel/l3clist.dtx
index b7957ada4..8279b3054 100644
--- a/l3kernel/l3clist.dtx
+++ b/l3kernel/l3clist.dtx
@@ -315,7 +315,9 @@
 % \begin{function}[updated = 2011-09-06]
 %   {
 %     \clist_remove_all:Nn,  \clist_remove_all:cn,
-%     \clist_gremove_all:Nn, \clist_gremove_all:cn
+%     \clist_remove_all:NV,  \clist_remove_all:cV,
+%     \clist_gremove_all:Nn, \clist_gremove_all:cn,
+%     \clist_gremove_all:NV, \clist_gremove_all:cV
 %   }
 %   \begin{syntax}
 %     \cs{clist_remove_all:Nn} \meta{comma list} \Arg{item}
@@ -1407,9 +1409,17 @@
 % \end{macro}
 % \end{macro}
 %
-% \begin{macro}{\clist_remove_all:Nn, \clist_remove_all:cn}
+% \begin{macro}
+%   {
+%     \clist_remove_all:Nn, \clist_remove_all:cn,
+%     \clist_remove_all:NV, \clist_remove_all:cV
+%   }
 % \UnitTested
-% \begin{macro}{\clist_gremove_all:Nn, \clist_gremove_all:cn}
+% \begin{macro}
+%   {
+%     \clist_gremove_all:Nn, \clist_gremove_all:cn,
+%     \clist_gremove_all:NV, \clist_remove_all:cV
+%   }
 % \UnitTested
 % \begin{macro}{\@@_remove_all:NNNn}
 % \begin{macro}{\@@_remove_all:w}
@@ -1482,8 +1492,8 @@
 \cs_new:Npn \@@_remove_all:
   { \exp_after:wN \@@_remove_all:w \@@_tmp:w , }
 \cs_new:Npn \@@_remove_all:w #1 , \s_@@_mark , #2 , { \exp_not:n {#1} }
-\cs_generate_variant:Nn \clist_remove_all:Nn  { c }
-\cs_generate_variant:Nn \clist_gremove_all:Nn { c }
+\cs_generate_variant:Nn \clist_remove_all:Nn  { c , NV , cV }
+\cs_generate_variant:Nn \clist_gremove_all:Nn { c , NV , cV }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
diff --git a/l3kernel/l3keys.dtx b/l3kernel/l3keys.dtx
index a0c6b470f..e3522a7d3 100644
--- a/l3kernel/l3keys.dtx
+++ b/l3kernel/l3keys.dtx
@@ -679,6 +679,31 @@
 % \cs{l_keys_choice_tl} and \cs{l_keys_choice_int} in exactly
 % the same way as described for \texttt{.choices:nn}.
 %
+% \subsection{Key usage scope}
+%
+% Some keys will be used as settings which have a strictly limited scope
+% of usage. Some will be only available once, others will only be valid
+% until typesetting begins. To allow formats to support this in a structured
+% way, \pkg{l3keys} allows this information to be specified using the
+% \texttt{.usage:n} property.
+%
+% \begin{function}[added = 2022-01-10]{.usage:n}
+%   \begin{syntax}
+%     \meta{key} .usage:n = \meta{scope}
+%   \end{syntax}
+%   Defines the \meta{key} to have usage within the \meta{scope}, which
+%   should be one of \texttt{general}, \texttt{preamble} or \texttt{load}.
+% \end{function}
+%
+% \begin{variable}[added = 2022-01-10]
+%   {\l_keys_usage_load_prop, \l_keys_usage_preamble_prop}
+%   \pkg{l3keys} itself does \emph{not} attempt to redefine keys based on the
+%   usage scope. Rather, this information is made available with these
+%   two property lists. These hold an entry for each module (prefix); the
+%   value of each entry is a comma-separated list of the usage-restricted
+%   key(s).
+% \end{variable}
+%
 % \section{Setting keys}
 %
 % \begin{function}[updated = 2017-11-14]
@@ -849,7 +874,8 @@
 %
 % \section{Utility functions for keys}
 %
-% \begin{function}[EXP, pTF, updated = 2017-11-14]{\keys_if_exist:nn}
+% \begin{function}[EXP, pTF, updated = 2022-01-10]
+%   {\keys_if_exist:nn, \keys_if_exist:ne}
 %   \begin{syntax}
 %     \cs{keys_if_exist_p:nn} \Arg{module} \Arg{key} \\
 %     \cs{keys_if_exist:nnTF} \Arg{module} \Arg{key} \Arg{true code} \Arg{false code}
@@ -1625,6 +1651,14 @@
 %    \end{macrocode}
 % \end{variable}
 %
+% \begin{variable}{\l_keys_usage_load_prop, \l_keys_usage_preamble_prop}
+%   Global data for document-level information.
+%    \begin{macrocode}
+\prop_new:N \l_keys_usage_load_prop
+\prop_new:N \l_keys_usage_preamble_prop
+%    \end{macrocode}
+% \end{variable}
+%
 % \subsubsection{Internal auxiliaries}
 %
 % \begin{variable}{\s_@@_nil,\s_@@_mark,\s_@@_stop}
@@ -2146,6 +2180,62 @@
 % \end{macro}
 % \end{macro}
 %
+% \begin{macro}{\@@_usage:n}
+% \begin{macro}{\@@_usage:NN}
+% \begin{macro}{\@@_usage:w}
+%   Save the relevant data.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_usage:n #1
+  {
+    \str_case:nnF {#1}
+      {
+        { general }
+          {
+            \@@_usage:NN \l_keys_usage_load_prop
+              \c_false_bool
+            \@@_usage:NN \l_keys_usage_preamble_prop
+              \c_false_bool
+          }
+        { load }
+          {
+            \@@_usage:NN \l_keys_usage_load_prop
+              \c_true_bool
+            \@@_usage:NN \l_keys_usage_preamble_prop
+              \c_false_bool
+          }
+        { preamble }
+          {
+            \@@_usage:NN \l_keys_usage_load_prop
+              \c_false_bool
+            \@@_usage:NN \l_keys_usage_preamble_prop
+              \c_true_bool
+          }
+      }
+      {
+        \msg_error:nnnn { keys }
+          { choice-unknown }
+          { .usage:n }
+          {#1}
+      }
+  }
+\cs_new_protected:Npn \@@_usage:NN #1#2
+  {
+    \prop_get:NVNF #1 \l_@@_module_str \l_@@_tmpa_tl
+      { \tl_clear:N \l_@@_tmpa_tl }
+    \tl_set:Nx \l_@@_tmpb_tl
+      { \exp_after:wN \@@_usage:w \l_keys_path_str \s_@@_stop }
+    \bool_if:NTF #2
+      { \clist_put_right:NV \l_@@_tmpa_tl \l_@@_tmpb_tl }
+      { \clist_remove_all:NV \l_@@_tmpa_tl \l_@@_tmpb_tl }
+    \prop_put:NVV #1 \l_@@_module_str
+      \l_@@_tmpa_tl
+  }
+\cs_new:Npn \@@_usage:w #1 / #2 \s_@@_stop {#2}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
 % \begin{macro}{\@@_variable_set:NnnN, \@@_variable_set:cnnN}
 % \begin{macro}{\@@_variable_set_required:NnnN, \@@_variable_set_required:cnnN}
 %   Setting a variable takes the type and scope separately so that
@@ -2547,6 +2637,13 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{.usage:n}
+%    \begin{macrocode}
+\cs_new_protected:cpn { \c_@@_props_root_str .usage:n } #1
+  { \@@_usage:n {#1} }
+%    \end{macrocode}
+% \end{macro}
+%
 % \begin{macro}{.value_forbidden:n}
 % \begin{macro}{.value_required:n}
 %   These are very similar, so both call the same function.
@@ -2559,6 +2656,29 @@
 % \end{macro}
 % \end{macro}
 %
+% \subsection{Key properties for \LaTeXe{} options}
+%
+% \begin{macro}{.if, .store, .usage}
+%    \begin{macrocode}
+\group_begin:
+  \cs_set_protected:Npn \@@_tmp:nn #1#2
+    {
+      \quark_if_recursion_tail_stop:n {#1}
+      \cs_new_eq:cc
+        { \c_@@_props_root_str . #2 }
+        { \c_@@_props_root_str . #1 }
+      \@@_tmp:nn
+    }
+  \@@_tmp:nn
+    { legacy_if:n } { if }
+    { tl_set:N }    { store }
+    { usage:n }     { usage }
+    { \q_recursion_tail } { }
+    \q_recursion_stop
+\group_end:
+%    \end{macrocode}
+% \end{macro}
+%
 % \subsection{Setting keys}
 %
 % \begin{macro}
@@ -3249,6 +3369,7 @@
       { \prg_return_true: }
       { \prg_return_false: }
   }
+\prg_generate_conditional_variant:Nnn \keys_if_exist:nn { ne } { T , F , TF }
 %    \end{macrocode}
 % \end{macro}
 %
diff --git a/l3kernel/testfiles/m3keys007.lvt b/l3kernel/testfiles/m3keys007.lvt
new file mode 100644
index 000000000..efa32b3e4
--- /dev/null
+++ b/l3kernel/testfiles/m3keys007.lvt
@@ -0,0 +1,56 @@
+% Copyright (C) 2021 The LaTeX Project
+
+
+\documentclass{minimal}
+\input{regression-test}
+
+\RequirePackage[enable-debug]{expl3}
+\ExplSyntaxOn
+\debug_on:n { check-declarations , deprecation , log-functions }
+\ExplSyntaxOff
+
+
+\begin{document}
+\START
+\AUTHOR{Joseph Wright}
+\ExplSyntaxOn
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\TEST { .usage:n ~ basics }
+  {
+    \keys_define:nn { module }
+      {
+        key-one .code:n  = #1 ,
+        key-one .usage:n = load ,
+        key-two .code:n  = #1 ,
+        key-two .usage:n = preamble ,
+        key-three .code:n  = #1 ,
+        key-three .usage:n = general ,
+        key-four .code:n  = #1 ,
+        key-four .usage:n = oops
+      }
+    \prop_show:N \l_keys_usage_load_prop
+    \prop_show:N \l_keys_usage_preamble_prop
+  }
+
+\TEST { .usage:n ~ adding ~ and ~ removing }
+  {
+    \keys_define:nn { module }
+      {
+        key-one .code:n  = #1 ,
+        key-one .usage:n = load ,
+        key-two .code:n  = #1 ,
+        key-two .usage:n = load ,
+        key-three .code:n  = #1 ,
+        key-three .usage:n = load ,
+        key-three .usage:n = preamble ,
+        key-four .code:n  = #1 ,
+        key-four .usage:n = load ,
+        key-four .usage:n = general
+      }
+    \prop_show:N \l_keys_usage_load_prop
+    \prop_show:N \l_keys_usage_preamble_prop
+  }
+
+\END
diff --git a/l3kernel/testfiles/m3keys007.tlg b/l3kernel/testfiles/m3keys007.tlg
new file mode 100644
index 000000000..a0f91975f
--- /dev/null
+++ b/l3kernel/testfiles/m3keys007.tlg
@@ -0,0 +1,45 @@
+This is a generated file for the LaTeX (2e + expl3) validation system.
+Don't change this file in any respect.
+Author: Joseph Wright
+============================================================
+TEST 1: .usage:n basics
+============================================================
+Defining key module/key-one on line ...
+Defining key module/key-two on line ...
+Defining key module/key-three on line ...
+Defining key module/key-four on line ...
+! LaTeX3 Error: Key '.usage:n' accepts only a fixed set of choices.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+The key '.usage:n' only accepts predefined values, and 'oops' is not one of
+these.
+The property list \l_keys_usage_load_prop contains the pairs (without outer
+braces):
+>  {module}  =>  {key-one}.
+<recently read> }
+l. ...  }
+The property list \l_keys_usage_preamble_prop contains the pairs (without
+outer braces):
+>  {module}  =>  {key-two}.
+<recently read> }
+l. ...  }
+============================================================
+============================================================
+TEST 2: .usage:n adding and removing
+============================================================
+Defining key module/key-one on line ...
+Defining key module/key-two on line ...
+Defining key module/key-three on line ...
+Defining key module/key-four on line ...
+The property list \l_keys_usage_load_prop contains the pairs (without outer
+braces):
+>  {module}  =>  {key-one,key-two}.
+<recently read> }
+l. ...  }
+The property list \l_keys_usage_preamble_prop contains the pairs (without
+outer braces):
+>  {module}  =>  {key-three}.
+<recently read> }
+l. ...  }
+============================================================





More information about the latex3-commits mailing list.