diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3prop.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3prop.dtx | 92 |
1 files changed, 90 insertions, 2 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx index 55d962b292b..16db6a427b0 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx @@ -2,7 +2,7 @@ % %% File: l3prop.dtx % -% Copyright (C) 1990-2021 The LaTeX Project +% Copyright (C) 1990-2022 The LaTeX Project % % It may be distributed and/or modified under the conditions of the % LaTeX Project Public License (LPPL), either version 1.3c of this @@ -43,7 +43,7 @@ % }^^A % } % -% \date{Released 2021-11-22} +% \date{Released 2022-01-12} % % \maketitle % @@ -311,6 +311,21 @@ % the input stream as an \meta{integer denotation}. % \end{function} % +% \begin{function}[EXP]{\prop_to_keyval:N} +% \begin{syntax} +% \cs{prop_to_keyval:N} \meta{property list} +% \end{syntax} +% Expands to the \meta{property list} in a key--value notation. Keep in mind +% that a \meta{property list} is \emph{unordered}, while key--value interfaces +% don't necessarily are, so this can't be used for arbitrary interfaces. +% \begin{texnote} +% The result is returned within the \tn{unexpanded} primitive +% (\cs{exp_not:n}), which means that the key--value list does not expand +% further when appearing in an \texttt{x}-type argument expansion. +% It also needs exactly two steps of expansion. +% \end{texnote} +% \end{function} +% % \section{Modifying property lists} % % \begin{function}[added = 2012-05-12] @@ -1055,6 +1070,79 @@ % \end{macro} % \end{macro} % +% \begin{macro}[EXP]{\prop_to_keyval:N} +% \begin{macro}[EXP] +% {\@@_to_keyval_exp_after:wN, \@@_to_keyval:nn, \@@_to_keyval:nnw} +% Each property name and value pair will be returned in the form +% \verb*| |\marg{name}\verb*|= |\marg{value}. As one of the main use cases for +% this macro is to pass the \meta{property list} on to a key--value parser, we +% have to make sure that the behaviour is as good as possible. Using a space +% before the opening brace we get the correct brace stripping behaviour for +% most of the key--value parsers available in \LaTeX. +% If \cs{tex_expanded:D} is available this function makes use of it, so there +% are two different implementations here. They both start with +% \cs{__kernel_exp_not:w} to start the expansion context to expand in two +% steps. If the \meta{property list} is empty they just leave an empty set of +% braces in the input stream for \cs{__kernel_exp_not:w}. +% \begin{macrocode} +\cs_if_exist:NTF \tex_expanded:D + { +% \end{macrocode} +% The variant using \cs{tex_expanded:D} can just iterate over the +% \meta{property list} and remove the leading comma afterwards. Only the value +% has to be protected in \cs{__kernel_exp_not:w} as the property name is +% always a string. After the loop the leading comma is removed by +% \cs{use_none:n} and afterwards \cs{__kernel_exp_not:w} eventually finds the +% opening brace of its argument. +% \begin{macrocode} + \cs_new:Npn \prop_to_keyval:N #1 + { + \__kernel_exp_not:w + \prop_if_empty:NTF #1 + { {} } + { + \exp_after:wN \exp_after:wN \exp_after:wN + { + \tex_expanded:D + { + \__kernel_exp_not:w { \use_none:n } + \prop_map_function:NN #1 \@@_to_keyval:nn + } + } + } + } + \cs_new:Npn \@@_to_keyval:nn #1#2 + { , ~ {#1} =~ { \__kernel_exp_not:w {#2} } } + } +% \end{macrocode} +% The other variant will iterate over the \meta{property list} and has to +% output the result in a group after the marker +% \cs{@@_to_keyval_exp_after:wN}. As a result this is considerably slower than +% the \cs{tex_expanded:D} using variant as it has to read the entire contents +% of the \meta{property list} for each item. Since the marker is just +% \cs{exp_after:wN} with another name, after the loop the leading comma is +% gobbled by \cs{use_none:n}, leaving the result as the argument to +% \cs{__kernel_exp_not:w}. +% \begin{macrocode} + { + \cs_new:Npn \prop_to_keyval:N #1 + { + \__kernel_exp_not:w + \prop_if_empty:NTF #1 + { {} } + { + \prop_map_function:NN #1 \@@_to_keyval:nnw + \@@_to_keyval_exp_after:wN { \use_none:n } + } + } + \cs_new_eq:NN \@@_to_keyval_exp_after:wN \exp_after:wN + \cs_new:Npn \@@_to_keyval:nnw #1#2#3 \@@_to_keyval_exp_after:wN #4 + { #3 \@@_to_keyval_exp_after:wN { #4 , ~ {#1} =~ {#2} } } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% % \begin{macro}[TF, tested = m3prop004] % {\prop_pop:NnN, \prop_pop:cnN, \prop_gpop:NnN, \prop_gpop:cnN} % Popping an item from a property list, keeping track of whether |