[latex3-commits] [git/LaTeX3-latex3-latex3] master: Correctly nest key filtering, etc. (fixes #526) (43fe0c7)

Joseph Wright joseph.wright at morningstar2.co.uk
Mon Jan 28 17:31:07 CET 2019


Repository : https://github.com/latex3/latex3
On branch  : master
Link       : https://github.com/latex3/latex3/commit/43fe0c7d38fe20dd87dccb0cc90dc9d4e2147d25

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

commit 43fe0c7d38fe20dd87dccb0cc90dc9d4e2147d25
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date:   Mon Jan 28 16:31:07 2019 +0000

    Correctly nest key filtering, etc. (fixes #526)


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

43fe0c7d38fe20dd87dccb0cc90dc9d4e2147d25
 l3kernel/CHANGELOG.md            |    4 ++
 l3kernel/l3keys.dtx              |  136 +++++++++++++++++++++-----------------
 l3kernel/testfiles/m3keys004.lvt |   13 ++++
 l3kernel/testfiles/m3keys004.tlg |   21 +++++-
 4 files changed, 109 insertions(+), 65 deletions(-)

diff --git a/l3kernel/CHANGELOG.md b/l3kernel/CHANGELOG.md
index 542ba4d..212206e 100644
--- a/l3kernel/CHANGELOG.md
+++ b/l3kernel/CHANGELOG.md
@@ -7,6 +7,10 @@ this project uses date-based 'snapshot' version identifiers.
 
 ## [Unreleased]
 
+### Fixed
+
+- Handling of nested key setting when filtering, _etc._ (see #526)
+
 ## [2019-01-28]
 
 ### Added
diff --git a/l3kernel/l3keys.dtx b/l3kernel/l3keys.dtx
index 9fdcda9..ca4d801 100644
--- a/l3kernel/l3keys.dtx
+++ b/l3kernel/l3keys.dtx
@@ -2010,16 +2010,36 @@
 %
 % \subsection{Setting keys}
 %
-% \begin{macro}{\keys_set:nn, \keys_set:nV, \keys_set:nv, \keys_set:no}
+% \begin{macro}
+%   {
+%     \keys_set:nn, \keys_set:nV, \keys_set:nv, \keys_set:no,
+%     \@@_set:nn
+%   }
 % \begin{macro}{\@@_set:nnn, \@@_set:onn}
-%   A simple wrapper again.
+%   A simple wrapper allowing or nesting.
 %    \begin{macrocode}
-\cs_new_protected:Npn \keys_set:nn
-  { \@@_set:onn { \l_@@_module_tl } }
+\cs_new_protected:Npn \keys_set:nn #1#2
+  {
+    \use:x
+      {
+        \bool_set_false:N \exp_not:N \l_@@_only_known_bool
+        \bool_set_false:N \exp_not:N \l_@@_filtered_bool
+        \bool_set_false:N \exp_not:N \l_@@_selective_bool
+        \@@_set:nn \exp_not:n { {#1} {#2} }
+        \bool_if:NT \l_@@_only_known_bool
+          { \bool_set_true:N \exp_not:N \l_@@_only_known_bool }
+        \bool_if:NT \l_@@_filtered_bool
+          { \bool_set_true:N \exp_not:N \l_@@_filtered_bool }
+        \bool_if:NT \l_@@_selective_bool
+          { \bool_set_true:N \exp_not:N \l_@@_selective_bool }
+      }
+  }
+\cs_new_protected:Npn \@@_set:nn #1#2
+  { \@@_set:onn { \l_@@_module_tl } {#1} {#2} }
 \cs_new_protected:Npn \@@_set:nnn #1#2#3
   {
     \tl_set:Nx \l_@@_module_tl { \@@_remove_spaces:n {#2} }
-    \keyval_parse:NNn \@@_set:n \@@_set:nn {#3}
+    \keyval_parse:NNn \@@_set_keyval:n \@@_set_keyval:nn {#3}
     \tl_set:Nn \l_@@_module_tl {#1}
   }
 \cs_generate_variant:Nn \keys_set:nn { nV , nv , no }
@@ -2039,7 +2059,6 @@
 %     \keys_set_known:nn, \keys_set_known:nV,
 %     \keys_set_known:nv, \keys_set_known:no
 %   }
-% \begin{macro}{\@@_keys_set_known:nn}
 %   Setting known keys simply means setting the appropriate flag, 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
@@ -2059,23 +2078,25 @@
 \cs_generate_variant:Nn \@@_set_known:nnnN { o }
 \cs_new_protected:Npn \keys_set_known:nn #1#2
   {
-    \bool_if:NTF \l_@@_only_known_bool
-      { \keys_set:nn }
-      { \@@_set_known:nn }
-      {#1} {#2}
+    \use:x
+      {
+        \bool_set_true:N \exp_not:N \l_@@_only_known_bool
+        \bool_set_false:N \exp_not:N \l_@@_filtered_bool
+        \bool_set_false:N \exp_not:N \l_@@_selective_bool
+        \@@_set:nn \exp_not:n { {#1} {#2} }
+        \bool_if:NF \l_@@_only_known_bool
+          { \bool_set_false:N \exp_not:N \l_@@_only_known_bool }
+        \bool_if:NT \l_@@_filtered_bool
+          { \bool_set_true:N \exp_not:N \l_@@_filtered_bool }
+        \bool_if:NT \l_@@_selective_bool
+          { \bool_set_true:N \exp_not:N \l_@@_selective_bool }
+      }
   }
 \cs_generate_variant:Nn \keys_set_known:nn { nV , nv , no }
-\cs_new_protected:Npn \@@_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
-  }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
 % \end{macro}
-% \end{macro}
 %
 % \begin{macro}
 %   {
@@ -2088,16 +2109,13 @@
 %     \keys_set_filter:nnn, \keys_set_filter:nnV, \keys_set_filter:nnv,
 %       \keys_set_filter:nno
 %   }
-% \begin{macro}{\@@_set_filter:nnn}
 % \begin{macro}
 %   {
 %     \keys_set_groups:nnn, \keys_set_groups:nnV, \keys_set_groups:nnv,
 %       \keys_set_groups:nno
 %   }
-%  \begin{macro}{\@@_set_groups:nnn}
 %  \begin{macro}{\@@_set_selective:nnn}
 %  \begin{macro}{\@@_set_selective:nnnn, \@@_set_selective:onnn}
-%  \begin{macro}{\@@_set_selective:nn}
 %   The idea of setting keys in a selective manner again uses flags
 %   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
@@ -2116,50 +2134,47 @@
 \cs_generate_variant:Nn \@@_set_filter:nnnnN { o }
 \cs_new_protected:Npn \keys_set_filter:nnn #1#2#3
   {
-    \bool_if:NTF \l_@@_filtered_bool
-      { \@@_set_selective:nnn }
-      { \@@_set_filter:nnn }
-      {#1} {#2} {#3}
+    \use:x
+      {
+        \bool_set_false:N \exp_not:N \l_@@_only_known_bool
+        \bool_set_true:N \exp_not:N \l_@@_filtered_bool
+        \bool_set_true:N \exp_not:N \l_@@_selective_bool
+        \@@_set_selective:nnn \exp_not:n { {#1} {#2} {#3} }
+        \bool_if:NT \l_@@_only_known_bool
+          { \bool_set_true:N \exp_not:N \l_@@_only_known_bool }
+        \bool_if:NF \l_@@_filtered_bool
+          { \bool_set_false:N \exp_not:N \l_@@_filtered_bool }
+        \bool_if:NF \l_@@_selective_bool
+          { \bool_set_false:N \exp_not:N \l_@@_selective_bool }
+      }
   }
 \cs_generate_variant:Nn \keys_set_filter:nnn { nnV , nnv , nno }
-\cs_new_protected:Npn \@@_set_filter:nnn #1#2#3
-  {
-    \bool_set_true:N \l_@@_filtered_bool
-    \@@_set_selective:nnn {#1} {#2} {#3}
-    \bool_set_false:N \l_@@_filtered_bool
-  }
 \cs_new_protected:Npn \keys_set_groups:nnn #1#2#3
   {
-    \bool_if:NTF \l_@@_filtered_bool
-      { \@@_set_groups:nnn }
-      { \@@_set_selective:nnn }
-      {#1} {#2} {#3}
+    \use:x
+      {
+        \bool_set_false:N \exp_not:N \l_@@_only_known_bool
+        \bool_set_false:N \exp_not:N \l_@@_filtered_bool
+        \bool_set_true:N \exp_not:N \l_@@_selective_bool
+        \@@_set_selective:nnn \exp_not:n { {#1} {#2} {#3} }
+        \bool_if:NT \l_@@_only_known_bool
+          { \bool_set_true:N \exp_not:N \l_@@_only_known_bool }
+        \bool_if:NF \l_@@_filtered_bool
+          { \bool_set_true:N \exp_not:N \l_@@_filtered_bool }
+        \bool_if:NF \l_@@_selective_bool
+          { \bool_set_false:N \exp_not:N \l_@@_selective_bool }
+      }
   }
 \cs_generate_variant:Nn \keys_set_groups:nnn { nnV , nnv , nno }
-\cs_new_protected:Npn \@@_set_groups:nnn #1#2#3
-  {
-    \bool_set_false:N \l_@@_filtered_bool
-    \@@_set_selective:nnn {#1} {#2} {#3}
-    \bool_set_true:N \l_@@_filtered_bool
-  }
 \cs_new_protected:Npn \@@_set_selective:nnn
   { \@@_set_selective:onnn \l_@@_selective_seq }
 \cs_new_protected:Npn \@@_set_selective:nnnn #1#2#3#4
   {
     \seq_set_from_clist:Nn \l_@@_selective_seq {#3}
-    \bool_if:NTF \l_@@_selective_bool
-      { \keys_set:nn }
-      { \@@_set_selective:nn }
-      {#2} {#4}
+    \@@_set:nn {#2} {#4}
     \tl_set:Nn \l_@@_selective_seq {#1}
   }
 \cs_generate_variant:Nn \@@_set_selective:nnnn { o }
-\cs_new_protected:Npn \@@_set_selective:nn #1#2
-  {
-    \bool_set_true:N \l_@@_selective_bool
-    \keys_set:nn {#1} {#2}
-    \bool_set_false:N \l_@@_selective_bool
-  }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -2167,28 +2182,25 @@
 % \end{macro}
 % \end{macro}
 % \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
 %
-% \begin{macro}{\@@_set:n, \@@_set:nn}
-% \begin{macro}{\@@_set_aux:nnn, \@@_set_aux:onn}
+% \begin{macro}{\@@_set_keyval:n, \@@_set_keyval:nn}
+% \begin{macro}{\@@_set_keyval:nnn, \@@_set_keyval:onn}
 % \begin{macro}{\@@_find_key_module:w}
-% \begin{macro}{\@@_set_aux:, \@@_set_selective:}
+% \begin{macro}{\@@_set_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
 %   code.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_set:n #1
+\cs_new_protected:Npn \@@_set_keyval:n #1
   {
     \bool_set_true:N \l_@@_no_value_bool
-    \@@_set_aux:onn \l_@@_module_tl {#1} { }
+    \@@_set_keyval:onn \l_@@_module_tl {#1} { }
   }
-\cs_new_protected:Npn \@@_set:nn #1#2
+\cs_new_protected:Npn \@@_set_keyval:nn #1#2
   {
     \bool_set_false:N \l_@@_no_value_bool
-    \@@_set_aux:onn \l_@@_module_tl {#1} {#2}
+    \@@_set_keyval:onn \l_@@_module_tl {#1} {#2}
   }
 %    \end{macrocode}
 %   The key path here can be fully defined, after which there is a search
@@ -2197,7 +2209,7 @@
 %   that happens on a per-key basis, we use the stack approach to restore
 %   the module name without a group.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_set_aux:nnn #1#2#3
+\cs_new_protected:Npn \@@_set_keyval:nnn #1#2#3
   {
     \tl_set:Nx \l_keys_path_tl
       {
@@ -2213,7 +2225,7 @@
       { \@@_execute: }
     \tl_set:Nn \l_@@_module_tl {#1}
   }
-\cs_generate_variant:Nn \@@_set_aux:nnn { o }
+\cs_generate_variant:Nn \@@_set_keyval:nnn { o }
 \cs_new_protected:Npn \@@_find_key_module:w #1 / #2 \q_stop
   {
     \tl_if_blank:nTF {#2}
diff --git a/l3kernel/testfiles/m3keys004.lvt b/l3kernel/testfiles/m3keys004.lvt
index 1f1c334..dfdee72 100644
--- a/l3kernel/testfiles/m3keys004.lvt
+++ b/l3kernel/testfiles/m3keys004.lvt
@@ -228,6 +228,19 @@
       }
   }
 
+\TEST { Nesting ~ setting }
+  {
+    \OMIT
+      \keys_define:nn { empty-module } { }
+      \keys_define:nn { module }
+        {
+          key-one .code:n = { \keys_set:nn { empty-module } { key-two } }
+        }
+    \TIMO
+    \keys_set_known:nnN { module } { key-one } \l_tmpa_clist
+    \clist_show:N \l_tmpa_clist
+  }
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 
 \OMIT
diff --git a/l3kernel/testfiles/m3keys004.tlg b/l3kernel/testfiles/m3keys004.tlg
index 536e742..8cdfc9b 100644
--- a/l3kernel/testfiles/m3keys004.tlg
+++ b/l3kernel/testfiles/m3keys004.tlg
@@ -129,7 +129,22 @@ Defining key module/key-four on line ...
 "other-value"
 ============================================================
 ============================================================
-TEST 7: \keys_if_exist:nnTF 
+TEST 7: Nesting setting
+============================================================
+! LaTeX3 Error: The key 'empty-module/key-two' is unknown and is being
+(LaTeX3)        ignored.
+For immediate help type H <return>.
+ ...                                              
+l. ...  }
+The module 'empty-module' does not have a key called 'empty-module/key-two'.
+Check that you have spelled the key name correctly.
+The comma list \l_tmpa_clist is empty
+> .
+<recently read> }
+l. ...  }
+============================================================
+============================================================
+TEST 8: \keys_if_exist:nnTF 
 ============================================================
 TRUE
 FALSE
@@ -137,7 +152,7 @@ TRUE
 FALSE
 ============================================================
 ============================================================
-TEST 8: \keys_if_choice_exist:nnnTF 
+TEST 9: \keys_if_choice_exist:nnnTF 
 ============================================================
 TRUE
 FALSE
@@ -149,7 +164,7 @@ FALSE
 FALSE
 ============================================================
 ============================================================
-TEST 9: \keys_show:nn 
+TEST 10: \keys_show:nn 
 ============================================================
 The key module/key-one has the properties:
 >  code  =>  \TYPE {"#1"}.





More information about the latex3-commits mailing list