[latex3-commits] [git/LaTeX3-latex3-latex3] main: l3prop: use \keyval_parse:nnn for ..._from_keyval:Nn (#1012) (ebc26cfd8)

GitHub noreply at github.com
Sun Nov 7 22:51:54 CET 2021


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

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

commit ebc26cfd8efaa9f6a14563572570bc5a069cbdeb
Author: Skillmon <Skillmon at users.noreply.github.com>
Date:   Sun Nov 7 22:51:54 2021 +0100

    l3prop: use \keyval_parse:nnn for ..._from_keyval:Nn (#1012)
    
    * use keyval_parse for prop_set etc.
    * faster prop_concat for long lists
    * update testfile for keyval error formatting
    * update color test files
    Plus upcoming commit for CHANGELOG and documenting that prop functions now allow active comma/equals.


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

ebc26cfd8efaa9f6a14563572570bc5a069cbdeb
 l3kernel/l3keys.dtx                     |  16 ++++-
 l3kernel/l3msg.dtx                      |   2 +-
 l3kernel/l3prop.dtx                     | 105 ++++++++++----------------------
 l3kernel/testfiles/m3color003.ptex.tlg  |   2 +-
 l3kernel/testfiles/m3color003.tlg       |   2 +-
 l3kernel/testfiles/m3color003.uptex.tlg |   2 +-
 l3kernel/testfiles/m3color003.xetex.tlg |   2 +-
 l3kernel/testfiles/m3prop005.tlg        |  75 +++++++++++++++--------
 8 files changed, 102 insertions(+), 104 deletions(-)

diff --git a/l3kernel/l3keys.dtx b/l3kernel/l3keys.dtx
index f652bc536..2123de13e 100644
--- a/l3kernel/l3keys.dtx
+++ b/l3kernel/l3keys.dtx
@@ -1022,6 +1022,16 @@
 %    \end{macrocode}
 % \end{variable}
 %
+% \begin{variable}{\l_@@_allow_blank_keys_bool}
+%   The general behavior of the \pkg{l3keys} module is to throw an error on
+%   blank key names. However to support the usage of \cs{keyval_parse:nnn} in
+%   the \pkg{l3prop} module we allow this error to be switched off temporarily
+%   and just ignore blank names.
+%    \begin{macrocode}
+\bool_new:N \l_@@_allow_blank_keys_bool
+%    \end{macrocode}
+% \end{variable}
+%
 %   This temporary macro will be used since some of the definitions will need an
 %   active comma or equals sign. Inside of this macro |#1| will be the active
 %   comma and |#2| will be the active equals sign.
@@ -1364,9 +1374,11 @@
 %    \begin{macrocode}
 \cs_new:Npn \@@_blank_true:w \s_@@_mark \s_@@_stop \@@_trim:nN #1 \@@_key:nn
   { \@@_loop_other:nnw }
-\cs_new:Npn \@@_blank_key_error:w #1 \@@_loop_other:nnw
+\cs_new:Npn \@@_blank_key_error:w \s_@@_mark \s_@@_stop #1 \@@_loop_other:nnw
   {
-    \msg_expandable_error:nn { keyval } { blank-key-name }
+    \bool_if:NTF \l_@@_allow_blank_keys_bool
+      { #1 }
+      { \msg_expandable_error:nn { keyval } { blank-key-name } }
     \@@_loop_other:nnw
   }
 %    \end{macrocode}
diff --git a/l3kernel/l3msg.dtx b/l3kernel/l3msg.dtx
index 722f902e2..83621280b 100644
--- a/l3kernel/l3msg.dtx
+++ b/l3kernel/l3msg.dtx
@@ -1979,7 +1979,7 @@
 \msg_new:nnn { prg } { negative-replication }
   { Negative~argument~for~\iow_char:N\\prg_replicate:nn. }
 \msg_new:nnn { prop } { prop-keyval }
-  { Missing/extra~'='~in~'#1'~(in~'..._keyval:Nn') }
+  { Missing~'='~in~'#1'~(in~'..._keyval:Nn') }
 \msg_new:nnn { kernel } { unknown-comparison }
   { Relation~'#1'~not~among~=,<,>,==,!=,<=,>=. }
 \msg_new:nnn { kernel } { zero-step }
diff --git a/l3kernel/l3prop.dtx b/l3kernel/l3prop.dtx
index df20a5c02..573ce667f 100644
--- a/l3kernel/l3prop.dtx
+++ b/l3kernel/l3prop.dtx
@@ -52,10 +52,10 @@
 % \LaTeX3 implements a \enquote{property list} data type, which contain
 % an unordered list of entries each of which consists of a \meta{key} and
 % an associated \meta{value}. The \meta{key} and \meta{value} may both
-% be any \meta{balanced text}, but the \meta{key} is processed using
-% \cs{tl_to_str:n}, meaning that category codes are ignored. It is
-% possible to map functions to property lists such that the function is
-% applied to every key--value pair within the list.
+% be any \meta{balanced text}, the \meta{key} is processed using
+% \cs{tl_to_str:n}, meaning that category codes are ignored. It is possible to
+% map functions to property lists such that the function is applied to every
+% key--value pair within the list.
 %
 % Each entry in a property list must have a unique \meta{key}: if an entry is
 % added to a property list which already contains the \meta{key} then the new
@@ -111,7 +111,7 @@
 %   \meta{property list_2}.
 % \end{function}
 %
-% \begin{function}[added = 2017-11-28, updated = 2019-08-25]
+% \begin{function}[added = 2017-11-28, updated = 2021-11-01]
 %   {
 %     \prop_set_from_keyval:Nn, \prop_set_from_keyval:cn,
 %     \prop_gset_from_keyval:Nn, \prop_gset_from_keyval:cn,
@@ -133,7 +133,7 @@
 %   signs.  The \meta{key} is then processed by \cs{tl_to_str:n}.
 % \end{function}
 %
-% \begin{function}[added = 2017-11-28, updated = 2019-08-25]
+% \begin{function}[added = 2017-11-28, updated = 2021-11-01]
 %   {\prop_const_from_keyval:Nn, \prop_const_from_keyval:cn}
 %   \begin{syntax}
 %     \cs{prop_const_from_keyval:Nn} \meta{prop~var}
@@ -205,7 +205,7 @@
 %   last value, namely the value in \meta{prop~var_3} is kept.
 % \end{function}
 %
-% \begin{function}[added = 2021-05-16]
+% \begin{function}[added = 2021-05-16, updated = 2021-11-01]
 %   {
 %     \prop_put_from_keyval:Nn, \prop_put_from_keyval:cn,
 %     \prop_gput_from_keyval:Nn, \prop_gput_from_keyval:cn,
@@ -793,7 +793,7 @@
 \cs_new_protected:Npn \@@_concat:NNNN #1#2#3#4
   {
     \prop_set_eq:NN \l_@@_internal_prop #3
-    \prop_map_tokens:Nn #4 { \prop_put:Nnn \l_@@_internal_prop }
+    \prop_map_inline:Nn #4 { \prop_put:Nnn \l_@@_internal_prop {##1} {##2} }
     #1 #2 \l_@@_internal_prop
   }
 %    \end{macrocode}
@@ -804,16 +804,7 @@
 % \begin{macro}{\prop_const_from_keyval:Nn, \prop_const_from_keyval:cn}
 % \begin{macro}{\prop_put_from_keyval:Nn, \prop_put_from_keyval:cn}
 % \begin{macro}{\prop_gput_from_keyval:Nn, \prop_gput_from_keyval:cn}
-% \begin{macro}
-%   {
-%     \@@_from_keyval:n,
-%     \@@_from_keyval_loop:w,
-%     \@@_from_keyval_split:Nw,
-%     \@@_from_keyval_key:n,
-%     \@@_from_keyval_key:w,
-%     \@@_from_keyval_value:n,
-%     \@@_from_keyval_value:w
-%   }
+% \begin{macro}{\@@_missing_eq:n}
 %   To avoid tracking throughout the loop the variable name and whether
 %   the assignment is local/global, do everything in a scratch variable
 %   and empty it afterwards to avoid wasting memory.  Loop through items
@@ -832,80 +823,48 @@
 %   output one key--value pair for the property list; otherwise complain
 %   about a missing or extra~|=|.
 %    \begin{macrocode}
-\cs_new_protected:Npn \prop_set_from_keyval:Nn #1#2
+\cs_new_protected:Npn \prop_set_from_keyval:Nn #1
   {
-    \prop_clear:N \l_@@_internal_prop
-    \@@_from_keyval:n {#2}
-    \prop_set_eq:NN #1 \l_@@_internal_prop
-    \prop_clear:N \l_@@_internal_prop
+    \prop_clear:N #1
+    \prop_put_from_keyval:Nn #1
   }
 \cs_generate_variant:Nn \prop_set_from_keyval:Nn { c }
-\cs_new_protected:Npn \prop_gset_from_keyval:Nn #1#2
+\cs_new_protected:Npn \prop_gset_from_keyval:Nn #1
   {
-    \prop_clear:N \l_@@_internal_prop
-    \@@_from_keyval:n {#2}
-    \prop_gset_eq:NN #1 \l_@@_internal_prop
-    \prop_clear:N \l_@@_internal_prop
+    \prop_gclear:N #1
+    \prop_gput_from_keyval:Nn #1
   }
 \cs_generate_variant:Nn \prop_gset_from_keyval:Nn { c }
 \cs_new_protected:Npn \prop_const_from_keyval:Nn #1#2
   {
-    \prop_clear:N \l_@@_internal_prop
-    \@@_from_keyval:n {#2}
+    \prop_set_from_keyval:Nn \l_@@_internal_prop {#2}
     \tl_const:Nx #1 { \exp_not:o \l_@@_internal_prop }
     \prop_clear:N \l_@@_internal_prop
   }
 \cs_generate_variant:Nn \prop_const_from_keyval:Nn { c }
-\cs_new_protected:Npn \prop_put_from_keyval:Nn #1#2
+\cs_new_protected:Npn \prop_put_from_keyval:Nn
   {
-    \prop_set_eq:NN \l_@@_internal_prop #1
-    \@@_from_keyval:n {#2}
-    \prop_set_eq:NN #1 \l_@@_internal_prop
-    \prop_clear:N \l_@@_internal_prop
+    \bool_if:NTF \l__keyval_allow_blank_keys_bool
+      { \@@_keyval_parse:NNNn \c_true_bool }
+      { \@@_keyval_parse:NNNn \c_false_bool }
+      \prop_put:Nnn
   }
 \cs_generate_variant:Nn \prop_put_from_keyval:Nn { c }
-\cs_new_protected:Npn \prop_gput_from_keyval:Nn #1#2
+\cs_new_protected:Npn \prop_gput_from_keyval:Nn
   {
-    \prop_set_eq:NN \l_@@_internal_prop #1
-    \@@_from_keyval:n {#2}
-    \prop_gset_eq:NN #1 \l_@@_internal_prop
-    \prop_clear:N \l_@@_internal_prop
+    \bool_if:NTF \l__keyval_allow_blank_keys_bool
+      { \@@_keyval_parse:NNNn \c_true_bool }
+      { \@@_keyval_parse:NNNn \c_false_bool }
+      \prop_gput:Nnn
   }
 \cs_generate_variant:Nn \prop_gput_from_keyval:Nn { c }
-\cs_new_protected:Npn \@@_from_keyval:n #1
-  {
-    \@@_from_keyval_loop:w \prg_do_nothing: #1 ,
-      \q_@@_recursion_tail , \q_@@_recursion_stop
-  }
-\cs_new_protected:Npn \@@_from_keyval_loop:w #1 ,
-  {
-    \@@_if_recursion_tail_stop:o {#1}
-    \@@_from_keyval_split:Nw \@@_from_keyval_key:n
-      #1 = = \s_@@_stop {#1}
-    \@@_from_keyval_loop:w \prg_do_nothing:
-  }
-\cs_new_protected:Npn \@@_from_keyval_split:Nw #1#2 =
-  { \tl_trim_spaces_apply:oN {#2} #1 }
-\cs_new_protected:Npn \@@_from_keyval_key:n #1
-  { \@@_from_keyval_key:w #1 \s_@@_mark }
-\cs_new_protected:Npn \@@_from_keyval_key:w #1 \s_@@_mark #2 \s_@@_stop
+\cs_new_protected:Npn \@@_missing_eq:n
+  { \msg_error:nnn { prop } { prop-keyval } }
+\cs_new_protected:Npn \@@_keyval_parse:NNNn #1#2#3#4
   {
-    \@@_from_keyval_split:Nw \@@_from_keyval_value:n
-      \prg_do_nothing: #2 \s_@@_stop {#1}
-  }
-\cs_new_protected:Npn \@@_from_keyval_value:n #1
-  { \@@_from_keyval_value:w #1 \s_@@_mark }
-\cs_new_protected:Npn \@@_from_keyval_value:w #1 \s_@@_mark #2 \s_@@_stop #3#4
-  {
-    \tl_if_single:nTF {#2}
-      { \prop_put:Nnn \l_@@_internal_prop {#3} {#1} }
-      {
-        \tl_if_empty:nF { #3 #1 #2 }
-          {
-            \msg_error:nnx { prop } { prop-keyval }
-              { \exp_not:o {#4} }
-          }
-      }
+    \bool_set_eq:NN \l__keyval_allow_blank_keys_bool \c_true_bool
+    \keyval_parse:nnn \@@_missing_eq:n { #2 #3 } {#4}
+    \bool_set_eq:NN \l__keyval_allow_blank_keys_bool #1
   }
 %    \end{macrocode}
 % \end{macro}
diff --git a/l3kernel/testfiles/m3color003.ptex.tlg b/l3kernel/testfiles/m3color003.ptex.tlg
index 3f4ebe310..0a586c114 100644
--- a/l3kernel/testfiles/m3color003.ptex.tlg
+++ b/l3kernel/testfiles/m3color003.ptex.tlg
@@ -307,7 +307,7 @@ l. ...  }
 LaTeX has been asked to create a separation color space, but no 
     alternative-model = <model>
 key was given with the correct information.
-! LaTeX3 Error: Missing/extra '=' in 'alternative-model' (in '..._keyval:Nn')
+! LaTeX3 Error: Missing '=' in 'alternative-model' (in '..._keyval:Nn')
 Type <return> to continue.
  ...                                              
 l. ...  }
diff --git a/l3kernel/testfiles/m3color003.tlg b/l3kernel/testfiles/m3color003.tlg
index 63d24f4b2..d026634c4 100644
--- a/l3kernel/testfiles/m3color003.tlg
+++ b/l3kernel/testfiles/m3color003.tlg
@@ -303,7 +303,7 @@ l. ...  }
 LaTeX has been asked to create a separation color space, but no 
     alternative-model = <model>
 key was given with the correct information.
-! LaTeX3 Error: Missing/extra '=' in 'alternative-model' (in '..._keyval:Nn')
+! LaTeX3 Error: Missing '=' in 'alternative-model' (in '..._keyval:Nn')
 Type <return> to continue.
  ...                                              
 l. ...  }
diff --git a/l3kernel/testfiles/m3color003.uptex.tlg b/l3kernel/testfiles/m3color003.uptex.tlg
index 3f4ebe310..0a586c114 100644
--- a/l3kernel/testfiles/m3color003.uptex.tlg
+++ b/l3kernel/testfiles/m3color003.uptex.tlg
@@ -307,7 +307,7 @@ l. ...  }
 LaTeX has been asked to create a separation color space, but no 
     alternative-model = <model>
 key was given with the correct information.
-! LaTeX3 Error: Missing/extra '=' in 'alternative-model' (in '..._keyval:Nn')
+! LaTeX3 Error: Missing '=' in 'alternative-model' (in '..._keyval:Nn')
 Type <return> to continue.
  ...                                              
 l. ...  }
diff --git a/l3kernel/testfiles/m3color003.xetex.tlg b/l3kernel/testfiles/m3color003.xetex.tlg
index 509d07d12..2616114a6 100644
--- a/l3kernel/testfiles/m3color003.xetex.tlg
+++ b/l3kernel/testfiles/m3color003.xetex.tlg
@@ -303,7 +303,7 @@ l. ...  }
 LaTeX has been asked to create a separation color space, but no 
     alternative-model = <model>
 key was given with the correct information.
-! LaTeX3 Error: Missing/extra '=' in 'alternative-model' (in '..._keyval:Nn')
+! LaTeX3 Error: Missing '=' in 'alternative-model' (in '..._keyval:Nn')
 Type <return> to continue.
  ...                                              
 l. ...  }
diff --git a/l3kernel/testfiles/m3prop005.tlg b/l3kernel/testfiles/m3prop005.tlg
index 70157b238..e70e03516 100644
--- a/l3kernel/testfiles/m3prop005.tlg
+++ b/l3kernel/testfiles/m3prop005.tlg
@@ -24,21 +24,30 @@ The property list \c_A_prop contains the pairs (without outer braces):
 ============================================================
 TEST 2: prop from_keyval invalid
 ============================================================
-! LaTeX3 Error: Missing/extra '=' in '{=}' (in '..._keyval:Nn')
-Type <return> to continue.
- ...                                              
+! Use of \??? doesn't match its definition.
+<argument> \???  
+                 ! LaTeX3 Error: Misplaced '=' in key-value input on line ...
 l. ...  }
-LaTeX does not know anything more about this error, sorry.
-Try typing <return> to proceed.
-If that doesn't work, type X <return> to quit.
-! LaTeX3 Error: Missing/extra '=' in 'a==b' (in '..._keyval:Nn')
+If you say, e.g., `\def\a1{...}', then you must always
+put `1' after `\a', since control sequence names are
+made up of letters only. The macro here has not been
+followed by the required stuff, so I'm ignoring it.
+! Use of \??? doesn't match its definition.
+<argument> \???  
+                 ! LaTeX3 Error: Misplaced '=' in key-value input on line ...
+l. ...  }
+If you say, e.g., `\def\a1{...}', then you must always
+put `1' after `\a', since control sequence names are
+made up of letters only. The macro here has not been
+followed by the required stuff, so I'm ignoring it.
+! LaTeX3 Error: Missing '=' in '=' (in '..._keyval:Nn')
 Type <return> to continue.
  ...                                              
 l. ...  }
 LaTeX does not know anything more about this error, sorry.
 Try typing <return> to proceed.
 If that doesn't work, type X <return> to quit.
-! LaTeX3 Error: Missing/extra '=' in '==' (in '..._keyval:Nn')
+! LaTeX3 Error: Missing '=' in '' (in '..._keyval:Nn')
 Type <return> to continue.
  ...                                              
 l. ...  }
@@ -47,21 +56,30 @@ Try typing <return> to proceed.
 If that doesn't work, type X <return> to quit.
 The property list \l_tmpa_prop is empty
 > .
-! LaTeX3 Error: Missing/extra '=' in '{=}' (in '..._keyval:Nn')
-Type <return> to continue.
- ...                                              
+! Use of \??? doesn't match its definition.
+<argument> \???  
+                 ! LaTeX3 Error: Misplaced '=' in key-value input on line ...
 l. ...  }
-LaTeX does not know anything more about this error, sorry.
-Try typing <return> to proceed.
-If that doesn't work, type X <return> to quit.
-! LaTeX3 Error: Missing/extra '=' in 'a==b' (in '..._keyval:Nn')
+If you say, e.g., `\def\a1{...}', then you must always
+put `1' after `\a', since control sequence names are
+made up of letters only. The macro here has not been
+followed by the required stuff, so I'm ignoring it.
+! Use of \??? doesn't match its definition.
+<argument> \???  
+                 ! LaTeX3 Error: Misplaced '=' in key-value input on line ...
+l. ...  }
+If you say, e.g., `\def\a1{...}', then you must always
+put `1' after `\a', since control sequence names are
+made up of letters only. The macro here has not been
+followed by the required stuff, so I'm ignoring it.
+! LaTeX3 Error: Missing '=' in '=' (in '..._keyval:Nn')
 Type <return> to continue.
  ...                                              
 l. ...  }
 LaTeX does not know anything more about this error, sorry.
 Try typing <return> to proceed.
 If that doesn't work, type X <return> to quit.
-! LaTeX3 Error: Missing/extra '=' in '==' (in '..._keyval:Nn')
+! LaTeX3 Error: Missing '=' in '' (in '..._keyval:Nn')
 Type <return> to continue.
  ...                                              
 l. ...  }
@@ -70,21 +88,30 @@ Try typing <return> to proceed.
 If that doesn't work, type X <return> to quit.
 The property list \g_tmpa_prop is empty
 > .
-! LaTeX3 Error: Missing/extra '=' in '{=}' (in '..._keyval:Nn')
-Type <return> to continue.
- ...                                              
+! Use of \??? doesn't match its definition.
+<argument> \???  
+                 ! LaTeX3 Error: Misplaced '=' in key-value input on line ...
 l. ...  }
-LaTeX does not know anything more about this error, sorry.
-Try typing <return> to proceed.
-If that doesn't work, type X <return> to quit.
-! LaTeX3 Error: Missing/extra '=' in 'a==b' (in '..._keyval:Nn')
+If you say, e.g., `\def\a1{...}', then you must always
+put `1' after `\a', since control sequence names are
+made up of letters only. The macro here has not been
+followed by the required stuff, so I'm ignoring it.
+! Use of \??? doesn't match its definition.
+<argument> \???  
+                 ! LaTeX3 Error: Misplaced '=' in key-value input on line ...
+l. ...  }
+If you say, e.g., `\def\a1{...}', then you must always
+put `1' after `\a', since control sequence names are
+made up of letters only. The macro here has not been
+followed by the required stuff, so I'm ignoring it.
+! LaTeX3 Error: Missing '=' in '=' (in '..._keyval:Nn')
 Type <return> to continue.
  ...                                              
 l. ...  }
 LaTeX does not know anything more about this error, sorry.
 Try typing <return> to proceed.
 If that doesn't work, type X <return> to quit.
-! LaTeX3 Error: Missing/extra '=' in '==' (in '..._keyval:Nn')
+! LaTeX3 Error: Missing '=' in '' (in '..._keyval:Nn')
 Type <return> to continue.
  ...                                              
 l. ...  }





More information about the latex3-commits mailing list.