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.dtx159
1 files changed, 125 insertions, 34 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
index 0a25ed683c7..303ce59414d 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx
@@ -7,7 +7,7 @@
% license or (at your option) any later version. The latest version
% of this license is in the file
%
-% http://www.latex-project.org/lppl.txt
+% https://www.latex-project.org/lppl.txt
%
% This file is part of the "l3kernel bundle" (The Work in LPPL)
% and all files in that bundle must be distributed together.
@@ -21,7 +21,7 @@
% for those people who are interested.
%
%<*driver>
-\documentclass[full]{l3doc}
+\documentclass[full,kernel]{l3doc}
\begin{document}
\DocInput{\jobname.dtx}
\end{document}
@@ -41,7 +41,7 @@
% }^^A
% }
%
-% \date{Released 2017/11/14}
+% \date{Released 2017/12/05}
%
% \maketitle
%
@@ -373,21 +373,27 @@
% \end{verbatim}
% Use outside of a \cs[no-index]{prop_map_\ldots} scenario leads to low
% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted
+% before further items are taken
+% from the input stream. This depends on the design of the mapping
+% function.
+% \end{texnote}
% \end{function}
%
% \begin{function}[updated = 2012-06-29, rEXP]{\prop_map_break:n}
% \begin{syntax}
-% \cs{prop_map_break:n} \Arg{tokens}
+% \cs{prop_map_break:n} \Arg{code}
% \end{syntax}
% Used to terminate a \cs[no-index]{prop_map_\ldots} function before all
% entries in the \meta{property list} have been processed, inserting
-% the \meta{tokens} after the mapping has ended. This
+% the \meta{code} after the mapping has ended. This
% normally takes place within a conditional statement, for example
% \begin{verbatim}
% \prop_map_inline:Nn \l_my_prop
% {
% \str_if_eq:nnTF { #1 } { bingo }
-% { \prop_map_break:n { <tokens> } }
+% { \prop_map_break:n { <code> } }
% {
% % Do something useful
% }
@@ -395,6 +401,12 @@
% \end{verbatim}
% Use outside of a \cs[no-index]{prop_map_\ldots} scenario leads to low
% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted
+% before the \meta{code} is
+% inserted into the input stream.
+% This depends on the design of the mapping function.
+% \end{texnote}
% \end{function}
%
% \section{Viewing property lists}
@@ -510,7 +522,7 @@
% (equal to \cs{scan_stop:}), and \cs{@@_pair:wn} can be used to map
% through the property list.
%
-% \begin{macro}[int]{\s_@@}
+% \begin{macro}{\s_@@}
% A private scan mark is used as a marker after each key, and at the
% very beginning of the property list.
% \begin{macrocode}
@@ -518,7 +530,7 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[int]{\@@_pair:wn}
+% \begin{macro}{\@@_pair:wn}
% The delimiter is always defined, but when misused simply triggers an
% error and removes its argument.
% \begin{macrocode}
@@ -614,11 +626,90 @@
% \end{variable}
% \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}
+% \begin{macro}
+% {
+% \@@_from_keyval:n,
+% \@@_from_keyval_loop:w,
+% \@@_from_keyval_split:Nw,
+% \@@_from_keyval_key:w,
+% \@@_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 (the internal
+% \cs{__tl_trim_spaces:nn} expects the \cs{q_mark} we give it) 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~|=|.
+% \begin{macrocode}
+\cs_new_protected:Npn \prop_set_from_keyval:Nn #1#2
+ { \tl_set:Nx #1 { \@@_from_keyval:n {#2} } }
+\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} } }
+\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} } }
+\cs_generate_variant:Nn \prop_const_from_keyval:Nn { c }
+\cs_new:Npn \@@_from_keyval:n #1
+ {
+ \s_@@
+ \@@_from_keyval_loop:w \q_mark #1 ,
+ \q_recursion_tail , \q_recursion_stop
+ }
+\cs_new:Npn \@@_from_keyval_loop:w #1 ,
+ {
+ \quark_if_recursion_tail_stop:o { \use_none:n #1 }
+ \@@_from_keyval_split:Nw \@@_from_keyval_key:w
+ #1 = = \q_stop { \use_none:n #1 }
+ \@@_from_keyval_loop:w \q_mark
+ }
+\cs_new:Npn \@@_from_keyval_split:Nw #1#2 =
+ {
+ \__tl_trim_spaces:nn {#2}
+ { \exp_last_unbraced:No #1 } \q_nil
+ }
+\cs_new:Npn \@@_from_keyval_key:w #1 \q_nil #2 \q_stop
+ {
+ \@@_from_keyval_split:Nw \@@_from_keyval_value:w
+ \q_mark #2 \q_stop {#1}
+ }
+\cs_new: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} { = }
+ {
+ \exp_not:N \@@_pair:wn \tl_to_str:n {#3}
+ \s_@@ { \exp_not:n {#1} }
+ }
+ {
+ \exp_args:Nnno \__msg_kernel_expandable_error:nnn
+ { kernel } { prop-keyval } {#4}
+ }
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
% \subsection{Accessing data in property lists}
%
-% \begin{macro}[int]{\@@_split:NnTF}
-% \begin{macro}[aux]{\@@_split_aux:NnTF}
-% \begin{macro}[aux, EXP]{\@@_split_aux:w}
+% \begin{macro}{\@@_split:NnTF}
+% \begin{macro}{\@@_split_aux:NnTF}
+% \begin{macro}[EXP]{\@@_split_aux:w}
% This function is used by most of the module, and hence must be fast.
% 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
@@ -746,7 +837,7 @@
% \end{macro}
%
% \begin{macro}[EXP]{\prop_item:Nn, \prop_item:cn}
-% \begin{macro}[aux, EXP]{\@@_item_Nn:nwwn}
+% \begin{macro}[EXP]{\@@_item_Nn:nwwn}
% Getting the value corresponding to a key in a property list in an
% expandable fashion is similar to mapping some tokens. Go through
% the property list one \meta{key}--\meta{value} pair at a time: the
@@ -826,7 +917,7 @@
% \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:NNnn}
+% \begin{macro}{\@@_put:NNnn}
% 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
@@ -870,7 +961,7 @@
% {\prop_put_if_new:Nnn, \prop_put_if_new:cnn}
% \begin{macro}[tested = m3prop002]
% {\prop_gput_if_new:Nnn, \prop_gput_if_new:cnn}
-% \begin{macro}[aux]{\@@_put_if_new:NNnn}
+% \begin{macro}{\@@_put_if_new:NNnn}
% Adding conditionally also splits. If the key is already present,
% the three brace groups given by \cs{@@_split:NnTF} are removed.
% If the key is new, then the value is added, being careful to
@@ -930,7 +1021,7 @@
% \prop_if_in:Nn, \prop_if_in:NV, \prop_if_in:No,
% \prop_if_in:cn, \prop_if_in:cV, \prop_if_in:co
% }
-% \begin{macro}[aux,EXP]{\@@_if_in:nwwn, \@@_if_in:N}
+% \begin{macro}[EXP]{\@@_if_in:nwwn, \@@_if_in:N}
% Testing expandably if a key is in a property list
% requires to go through the key--value pairs one by one.
% This is rather slow, and a faster test would be
@@ -1030,7 +1121,7 @@
% \prop_map_function:NN, \prop_map_function:Nc,
% \prop_map_function:cN, \prop_map_function:cc
% }
-% \begin{macro}[aux]{\@@_map_function:Nwwn}
+% \begin{macro}{\@@_map_function:Nwwn}
% 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
@@ -1100,27 +1191,27 @@
%
% \subsection{Viewing property lists}
%
-% \begin{macro}[tested = m3show001]{\prop_show:N, \prop_show:c}
-% Apply the general \cs{__msg_show_variable:NNNnn}. Contrarily
-% to sequences and comma lists, we use \cs{__msg_show_item:nn}
-% to format both the key and the value for each pair.
+% \begin{macro}[tested = m3show001]
+% {\prop_show:N, \prop_show:c, \prop_log:N, \prop_log:c}
+% Apply the general \cs{__kernel_check_defined:NT} and
+% \cs{msg_show:nnnnnn}. Contrarily to sequences and comma lists,
+% we use \cs{msg_show_item:nn} to format both the key and the value
+% for each pair.
% \begin{macrocode}
-\cs_new_protected:Npn \prop_show:N #1
- {
- \__msg_show_variable:NNNnn #1
- \prop_if_exist:NTF \prop_if_empty:NTF { prop }
- { \prop_map_function:NN #1 \__msg_show_item:nn }
- }
+\cs_new_protected:Npn \prop_show:N { \@@_show:NN \msg_show:nnxxxx }
\cs_generate_variant:Nn \prop_show:N { c }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\prop_log:N, \prop_log:c}
-% Redirect output of \cs{prop_show:N} to the log.
-% \begin{macrocode}
-\cs_new_protected:Npn \prop_log:N
- { \__msg_log_next: \prop_show:N }
+\cs_new_protected:Npn \prop_log:N { \@@_show:NN \msg_log:nnxxxx }
\cs_generate_variant:Nn \prop_log:N { c }
+\cs_new_protected:Npn \@@_show:NN #1#2
+ {
+ \__kernel_check_defined:NT #2
+ {
+ #1 { LaTeX/kernel } { show-prop }
+ { \token_to_str:N #2 }
+ { \prop_map_function:NN #2 \msg_show_item:nn }
+ { } { }
+ }
+ }
% \end{macrocode}
% \end{macro}
%