summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3prop.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3prop.dtx339
1 files changed, 167 insertions, 172 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
index d8bec5ee50d..3046ae59e8b 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-%% File: l3prop.dtx Copyright (C) 1990-2012 The LaTeX3 Project
+%% File: l3prop.dtx Copyright (C) 1990-2013 The LaTeX3 Project
%%
%% It may be distributed and/or modified under the conditions of the
%% LaTeX Project Public License (LPPL), either version 1.3c of this
@@ -35,7 +35,7 @@
%
%<*driver|package>
\RequirePackage{l3bootstrap}
-\GetIdInfo$Id: l3prop.dtx 4212 2012-09-09 12:24:04Z bruno $
+\GetIdInfo$Id: l3prop.dtx 4423 2013-01-09 00:05:30Z bruno $
{L3 Property lists}
%</driver|package>
%<*driver>
@@ -245,7 +245,7 @@
% check that the \meta{property list} really is a property list variable.
% \end{function}
%
-% \begin{function}[EXP,pTF]{\prop_if_empty:N, \prop_if_empty:c}
+% \begin{function}[EXP, pTF]{\prop_if_empty:N, \prop_if_empty:c}
% \begin{syntax}
% \cs{prop_if_empty_p:N} \meta{property list}
% \cs{prop_if_empty:NTF} \meta{property list} \Arg{true code} \Arg{false code}
@@ -331,7 +331,7 @@
%
% \section{Mapping to property lists}
%
-% \begin{function}[updated = 2012-06-29, rEXP]
+% \begin{function}[updated = 2013-01-08, rEXP]
% {\prop_map_function:NN, \prop_map_function:cN}
% \begin{syntax}
% \cs{prop_map_function:NN} \meta{property list} \meta{function}
@@ -343,7 +343,7 @@
% should not be relied upon.
% \end{function}
%
-% \begin{function}[updated = 2012-06-29]
+% \begin{function}[updated = 2013-01-08]
% {\prop_map_inline:Nn, \prop_map_inline:cn}
% \begin{syntax}
% \cs{prop_map_inline:Nn} \meta{property list} \Arg{inline function}
@@ -432,29 +432,39 @@
%
% \section{Internal property list functions}
%
-% \begin{variable}{\q__prop}
-% The internal token used to separate out property list entries, separating
-% both the \meta{key} from the \meta{value} and also one entry from another.
+% \begin{variable}{\s__prop}
+% The internal token used to separate out property list entries,
+% surrounding each \meta{key}.
% \end{variable}
%
-% \begin{function}{\__prop_split:NnTF}
+% \begin{variable}{\l__prop_internal_tl}
+% Token list used to store new key--value pairs to be inserted by
+% functions of the \cs{prop_put:Nnn} family.
+% \end{variable}
+%
+% \begin{function}[updated = 2013-01-08]{\__prop_split:NnTF}
% \begin{syntax}
% \cs{__prop_split:NnTF} \meta{property list} \Arg{key} \Arg{true code} \Arg{false code}
% \end{syntax}
% Splits the \meta{property list} at the \meta{key}, giving three
-% groups: the \meta{extract} of \meta{property list} before the
+% token lists: the \meta{extract} of \meta{property list} before the
% \meta{key}, the \meta{value} associated with the \meta{key} and the
% \meta{extract} of the \meta{property list} after the \meta{value}.
-% The first \meta{extract} retains the internal structure of a property
-% list. The second is only missing the leading separator \cs{q__prop}.
-% This ensures that the concatenation of the two \meta{extracts} is a
+% Both \meta{extracts} retain the internal structure of a property
+% list, and the concatenation of the two \meta{extracts} is a
% property list.
% If the \meta{key} is present in the \meta{property list} then the
-% \meta{true code} is left in the input stream, followed by the three
-% groups: thus the \meta{true code} should properly absorb three arguments.
+% \meta{true code} is left in the input stream, with |#1|, |#2|, and
+% |#3| replaced by the first \meta{extract}, the \meta{value}, and the
+% second extract.
% If the \meta{key} is not present in the \meta{property list} then
% the \meta{false code} is left in the input stream, with no trailing
% material.
+% Both \meta{true code} and \meta{false code} are used in the
+% replacement text of a macro defined internally, hence macro
+% parameter characters should be doubled, except |#1|, |#2|, and |#3|
+% which stand in the \meta{true code} for the three extracts from the
+% property list.
% The \meta{key} comparison takes place as described for \cs{str_if_eq:nn}.
% \end{function}
%
@@ -484,47 +494,51 @@
%
% A property list is a macro whose top-level expansion is for the form
% \begin{quote}
-% \cs{q_@@} \meta{key_1} \cs{q_@@} \Arg{value_1} \\
+% \cs{s_@@} \meta{key_1} \cs{s_@@} \Arg{value_1} \\
% \ldots{} \\
-% \cs{q_@@} \meta{key_n} \cs{q_@@} \Arg{value_n} \\
-% \cs{q_@@}
+% \cs{s_@@} \meta{key_n} \cs{s_@@} \Arg{value_n} \\
% \end{quote}
-% where the trailing \cs{q_@@} is always present for performance
-% reasons: this means that empty property lists are not actually empty.
%
-% \begin{macro}[int]{\q_@@}
-% A private quark is used as a marker between entries.
+% \begin{macro}[int]{\s_@@}
+% A private scan mark is used as a marker surrounding each key.
% \begin{macrocode}
-\quark_new:N \q_@@
+\__scan_new:N \s_@@
% \end{macrocode}
% \end{macro}
%
+% \begin{variable}{\l_@@_internal_tl}
+% Token list used to store the new key--value pair inserted by
+% \cs{prop_put:Nnn} and friends.
+% \begin{macrocode}
+\tl_new:N \l_@@_internal_tl
+% \end{macrocode}
+% \end{variable}
+%
% \begin{variable}[tested = m3prop004]{\c_empty_prop}
-% An empty prop contains exactly one \cs{q_@@}.
+% An empty prop is an empty token list.
% \begin{macrocode}
-\tl_const:Nn \c_empty_prop { \q_@@ }
+\cs_new_eq:NN \c_empty_prop \c_empty_tl
% \end{macrocode}
% \end{variable}
%
% \subsection{Allocation and initialisation}
%
-% \begin{macro}[tested = m3prop001]{\prop_new:N,\prop_new:c}
-% Internally, property lists are token lists, but an empty prop
-% is not an empty tl, so we need to do things by hand.
+% \begin{macro}[tested = m3prop001]{\prop_new:N, \prop_new:c}
+% Internally, property lists are just token lists.
% \begin{macrocode}
-\cs_new_protected:Npn \prop_new:N #1 { \cs_new_eq:NN #1 \c_empty_prop }
-\cs_new_protected:Npn \prop_new:c #1 { \cs_new_eq:cN {#1} \c_empty_prop }
+\cs_new_eq:NN \prop_new:N \tl_new:N
+\cs_new_eq:NN \prop_new:c \tl_new:c
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[tested = m3prop001]{\prop_clear:N, \prop_clear:c}
% \begin{macro}[tested = m3prop001]{\prop_gclear:N, \prop_gclear:c}
-% The same idea for clearing
+% The same idea for clearing.
% \begin{macrocode}
-\cs_new_protected:Npn \prop_clear:N #1 { \cs_set_eq:NN #1 \c_empty_prop }
-\cs_generate_variant:Nn \prop_clear:N { c }
-\cs_new_protected:Npn \prop_gclear:N #1 { \cs_gset_eq:NN #1 \c_empty_prop }
-\cs_generate_variant:Nn \prop_gclear:N { c }
+\cs_new_eq:NN \prop_clear:N \tl_clear:N
+\cs_new_eq:NN \prop_clear:c \tl_clear:c
+\cs_new_eq:NN \prop_gclear:N \tl_gclear:N
+\cs_new_eq:NN \prop_gclear:c \tl_gclear:c
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -533,12 +547,10 @@
% \begin{macro}[tested = m3prop001]{\prop_gclear_new:N, \prop_gclear_new:c}
% Once again a simple copy from the token list functions.
% \begin{macrocode}
-\cs_new_protected:Npn \prop_clear_new:N #1
- { \prop_if_exist:NTF #1 { \prop_clear:N #1 } { \prop_new:N #1 } }
-\cs_generate_variant:Nn \prop_clear_new:N { c }
-\cs_new_protected:Npn \prop_gclear_new:N #1
- { \prop_if_exist:NTF #1 { \prop_gclear:N #1 } { \prop_new:N #1 } }
-\cs_generate_variant:Nn \prop_gclear_new:N { c }
+\cs_new_eq:NN \prop_clear_new:N \tl_clear_new:N
+\cs_new_eq:NN \prop_clear_new:c \tl_clear_new:c
+\cs_new_eq:NN \prop_gclear_new:N \tl_gclear_new:N
+\cs_new_eq:NN \prop_gclear_new:c \tl_gclear_new:c
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -577,67 +589,69 @@
%
% \begin{macro}[int]{\@@_split:NnTF}
% \begin{macro}[aux]{\@@_split_aux:NnTF}
-% \begin{macro}[aux]{\@@_split_aux:nnnn}
-% \begin{macro}[aux]{\@@_split_aux:w}
+% \begin{macro}[aux, EXP]{\@@_split_aux:w}
% This function is used by most of the module, and hence must be fast.
-% The aim here is to split a property list at a given key into the part
-% before the key--value pair, the value associated with the key and the part
-% after the key--value pair. To do this, the key is first detokenized (to
-% avoid repeatedly doing this), then a delimited function is constructed to
-% match the key. It will match \cs{q_@@} \meta{detokenized key} \cs{q_@@}
-% \Arg{value} \meta{extra argument}, effectively separating an
-% \meta{extract_1} before the key in the property list and an \meta{extract_2}
-% after the key.
-%
-% If the key is present in the property list, then \meta{extra argument}
-% is simply \cs{q_@@}, and \cs{@@_split_aux:nnnn} will gobble this
-% and the false branch (|#4|), leaving the correct code on the input
-% stream. More precisely, it leaves the user code (true branch), followed
-% by three groups, \Arg{extract_1} \Arg{value} \Arg{extract_2}.
-% In order for \meta{extract_1}\meta{extract_2} to be a well-formed
-% property list, \meta{extract_1} has a leading and trailing \cs{q_@@},
-% retaining exactly the structure of a property list, while \meta{extract_2}
-% omits the leading \cs{q_@@}.
-%
-% If the key is not there, then \meta{extra argument} is |?|
-% \cs{use_ii:nn} |{ }|, and \cs{@@_split_aux:nnnn} |?| \cs{use_ii:nn}
-% |{ }| removes the three brace groups that just follow. Then
-% \cs{use_ii:nn} removes the true branch, leaving the false branch,
-% with no trailing material.
+% It receives a \meta{property list}, a \meta{key}, a \meta{true code}
+% and a \meta{false code}. 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{quote}
+% \cs{cs_set:Npn} \cs{@@_split_aux:w} |#1| \\
+% \quad \cs{s_@@} \meta{key} \cs{s_@@} |#2| \\
+% \quad |#3| \cs{q_mark} |#4| |#5| \cs{q_stop} \\
+% \quad |{| |#4| \Arg{true code} \Arg{false code} |}|
+% \end{quote}
+%
+% If the \meta{key} is present in the property list,
+% \cs{@@_split_aux:w}'s |#1| is the part before the \meta{key}, |#2|
+% is the \meta{value}, |#3| is the part after the \meta{key}, |#4| is
+% \cs{use_i:nn}, and |#5| is additional tokens that we do not care
+% about. The \meta{true code} is left in the input stream, and can
+% use the parameters |#1|, |#2|, |#3| for the three parts of the
+% property list as desired.
+%
+% If the \meta{key} is not there, then the \meta{function} is
+% \cs{use_ii:nn}, which keeps the \meta{false code}.
% \begin{macrocode}
\cs_new_protected:Npn \@@_split:NnTF #1#2
{ \exp_args:NNo \@@_split_aux:NnTF #1 { \tl_to_str:n {#2} } }
-\cs_new_protected:Npn \@@_split_aux:NnTF #1#2
+\cs_new_protected:Npn \@@_split_aux:NnTF #1#2#3#4
{
- \cs_set_protected:Npn \@@_split_aux:w
- ##1 \q_@@ #2 \q_@@ ##2 ##3 ##4 \q_mark ##5 \q_stop
- { \@@_split_aux:nnnn ##3 { {##1 \q_@@ } {##2} {##4} } }
- \exp_after:wN \@@_split_aux:w #1 \q_mark
- \q_@@ #2 \q_@@ { } { ? \use_ii:nn { } } \q_mark \q_stop
+ \cs_set:Npn \@@_split_aux:w ##1
+ \s_@@ #2 \s_@@ ##2 ##3 \q_mark ##4 ##5 \q_stop
+ { ##4 {#3} {#4} }
+ \exp_after:wN \@@_split_aux:w #1 \q_mark \use_i:nn
+ \s_@@ #2 \s_@@ { } \q_mark \use_ii:nn \q_stop
}
-\cs_new:Npn \@@_split_aux:nnnn #1#2#3#4 { #3 #2 }
-\cs_new_protected:Npn \@@_split_aux:w { }
+\cs_new:Npn \@@_split_aux:w { }
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
%
% \begin{macro}[tested = m3prop002]
% {\prop_remove:Nn, \prop_remove:NV, \prop_remove:cn, \prop_remove:cV}
% \begin{macro}[tested = m3prop002]
% {\prop_gremove:Nn, \prop_gremove:NV, \prop_gremove:cn, \prop_gremove:cV}
-% \begin{macro}[aux]{\@@_remove:NNnnn}
% Deleting from a property starts by splitting the list.
% If the key is present in the property list, the returned value is ignored.
% If the key is missing, nothing happens.
% \begin{macrocode}
\cs_new_protected:Npn \prop_remove:Nn #1#2
- { \@@_split:NnTF #1 {#2} { \@@_remove:NNnnn \tl_set:Nn #1 } { } }
+ {
+ \@@_split:NnTF #1 {#2}
+ { \tl_set:Nn #1 { ##1 ##3 } }
+ { }
+ }
\cs_new_protected:Npn \prop_gremove:Nn #1#2
- { \@@_split:NnTF #1 {#2} { \@@_remove:NNnnn \tl_gset:Nn #1 } { } }
-\cs_new_protected:Npn \@@_remove:NNnnn #1#2#3#4#5
- { #1 #2 { #3 #5 } }
+ {
+ \@@_split:NnTF #1 {#2}
+ { \tl_gset:Nn #1 { ##1 ##3 } }
+ { }
+ }
\cs_generate_variant:Nn \prop_remove:Nn { NV }
\cs_generate_variant:Nn \prop_remove:Nn { c , cV }
\cs_generate_variant:Nn \prop_gremove:Nn { NV }
@@ -645,14 +659,12 @@
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
%
% \begin{macro}[tested = m3prop002]
% {
% \prop_get:NnN, \prop_get:NVN, \prop_get:NoN,
% \prop_get:cnN, \prop_get:cVN, \prop_get:coN
% }
-% \begin{macro}[aux]{\@@_get:Nnnn}
% Getting an item from a list is very easy: after splitting,
% if the key is in the property list, just set the token list variable
% to the return value, otherwise to \cs{q_no_value}.
@@ -660,22 +672,18 @@
\cs_new_protected:Npn \prop_get:NnN #1#2#3
{
\@@_split:NnTF #1 {#2}
- { \@@_get:Nnnn #3 }
+ { \tl_set:Nn #3 {##2} }
{ \tl_set:Nn #3 { \q_no_value } }
}
-\cs_new_protected:Npn \@@_get:Nnnn #1#2#3#4
- { \tl_set:Nn #1 {#3} }
\cs_generate_variant:Nn \prop_get:NnN { NV , No }
\cs_generate_variant:Nn \prop_get:NnN { c , cV , co }
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
% \begin{macro}[tested = m3prop002]
% {\prop_pop:NnN, \prop_pop:NoN, \prop_pop:cnN, \prop_pop:coN}
% \begin{macro}[tested = m3prop002]
% {\prop_gpop:NnN, \prop_gpop:NoN, \prop_gpop:cnN, \prop_gpop:coN}
-% \begin{macro}[aux]{\@@_pop:NNNnnn}
% Popping a value also starts by doing the split.
% If the key is present, save the value in the token list and update the
% property list as when deleting.
@@ -684,20 +692,21 @@
\cs_new_protected:Npn \prop_pop:NnN #1#2#3
{
\@@_split:NnTF #1 {#2}
- { \@@_pop:NNNnnn \tl_set:Nn #1 #3 }
+ {
+ \tl_set:Nn #3 {##2}
+ \tl_set:Nn #1 { ##1 ##3 }
+ }
{ \tl_set:Nn #3 { \q_no_value } }
}
\cs_new_protected:Npn \prop_gpop:NnN #1#2#3
{
\@@_split:NnTF #1 {#2}
- { \@@_pop:NNNnnn \tl_gset:Nn #1 #3 }
+ {
+ \tl_set:Nn #3 {##2}
+ \tl_gset:Nn #1 { ##1 ##3 }
+ }
{ \tl_set:Nn #3 { \q_no_value } }
}
-\cs_new_protected:Npn \@@_pop:NNNnnn #1#2#3#4#5#6
- {
- \tl_set:Nn #3 {#5}
- #1 #2 { #4 #6 }
- }
\cs_generate_variant:Nn \prop_pop:NnN { No }
\cs_generate_variant:Nn \prop_pop:NnN { c , co }
\cs_generate_variant:Nn \prop_gpop:NnN { No }
@@ -705,11 +714,9 @@
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
%
% \begin{macro}[TF, tested = m3prop004]
% {\prop_pop:NnN, \prop_pop:cnN, \prop_gpop:NnN, \prop_gpop:cnN}
-% \begin{macro}[aux]{\@@_pop_true:NNNnnn}
% Popping an item from a property list, keeping track of whether
% the key was present or not, is implemented as a conditional.
% If the key was missing, neither the property list, nor the token
@@ -719,21 +726,23 @@
\prg_new_protected_conditional:Npnn \prop_pop:NnN #1#2#3 { T , F , TF }
{
\@@_split:NnTF #1 {#2}
- { \@@_pop_true:NNNnnn \tl_set:Nn #1 #3 }
+ {
+ \tl_set:Nn #3 {##2}
+ \tl_set:Nn #1 { ##1 ##3 }
+ \prg_return_true:
+ }
{ \prg_return_false: }
}
\prg_new_protected_conditional:Npnn \prop_gpop:NnN #1#2#3 { T , F , TF }
{
\@@_split:NnTF #1 {#2}
- { \@@_pop_true:NNNnnn \tl_gset:Nn #1 #3 }
+ {
+ \tl_set:Nn #3 {##2}
+ \tl_gset:Nn #1 { ##1 ##3 }
+ \prg_return_true:
+ }
{ \prg_return_false: }
}
-\cs_new_protected:Npn \@@_pop_true:NNNnnn #1#2#3#4#5#6
- {
- \tl_set:Nn #3 {#5}
- #1 #2 { #4 #6 }
- \prg_return_true:
- }
\cs_generate_variant:Nn \prop_pop:NnNT { c }
\cs_generate_variant:Nn \prop_pop:NnNF { c }
\cs_generate_variant:Nn \prop_pop:NnNTF { c }
@@ -742,7 +751,6 @@
\cs_generate_variant:Nn \prop_gpop:NnNTF { c }
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
% \begin{macro}[tested = m3prop002]
% {
@@ -758,32 +766,31 @@
% \prop_gput:cnn, \prop_gput:cnV, \prop_gput:cno, \prop_gput:cnx,
% \prop_gput:cVn, \prop_gput:cVV, \prop_gput:con, \prop_gput:coo
% }
-% \begin{macro}[aux]{\@@_put:NNNnn, \@@_put:NNnnnnn}
-% Putting a key--value pair in a property list starts by splitting to
-% remove any existing value. If the \meta{key} was absent, append the
-% new key--value pair. Otherwise, the property list is reconstructed
-% from the two remaining parts |#5| and |#7|, and the updated entry.
-% The updated entry is placed at the same spot as the original
-% \meta{key} in the property list, preserving the order of entries.
+% \begin{macro}[aux]{\@@_put:NNNnn}
+% Since the branches of \cs{@@_split:NnTF} are used as the replacement
+% text of an internal macro, and since the \meta{key} and new
+% \meta{value} may contain arbitrary tokens, it is not safe to include
+% them in the argument of \cs{@@_split:NnTF}. We thus start by
+% storing in \cs{l_@@_internal_tl} tokens which (after
+% \texttt{x}-expansion) encode the key--value pair. This variable can
+% safely be used in \cs{@@_split:NnTF}. If the \meta{key} was absent,
+% append the new key--value to the list. Otherwise concatenate the
+% extracts |##1| and |##3| with the new key--value pair
+% \cs{l_@@_internal_tl}. The updated entry is placed at the same spot
+% as the original \meta{key} in the property list, preserving the
+% order of entries.
% \begin{macrocode}
-\cs_new_protected:Npn \prop_put:Nnn
+\cs_new_protected_nopar:Npn \prop_put:Nnn
{ \@@_put:NNNnn \tl_set:Nx \tl_put_right:Nx }
-\cs_new_protected:Npn \prop_gput:Nnn
+\cs_new_protected_nopar:Npn \prop_gput:Nnn
{ \@@_put:NNNnn \tl_gset:Nx \tl_gput_right:Nx }
\cs_new_protected:Npn \@@_put:NNNnn #1#2#3#4#5
{
+ \tl_set:Nn \l_@@_internal_tl
+ { \s_@@ \tl_to_str:n {#4} \s_@@ { \exp_not:n {#5} } }
\@@_split:NnTF #3 {#4}
- { \@@_put:NNnnnnn #1 #3 {#4} {#5} }
- { #2 #3 { \tl_to_str:n {#4} \exp_not:n { \q_@@ {#5} \q_@@ } } }
- }
-\cs_new_protected:Npn \@@_put:NNnnnnn #1#2#3#4#5#6#7
- {
- #1 #2
- {
- \exp_not:n {#5}
- \tl_to_str:n {#3} \exp_not:n { \q_@@ {#4} \q_@@ }
- \exp_not:n {#7}
- }
+ { #1 #3 { \exp_not:n {##1} \l_@@_internal_tl \exp_not:n {##3} } }
+ { #2 #3 { \l_@@_internal_tl } }
}
\cs_generate_variant:Nn \prop_put:Nnn
{ NnV , Nno , Nnx , NV , NVV , No , Noo }
@@ -814,12 +821,11 @@
{ \@@_put_if_new:NNnn \tl_gput_right:Nx }
\cs_new_protected:Npn \@@_put_if_new:NNnn #1#2#3#4
{
+ \tl_set:Nn \l_@@_internal_tl
+ { \s_@@ \tl_to_str:n {#3} \s_@@ \exp_not:n { {#4} } }
\@@_split:NnTF #2 {#3}
- { \use_none:nnn }
- {
- #1 #2
- { \tl_to_str:n {#3} \exp_not:n { \q_@@ {#4} \q_@@ } }
- }
+ { }
+ { #1 #2 { \l_@@_internal_tl } }
}
\cs_generate_variant:Nn \prop_put_if_new:Nnn { c }
\cs_generate_variant:Nn \prop_gput_if_new:Nnn { c }
@@ -833,32 +839,18 @@
% \begin{macro}[pTF, tested = m3prop004]{\prop_if_exist:N, \prop_if_exist:c}
% Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
% \begin{macrocode}
-\cs_new_eq:NN \prop_if_exist:NTF \cs_if_exist:NTF
-\cs_new_eq:NN \prop_if_exist:NT \cs_if_exist:NT
-\cs_new_eq:NN \prop_if_exist:NF \cs_if_exist:NF
-\cs_new_eq:NN \prop_if_exist_p:N \cs_if_exist_p:N
-\cs_new_eq:NN \prop_if_exist:cTF \cs_if_exist:cTF
-\cs_new_eq:NN \prop_if_exist:cT \cs_if_exist:cT
-\cs_new_eq:NN \prop_if_exist:cF \cs_if_exist:cF
-\cs_new_eq:NN \prop_if_exist_p:c \cs_if_exist_p:c
+\prg_new_eq_conditional:NNn \prop_if_exist:N \cs_if_exist:N { TF , T , F , p }
+\prg_new_eq_conditional:NNn \prop_if_exist:c \cs_if_exist:c { TF , T , F , p }
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[pTF, tested = m3prop003]{\prop_if_empty:N, \prop_if_empty:c}
-% The test here uses \cs{c_empty_prop} as it is not really empty!
+% Same test as for token lists.
% \begin{macrocode}
-\prg_new_conditional:Npnn \prop_if_empty:N #1 { p, T , F , TF }
- {
- \if_meaning:w #1 \c_empty_prop
- \prg_return_true:
- \else:
- \prg_return_false:
- \fi:
- }
-\cs_generate_variant:Nn \prop_if_empty_p:N {c}
-\cs_generate_variant:Nn \prop_if_empty:NTF {c}
-\cs_generate_variant:Nn \prop_if_empty:NT {c}
-\cs_generate_variant:Nn \prop_if_empty:NF {c}
+\prg_new_eq_conditional:NNn \prop_if_empty:N \tl_if_empty:N
+ { p , T , F , TF }
+\prg_new_eq_conditional:NNn \prop_if_empty:c \tl_if_empty:c
+ { p , T , F , TF }
% \end{macrocode}
% \end{macro}
%
@@ -885,12 +877,12 @@
% but \cs{@@_split:NnTF} is non-expandable.
%
% Instead, the key is compared to each key in turn using \cs{str_if_eq_x:nn},
-% which is expandable. To terminate the mapping, we add the key that
-% is search for at the end of the property list. This second
+% which is expandable. To terminate the mapping, we append to the property
+% list the key that is searched for. This second
% \cs{tl_to_str:n} is not expanded at the start, but only when included
% in the \cs{str_if_eq_x:nn}. It cannot make the breaking mechanism choke,
% because the arbitrary token list material is enclosed in braces.
-% When ending, we test the next token: it is either \cs{q_@@}
+% When ending, we test the next token: it is either \cs{s_@@}
% or \cs{q_recursion_tail} in the case of a missing key.
% Here, \cs{prop_map_function:NN} is not sufficient for the mapping,
% since it can only map a single token, and cannot carry the key that
@@ -900,11 +892,11 @@
{
\exp_last_unbraced:Noo \@@_if_in:nwn
{ \tl_to_str:n {#2} } #1
- \tl_to_str:n {#2} \q_@@ { }
- \q_recursion_tail % could be any cs != \q_@@
+ \s_@@ \tl_to_str:n {#2} \s_@@ { }
+ \q_recursion_tail
\__prg_break_point:
}
-\cs_new:Npn \@@_if_in:nwn #1 \q_@@ #2 \q_@@ #3
+\cs_new:Npn \@@_if_in:nwn #1 \s_@@ #2 \s_@@ #3
{
\str_if_eq_x:nnTF {#1} {#2}
{ \@@_if_in:N }
@@ -912,7 +904,7 @@
}
\cs_new:Npn \@@_if_in:N #1
{
- \if_meaning:w \q_@@ #1
+ \if_meaning:w \s_@@ #1
\prg_return_true:
\else:
\prg_return_false:
@@ -938,7 +930,6 @@
% \prop_get:NnN, \prop_get:NVN, \prop_get:NoN,
% \prop_get:cnN, \prop_get:cVN, \prop_get:coN
% }
-% \begin{macro}[aux]{\@@_get_true:Nnnn}
% Getting the value corresponding to a key, keeping track of whether
% the key was present or not, is implemented as a conditional (with
% side effects). If the key was absent, the token list is not altered.
@@ -946,14 +937,12 @@
\prg_new_protected_conditional:Npnn \prop_get:NnN #1#2#3 { T , F , TF }
{
\@@_split:NnTF #1 {#2}
- { \@@_get_true:Nnnn #3 }
+ {
+ \tl_set:Nn #3 {##2}
+ \prg_return_true:
+ }
{ \prg_return_false: }
}
-\cs_new_protected:Npn \@@_get_true:Nnnn #1#2#3#4
- {
- \tl_set:Nn #1 {#3}
- \prg_return_true:
- }
\cs_generate_variant:Nn \prop_get:NnNT { NV , No }
\cs_generate_variant:Nn \prop_get:NnNF { NV , No }
\cs_generate_variant:Nn \prop_get:NnNTF { NV , No }
@@ -962,7 +951,6 @@
\cs_generate_variant:Nn \prop_get:NnNTF { c , cV , co }
% \end{macrocode}
% \end{macro}
-% \end{macro}
%
% \subsection{Mapping to property lists}
%
@@ -972,19 +960,24 @@
% \prop_map_function:cN, \prop_map_function:cc
% }
% \begin{macro}[aux]{\@@_map_function:Nwn}
-% The fastest way to do a recursion here would be to use an
+% The fastest way to do a recursion here is to use an
% \cs{if_meaning:w} test: the keys are strings, and thus
% cannot match the marker \cs{q_recursion_tail}.
+% A special case to note is when the key |#2| is empty:
+% then \cs{q_recursion_tail} is compared to \cs{exp_after:wN},
+% also different.
% \begin{macrocode}
\cs_new:Npn \prop_map_function:NN #1#2
{
\exp_last_unbraced:NNo \@@_map_function:Nwn #2
- #1 \q_recursion_tail \q_@@ { }
+ #1 \s_@@ \q_recursion_tail \s_@@ { }
\__prg_break_point:Nn \prop_map_break: { }
}
-\cs_new:Npn \@@_map_function:Nwn #1 \q_@@ #2 \q_@@ #3
+\cs_new:Npn \@@_map_function:Nwn #1 \s_@@ #2 \s_@@ #3
{
- \__quark_if_recursion_tail_break:nN {#2} \prop_map_break:
+ \if_meaning:w \q_recursion_tail #2
+ \exp_after:wN \prop_map_break:
+ \fi:
#1 {#2} {#3}
\@@_map_function:Nwn #1
}
@@ -1004,7 +997,7 @@
\exp_last_unbraced:Nco \@@_map_function:Nwn
{ __prg_map_ \int_use:N \g__prg_map_int :w }
#1
- \q_recursion_tail \q_@@ { }
+ \s_@@ \q_recursion_tail \s_@@ { }
\__prg_break_point:Nn \prop_map_break: { \int_gdecr:N \g__prg_map_int }
}
\cs_generate_variant:Nn \prop_map_inline:Nn { c }
@@ -1119,6 +1112,7 @@
% \begin{macro}{\prop_del:Nn, \prop_del:NV, \prop_del:cn, \prop_del:cV}
% \begin{macro}{\prop_gdel:Nn, \prop_gdel:NV, \prop_gdel:cn, \prop_gdel:cV}
% \begin{macrocode}
+%<*deprecated>
\cs_new_eq:NN \prop_del:Nn \prop_remove:Nn
\cs_new_eq:NN \prop_del:NV \prop_remove:NV
\cs_new_eq:NN \prop_del:cn \prop_remove:cn
@@ -1127,6 +1121,7 @@
\cs_new_eq:NN \prop_gdel:NV \prop_gremove:NV
\cs_new_eq:NN \prop_gdel:cn \prop_gremove:cn
\cs_new_eq:NN \prop_gdel:cV \prop_gremove:cV
+%</deprecated>
% \end{macrocode}
% \end{macro}
% \end{macro}