[latex3-commits] [git/LaTeX3-latex3-latex3] master: Remove duplicate keys in `\prop_set_from_keyval:Nn` (fixes #572) (17e364079)

Bruno Le Floch bruno at le-floch.fr
Sun Aug 25 14:51:58 CEST 2019


Repository : https://github.com/latex3/latex3
On branch  : master
Link       : https://github.com/latex3/latex3/commit/17e3640797d26ebca0a77f7c999ac920a46b91a9

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

commit 17e3640797d26ebca0a77f7c999ac920a46b91a9
Author: Bruno Le Floch <bruno at le-floch.fr>
Date:   Sun Aug 25 14:51:58 2019 +0200

    Remove duplicate keys in `\prop_set_from_keyval:Nn` (fixes #572)
    
    Not efficiently, but there is no good solution


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

17e3640797d26ebca0a77f7c999ac920a46b91a9
 l3kernel/CHANGELOG.md                   |   2 +-
 l3kernel/l3candidates.dtx               |   7 +-
 l3kernel/l3prop.dtx                     | 102 +++++++++++++---------
 l3kernel/testfiles/m3expl001.luatex.tlg |   1 +
 l3kernel/testfiles/m3expl001.ptex.tlg   |   1 +
 l3kernel/testfiles/m3expl001.tlg        |   1 +
 l3kernel/testfiles/m3expl001.uptex.tlg  |   1 +
 l3kernel/testfiles/m3expl001.xetex.tlg  |   1 +
 l3kernel/testfiles/m3expl003.luatex.tlg |   1 +
 l3kernel/testfiles/m3expl003.ptex.tlg   |   1 +
 l3kernel/testfiles/m3expl003.tlg        |   1 +
 l3kernel/testfiles/m3expl003.uptex.tlg  |   1 +
 l3kernel/testfiles/m3expl003.xetex.tlg  |   1 +
 l3kernel/testfiles/m3prop005.lvt        |   2 +-
 l3kernel/testfiles/m3prop005.tlg        | 145 ++++++++++++++------------------
 15 files changed, 138 insertions(+), 130 deletions(-)

diff --git a/l3kernel/CHANGELOG.md b/l3kernel/CHANGELOG.md
index d4ab00a61..1515574f8 100644
--- a/l3kernel/CHANGELOG.md
+++ b/l3kernel/CHANGELOG.md
@@ -19,9 +19,9 @@ this project uses date-based 'snapshot' version identifiers.
 
 - `\tl_rescan:nn` and `\tl_(g)set_rescan:Nnn` when single-line input
   contains a comment character (see #607)
-
 - Final value of the variable in `\tl_map_variable:NNn` and
   `\clist_map_variable:NNn`.
+- Remove duplicate keys in `\prop_set_from_keyval:Nn` (see #572)
 
 ## [2019-08-14]
 
diff --git a/l3kernel/l3candidates.dtx b/l3kernel/l3candidates.dtx
index c34627161..435c9e400 100644
--- a/l3kernel/l3candidates.dtx
+++ b/l3kernel/l3candidates.dtx
@@ -624,7 +624,7 @@
 %   \end{texnote}
 % \end{function}
 %
-% \begin{function}[added = 2017-11-28]
+% \begin{function}[added = 2017-11-28, updated = 2019-08-25]
 %   {
 %     \prop_set_from_keyval:Nn, \prop_set_from_keyval:cn,
 %     \prop_gset_from_keyval:Nn, \prop_gset_from_keyval:cn,
@@ -637,10 +637,10 @@
 %       \}
 %   \end{syntax}
 %   Sets \meta{prop~var} to contain key--value pairs given in the second
-%   argument.
+%   argument.  If duplicate keys appear only one of the values is kept.
 % \end{function}
 %
-% \begin{function}[added = 2017-11-28]
+% \begin{function}[added = 2017-11-28, updated = 2019-08-25]
 %   {\prop_const_from_keyval:Nn, \prop_const_from_keyval:cn}
 %   \begin{syntax}
 %     \cs{prop_const_from_keyval:Nn} \meta{prop~var}
@@ -652,6 +652,7 @@
 %   Creates a new constant \meta{prop~var} or raises an error if the
 %   name is already taken. The \meta{prop~var} is set globally to
 %   contain key--value pairs given in the second argument.
+%   If duplicate keys appear only one of the values is kept.
 % \end{function}
 %
 % \section{Additions to \pkg{l3seq}}
diff --git a/l3kernel/l3prop.dtx b/l3kernel/l3prop.dtx
index 9f340d0b9..32e827a4a 100644
--- a/l3kernel/l3prop.dtx
+++ b/l3kernel/l3prop.dtx
@@ -638,6 +638,13 @@
 % \end{variable}
 % \end{variable}
 %
+% \begin{variable}{\l_@@_internal_prop}
+%   Property list used by \cs{prop_set_from_keyval:Nn} and others.
+%    \begin{macrocode}
+\prop_new:N \l_@@_internal_prop
+%    \end{macrocode}
+% \end{variable}
+%
 % \begin{macro}{\prop_set_from_keyval:Nn, \prop_set_from_keyval:cn}
 % \begin{macro}{\prop_gset_from_keyval:Nn, \prop_gset_from_keyval:cn}
 % \begin{macro}{\prop_const_from_keyval:Nn, \prop_const_from_keyval:cn}
@@ -651,69 +658,80 @@
 %     \@@_from_keyval_value:n,
 %     \@@_from_keyval_value:w
 %   }
-%   Loop through items separated by commas, with \cs{q_mark} to avoid
-%   losing braces.  After checking for termination, split the item at
-%   the first then at the second |=| (which ought to be the first of the
-%   trailing~|=|).  At both splits, trim spaces and
-%   call \cs{@@_from_keyval_key:w}, then \cs{@@_from_keyval_value:w},
-%   followed by the trimmed material, \cs{q_nil}, the subsequent part of
-%   the item, and the trailing |=|'s and \cs{q_stop}.  After finding the
-%   \meta{key} just store it after \cs{q_stop}.  After finding the
-%   \meta{value} ignore completely empty items (both trailing~|=| were
-%   used as delimiters and all parts are empty); if the remaining
-%   part~|#2| consists exactly of the second trailing~|=| (namely there
-%   was exactly one |=|~in the item) then output one key--value pair for
-%   the property list; otherwise complain about a missing or extra~|=|.
+%   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
+%   separated by commas, with \cs{prg_do_nothing:} to avoid losing
+%   braces.  After checking for termination, split the item at the first
+%   and then at the second |=| (which ought to be the first of the
+%   trailing~|=| that we added).  For both splits trim spaces and call a
+%   function (first \cs{@@_from_keyval_key:w} then
+%   \cs{@@_from_keyval_value:w}), followed by the trimmed material,
+%   \cs{q_nil}, the subsequent part of the item, and the trailing |=|'s
+%   and \cs{q_stop}.  After finding the \meta{key} just store it after
+%   \cs{q_stop}.  After finding the \meta{value} ignore completely empty
+%   items (both trailing~|=| were used as delimiters and all parts are
+%   empty); if the remaining part~|#2| consists exactly of the second
+%   trailing~|=| (namely there was exactly one |=|~in the item) then
+%   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
-  { \tl_set:Nx #1 { \@@_from_keyval:n {#2} } }
+  {
+    \prop_clear:N \l_@@_internal_prop
+    \@@_from_keyval:n {#2}
+    \prop_set_eq:NN #1 \l_@@_internal_prop
+    \prop_clear:N \l_@@_internal_prop
+  }
 \cs_generate_variant:Nn \prop_set_from_keyval:Nn { c }
 \cs_new_protected:Npn \prop_gset_from_keyval:Nn #1#2
-  { \tl_gset:Nx #1 { \@@_from_keyval:n {#2} } }
+  {
+    \prop_clear:N \l_@@_internal_prop
+    \@@_from_keyval:n {#2}
+    \prop_gset_eq:NN #1 \l_@@_internal_prop
+    \prop_clear:N \l_@@_internal_prop
+  }
 \cs_generate_variant:Nn \prop_gset_from_keyval:Nn { c }
 \cs_new_protected:Npn \prop_const_from_keyval:Nn #1#2
-  { \tl_const:Nx #1 { \@@_from_keyval:n {#2} } }
+  {
+    \prop_clear:N \l_@@_internal_prop
+    \@@_from_keyval:n {#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:Npn \@@_from_keyval:n #1
+\cs_new_protected:Npn \@@_from_keyval:n #1
   {
-    \s_@@
-    \@@_from_keyval_loop:w \q_mark #1 ,
+    \@@_from_keyval_loop:w \prg_do_nothing: #1 ,
       \q_recursion_tail , \q_recursion_stop
   }
-\cs_new:Npn \@@_from_keyval_loop:w #1 ,
+\cs_new_protected:Npn \@@_from_keyval_loop:w #1 ,
   {
-    \quark_if_recursion_tail_stop:o { \use_none:n #1 }
+    \quark_if_recursion_tail_stop:o {#1}
     \@@_from_keyval_split:Nw \@@_from_keyval_key:n
-      #1 = = \q_stop { \use_none:n #1 }
-    \@@_from_keyval_loop:w \q_mark
+      #1 = = \q_stop {#1}
+    \@@_from_keyval_loop:w \prg_do_nothing:
   }
-\cs_new:Npn \@@_from_keyval_split:Nw #1#2 =
-  {
-    \tl_trim_spaces_apply:oN { \use_none:n #2 } #1
-      \q_nil
-  }
-\cs_new:Npn \@@_from_keyval_key:n #1
-  { \@@_from_keyval_key:w #1 }
-\cs_new:Npn \@@_from_keyval_key:w #1 \q_nil #2 \q_stop
+\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 \q_nil }
+\cs_new_protected:Npn \@@_from_keyval_key:w #1 \q_nil #2 \q_stop
   {
     \@@_from_keyval_split:Nw \@@_from_keyval_value:n
-      \q_mark #2 \q_stop {#1}
+      \prg_do_nothing: #2 \q_stop {#1}
   }
-\cs_new:Npn \@@_from_keyval_value:n #1
-  { \@@_from_keyval_value:w #1 }
-\cs_new:Npn \@@_from_keyval_value:w #1 \q_nil #2 \q_stop #3#4
+\cs_new_protected:Npn \@@_from_keyval_value:n #1
+  { \@@_from_keyval_value:w #1 \q_nil }
+\cs_new_protected:Npn \@@_from_keyval_value:w #1 \q_nil #2 \q_stop #3#4
   {
     \tl_if_empty:nF { #3 #1 #2 }
       {
         \str_if_eq:nnTF {#2} { = }
+          { \prop_put:Nnn \l_@@_internal_prop {#3} {#1} }
           {
-            \exp_not:N \@@_pair:wn \tl_to_str:n {#3}
-            \s_@@ { \exp_not:n {#1} }
-          }
-          {
-            \__kernel_msg_expandable_error:nnf
-              { kernel } { prop-keyval }
-              { \exp_after:wN \exp_stop_f: #4 }
+            \__kernel_msg_error:nnx { kernel } { prop-keyval }
+              { \exp_not:o {#4} }
           }
       }
   }
diff --git a/l3kernel/testfiles/m3expl001.luatex.tlg b/l3kernel/testfiles/m3expl001.luatex.tlg
index 87e545402..c0506d0bd 100644
--- a/l3kernel/testfiles/m3expl001.luatex.tlg
+++ b/l3kernel/testfiles/m3expl001.luatex.tlg
@@ -2293,6 +2293,7 @@ Defining \l_tmpa_prop on line ...
 Defining \l_tmpb_prop on line ...
 Defining \g_tmpa_prop on line ...
 Defining \g_tmpb_prop on line ...
+Defining \l__prop_internal_prop on line ...
 Defining \prop_set_from_keyval:Nn on line ...
 Defining \prop_set_from_keyval:cn on line ...
 Defining \prop_gset_from_keyval:Nn on line ...
diff --git a/l3kernel/testfiles/m3expl001.ptex.tlg b/l3kernel/testfiles/m3expl001.ptex.tlg
index 90e3cd893..fbb5927f0 100644
--- a/l3kernel/testfiles/m3expl001.ptex.tlg
+++ b/l3kernel/testfiles/m3expl001.ptex.tlg
@@ -2547,6 +2547,7 @@ Defining \l_tmpa_prop on line ...
 Defining \l_tmpb_prop on line ...
 Defining \g_tmpa_prop on line ...
 Defining \g_tmpb_prop on line ...
+Defining \l__prop_internal_prop on line ...
 Defining \prop_set_from_keyval:Nn on line ...
 Defining \prop_set_from_keyval:cn on line ...
 Defining \prop_gset_from_keyval:Nn on line ...
diff --git a/l3kernel/testfiles/m3expl001.tlg b/l3kernel/testfiles/m3expl001.tlg
index 76ac6ba9f..a27bc3999 100644
--- a/l3kernel/testfiles/m3expl001.tlg
+++ b/l3kernel/testfiles/m3expl001.tlg
@@ -2547,6 +2547,7 @@ Defining \l_tmpa_prop on line ...
 Defining \l_tmpb_prop on line ...
 Defining \g_tmpa_prop on line ...
 Defining \g_tmpb_prop on line ...
+Defining \l__prop_internal_prop on line ...
 Defining \prop_set_from_keyval:Nn on line ...
 Defining \prop_set_from_keyval:cn on line ...
 Defining \prop_gset_from_keyval:Nn on line ...
diff --git a/l3kernel/testfiles/m3expl001.uptex.tlg b/l3kernel/testfiles/m3expl001.uptex.tlg
index 77437160e..b9cbabc59 100644
--- a/l3kernel/testfiles/m3expl001.uptex.tlg
+++ b/l3kernel/testfiles/m3expl001.uptex.tlg
@@ -2547,6 +2547,7 @@ Defining \l_tmpa_prop on line ...
 Defining \l_tmpb_prop on line ...
 Defining \g_tmpa_prop on line ...
 Defining \g_tmpb_prop on line ...
+Defining \l__prop_internal_prop on line ...
 Defining \prop_set_from_keyval:Nn on line ...
 Defining \prop_set_from_keyval:cn on line ...
 Defining \prop_gset_from_keyval:Nn on line ...
diff --git a/l3kernel/testfiles/m3expl001.xetex.tlg b/l3kernel/testfiles/m3expl001.xetex.tlg
index b9d3f8272..ae407547d 100644
--- a/l3kernel/testfiles/m3expl001.xetex.tlg
+++ b/l3kernel/testfiles/m3expl001.xetex.tlg
@@ -2291,6 +2291,7 @@ Defining \l_tmpa_prop on line ...
 Defining \l_tmpb_prop on line ...
 Defining \g_tmpa_prop on line ...
 Defining \g_tmpb_prop on line ...
+Defining \l__prop_internal_prop on line ...
 Defining \prop_set_from_keyval:Nn on line ...
 Defining \prop_set_from_keyval:cn on line ...
 Defining \prop_gset_from_keyval:Nn on line ...
diff --git a/l3kernel/testfiles/m3expl003.luatex.tlg b/l3kernel/testfiles/m3expl003.luatex.tlg
index 87e545402..c0506d0bd 100644
--- a/l3kernel/testfiles/m3expl003.luatex.tlg
+++ b/l3kernel/testfiles/m3expl003.luatex.tlg
@@ -2293,6 +2293,7 @@ Defining \l_tmpa_prop on line ...
 Defining \l_tmpb_prop on line ...
 Defining \g_tmpa_prop on line ...
 Defining \g_tmpb_prop on line ...
+Defining \l__prop_internal_prop on line ...
 Defining \prop_set_from_keyval:Nn on line ...
 Defining \prop_set_from_keyval:cn on line ...
 Defining \prop_gset_from_keyval:Nn on line ...
diff --git a/l3kernel/testfiles/m3expl003.ptex.tlg b/l3kernel/testfiles/m3expl003.ptex.tlg
index 90e3cd893..fbb5927f0 100644
--- a/l3kernel/testfiles/m3expl003.ptex.tlg
+++ b/l3kernel/testfiles/m3expl003.ptex.tlg
@@ -2547,6 +2547,7 @@ Defining \l_tmpa_prop on line ...
 Defining \l_tmpb_prop on line ...
 Defining \g_tmpa_prop on line ...
 Defining \g_tmpb_prop on line ...
+Defining \l__prop_internal_prop on line ...
 Defining \prop_set_from_keyval:Nn on line ...
 Defining \prop_set_from_keyval:cn on line ...
 Defining \prop_gset_from_keyval:Nn on line ...
diff --git a/l3kernel/testfiles/m3expl003.tlg b/l3kernel/testfiles/m3expl003.tlg
index 76ac6ba9f..a27bc3999 100644
--- a/l3kernel/testfiles/m3expl003.tlg
+++ b/l3kernel/testfiles/m3expl003.tlg
@@ -2547,6 +2547,7 @@ Defining \l_tmpa_prop on line ...
 Defining \l_tmpb_prop on line ...
 Defining \g_tmpa_prop on line ...
 Defining \g_tmpb_prop on line ...
+Defining \l__prop_internal_prop on line ...
 Defining \prop_set_from_keyval:Nn on line ...
 Defining \prop_set_from_keyval:cn on line ...
 Defining \prop_gset_from_keyval:Nn on line ...
diff --git a/l3kernel/testfiles/m3expl003.uptex.tlg b/l3kernel/testfiles/m3expl003.uptex.tlg
index 77437160e..b9cbabc59 100644
--- a/l3kernel/testfiles/m3expl003.uptex.tlg
+++ b/l3kernel/testfiles/m3expl003.uptex.tlg
@@ -2547,6 +2547,7 @@ Defining \l_tmpa_prop on line ...
 Defining \l_tmpb_prop on line ...
 Defining \g_tmpa_prop on line ...
 Defining \g_tmpb_prop on line ...
+Defining \l__prop_internal_prop on line ...
 Defining \prop_set_from_keyval:Nn on line ...
 Defining \prop_set_from_keyval:cn on line ...
 Defining \prop_gset_from_keyval:Nn on line ...
diff --git a/l3kernel/testfiles/m3expl003.xetex.tlg b/l3kernel/testfiles/m3expl003.xetex.tlg
index b9d3f8272..ae407547d 100644
--- a/l3kernel/testfiles/m3expl003.xetex.tlg
+++ b/l3kernel/testfiles/m3expl003.xetex.tlg
@@ -2291,6 +2291,7 @@ Defining \l_tmpa_prop on line ...
 Defining \l_tmpb_prop on line ...
 Defining \g_tmpa_prop on line ...
 Defining \g_tmpb_prop on line ...
+Defining \l__prop_internal_prop on line ...
 Defining \prop_set_from_keyval:Nn on line ...
 Defining \prop_set_from_keyval:cn on line ...
 Defining \prop_gset_from_keyval:Nn on line ...
diff --git a/l3kernel/testfiles/m3prop005.lvt b/l3kernel/testfiles/m3prop005.lvt
index 466d6a773..4b21876bd 100644
--- a/l3kernel/testfiles/m3prop005.lvt
+++ b/l3kernel/testfiles/m3prop005.lvt
@@ -28,7 +28,7 @@
       { \a = b , ~ \c ~ = ~ { ~ \d = e ~ } , , = , { = } = , ~ { } ~ = { , } , }
     \prop_log:N \g_tmpa_prop
     \prop_const_from_keyval:Nn \c_A_prop
-      { \a = b , ~ \c ~ = ~ { ~ \d = e ~ } , , = , { = } = , ~ { } ~ = { , } , }
+      { \a = b , ~ \c ~ = ~ { ~ \d = e ~ } , , = , { = } = , ~ { } ~ = { , } , ~ {\a} = Z }
     \prop_log:N \c_A_prop
   }
 
diff --git a/l3kernel/testfiles/m3prop005.tlg b/l3kernel/testfiles/m3prop005.tlg
index e9614db2a..d64191f91 100644
--- a/l3kernel/testfiles/m3prop005.tlg
+++ b/l3kernel/testfiles/m3prop005.tlg
@@ -7,112 +7,91 @@ TEST 1: prop from_keyval
 The property list \l_tmpa_prop contains the pairs (without outer braces):
 >  {\a }  =>  {b}
 >  {\c }  =>  { \d =e }
->  {}  =>  {}
->  {=}  =>  {}
->  {}  =>  {,}.
+>  {}  =>  {,}
+>  {=}  =>  {}.
 The property list \g_tmpa_prop contains the pairs (without outer braces):
 >  {\a }  =>  {b}
 >  {\c }  =>  { \d =e }
->  {}  =>  {}
->  {=}  =>  {}
->  {}  =>  {,}.
+>  {}  =>  {,}
+>  {=}  =>  {}.
 Defining \c_A_prop on line ...
 The property list \c_A_prop contains the pairs (without outer braces):
->  {\a }  =>  {b}
+>  {\a }  =>  {Z}
 >  {\c }  =>  { \d =e }
->  {}  =>  {}
->  {=}  =>  {}
->  {}  =>  {,}.
+>  {}  =>  {,}
+>  {=}  =>  {}.
 ============================================================
 ============================================================
 TEST 2: prop from_keyval invalid
 ============================================================
-! Undefined control sequence.
-<argument> \LaTeX3 error: 
-                           Missing/extra '=' in '{=}' (in '..._keyval:Nn')
+! LaTeX3 Error: Missing/extra '=' in '{=}' (in '..._keyval:Nn')
+Type <return> to continue.
+ ...                                              
 l. ...  }
-The control sequence at the end of the top line
-of your error message was never \def'ed. If you have
-misspelled it (e.g., `\hobx'), type `I' and the correct
-spelling (e.g., `I\hbox'). Otherwise just continue,
-and I'll forget about whatever was undefined.
-! Undefined control sequence.
-<argument> \LaTeX3 error: 
-                           Missing/extra '=' in 'a==b' (in '..._keyval:Nn')
+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')
+Type <return> to continue.
+ ...                                              
 l. ...  }
-The control sequence at the end of the top line
-of your error message was never \def'ed. If you have
-misspelled it (e.g., `\hobx'), type `I' and the correct
-spelling (e.g., `I\hbox'). Otherwise just continue,
-and I'll forget about whatever was undefined.
-! Undefined control sequence.
-<argument> \LaTeX3 error: 
-                           Missing/extra '=' in '==' (in '..._keyval:Nn')
+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')
+Type <return> to continue.
+ ...                                              
 l. ...  }
-The control sequence at the end of the top line
-of your error message was never \def'ed. If you have
-misspelled it (e.g., `\hobx'), type `I' and the correct
-spelling (e.g., `I\hbox'). Otherwise just continue,
-and I'll forget about whatever was undefined.
+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.
 The property list \l_tmpa_prop is empty
 > .
-! Undefined control sequence.
-<argument> \LaTeX3 error: 
-                           Missing/extra '=' in '{=}' (in '..._keyval:Nn')
+! LaTeX3 Error: Missing/extra '=' in '{=}' (in '..._keyval:Nn')
+Type <return> to continue.
+ ...                                              
 l. ...  }
-The control sequence at the end of the top line
-of your error message was never \def'ed. If you have
-misspelled it (e.g., `\hobx'), type `I' and the correct
-spelling (e.g., `I\hbox'). Otherwise just continue,
-and I'll forget about whatever was undefined.
-! Undefined control sequence.
-<argument> \LaTeX3 error: 
-                           Missing/extra '=' in 'a==b' (in '..._keyval:Nn')
+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')
+Type <return> to continue.
+ ...                                              
 l. ...  }
-The control sequence at the end of the top line
-of your error message was never \def'ed. If you have
-misspelled it (e.g., `\hobx'), type `I' and the correct
-spelling (e.g., `I\hbox'). Otherwise just continue,
-and I'll forget about whatever was undefined.
-! Undefined control sequence.
-<argument> \LaTeX3 error: 
-                           Missing/extra '=' in '==' (in '..._keyval:Nn')
+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')
+Type <return> to continue.
+ ...                                              
 l. ...  }
-The control sequence at the end of the top line
-of your error message was never \def'ed. If you have
-misspelled it (e.g., `\hobx'), type `I' and the correct
-spelling (e.g., `I\hbox'). Otherwise just continue,
-and I'll forget about whatever was undefined.
+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.
 The property list \g_tmpa_prop is empty
 > .
-Defining \c_B_prop on line ...
-! Undefined control sequence.
-<argument> \LaTeX3 error: 
-                           Missing/extra '=' in '{=}' (in '..._keyval:Nn')
+! LaTeX3 Error: Missing/extra '=' in '{=}' (in '..._keyval:Nn')
+Type <return> to continue.
+ ...                                              
 l. ...  }
-The control sequence at the end of the top line
-of your error message was never \def'ed. If you have
-misspelled it (e.g., `\hobx'), type `I' and the correct
-spelling (e.g., `I\hbox'). Otherwise just continue,
-and I'll forget about whatever was undefined.
-! Undefined control sequence.
-<argument> \LaTeX3 error: 
-                           Missing/extra '=' in 'a==b' (in '..._keyval:Nn')
+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')
+Type <return> to continue.
+ ...                                              
 l. ...  }
-The control sequence at the end of the top line
-of your error message was never \def'ed. If you have
-misspelled it (e.g., `\hobx'), type `I' and the correct
-spelling (e.g., `I\hbox'). Otherwise just continue,
-and I'll forget about whatever was undefined.
-! Undefined control sequence.
-<argument> \LaTeX3 error: 
-                           Missing/extra '=' in '==' (in '..._keyval:Nn')
+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')
+Type <return> to continue.
+ ...                                              
 l. ...  }
-The control sequence at the end of the top line
-of your error message was never \def'ed. If you have
-misspelled it (e.g., `\hobx'), type `I' and the correct
-spelling (e.g., `I\hbox'). Otherwise just continue,
-and I'll forget about whatever was undefined.
+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.
+Defining \c_B_prop on line ...
 The property list \c_B_prop is empty
 > .
 ============================================================





More information about the latex3-commits mailing list