diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3prop.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3prop.dtx | 1206 |
1 files changed, 1206 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx new file mode 100644 index 00000000000..744cea629fc --- /dev/null +++ b/Master/texmf-dist/source/latex/l3kernel/l3prop.dtx @@ -0,0 +1,1206 @@ +% \iffalse meta-comment +% +%% File: l3prop.dtx Copyright (C) 1990-2011 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 +%% 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 +%% +%% This file is part of the "expl3 bundle" (The Work in LPPL) +%% and all files in that bundle must be distributed together. +%% +%% The released version of this bundle is available from CTAN. +%% +%% ----------------------------------------------------------------------- +%% +%% The development version of the bundle can be found at +%% +%% http://www.latex-project.org/svnroot/experimental/trunk/ +%% +%% for those people who are interested. +%% +%%%%%%%%%%% +%% NOTE: %% +%%%%%%%%%%% +%% +%% Snapshots taken from the repository represent work in progress and may +%% not work or may contain conflicting material! We therefore ask +%% people _not_ to put them into distributions, archives, etc. without +%% prior consultation with the LaTeX3 Project. +%% +%% ----------------------------------------------------------------------- +% +%<*driver|package> +\RequirePackage{l3names} +\GetIdInfo$Id: l3prop.dtx 2478 2011-06-19 21:34:23Z joseph $ + {L3 Experimental property lists} +%</driver|package> +%<*driver> +\documentclass[full]{l3doc} +\begin{document} + \DocInput{\jobname.dtx} +\end{document} +%</driver> +% \fi +% +% \title{^^A +% The \pkg{l3prop} package\\ Property lists^^A +% \thanks{This file describes v\ExplFileVersion, +% last revised \ExplFileDate.}^^A +% } +% +% \author{^^A +% The \LaTeX3 Project\thanks +% {^^A +% E-mail: +% \href{mailto:latex-team@latex-project.org} +% {latex-team@latex-project.org}^^A +% }^^A +% } +% +% \date{Released \ExplFileDate} +% +% \maketitle +% +% \begin{documentation} +% +% \LaTeX3 implements a \enquote{property list} data type, which contain +% an unordered list of entries each of which consists of a \meta{key} and +% an associated \meta{value}. The \meta{key} and \meta{value} may both be +% any \meta{balanced text}. It is possible to map functions to property lists +% such that the function is applied to every key--value pair within +% the list. +% +% Each entry in a property list must have a unique \meta{key}: if an entry is +% added to a property list which already contains the \meta{key} then the new +% entry will overwrite the existing one. The \meta{keys} are compared on a +% string basis, using the same method as \cs{str_if_eq:nn}. +% +% \section{Creating and initialising property lists} +% +% \begin{function}{\prop_new:N, \prop_new:c} +% \begin{syntax} +% \cs{prop_new:N} \meta{property list} +% \end{syntax} +% Creates a new \meta{property list} or raises an error if the name is +% already taken. The declaration is global. The \meta{property lists} will +% initially contain no entries. +% \end{function} +% +% \begin{function}{\prop_clear:N, \prop_clear:c} +% \begin{syntax} +% \cs{prop_clear:N} \meta{property list} +% \end{syntax} +% Clears all entries from the \meta{property list} within the scope of +% the current \TeX{} group. +% \end{function} +% +% \begin{function}{\prop_gclear:N, \prop_gclear:c} +% \begin{syntax} +% \cs{prop_gclear:N} \meta{property list} +% \end{syntax} +% Clears all entries from the \meta{property list} globally. +% \end{function} +% +% \begin{function}{\prop_clear_new:N, \prop_clear_new:c} +% \begin{syntax} +% \cs{prop_clear_new:N} \meta{property list} +% \end{syntax} +% If the \meta{property list} already exists, clears it within the scope +% of the current \TeX{} group. If the \meta{property list} is not defined, +% it will be created (using \cs{prop_new:N}). Thus the property list is +% guaranteed to be available and clear within the current \TeX{} +% group. The \meta{property list} will exist globally, but the content +% outside of the current \TeX{} group is not specified. +% \end{function} +% +% \begin{function}{\prop_gclear_new:N, \prop_gclear_new:c} +% \begin{syntax} +% \cs{prop_gclear_new:N} \meta{property list} +% \end{syntax} +% If the \meta{property list} already exists, clears it globally. If the +% \meta{property list} is not defined, it will be created (using +% \cs{prop_new:N}). Thus the property list is guaranteed to be available +% and globally clear. +% \end{function} +% +% \begin{function} +% {\prop_set_eq:NN, \prop_set_eq:cN, \prop_set_eq:Nc, \prop_set_eq:cc} +% \begin{syntax} +% \cs{prop_set_eq:NN} \meta{property list1} \meta{property list2} +% \end{syntax} +% Sets the content of \meta{property list1} equal to that of +% \meta{property list2}. This assignment is restricted to the current +% \TeX{} group level. +% \end{function} +% +% \begin{function} +% {\prop_gset_eq:NN, \prop_gset_eq:cN, \prop_gset_eq:Nc, \prop_gset_eq:cc} +% \begin{syntax} +% \cs{prop_gset_eq:NN} \meta{property list1} \meta{property list2} +% \end{syntax} +% Sets the content of \meta{property list1} equal to that of +% \meta{property list2}. This assignment is global and so is not +% limited by the current \TeX{} group level. +% \end{function} +% +% \section{Adding entries to property lists} +% +% \begin{function} +% { +% \prop_put:Nnn, \prop_put:NnV, \prop_put:Nno, \prop_put:Nnx, +% \prop_put:NVn, \prop_put:NVV, \prop_put:Non, \prop_put:Noo, +% \prop_put:cnn, \prop_put:cnV, \prop_put:cno, \prop_put:cnx, +% \prop_put:cVn, \prop_put:cVV, \prop_put:con, \prop_put:coo +% } +% \begin{syntax} +% \cs{prop_put:Nnn} \meta{property list} \Arg{key} \Arg{value} +% \end{syntax} +% Adds an entry to the \meta{property list} which may be accessed +% using the \meta{key} and which has \meta{value}. Both the \meta{key} +% and \meta{value} may contain any \meta{balanced text}. The \meta{key} +% is stored after processing with \cs{tl_to_str:n}, meaning that +% category codes are ignored. If the \meta{key} is already present +% in the \meta{property list}, the existing entry is overwritten +% by the new \meta{value}. The assignment is restricted to the current +% \TeX{} group. +% \end{function} +% +% \begin{function} +% { +% \prop_gput:Nnn, \prop_gput:NnV, \prop_gput:Nno, \prop_gput:Nnx, +% \prop_gput:NVn, \prop_gput:NVV, \prop_gput:Non, \prop_gput:Noo, +% \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{syntax} +% \cs{prop_gput:Nnn} \meta{property list} \Arg{key} \Arg{value} +% \end{syntax} +% Adds an entry to the \meta{property list} which may be accessed +% using the \meta{key} and which has \meta{value}. Both the \meta{key} +% and \meta{value} may contain any \meta{balanced text}. The \meta{key} +% is stored after processing with \cs{tl_to_str:n}, meaning that +% category codes are ignored. If the \meta{key} is already present +% in the \meta{property list}, the existing entry is overwritten +% by the new \meta{value}. The assignment is global. +% \end{function} +% +% \begin{function}{\prop_put_if_new:Nnn, \prop_put_if_new:cnn} +% \begin{syntax} +% \cs{prop_put_if_new:Nnn} \meta{property list} \Arg{key} \Arg{value} +% \end{syntax} +% If the \meta{key} is present in the \meta{property list} then +% no action is taken. If the \meta{key} is not present in the +% \meta{property list} then a new entry is added. Both the \meta{key} +% and \meta{value} may contain any \meta{balanced text}. The \meta{key} +% is stored after processing with \cs{tl_to_str:n}, meaning that +% category codes are ignored. The assignment is restricted to the current +% \TeX{} group. +% \end{function} +% +% \begin{function}{\prop_gput_if_new:Nnn, \prop_gput_if_new:cnn} +% \begin{syntax} +% \cs{prop_gput_if_new:Nnn} \meta{property list} \Arg{key} \Arg{value} +% \end{syntax} +% If the \meta{key} is present in the \meta{property list} then +% no action is taken. If the \meta{key} is not present in the +% \meta{property list} then a new entry is added. Both the \meta{key} +% and \meta{value} may contain any \meta{balanced text}. The \meta{key} +% is stored after processing with \cs{tl_to_str:n}, meaning that +% category codes are ignored. The assignment is global. +% \end{function} +% +% \section{Recovering values from property lists} +% +% \begin{function} +% { +% \prop_get:NnN, \prop_get:NVN, \prop_get:NoN, +% \prop_get:cnN, \prop_get:cVN, \prop_get:coN, +% } +% \begin{syntax} +% \cs{prop_get:NnN} \meta{property list} \Arg{key} \meta{tl var} +% \end{syntax} +% Recovers the \meta{value} stored with \meta{key} from the +% \meta{property list}, and places this in the \meta{token list +% variable}. If the \meta{key} is not found in the +% \meta{property list} then the \meta{token list variable} will +% contain the special marker \cs{q_no_value}. The \meta{token list +% variable} is set within the current \TeX{} group. +% \end{function} +% +% \begin{function}{\prop_pop:NnN, \prop_pop:NoN, \prop_pop:cnN, \prop_pop:coN} +% \begin{syntax} +% \cs{prop_pop:NnN} \meta{property list} \Arg{key} \meta{tl var} +% \end{syntax} +% Recovers the \meta{value} stored with \meta{key} from the +% \meta{property list}, and places this in the \meta{token list +% variable}. If the \meta{key} is not found in the +% \meta{property list} then the \meta{token list variable} will +% contain the special marker \cs{q_no_value}. The \meta{key} and +% \meta{value} are then deleted from the property list. Both +% assignments are local. +% \end{function} +% +% \begin{function} +% {\prop_gpop:NnN, \prop_gpop:NoN, \prop_gpop:cnN, \prop_gpop:coN} +% \begin{syntax} +% \cs{prop_gpop:NnN} \meta{property list} \Arg{key} \meta{tl var} +% \end{syntax} +% Recovers the \meta{value} stored with \meta{key} from the +% \meta{property list}, and places this in the \meta{token list +% variable}. If the \meta{key} is not found in the +% \meta{property list} then the \meta{token list variable} will +% contain the special marker \cs{q_no_value}. The \meta{key} and +% \meta{value} are then deleted from the property list. +% The \meta{property list} is modified globally, while the assignment of +% the \meta{token list variable} is local. +% \end{function} +% +% \section{Modifying property lists} +% +% \begin{function}{\prop_del:Nn, \prop_del:NV, \prop_del:cn, \prop_del:cV} +% \begin{syntax} +% \cs{prop_del:Nn} \meta{property list} \Arg{key} +% \end{syntax} +% Deletes the entry listed under \meta{key} from the +% \meta{property list} which may be accessed. If the \meta{key} is +% not found in the \meta{property list} no change occurs, +% \emph{i.e}~there is no need to test for the existence of a key before +% deleting it. The deletion is restricted to the current \TeX{} group. +% \end{function} +% +% \begin{function}{\prop_gdel:Nn, \prop_gdel:NV, \prop_gdel:cn, \prop_gdel:cV} +% \begin{syntax} +% \cs{prop_gdel:Nn} \meta{property list} \Arg{key} +% \end{syntax} +% Deletes the entry listed under \meta{key} from the +% \meta{property list} which may be accessed. If the \meta{key} is +% not found in the \meta{property list} no change occurs, +% \emph{i.e}~there is no need to test for the existence of a key before +% deleting it. The deletion is not restricted to the current \TeX{} +% group: it is global. +% \end{function} +% +% \section{Property list conditionals} +% +% \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} +% \end{syntax} +% Tests if the \meta{property list} is empty (containing no entries). The +% branching versions then leave either \meta{true code} or +% \meta{false code} in the input stream, as appropriate to the truth of +% the test and the variant of the function chosen. The logical truth of +% the test is left in the input stream by the predicate version. +% \end{function} +% +% \begin{function}[EXP,pTF]{ +% \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{syntax} +% \cs{prop_if_in:NnTF} \meta{property list} \Arg{key} +% ~~\Arg{true code} \Arg{false code} +% \end{syntax} +% Tests if the \meta{key} is present in the \meta{property list}, +% making the comparison using the method described by \cs{str_if_eq:nnTF}. +% Either the \meta{true code} or \meta{false code} in the input stream, as +% appropriate to the truth of the test and the variant of the function +% chosen. +% \begin{texnote} +% This function iterates through every key--value pair in the +% \meta{property list} and is therefore slower than using the +% non-expandable \cs{prop_get:NnNTF}. +% \end{texnote} +% \end{function} +% +% \section{Mapping to property lists} +% +% \begin{function}[EXP]{\prop_map_function:NN, \prop_map_function:cN} +% \begin{syntax} +% \cs{prop_map_function:NN} \meta{property list} \meta{function} +% \end{syntax} +% Applies \meta{function} to every \meta{entry} stored in the +% \meta{property list}. The \meta{function} will receive two argument for +% each iteration.: the \meta{key} and associated \meta{value}. +% The order in which \meta{entries} are returned is not defined and +% should not be relied upon. +% \end{function} +% +% \begin{function}{\prop_map_inline:Nn, \prop_map_inline:cn} +% \begin{syntax} +% \cs{prop_map_inline:Nn} \meta{property list} \Arg{inline function} +% \end{syntax} +% Applies \meta{inline function} to every \meta{entry} stored +% within the \meta{property list}. The \meta{inline function} should +% consist of code which will receive the \meta{key} as |#1| and the +% \meta{value} as |#2|. +% The order in which \meta{entries} are returned is not defined and +% should not be relied upon. +% \end{function} +% +% \begin{function}[EXP]{\prop_map_break:} +% \begin{syntax} +% \cs{prop_map_break:} +% \end{syntax} +% Used to terminate a \cs{prop_map_\ldots} function before all +% entries in the \meta{property list} have been processed. This will +% normally take 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: } +% { +% % Do something useful +% } +% } +% \end{verbatim} +% Use outside of a \cs{prop_map_\ldots} scenario will lead low +% level \TeX{} errors. +% \end{function} +% +% \begin{function}[EXP]{\prop_map_break:n} +% \begin{syntax} +% \cs{prop_map_break:n} \Arg{tokens} +% \end{syntax} +% Used to terminate a \cs{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 will +% normally take 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> } } +% { +% % Do something useful +% } +% } +% \end{verbatim} +% Use outside of a \cs{prop_map_\ldots} scenario will lead low +% level \TeX{} errors. +% \end{function} +% +% \section{Viewing property lists} +% +% \begin{function}{\prop_show:N, \prop_show:c} +% \begin{syntax} +% \cs{prop_show:N} \meta{property list} +% \end{syntax} +% Displays the entries in the \meta{property list} in the terminal. +% \end{function} +% +% \section{Experimental property list functions} +% +% This section contains functions which may or may not be retained, depending +% on how useful they are found to be. +% +% \begin{function}[TF]{\prop_get:NnN} +% \begin{syntax} +% \cs{prop_get:NnNTF} \meta{property list} \Arg{key} +% ~~\meta{token list variable} \Arg{true code} \Arg{false code} +% \end{syntax} +% If the \meta{key} is not present in the \meta{property list}, leaves +% the \meta{false code} in the input stream and leaves the +% \meta{token list variable} unchanged. If the \meta{key} is present in +% the \meta{property list}, stores the corresponding \meta{value} +% in the \meta{token list variable} without removing it from the +% \meta{property list}. The \meta{true code} is then left in the input +% stream. The \meta{token list variable} is assigned locally. +% \end{function} +% +% \begin{function}[TF]{\prop_pop:NnN} +% \begin{syntax} +% \cs{prop_pop:NnNTF} \meta{property list} \Arg{key} +% ~~\meta{token list variable} \Arg{true code} \Arg{false code} +% \end{syntax} +% If the \meta{key} is not present in the \meta{property list}, leaves +% the \meta{false code} in the input stream and leaves the +% \meta{token list variable} unchanged. If the \meta{key} is present in +% the \meta{property list}, pops the corresponding \meta{value} +% in the \meta{token list variable}, \emph{i.e.}~removes the item from +% the \meta{property list}. The \meta{true code} is then left in the input +% stream. Both the \meta{property list} and the \meta{token list variable} +% are assigned locally. +% \end{function} +% +% \begin{function}[TF]{\prop_gpop:NnN} +% \begin{syntax} +% \cs{prop_gpop:NnNTF} \meta{property list} \Arg{key} +% ~~\meta{token list variable} \Arg{true code} \Arg{false code} +% \end{syntax} +% If the \meta{key} is not present in the \meta{property list}, leaves +% the \meta{false code} in the input stream and leaves the +% \meta{token list variable} unchanged. If the \meta{key} is present in +% the \meta{property list}, pops the corresponding \meta{value} +% in the \meta{token list variable}, \emph{i.e.}~removes the item from +% the \meta{property list}. The \meta{true code} is then left in the input +% stream. The \meta{property list} is modified globally, while the +% \meta{token list variable} is assigned locally. +% \end{function} +% +% \begin{function}[EXP]{\prop_map_tokens:Nn} +% \begin{syntax} +% \cs{prop_map_tokens:Nn} \meta{property list} \Arg{code} +% \end{syntax} +% Analogue of \cs{prop_map_function:NN} which maps several tokens instead +% of a single function. Useful in particular when mapping through a +% property list while keeping track of a given key. +% \end{function} +% +% \begin{function}[EXP]{\prop_get:Nn} +% \begin{syntax} +% \cs{prop_get:Nn} \meta{property list} \Arg{key} +% \end{syntax} +% Expands to the \meta{value} corresponding to the \meta{key} in +% the \meta{property list}. If the \meta{key} is missing, this has +% an empty expansion. +% \begin{texnote} +% This function is slower than the non-expandable analogue +% \cs{prop_get:NnN}. +% \end{texnote} +% \end{function} +% +% \section{Internal property list functions} +% +% \begin{function}{\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. +% \end{function} +% +% \begin{function}{\c_empty_prop} +% A permanently-empty property list used for internal comparisons. +% \end{function} +% +% \begin{function}{\prop_split:Nnn} +% \begin{syntax} +% \cs{prop_spilt:Nnn} \meta{property list} \Arg{key} \Arg{code} +% \end{syntax} +% Splits the \meta{property list} at the \meta{key}, giving three +% groups: 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 +% property list. +% If the \meta{key} is not present in the \meta{property list} then +% the second group will contain the marker \cs{q_no_value} and the third +% is empty. +% Once the split has occurred, the \meta{code} is inserted followed by the +% three groups: thus the \meta{code} should properly absorb three +% arguments. +% The \meta{key} comparison takes place as described for \cs{str_if_eq:nn}. +% \end{function} +% +% \begin{function}{\prop_split:NnTF} +% \begin{syntax} +% \cs{prop_spilt: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 +% \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 +% 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. +% 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. +% The \meta{key} comparison takes place as described for \cs{str_if_eq:nn}. +% \end{function} +% +% \end{documentation} +% +% \begin{implementation} +% +% \section{\pkg{l3prop} implementation} +% +% \TestFiles{m3prop001} +% +% \begin{macrocode} +%<*initex|package> +% \end{macrocode} +% +% \begin{macrocode} +%<*package> +\ProvidesExplPackage + {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} +\package_check_loaded_expl: +%</package> +% \end{macrocode} +% +% A property list is a macro whose top-level expansion is for the form +% \enquote{\cs{q_prop} \meta{key$_0$} \cs{q_prop} \Arg{value$_0$} \cs{q_prop} +% \ldots \cs{q_prop} \meta{key$_{n-1}$} \cs{q_prop} \Arg{value$_{n-1}$} +% \cs{q_prop}}. +% The trailing \cs{q_prop} is always present for performance reasons: this +% means that empty property lists are not actually empty. +% +% \begin{macro}[int]{\q_prop} +% A private quark is used as a marker between entries. +% \begin{macrocode} +\quark_new:N \q_prop +% \end{macrocode} +% \end{macro} +% +% \begin{variable}{\c_empty_prop} +% An empty prop contains exactly one \cs{q_prop}. +% \begin{macrocode} +\tl_const:Nn \c_empty_prop { \q_prop } +% \end{macrocode} +% \end{variable} +% +% \subsection{Allocation and initialisation} +% +% \begin{macro}{\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{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 } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\prop_clear:N, \prop_clear:c} +% \begin{macro}{\prop_gclear:N, \prop_gclear:c} +% The same idea for clearing +% \begin{macrocode} +\cs_new_protected:Npn \prop_clear:N #1 { \cs_set_eq:NN #1 \c_empty_prop } +\cs_new_protected:Npn \prop_clear:c #1 { \cs_set_eq:cN {#1} \c_empty_prop } +\cs_new_protected:Npn \prop_gclear:N #1 { \cs_gset_eq:NN #1 \c_empty_prop } +\cs_new_protected:Npn \prop_gclear:c #1 { \cs_gset_eq:cN {#1} \c_empty_prop } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\prop_clear_new:N, \prop_clear_new:c} +% \begin{macro}{\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 + { \cs_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 + { \cs_if_exist:NTF #1 { \prop_gclear:N #1 } { \prop_new:N #1 } } +\cs_new_eq:NN \prop_gclear_new:c \prop_gclear:c +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro} +% {\prop_set_eq:NN, \prop_set_eq:cN, \prop_set_eq:Nc, \prop_set_eq:cc} +% \begin{macro} +% {\prop_gset_eq:NN, \prop_gset_eq:cN, \prop_gset_eq:Nc, \prop_gset_eq:cc} +% Once again, these are simply copies from the token list functions. +% \begin{macrocode} +\cs_new_eq:NN \prop_set_eq:NN \tl_set_eq:NN +\cs_new_eq:NN \prop_set_eq:Nc \tl_set_eq:Nc +\cs_new_eq:NN \prop_set_eq:cN \tl_set_eq:cN +\cs_new_eq:NN \prop_set_eq:cc \tl_set_eq:cc +\cs_new_eq:NN \prop_gset_eq:NN \tl_gset_eq:NN +\cs_new_eq:NN \prop_gset_eq:Nc \tl_gset_eq:Nc +\cs_new_eq:NN \prop_gset_eq:cN \tl_gset_eq:cN +\cs_new_eq:NN \prop_gset_eq:cc \tl_gset_eq:cc +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Accessing data in property lists} +% +% \begin{macro}[int]{\prop_split:NnTF} +% \begin{macro}[aux]{\prop_split_aux:NnTF} +% \begin{macro}[aux]{\prop_split_aux:nnnn} +% \begin{macro}[aux]{\prop_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_prop} \meta{detokenized key} \cs{q_prop} +% \marg{value} \meta{extra argument}, effectively separating an +% \meta{extract1} before the key in the property list and an \meta{extract2} +% after the key. +% +% If the key is present in the property list, then \meta{extra argument} +% is simply \cs{q_prop}, and \cs{prop_splot_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{extract1} \Arg{value} \Arg{extract2}. +% In order for \meta{extract1}\meta{extract2} to be a well-formed +% property list, \meta{extract1} has a leading and trailing \cs{q_prop}, +% retaining exactly the structure of a property list, while \meta{extract2} +% omits the leading \cs{q_prop}. +% +% If the key is not there, then \meta{extra argument} is +% |? \use_ii:nn { }|, and |\prop_split_aux:nnnn ? \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. +% \begin{macrocode} +\cs_set_protected:Npn \prop_split:NnTF #1#2 + { \exp_args:NNo \prop_split_aux:NnTF #1 { \tl_to_str:n {#2} } } +\cs_new_protected:Npn \prop_split_aux:NnTF #1#2 + { + \cs_set_protected:Npn \prop_split_aux:w + ##1 \q_prop #2 \q_prop ##2 ##3 ##4 \q_mark ##5 \q_stop + { \prop_split_aux:nnnn ##3 { {##1 \q_prop } {##2} {##4} } } + \exp_after:wN \prop_split_aux:w #1 \q_mark + \q_prop #2 \q_prop { } { ? \use_ii:nn { } } \q_mark \q_stop + } +\cs_new:Npn \prop_split_aux:nnnn #1#2#3#4 { #3 #2 } +\cs_new_protected:Npn \prop_split_aux:w { } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[int]{\prop_split:Nnn} +% The goal here is to provide a common interface for both true and false +% branches of \cs{prop_split:NnTF}. In both cases, the code given by the +% user will be placed in front of three brace groups, \Arg{extract1} +% \Arg{value} \Arg{extract2}. +% If the key was missing from the property list, then \meta{extract1} +% is the full property list, \meta{value} is \cs{q_no_value}, and +% \meta{extract2} is empty. +% Otherwise, \meta{extract1} is the part of the property list before the +% \meta{key}, and has the structure of a property list, \meta{value} is +% the value corresponding to the \meta{key}, and \meta{extract2} (the part +% after the \meta{key}) is missing the leading \cs{q_prop}. +% \begin{macrocode} +\cs_set_protected:Npn \prop_split:Nnn #1#2#3 + { + \prop_split:NnTF #1 {#2} + {#3} + { \exp_args:Nno \use:n {#3} {#1} { \q_no_value } { } } + } +% \end{macrocode} +% \end{macro} +% +% \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{macro}[aux]{\prop_del_aux: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_del:Nn #1#2 + { \prop_split:NnTF #1 {#2} { \prop_del_aux:NNnnn \tl_set:Nn #1 } { } } +\cs_new_protected:Npn \prop_gdel:Nn #1#2 + { \prop_split:NnTF #1 {#2} { \prop_del_aux:NNnnn \tl_gset:Nn #1 } { } } +\cs_new_protected:Npn \prop_del_aux:NNnnn #1#2#3#4#5 + { #1 #2 { #3 #5 } } +\cs_generate_variant:Nn \prop_del:Nn { NV } +\cs_generate_variant:Nn \prop_del:Nn { c , cV } +\cs_generate_variant:Nn \prop_gdel:Nn { NV } +\cs_generate_variant:Nn \prop_gdel:Nn { c , cV } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro} +% { +% \prop_get:NnN, \prop_get:NVN, \prop_get:NoN, +% \prop_get:cnN, \prop_get:cVN, \prop_get:NoN +% } +% \begin{macro}[aux]{\prop_get_aux: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}. +% \begin{macrocode} +\cs_new_protected:Npn \prop_get:NnN #1#2#3 + { + \prop_split:NnTF #1 {#2} + { \prop_get_aux:Nnnn #3 } + { \tl_set:Nn #3 { \q_no_value } } + } +\cs_new_protected:Npn \prop_get_aux: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}{\prop_pop:NnN, \prop_pop:NoN, \prop_pop:cnN, \prop_pop:coN} +% \begin{macro}{\prop_gpop:NnN, \prop_gpop:NoN, \prop_gpop:cnN, \prop_gpop:coN} +% \begin{macro}[aux]{\prop_pop_aux: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. +% If the key is missing, save \cs{q_no_value} in the token list. +% \begin{macrocode} +\cs_new_protected:Npn \prop_pop:NnN #1#2#3 + { + \prop_split:NnTF #1 {#2} + { \prop_pop_aux:NNNnnn \tl_set:Nn #1 #3 } + { \tl_set:Nn #3 { \q_no_value } } + } +\cs_new_protected:Npn \prop_gpop:NnN #1#2#3 + { + \prop_split:NnTF #1 {#2} + { \prop_pop_aux:NNNnnn \tl_gset:Nn #1 #3 } + { \tl_set:Nn #3 { \q_no_value } } + } +\cs_new_protected:Npn \prop_pop_aux: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 } +\cs_generate_variant:Nn \prop_gpop:NnN { c , co } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro} +% { +% \prop_put:Nnn, \prop_put:NnV, \prop_put:Nno, \prop_put:Nnx, +% \prop_put:NVn, \prop_put:NVV, \prop_put:Non, \prop_put:Noo, +% \prop_put:cnn, \prop_put:cnV, \prop_put:cno, \prop_put:cnx, +% \prop_put:cVn, \prop_put:cVV, \prop_put:con, \prop_put:coo +% } +% \begin{macro} +% { +% \prop_gput:Nnn, \prop_gput:NnV, \prop_gput:Nno, \prop_gput:Nnx, +% \prop_gput:NVn, \prop_gput:NVV, \prop_gput:Non, \prop_gput:Noo, +% \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]{\prop_put_aux:NNnnnnn} +% Putting a key--value pair in a property list starts by splitting +% to remove any existing value. The property list is then +% reconstructed with the two remaining parts |#5| and |#7| first, +% followed by the new or updated entry. +% \begin{macrocode} +\cs_new_protected:Npn \prop_put:Nnn { \prop_put_aux:NNnn \tl_set:Nx } +\cs_new_protected:Npn \prop_gput:Nnn { \prop_put_aux:NNnn \tl_gset:Nx } +\cs_new_protected:Npn \prop_put_aux:NNnn #1#2#3#4 + { + \prop_split:Nnn #2 {#3} { \prop_put_aux:NNnnnnn #1 #2 {#3} {#4} } + } +\cs_new_protected:Npn \prop_put_aux:NNnnnnn #1#2#3#4#5#6#7 + { + #1 #2 + { + \exp_not:n { #5 #7 } + \tl_to_str:n {#3} \exp_not:n { \q_prop {#4} \q_prop } + } + } +\cs_generate_variant:Nn \prop_put:Nnn + { NnV , Nno , Nnx , NV , NVV , No , Noo } +\cs_generate_variant:Nn \prop_put:Nnn + { c , cnV , cno , cnx , cV , cVV , co , coo } +\cs_generate_variant:Nn \prop_gput:Nnn + { NnV , Nno , Nnx , NV , NVV , No , Noo } +\cs_generate_variant:Nn \prop_gput:Nnn + { c , cnV , cno , cnx , cV , cVV , co , coo } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\prop_put_if_new:Nnn, \prop_put_if_new:cnn} +% \begin{macro}{\prop_gput_if_new:Nnn, \prop_gput_if_new:cnn} +% Adding conditionally also splits. If the key is already present, +% the three brace groups given by \cs{prop_split:NnTF} are removed. +% If the key is new, then the value is added, being careful to +% convert the key to a string using \cs{tl_to_str:n}. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \prop_put_if_new:Nnn + { \prop_put_if_new_aux:NNnn \tl_put_right:Nx } +\cs_new_protected_nopar:Npn \prop_gput_if_new:Nnn + { \prop_put_if_new_aux:NNnn \tl_gput_right:Nx } +\cs_new_protected:Npn \prop_put_if_new_aux:NNnn #1#2#3#4 + { + \prop_split:NnTF #2 {#3} + { \use_none:nnn } + { + #1 #2 + { \tl_to_str:n {#3} \exp_not:n { \q_prop {#4} \q_prop } } + } + } +\cs_generate_variant:Nn \prop_put_if_new:Nnn { c } +\cs_generate_variant:Nn \prop_gput_if_new:Nnn { c } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Property list conditionals} +% +% \begin{macro}[pTF]{\prop_if_empty:N, \prop_if_empty:c} +% The test here uses \cs{c_empty_prop} as it is not really empty! +% \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} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[pTF] +% { +% \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]{\prop_if_in_aux:w} +% 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 +% \begin{verbatim} +% \prg_new_protected_conditional:Npnn \prop_if_in:Nn #1 #2 +% { +% \prop_split:NnTF #1 {#2} +% { +% \prg_return_true: +% \use_none:nnn +% } +% { \prg_return_false: } +% } +% \end{verbatim} +% but \cs{prop_split:NnTF} is non-expandable. +% +% Instead, the key is compared to each key in turn using \cs{str_if_eq:nn}, +% which is expandable. The mapping is stopped using |A|, which cannot appear +% within a key of the property list, since keys are strings. +% 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 +% is searched for. +% \begin{macrocode} +\prg_new_conditional:Npnn \prop_if_in:Nn #1#2 { p , T , F , TF } + { + \exp_last_unbraced:Noo \prop_if_in_aux:nwn + { \tl_to_str:n {#2} } #1 + A \q_prop { } \q_stop + } +\cs_new:Npn \prop_if_in_aux:nwn #1 \q_prop #2 \q_prop #3 + { + \if_catcode:w A #2 + \prg_return_false: + \exp_after:wN \use_none_delimit_by_q_stop:w + \fi: + \str_if_eq:nnT {#1} {#2} + { + \prg_return_true: + \use_none_delimit_by_q_stop:w + } + \prop_if_in_aux:nwn {#1} + } +\cs_generate_variant:Nn \prop_if_in_p:Nn { NV , No } +\cs_generate_variant:Nn \prop_if_in_p:Nn { c , cV , co } +\cs_generate_variant:Nn \prop_if_in:NnT { NV , No } +\cs_generate_variant:Nn \prop_if_in:NnT { c , cV , co } +\cs_generate_variant:Nn \prop_if_in:NnF { NV , No } +\cs_generate_variant:Nn \prop_if_in:NnF { c , cV , co } +\cs_generate_variant:Nn \prop_if_in:NnTF { NV , No } +\cs_generate_variant:Nn \prop_if_in:NnTF { c , cV , co } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Mapping to property lists} +% +% \begin{macro} +% { +% \prop_map_function:NN, \prop_map_function:Nc, +% \prop_map_function:cN, \prop_map_function:cc +% } +% \begin{macro}[aux]{\prop_map_function_aux:Nwn} +% The fastest way to do a recursion here is to use an +% \cs{if_catcode:w} test: the keys are strings, and thus +% cannot match the marker |A| (which has catcode \enquote{letter}). +% \begin{macrocode} +\cs_new_nopar:Npn \prop_map_function:NN #1#2 + { + \exp_last_unbraced:NNo \prop_map_function_aux:Nwn #2 + #1 A \q_prop { } \q_recursion_stop + } +\cs_new:Npn \prop_map_function_aux:Nwn #1 \q_prop #2 \q_prop #3 + { + \if_catcode:w A #2 + \exp_after:wN \prop_map_break: + \fi: + #1 {#2} {#3} + \prop_map_function_aux:Nwn #1 + } +\cs_generate_variant:Nn \prop_map_function:NN { Nc } +\cs_generate_variant:Nn \prop_map_function:NN { c , cc } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{variable}{\g_prop_map_inline_int} +% A nesting counter for mapping. +% \begin{macrocode} +\int_new:N \g_prop_map_inline_int +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\prop_map_inline:Nn, \prop_map_inline:cn} +% Mapping in line requires a nesting level counter. +% \begin{macrocode} +\cs_new_protected:Npn \prop_map_inline:Nn #1#2 + { + \int_gincr:N \g_prop_map_inline_int + \cs_gset:cpn { prop_map_inline_ \int_use:N \g_prop_map_inline_int :nn } + ##1##2 {#2} + \prop_map_function:Nc #1 + { prop_map_inline_ \int_use:N \g_prop_map_inline_int :nn } + \int_gdecr:N \g_prop_map_inline_int + } +\cs_generate_variant:Nn \prop_map_inline:Nn { c } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\prop_map_break:} +% Breaking the map function simply means removing everything up to +% the \cs{q_stop} marker. +% \begin{macrocode} +\cs_new_eq:NN \prop_map_break: \use_none_delimit_by_q_recursion_stop:w +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\prop_map_break:n} +% The same idea for using one set of tokens. +% \begin{macrocode} +\cs_new_eq:NN \prop_map_break:n \use_i_delimit_by_q_recursion_stop:nw +% \end{macrocode} +% \end{macro} +% +% \subsection{Viewing property lists} +% +% \begin{variable}{\l_prop_show_tl} +% Used to store the material for display. +% \begin{macrocode} +\tl_new:N \l_prop_show_tl +% \end{macrocode} +% \end{variable} +% +% \begin{macro}{\prop_show:N, \prop_show:c} +% \begin{macro}[aux]{\prop_show_aux:n} +% \begin{macro}[aux]{\prop_show_aux:w} +% The aim of the mapping here is to create a token list containing the +% formatted property list. The very first item needs the new line and +% \verb*|> | removing, which is achieved using a \texttt{w}-type auxiliary. +% To avoid a low-level \TeX{} error if there is an empty property list, a +% simple test is used to keep the output \enquote{clean}. +% \begin{macrocode} +\cs_new_protected_nopar:Npn \prop_show:N #1 + { + \prop_if_empty:NTF #1 + { + \iow_term:x { Property~list~\token_to_str:N #1 \c_space_tl is~empty } + \tl_show:n { } + } + { + \iow_term:x + { + Property~list~\token_to_str:N #1 \c_space_tl + contains~the~pairs~(without~outer~braces): + } + \tl_set:Nx \l_prop_show_tl + { \prop_map_function:NN #1 \prop_show_aux:nn } + \tl_show:n \exp_after:wN \exp_after:wN \exp_after:wN + { \exp_after:wN \prop_show_aux:w \l_prop_show_tl } + } + } +\cs_new:Npn \prop_show_aux:nn #1#2 + { + \iow_newline: > \c_space_tl \c_space_tl + \iow_char:N \{ #1 \iow_char:N \} + \c_space_tl \c_space_tl => \c_space_tl \c_space_tl + \iow_char:N \{ \exp_not:n {#2} \iow_char:N \} + } +\cs_new:Npn \prop_show_aux:w #1 > ~ { } +\cs_generate_variant:Nn \prop_show:N { c } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsection{Experimental functions} +% +% \begin{macro}[TF]{\prop_get:NnN} +% \begin{macro}[aux]{\prop_get_aux_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. +% \begin{macrocode} +\prg_new_protected_conditional:Npnn \prop_get:NnN #1#2#3 { T , F , TF } + { + \prop_split:NnTF #1 {#2} + { \prop_get_aux_true:Nnnn #3 } + { \prg_return_false: } + } +\cs_new_protected:Npn \prop_get_aux_true:Nnnn #1#2#3#4 + { + \tl_set:Nn #1 {#3} + \prg_return_true: + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[TF]{\prop_pop:NnN,\prop_gpop:NnN} +% \begin{macro}[aux]{\prop_pop_aux_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 +% list are altered. Otherwise, \cs{prg_return_true:} is used after +% the assignments. +% \begin{macrocode} +\prg_new_protected_conditional:Npnn \prop_pop:NnN #1#2#3 {T,F,TF} + { + \prop_split:NnTF #1 {#2} + { \prop_pop_aux_true:NNNnnn \tl_set:Nn #1 #3 } + { \prg_return_false: } + } +\prg_new_protected_conditional:Npnn \prop_gpop:NnN #1#2#3 {T,F,TF} + { + \prop_split:NnTF #1 {#2} + { \prop_pop_aux_true:NNNnnn \tl_gset:Nn #1 #3 } + { \prg_return_false: } + } +\cs_new_protected:Npn \prop_pop_aux_true:NNNnnn #1#2#3#4#5#6 + { + \tl_set:Nn #3 {#5} + #1 #2 { #4 #6 } + \prg_return_true: + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\prop_map_tokens:Nn} +% \begin{macro}[aux]{\prop_map_tokens_aux:nwn} +% The mapping grabs one key--value pair at a time, and stops when +% reaching the marker key |A|, with catcode \enquote{letter}, which +% cannot appear in normal keys since those are strings. The odd +% construction |\use:n {#1}| allows |#1| to contain any token. +% \begin{macrocode} +\cs_new:Npn \prop_map_tokens:Nn #1#2 + { + \exp_last_unbraced:Nno \prop_map_tokens_aux:nwn {#2} #1 + A \q_prop { } \q_recursion_stop + } +\cs_new:Npn \prop_map_tokens_aux:nwn #1 \q_prop #2 \q_prop #3 + { + \if_catcode:w A #2 + \exp_after:wN \prop_map_break: + \fi: + \use:n {#1} {#2} {#3} + \prop_map_tokens_aux:nwn {#1} + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[EXP]{\prop_get:Nn} +% \begin{macro}[aux]{\prop_get_aux:nnn} +% Getting expandably the value corresponding to a key in a property list +% is a simple instance of mapping some tokens. +% Map the function \cs{prop_get_aux:nnn} which takes as its three +% arguments the \meta{key} that we are looking for, the current +% \meta{key} and the current \meta{value}. If the \meta{keys} match, +% the \meta{value} is returned. If none of the keys match, this expands +% to nothing. +% \begin{macrocode} +\cs_new:Npn \prop_get:Nn #1 #2 + { \prop_map_tokens:Nn #1 { \prop_get_aux:nnn {#2} } } +\cs_new:Npn \prop_get_aux:nnn #1 #2 #3 + { \str_if_eq:nnT {#1} {#2} { \prop_map_break:n {#3} } } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \subsection{Deprecated interfaces} +% +% Deprecated on 2011-05-27, for removal by 2011-08-31. +% +% \begin{macro}{\prop_display:N, \prop_display:c} +% An older name for \cs{prop_show:N}. +% \begin{macrocode} +\cs_new_eq:NN \prop_display:N \prop_show:N +\cs_new_eq:NN \prop_display:c \prop_show:c +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\prop_gget:NnN, \prop_gget:NVN, \prop_gget:cnN, \prop_gget:cVN} +% \begin{macro}[aux]{\prop_gget_aux:Nnnn} +% Getting globally is no longer supported: this is a conceptual change, so +% the necessary code for the transition is provided directly. +% \begin{macrocode} +\cs_new_protected:Npn \prop_gget:NnN #1#2#3 + { \prop_split:Nnn #1 {#2} { \prop_gget_aux:Nnnn #3 } } +\cs_new_protected:Npn \prop_gget_aux:Nnnn #1#2#3#4 + { \tl_gset:Nn #1 {#3} } +\cs_generate_variant:Nn \prop_gget:NnN { NV } +\cs_generate_variant:Nn \prop_gget:NnN { c , cV } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\prop_get_gdel:NnN} +% This name seems very odd. +% \begin{macrocode} +\cs_new_eq:NN \prop_get_gdel:NnN \prop_gpop:NnN +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[TF]{\prop_if_in:cc} +% A hang-over from an ancient implementation +% \begin{macrocode} +\cs_generate_variant:Nn \prop_if_in:NnT { cc } +\cs_generate_variant:Nn \prop_if_in:NnF { cc } +\cs_generate_variant:Nn \prop_if_in:NnTF { cc } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\prop_gput:ccx} +% Another one. +% \begin{macrocode} +\cs_generate_variant:Nn \prop_gput:Nnn { ccx } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[pTF] +% {\prop_if_eq:NN, \prop_if_eq:Nc, \prop_if_eq:cN, \prop_if_eq:cc} +% These ones do no even make sense! +% \begin{macrocode} +\prg_new_eq_conditional:NNn \prop_if_eq:NN \tl_if_eq:NN { p , T , F , TF } +\prg_new_eq_conditional:NNn \prop_if_eq:cN \tl_if_eq:cN { p , T , F , TF } +\prg_new_eq_conditional:NNn \prop_if_eq:Nc \tl_if_eq:Nc { p , T , F , TF } +\prg_new_eq_conditional:NNn \prop_if_eq:cc \tl_if_eq:cc { p , T , F , TF } +% \end{macrocode} +% \end{macro} +% +% \begin{macrocode} +%</initex|package> +% \end{macrocode} +% +% \end{implementation} +% +% \PrintIndex
\ No newline at end of file |