From 2f56d3421e4663856409792eb5b08a2c57b38a8c Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Wed, 21 Feb 2024 03:01:35 +0000
Subject: CTAN sync 202402210301

---
 macros/latex/contrib/l3kernel/l3prop.dtx | 139 ++++++++++++++++++++-----------
 1 file changed, 89 insertions(+), 50 deletions(-)

(limited to 'macros/latex/contrib/l3kernel/l3prop.dtx')

diff --git a/macros/latex/contrib/l3kernel/l3prop.dtx b/macros/latex/contrib/l3kernel/l3prop.dtx
index acab35c56e..dcf14be536 100644
--- a/macros/latex/contrib/l3kernel/l3prop.dtx
+++ b/macros/latex/contrib/l3kernel/l3prop.dtx
@@ -43,7 +43,7 @@
 %    }^^A
 % }
 %
-% \date{Released 2024-02-18}
+% \date{Released 2024-02-20}
 %
 % \maketitle
 %
@@ -1504,64 +1504,103 @@
 % consecutive entries \cs{@@_pair:wn} \meta{key_i} \cs{s_@@}
 % \Arg{value_i}.  If the \meta{key} is present in the \meta{property
 % list} then the \meta{true code} is left in the input stream, with
-% |#2|, |#3|, and |#4| replaced by the \meta{entries before},
+% |#1|, |#2|, and |#3| replaced by the \meta{entries before},
 % \meta{value}, and \meta{entries after}.  If the \meta{key} is not
 % present in the \meta{property list} then the \meta{false code} is left
 % in the input stream.  Only the \meta{true code} is used in the
 % replacement text of a macro defined internally, which requires
 % |##|~doubling.
 %
-% \begin{macro}{\@@_split:NnTFn}
-% \begin{macro}{\@@_split_aux:NnTFn}
-% \begin{macro}{\@@_split_aux:w}
-%   The aim is to split the \meta{property list} at the given \meta{key}
-%   into the \meta{extract_1} before the key--value pair, the
-%   \meta{value} associated with the \meta{key} and the \meta{extract_2}
-%   after the key--value pair.  This is done using a delimited function,
-%   whose definition is as follows, where the \meta{key} is turned into
-%   a string.
+% \begin{macro}
+%   {
+%     \@@_split:NnTFn, \@@_split_aux:nNTFn, \@@_split_test:wn,
+%     \@@_split_flat:w, \@@_split_linked:w, \@@_split_wrong:Nw
+%   }
+%   The aim is to distinguish four cases: a flat prop that contains the
+%   given \meta{key}, a flat prop that does not contain it, a linked
+%   prop, and an invalid prop.  The last case includes those that are
+%   set to \tn{relax} by \texttt{c}-expansion, as well as unrelated
+%   token list variables since these unfortunately used to
+%   \enquote{work} in earlier implementations.
+%   In the first three cases we run the \texttt{T}, \texttt{F}, and
+%   \texttt{n} arguments, and in the last case we raise an error, set
+%   the variable to a known state (empty prop), and run the \texttt{F}
+%   code (some conditionals such as \cs{prop_pop:NnNTF} otherwise blow
+%   up pretty badly).
+%
+%   The first distinction between these cases is done by
+%   \cs{@@_split_test:wn}, which looks for the argument after \cs{s_@@}.
+%   For a flat prop it will be \cs{@@_chk:w}, which leads to running
+%   \cs{@@_split_flat:w}, explained below.  For a linked prop it is the
+%   prefix, consisting of characters, so we end up running
+%   \cs{@@_split_linked:w}, which cleans up and selects the
+%   aforementioned \texttt{n} argument.  For invalid props, or rather,
+%   variables that do not contain \cs{s_@@}, the argument includes
+%   \cs{fi:}, and we end up calling \cs{@@_split_wrong:Nw}, which calls
+%   \cs{prop_show:N} to raise a detailed error stating how the variable
+%   is wrong.
+%
+%   Let us return to \cs{@@_split_flat:w}.  This function is defined
+%   dynamically as
 %   \begin{quote}
-%     \cs{cs_set:Npn} \cs{@@_split_aux:w} |#1| \cs{@@_chk:w} |#2| \\
-%     \quad \cs{@@_pair:wn} \meta{key} \cs{s_@@} |#3| \\
-%     \quad |#4| \cs{s_@@_mark} |#5| |#6| \cs{s_@@_stop} \\
-%     \quad |{| |#5| \Arg{true code} |}|
+%     \cs{cs_set:Npn} \cs{@@_split_flat:w} \cs{@@_split_linked:w} |#1| \\
+%     \quad \cs{@@_pair:wn} \meta{key} \cs{s_@@} |#2| \\
+%     \quad |#3| \cs{s_@@_mark} |#4| |#5| \cs{s_@@_stop} \\
+%     \quad |{| |#4| \Arg{true code} |}|
 %   \end{quote}
-%
-%   If the \meta{key} is present in the property list,
-%   \cs{@@_split_aux:w}'s |#2| is the part before the \meta{key}, |#3|
-%   is the \meta{value}, |#4| is the part after the \meta{key}, |#5| is
-%   \cs{use_i:nnn}, and |#6| is additional tokens that we do not care
-%   about.  The \meta{true code} is left in the input stream, and can
-%   use the parameters |#2|, |#3|, |#4| for the three parts of the
-%   property list as desired.  Namely, the original property list is in
-%   this case \cs{s_@@} \cs{@@_chk:w} |#2| \cs{@@_pair:wn} \meta{key}
-%   \cs{s_@@} |{#3}| |#4|.
-%
-%   If the \meta{key} is not there, then the \meta{function} is
-%   \cs{use_ii:nnn}, which keeps the \meta{false code}.  If the property
-%   list uses the doubly-linked list storage, then the argument
-%   delimited by \cs{@@_chk:w} includes the whole property list, |#2|,
-%   |#3|, |#4| are empty, and |#5| is \cs{use_iii:nnn}.  In all three
-%   cases, the appopriate code among \meta{true code}, \meta{false
-%   code}, and \meta{linked code} is run.
+%   Its job is to seek the \meta{key} in the property list (known to be
+%   flat at this stage) by using an argument |#1| delimited essentially
+%   by that key.  If indeed the variable contained the \meta{key}, then
+%   |#1|~is the \meta{extract_1} before the key--value pair, |#2|~is the
+%   \meta{value} associated with the \meta{key}, |#3|~is the
+%   \meta{extract_2} after the key--value pair, |#4|~is \cs{use_i:nnn},
+%   and we run \cs{use_i:nnn} \Arg{true code} \Arg{false code} \Arg{link
+%   code}, selecting the \meta{true code}.  Otherwise, the whole
+%   property list together with \cs{s_@@_mark} \cs{use_i:nnn} is taken
+%   in as |#1|, then |#2| is some tokens |?| \cs{fi:}
+%   \cs{@@_split_wrong:Nw} \meta{variable} that were only useful in the
+%   case of invalid props, |#3|~is empty, and most importantly |#4| is
+%   \cs{use_ii:nnn}.  This command selects the \meta{false code}.
+%
+%   Note that we define \cs{@@_split_flat:w} in all cases even though it
+%   is only used in the flat case.  Indeed, to avoid taking in the whole
+%   property list (which may be large) as an argument more than strictly
+%   necessary, we would have to keep the \meta{true code} positioned
+%   before the expansion of the prop variable in order to use it in the
+%   definition.  The only way to do that is to store it using an
+%   assignment so we might as well just perform the assignment that we
+%   can actually use in the flat case.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_split:NnTFn #1#2
-  { \exp_args:NNo \@@_split_aux:NnTFn #1 { \tl_to_str:n {#2} } }
-\cs_new_protected:Npn \@@_split_aux:NnTFn #1#2#3
-  {
-    \cs_set:Npn \@@_split_aux:w ##1 \@@_chk:w ##2
-      \@@_pair:wn #2 \s_@@ ##3 ##4 \s_@@_mark ##5 ##6 \s_@@_stop
-      { ##5 {#3} }
-    \exp_after:wN \@@_split_aux:w #1 \s_@@_mark \use_i:nnn
-      \@@_pair:wn #2 \s_@@ { } \s_@@_mark \use_ii:nnn
-      \@@_chk:w
-      \@@_pair:wn #2 \s_@@ { } \s_@@_mark \use_iii:nnn
+  {
+    \exp_after:wN \@@_split_aux:nNTFn
+    \exp_after:wN { \tl_to_str:n {#2} } #1
+  }
+\cs_new_protected:Npn \@@_split_aux:nNTFn #1#2#3
+  {
+    \cs_set:Npn \@@_split_flat:w \@@_split_linked:w ##1
+      \@@_pair:wn #1 \s_@@ ##2 ##3 \s_@@_mark ##4 ##5 \s_@@_stop
+      { ##4 {#3} }
+    \exp_after:wN \@@_split_test:wn #2 \s_@@_mark \use_i:nnn
+      \@@_pair:wn #1 \s_@@ { ? \fi: \@@_split_wrong:Nw #2 }
+      \s_@@_mark \use_ii:nnn
       \s_@@_stop
   }
+\cs_new:Npn \@@_split_flat:w { }
+\cs_new_protected:Npn \@@_split_test:wn #1 \s_@@ #2
+  {
+    \if_meaning:w \@@_chk:w #2 \exp_after:wN \@@_split_flat:w \fi:
+    \@@_split_linked:w
+  }
+\cs_new_protected:Npn \@@_split_linked:w #1 \s_@@_stop #2#3 {#3}
+\cs_new_protected:Npn \@@_split_wrong:Nw #1#2 \s_@@_stop #3#4
+  {
+    \prop_show:N #1
+    \cs_gset_eq:NN #1 \c_empty_prop
+    #3
+  }
 %    \end{macrocode}
 % \end{macro}
-% \end{macro}
-% \end{macro}
 %
 % \begin{macro}[tested = m3prop002]
 %   {
@@ -1611,7 +1650,7 @@
 \cs_new_protected:Npn \@@_get:NnnTF #1#2#3#4#5
   {
     \@@_split:NnTFn #1 {#2}
-      { #3 {##3} #4 }
+      { #3 {##2} #4 }
       {#5}
       { \exp_after:wN \@@_get_linked:w #1 {#2} {#3} {#4} {#5} }
   }
@@ -1715,8 +1754,8 @@
   {
     \@@_split:NnTFn #1 {#2}
       {
-        #4 #1 { \exp_not:n { \s_@@ \@@_chk:w ##2 ##4 } }
-        #5 {##3}
+        #4 #1 { \exp_not:n { \s_@@ \@@_chk:w ##1 ##3 } }
+        #5 {##2}
         #6
       }
       {#7}
@@ -2000,8 +2039,8 @@
       {
         #1 #2 #3
           {
-            \s_@@ \@@_chk:w \exp_not:n {##2}
-            \l_@@_internal_tl \exp_not:n {##4}
+            \s_@@ \@@_chk:w \exp_not:n {##1}
+            \l_@@_internal_tl \exp_not:n {##3}
           }
       }
       { #2 #3 { \exp_not:o {#3} \l_@@_internal_tl } }
-- 
cgit v1.2.3

