diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3prop.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3prop.dtx | 159 |
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} % |