diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3clist.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3clist.dtx | 517 |
1 files changed, 317 insertions, 200 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx index bd15dbffb01..b2c09e72e15 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx @@ -36,7 +36,7 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3clist.dtx 2666 2011-08-26 06:10:09Z joseph $ +\GetIdInfo$Id: l3clist.dtx 2725 2011-09-05 18:53:03Z bruno $ {L3 Experimental comma separated lists} %</driver|package> %<*driver> @@ -69,15 +69,25 @@ % \begin{documentation} % % Comma lists contain ordered data where items can be added to the left -% or right end of the sequence. This gives an ordered list which can -% then be utilised with the \cs{clist_map_function:NN} function. Comma -% Comma lists cannot contain empty items, thus +% or right end of the list. The resulting ordered list can then +% be mapped over using \cs{clist_map_function:NN}. Several items can +% be added at once, and spaces are removed from both sides of each item +% on input. Hence, % \begin{verbatim} % \clist_new:N \l_my_clist -% \clist_put_right:Nn \l_my_clist { } +% \clist_put_left:Nn \l_my_clist { ~ a ~ , ~ {b} ~ } +% \clist_put_right:Nn \l_my_clist { ~ { c ~ } , d } +% \end{verbatim} +% results in \cs{l_my_clist} containing |a,{b},{c~},d|. +% Comma lists cannot contain empty items, thus +% \begin{verbatim} +% \clist_clear_new:N \l_my_clist +% \clist_put_right:Nn \l_my_clist { , ~ , , } % \clist_if_empty:NTF \l_my_clist { true } { false } % \end{verbatim} -% will leave \texttt{true} in the input stream. +% will leave \texttt{true} in the input stream. To include an item +% which contains a comma, or starts or ends with a space, +% surround it with braces. % % \section{Creating and initialising comma lists} % @@ -183,9 +193,10 @@ % \clist_put_left:co, \clist_put_left:cx % } % \begin{syntax} -% \cs{clist_put_left:Nn} \meta{comma list} \Arg{item} +% \cs{clist_put_left:Nn} \meta{comma list} |{|\meta{item1},\ldots{},\meta{item$_n$}|}| % \end{syntax} -% Appends the \meta{item} to the left of the \meta{comma list}. +% Appends the \meta{items} to the left of the \meta{comma list}. +% Spaces are removed from both sides of each item. % The assignment is restricted to the current \TeX{} group. % \end{function} % @@ -196,9 +207,10 @@ % \clist_gput_left:co, \clist_gput_left:cx % } % \begin{syntax} -% \cs{clist_gput_left:Nn} \meta{comma list} \Arg{item} +% \cs{clist_gput_left:Nn} \meta{comma list} |{|\meta{item1},\ldots{},\meta{item$_n$}|}| % \end{syntax} -% Appends the \meta{item} to the left of the \meta{comma list}. +% Appends the \meta{items} to the left of the \meta{comma list}. +% Spaces are removed from both sides of each item. % The assignment is global. % \end{function} % @@ -209,9 +221,10 @@ % \clist_put_right:co, \clist_put_right:cx % } % \begin{syntax} -% \cs{clist_put_right:Nn} \meta{comma list} \Arg{item} +% \cs{clist_put_right:Nn} \meta{comma list} |{|\meta{item1},\ldots{},\meta{item$_n$}|}| % \end{syntax} -% Appends the \meta{item} to the right of the \meta{comma list}. +% Appends the \meta{items} to the right of the \meta{comma list}. +% Spaces are removed from both sides of each item. % The assignment is restricted to the current \TeX{} group. % \end{function} % @@ -222,77 +235,13 @@ % \clist_gput_right:co, \clist_gput_right:cx % } % \begin{syntax} -% \cs{clist_gput_right:Nn} \meta{comma list} \Arg{item} +% \cs{clist_gput_right:Nn} \meta{comma list} |{|\meta{item1},\ldots{},\meta{item$_n$}|}| % \end{syntax} % Appends the \meta{item} to the right of the \meta{comma list}. +% Spaces are removed from both sides of each item. % The assignment is global. % \end{function} % -% \section{Comma lists as stacks} -% -% \begin{function}{\clist_get:NN, \clist_get:cN} -% \begin{syntax} -% \cs{clist_get:NN} \meta{comma list} \meta{token list variable} -% \end{syntax} -% Stores the left-most item from a \meta{comma list} in the -% \meta{token list variable} without removing it from the -% \meta{comma list}. The \meta{token list variable} is assigned locally. -% \end{function} -% -% \begin{function}{\clist_get:NN, \clist_get:cN} -% \begin{syntax} -% \cs{clist_get:NN} \meta{comma list} \meta{token list variable} -% \end{syntax} -% Stores the right-most item from a \meta{comma list} in the -% \meta{token list variable} without removing it from the -% \meta{comma list}. The \meta{token list variable} is assigned locally. -% \end{function} -% -% \begin{function}{\clist_pop:NN, \clist_pop:cN} -% \begin{syntax} -% \cs{clist_pop:NN} \meta{comma list} \meta{token list variable} -% \end{syntax} -% Pops the left-most item from a \meta{comma list} into the -% \meta{token list variable}, \emph{i.e.}~removes the item from the -% comma list and stores it in the \meta{token list variable}. -% Both of the variables are assigned locally. -% \end{function} -% -% \begin{function}{\clist_gpop:NN, \clist_gpop:cN} -% \begin{syntax} -% \cs{clist_gpop:NN} \meta{comma list} \meta{token list variable} -% \end{syntax} -% Pops the left-most item from a \meta{comma list} into the -% \meta{token list variable}, \emph{i.e.}~removes the item from the -% comma list and stores it in the \meta{token list variable}. -% The \meta{comma list} is modified globally, while the assignment of -% the \meta{token list variable} is local. -% \end{function} -% -% \begin{function} -% { -% \clist_push:Nn, \clist_push:NV, \clist_push:No, \clist_push:Nx, -% \clist_push:cn, \clist_push:cV, \clist_push:co, \clist_push:cx -% } -% \begin{syntax} -% \cs{clist_push:Nn} \meta{sequence} \Arg{item} -% \end{syntax} -% Adds the \Arg{item} to the top of the \meta{comma list}. -% The assignment is restricted to the current \TeX{} group. -% \end{function} -% -% \begin{function} -% { -% \clist_gpush:Nn, \clist_gpush:NV, \clist_gpush:No, \clist_gpush:Nx, -% \clist_gpush:cn, \clist_gpush:cV, \clist_gpush:co, \clist_gpush:cx -% } -% \begin{syntax} -% \cs{clist_gpush:Nn} \meta{sequence} \Arg{item} -% \end{syntax} -% Pushes the \meta{item} onto the end of the top of the -% \meta{comma list}. The assignment is global. -% \end{function} -% % \section{Using comma lists} % % \begin{function}[EXP]{\clist_use:N, \clist_use:c} @@ -322,6 +271,9 @@ % This function iterates through every item in the \meta{comma list} and % does a comparison with the \meta{items} already checked. It is therefore % relatively slow with large comma lists. +% Furthermore, it will not work if any of the items in the +% \meta{comma list} contains |{|, |}|, or |#| +% (assuming the usual \TeX{} category codes apply). % \end{texnote} % \end{function} % @@ -337,6 +289,9 @@ % This function iterates through every item in the \meta{comma list} and % does a comparison with the \meta{items} already checked. It is therefore % relatively slow with large comma lists. +% Furthermore, it will not work if any of the items in the +% \meta{comma list} contains |{|, |}|, or |#| +% (assuming the usual \TeX{} category codes apply). % \end{texnote} % \end{function} % @@ -347,6 +302,10 @@ % Removes every occurrence of \meta{item} from the \meta{comma list}. % The \meta{item} comparison takes place on a token basis, as for % \cs{tl_if_eq:nn(TF)}. The removal is local to the current \TeX{} group. +% \begin{texnote} +% The \meta{item} may not contain |{|, |}|, or |#| +% (assuming the usual \TeX{} category codes apply). +% \end{texnote} % \end{function} % % \begin{function}{\clist_gremove_all:Nn, \clist_gremove_all:cn} @@ -356,33 +315,10 @@ % Removes each occurrence of \meta{item} from the \meta{comma list}. % The \meta{item} comparison takes place on a token basis, as for % \cs{tl_if_eq:nn(TF)}. The removal is applied globally. -% \end{function} -% -% \begin{function}{\clist_trim_spaces:N, \clist_trim_spaces:c} -% \begin{syntax} -% \cs{clist_trim_spaces:N} \meta{comma list} -% \end{syntax} -% Removes leading and trailing spaces from each \meta{item} in the -% \meta{comma list} within the current \TeX{} group. This space-removal -% process takes place as described for \cs{tl_trim_spaces:n}. -% \end{function} -% -% \begin{function}{\clist_gtrim_spaces:N, \clist_gtrim_spaces:c} -% \begin{syntax} -% \cs{clist_gtrim_spaces:N} \meta{comma list} -% \end{syntax} -% Removes leading and trailing spaces from each \meta{item} in the -% \meta{comma list} globally. This space-removal -% process takes place as described for \cs{tl_trim_spaces:n}. -% \end{function} -% -% \begin{function}[EXP]{\clist_trim_spaces:n} -% \begin{syntax} -% \cs{clist_trim_spaces:N} \meta{comma list} -% \end{syntax} -% Removes leading and trailing spaces from each \meta{item} in the -% \meta{comma list}, leaving the resulting modified list in the -% input stream. +% \begin{texnote} +% The \meta{item} may not contain |{|, |}|, or |#| +% (assuming the usual \TeX{} category codes apply). +% \end{texnote} % \end{function} % % \section{Comma list conditionals} @@ -418,11 +354,32 @@ % ~~\Arg{true code} \Arg{false code} % \end{syntax} % Tests if the \meta{item} is present in the \meta{comma list}. +% \begin{texnote} +% The \meta{item} may not contain |{|, |}|, or |#| +% (assuming the usual \TeX{} category codes apply). +% \end{texnote} % \end{function} % % \section{Mapping to comma lists} % -% \begin{function}[EXP] +% The functions described in this section apply a specified function +% to each item of a comma list. +% +% When the comma list is given explicitly, as an \texttt{n}-type argument, +% spaces are trimmed around each item. +% If the result of trimming spaces is empty, the item is ignored. +% Otherwise, if the item is surrounded by braces, one set is removed, +% and the result is passed to the mapped function. Thus, if your +% comma list that is being mapped is \verb*|{a , {b }, ,{}, {c},}| +% then the arguments passed to the mapped function are +% `\verb*|a|', `\verb*|{b }|', an empty argument, and `\verb*|c|'. +% +% When the comma list is given as an \texttt{N}-type argument, spaces +% have already been trimmed on input, and items are simply stripped +% of one set of braces if any. This case is more efficient than using +% \texttt{n}-type comma lists. +% +% \begin{function}[rEXP] % {\clist_map_function:NN, \clist_map_function:cN, \clist_map_function:nN} % \begin{syntax} % \cs{clist_map_function:NN} \meta{comma list} \meta{function} @@ -461,7 +418,7 @@ % are returned from left to right. % \end{function} % -% \begin{function}[EXP]{\clist_map_break:} +% \begin{function}[rEXP]{\clist_map_break:} % \begin{syntax} % \cs{clist_map_break:} % \end{syntax} @@ -480,7 +437,7 @@ % \end{verbatim} % Use outside of a \cs{clist_map_\ldots} scenario will lead to low % level \TeX{} errors. -% \begin{texnote} +% \begin{texnote}^^A temporarily untrue, fixed next week. % When the mapping is broken, additional tokens may be inserted by the % internal macro \cs{clist_break_point:n} before further items are taken % from the input stream. This will depend on the design of the mapping @@ -488,7 +445,7 @@ % \end{texnote} % \end{function} % -% \begin{function}[EXP]{\clist_map_break:n} +% \begin{function}[rEXP]{\clist_map_break:n} % \begin{syntax} % \cs{clist_map_break:n} \Arg{tokens} % \end{syntax} @@ -525,50 +482,64 @@ % in the previous section: a comma list should either be used as an % ordered data type or as a stack, but not in both ways. % +% \section{Comma lists as stacks} +% % \begin{function}{\clist_get:NN, \clist_get:cN} % \begin{syntax} % \cs{clist_get:NN} \meta{comma list} \meta{token list variable} % \end{syntax} -% Reads the top item from a \meta{comma list} into the +% Stores the left-most item from a \meta{comma list} in the +% \meta{token list variable} without removing it from the +% \meta{comma list}. The \meta{token list variable} is assigned locally. +% \end{function} +% +% \begin{function}{\clist_get:NN, \clist_get:cN} +% \begin{syntax} +% \cs{clist_get:NN} \meta{comma list} \meta{token list variable} +% \end{syntax} +% Stores the right-most item from a \meta{comma list} in the % \meta{token list variable} without removing it from the % \meta{comma list}. The \meta{token list variable} is assigned locally. -% If \meta{comma list} is empty an error will be raised. % \end{function} % % \begin{function}{\clist_pop:NN, \clist_pop:cN} % \begin{syntax} % \cs{clist_pop:NN} \meta{comma list} \meta{token list variable} % \end{syntax} -% Pops the top item from a \meta{comma list} into the -% \meta{token list variable}. Both of the variables are assigned -% locally. If \meta{comma list} is empty an error will be raised. +% Pops the left-most item from a \meta{comma list} into the +% \meta{token list variable}, \emph{i.e.}~removes the item from the +% comma list and stores it in the \meta{token list variable}. +% Both of the variables are assigned locally. % \end{function} % % \begin{function}{\clist_gpop:NN, \clist_gpop:cN} % \begin{syntax} % \cs{clist_gpop:NN} \meta{comma list} \meta{token list variable} % \end{syntax} -% Pops the top item from a \meta{comma list} into the -% \meta{token list variable}. The \meta{comma list} is modified globally, -% while the \meta{token list variable} is assigned locally. If -% \meta{comma list} is empty an error will be raised. +% Pops the left-most item from a \meta{comma list} into the +% \meta{token list variable}, \emph{i.e.}~removes the item from the +% comma list and stores it in the \meta{token list variable}. +% The \meta{comma list} is modified globally, while the assignment of +% the \meta{token list variable} is local. % \end{function} % -% \begin{function}{ -% \clist_push:Nn, \clist_push:NV, \clist_push:No, \clist_push:Nx, -% \clist_push:cn, \clist_push:cV, \clist_push:co, \clist_push:cx -% } +% \begin{function} +% { +% \clist_push:Nn, \clist_push:NV, \clist_push:No, \clist_push:Nx, +% \clist_push:cn, \clist_push:cV, \clist_push:co, \clist_push:cx +% } % \begin{syntax} % \cs{clist_push:Nn} \meta{comma list} \Arg{item} % \end{syntax} % Adds the \Arg{item} to the top of the \meta{comma list}. -% The assignment is restricted to the current \TeX{} group. +% The assignment is restricted to the current \TeX{} group. % \end{function} % -% \begin{function}{ -% \clist_gpush:Nn, \clist_gpush:NV, \clist_gpush:No, \clist_gpush:Nx, -% \clist_gpush:cn, \clist_gpush:cV, \clist_gpush:co, \clist_gpush:cx -% } +% \begin{function} +% { +% \clist_gpush:Nn, \clist_gpush:NV, \clist_gpush:No, \clist_gpush:Nx, +% \clist_gpush:cn, \clist_gpush:cV, \clist_gpush:co, \clist_gpush:cx +% } % \begin{syntax} % \cs{clist_gpush:Nn} \meta{comma list} \Arg{item} % \end{syntax} @@ -638,6 +609,36 @@ % \meta{sequence}. % \end{function} % +% \section{Deprecated comma-list functions} +% +% \begin{function}{\clist_trim_spaces:N, \clist_trim_spaces:c} +% \begin{syntax} +% \cs{clist_trim_spaces:N} \meta{comma list} +% \end{syntax} +% Removes leading and trailing spaces from each \meta{item} in the +% \meta{comma list} within the current \TeX{} group. This space-removal +% process takes place as described for \cs{tl_trim_spaces:n}. +% \end{function} +% +% \begin{function}{\clist_gtrim_spaces:N, \clist_gtrim_spaces:c} +% \begin{syntax} +% \cs{clist_gtrim_spaces:N} \meta{comma list} +% \end{syntax} +% Removes leading and trailing spaces from each \meta{item} in the +% \meta{comma list} globally. This space-removal +% process takes place as described for \cs{tl_trim_spaces:n}. +% \end{function} +% +% \begin{function}[rEXP]{\clist_trim_spaces:n} +% \begin{syntax} +% \cs{clist_trim_spaces:N} \meta{comma list} +% \end{syntax} +% Removes leading and trailing spaces from each \meta{item} in the +% \meta{comma list}, leaving the resulting modified list in the +% input stream. +% \end{function} +% +% % \end{documentation} % % \begin{implementation} @@ -658,6 +659,8 @@ %</package> % \end{macrocode} % +%^^A todo: provide users with \l_tmpa_clist and friends? +% % \begin{variable}{\l_clist_tmpa_tl, \l_clist_tmpb_tl} % Scratch space for various internal uses. % \begin{macrocode} @@ -765,6 +768,91 @@ % \end{macro} % \end{macro} % +% \subsection{Removing spaces around items} +% +% \begin{macro}[aux]{\clist_tmp:w} +% A temporary function for various purposes. +% \begin{macrocode} +\cs_new_protected:Npn \clist_tmp:w { } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}[int,EXP]{\clist_trim_spaces_generic:nw} +% \begin{macro}[aux]{\clist_trim_spaces_generic_aux:w} +% \begin{macro}[aux]{\clist_trim_spaces_generic_aux_ii:nn} +% Used as `\cs{clist_trim_spaces_generic:nw} \Arg{code} +% \cs{q_mark} \meta{item} |,|' (including the comma). +% This expands to the \meta{code}, followed by a brace group +% containing the \meta{item}, with leading and trailing spaces removed. +% The calling function is responsible for inserting \cs{q_mark} +% in front of the \meta{item}, as well as testing for the end of the list. +% See \cs{tl_trim_spaces:n} for a partial explanation of what +% is happening here. We changed \cs{tl_trim_spaces_aux_iv:w} +% into \cs{clist_trim_spaces_generic_aux:w} compared to +% \cs{tl_trim_spaces:n}, and dropped a \cs{q_mark}, which is +% already included in the argument |##2|. +% \begin{macrocode} +\cs_set:Npn \clist_tmp:w #1 + { + \cs_new:Npn \clist_trim_spaces_generic:nw ##1 ##2 , + { + \tl_trim_spaces_aux_i:w + ##2 + \q_nil + \q_mark #1 { } + \q_mark \tl_trim_spaces_aux_ii:w + \tl_trim_spaces_aux_iii:w + #1 \q_nil + \clist_trim_spaces_generic_aux:w + \q_stop + {##1} + } + } +\clist_tmp:w {~} +\cs_new:Npn \clist_trim_spaces_generic_aux:w #1 \q_nil #2 \q_stop + { \exp_args:No \clist_trim_spaces_generic_aux_ii:nn { \use_none:n #1 } } +\cs_new:Npn \clist_trim_spaces_generic_aux_ii:nn #1 #2 { #2 {#1} } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}[int,rEXP]{\clist_trim_spaces:n} +% \begin{macro}[aux]{\clist_trim_spaces_aux:n,\clist_trim_spaces_aux_ii:nn} +% The argument of \cs{clist_trim_spaces_aux:n} is initially empty, +% and later a comma, namely, as soon as we have added an item to the +% resulting list. The second auxiliary tests for the end of the list, +% and also prevents empty arguments from finding their way into the +% output. +% \begin{macrocode} +\cs_new:Npn \clist_trim_spaces:n #1 + { + \clist_trim_spaces_aux:n { } \q_mark #1 , + \q_recursion_tail, \q_recursion_stop + } +\cs_new:Npn \clist_trim_spaces_aux:n #1 + { + \clist_trim_spaces_generic:nw + { \clist_trim_spaces_aux_ii:nn {#1} } + } +\cs_new:Npn \clist_trim_spaces_aux_ii:nn #1 #2 + { + \quark_if_recursion_tail_stop:n {#2} + \tl_if_empty:nTF {#2} + { + \clist_trim_spaces_aux:n {#1} \q_mark + } + { + #1 \exp_not:n {#2} + \clist_trim_spaces_aux:n { , } \q_mark + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% % \subsection{Appending items to comma lists} % % \begin{macro} @@ -774,7 +862,7 @@ % \clist_put_left:cn, \clist_put_left:cV, % \clist_put_left:co, \clist_put_left:cx % } -% \UnitTested +%^^A \UnitTested % \begin{macro} % { % \clist_gput_left:Nn, \clist_gput_left:NV, @@ -782,19 +870,23 @@ % \clist_gput_left:cn, \clist_gput_left:cV, % \clist_gput_left:co, \clist_gput_left:cx % } -% \UnitTested +%^^A \UnitTested % Comma lists cannot hold empty values: there are therefore a couple % of sanity checks to avoid accumulating commas. % \begin{macrocode} \cs_new_protected_nopar:Npn \clist_put_left:Nn - { \clist_put_aux:NNnnNn \tl_set:Nn \tl_put_left:Nn { } , } + { \clist_put_aux:NNnnNn \tl_set_eq:NN \tl_put_left:Nx { } , } \cs_new_protected_nopar:Npn \clist_gput_left:Nn - { \clist_put_aux:NNnnNn \tl_gset:Nn \tl_gput_left:Nn { } , } + { \clist_put_aux:NNnnNn \tl_gset_eq:NN \tl_gput_left:Nx { } , } \cs_new_protected:Npn \clist_put_aux:NNnnNn #1#2#3#4#5#6 { + \tl_set:Nx \l_clist_tmpa_tl { \clist_trim_spaces:n {#6} } \clist_if_empty:NTF #5 - { #1 #5 {#6} } - { \tl_if_empty:nF {#6} { #2 #5 { #3 #6 #4 } } } + { #1 #5 \l_clist_tmpa_tl } + { + \tl_if_empty:NF \l_clist_tmpa_tl + { #2 #5 { #3 \exp_not:o \l_clist_tmpa_tl #4 } } + } } \cs_generate_variant:Nn \clist_put_left:Nn { NV , No , Nx } \cs_generate_variant:Nn \clist_put_left:Nn { c , cV , co , cx } @@ -811,6 +903,7 @@ % \clist_put_right:cn, \clist_put_right:cV, % \clist_put_right:co, \clist_put_right:cx % } +% \UnitTested % \begin{macro} % { % \clist_gput_right:Nn, \clist_gput_right:NV, @@ -818,12 +911,12 @@ % \clist_gput_right:cn, \clist_gput_right:cV, % \clist_gput_right:co, \clist_gput_right:cx % } -% The same for the right side. +% \UnitTested % \begin{macrocode} \cs_new_protected:Npn \clist_put_right:Nn - { \clist_put_aux:NNnnNn \tl_set:Nn \tl_put_right:Nn , { } } + { \clist_put_aux:NNnnNn \tl_set_eq:NN \tl_put_right:Nx , { } } \cs_new_protected_nopar:Npn \clist_gput_right:Nn - { \clist_put_aux:NNnnNn \tl_gset:Nn \tl_gput_right:Nn , { } } + { \clist_put_aux:NNnnNn \tl_gset_eq:NN \tl_gput_right:Nx , { } } \cs_generate_variant:Nn \clist_put_right:Nn { NV , No , Nx } \cs_generate_variant:Nn \clist_put_right:Nn { c , cV , co , cx } \cs_generate_variant:Nn \clist_gput_right:Nn { NV , No , Nx } @@ -859,6 +952,7 @@ % |#2| containing either the remainder of the list \emph{or} \cs{q_nil} % if there were insufficient items. That keeps the number of auxiliary % functions down. +%^^A broken for {a,{b,c}}, which unbraces {b,c}. % \begin{macrocode} \cs_new_protected_nopar:Npn \clist_pop:NN { \clist_pop_aux:NNN \tl_set:Nn } @@ -1010,47 +1104,9 @@ % \end{macro} % \end{macro} % \end{macro} -% -% \begin{macro}{\clist_trim_spaces:n} -% \begin{macro} -% { -% \clist_trim_spaces:N, \clist_trim_spaces:c, -% \clist_gtrim_spaces:N, \clist_gtrim_spaces:c -% } -% \begin{macro}{\clist_trim_spaces_aux_i:n} -% \begin{macro}{\clist_trim_spaces_aux_ii:n} -% Here, the basic plan is to use \cs{tl_trim_spaces:n} to do the work: -% the only issue is to make sure that the number of commas at the end of -% the process is correct. -% \begin{macrocode} -\cs_new:Npn \clist_trim_spaces:n #1 - { - \exp_args:Nf \clist_trim_spaces_aux_i:n - { \clist_map_function:nN {#1} \clist_trim_spaces_aux_ii:n } - } -\cs_new:Npn \clist_trim_spaces_aux_i:n #1 { \use_ii:nn #1 } -\cs_new:Npn \clist_trim_spaces_aux_ii:n #1 - { , \tl_trim_spaces:n {#1} } -\cs_new_protected:Npn \clist_trim_spaces:N #1 - { \tl_set:Nf #1 { \exp_args:No \clist_trim_spaces:n #1 } } -\cs_new_protected:Npn \clist_gtrim_spaces:N #1 - { \tl_gset:Nf #1 { \exp_args:No \clist_trim_spaces:n #1 } } -\cs_generate_variant:Nn \clist_trim_spaces:N { c } -\cs_generate_variant:Nn \clist_gtrim_spaces:N { c } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % -% \subsection{Comma list conditionals} % -% \begin{macro}[aux]{\clist_tmp:w} -% A temporary function for comparison. -% \begin{macrocode} -\cs_new_protected:Npn \clist_tmp:w { } -% \end{macrocode} -% \end{macro} +% \subsection{Comma list conditionals} % % \begin{macro}[pTF]{\clist_if_empty:N, \clist_if_empty:c} % \UnitTested @@ -1135,14 +1191,6 @@ , \q_recursion_tail , \q_recursion_stop } } -\cs_new:Npn \clist_map_function:nN #1#2 - { - \tl_if_empty:nF {#1} - { - \clist_map_function_aux:Nw #2 #1 - , \q_recursion_tail , \q_recursion_stop - } - } \cs_new:Npn \clist_map_function_aux:Nw #1#2 , { \quark_if_recursion_tail_stop:n {#2} @@ -1197,32 +1245,78 @@ % % \begin{macro}{\clist_map_variable:NNn, \clist_map_variable:cNn} % \UnitTested -% This is just a dedicated version of the inline mapping. +% \begin{macro}{\clist_map_variable:nNn} +% \begin{macro}[aux]{\clist_map_variable_aux:Nnw} +% This is similar to the \cs{clist_map_function:NN} code. +% The \texttt{n} version is done by first trimming all spaces, +% then using the \texttt{N} version. % \begin{macrocode} \cs_new_protected:Npn \clist_map_variable:NNn #1#2#3 { - \clist_map_inline:Nn #1 + \clist_if_empty:NF #1 { - \tl_set:Nn #2 {##1} - #3 + \exp_args:Nno \use:nn + { \clist_map_variable_aux:Nnw #2 {#3} } + #1 + , \q_recursion_tail , \q_recursion_stop } } -\cs_new_protected:Npn \clist_map_variable:nNn #1#2#3 +\cs_new_protected:Npn \clist_map_variable_aux:Nnw #1#2#3 , { - \clist_map_inline:nn {#1} - { - \tl_set:Nn #2 {##1} - #3 - } + \quark_if_recursion_tail_stop:n {#3} + \tl_set:Nn #1 {#3} + #2 + \clist_map_variable_aux:Nnw #1 {#2} + } +\cs_new_protected:Npn \clist_map_variable:nNn #1 + { + \tl_set:Nx \l_clist_tmpa_tl { \clist_trim_spaces:n {#1} } + \clist_map_variable:NNn \l_clist_tmpa_tl } \cs_generate_variant:Nn \clist_map_variable:NNn { c } % \end{macrocode} % \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\clist_map_aux_unbrace:Nw} +% Within mappings with explicit \texttt{n}-type comma lists, +% braces must be stripped after space trimming. Here, |#1| +% is the function to map, and |#2| the item to brace-strip. +% \begin{macrocode} +\cs_new:Npn \clist_map_aux_unbrace:Nw #1 #2, { #1 {#2} } +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clist_map_function:nN} +% \begin{macro}[aux]{\clist_map_function_n_aux:Nn} +% Space trimming is again based on \cs{clist_trim_spaces_generic:nw}. +% The auxiliary \cs{clist_map_function_n_aux:Nn} receives +% as arguments the function, and the result of removing leading +% and trailing spaces from the item which lies until the next comma. +% Empty items are ignored before brace stripping by +% \cs{clist_map_aux_unbrace:Nw}. +% \begin{macrocode} +\cs_new:Npn \clist_map_function:nN #1#2 + { + \clist_trim_spaces_generic:nw { \clist_map_function_n_aux:Nn #2 } + \q_mark #1, \q_recursion_tail, \q_recursion_stop + } +\cs_new:Npn \clist_map_function_n_aux:Nn #1 #2 + { + \quark_if_recursion_tail_stop:n {#2} + \tl_if_empty:nF {#2} { \clist_map_aux_unbrace:Nw #1 #2, } + \clist_trim_spaces_generic:nw { \clist_map_function_n_aux:Nn #1 } + \q_mark + } +% \end{macrocode} +% \end{macro} +% \end{macro} % % \begin{macro}{\clist_map_break:} % \UnitTested % \begin{macro}{\clist_map_break:n} -% Both are simple renaming. +% Both are simple renaming.^^A todo: fix \clist_map_break:n (cf. seq). % \begin{macrocode} \cs_new_eq:NN \clist_map_break: \use_none_delimit_by_q_recursion_stop:w \cs_new_eq:NN \clist_map_break:n \use_i_delimit_by_q_recursion_stop:nw @@ -1246,13 +1340,13 @@ { \clist_if_empty:NTF #1 { - \iow_term:x { Comma~list~\token_to_str:N #1 \c_space_tl is~empty } + \iow_term:x { Comma~list~\token_to_str:N #1~is~empty } \tl_show:n { } } { \iow_term:x { - Comma~list~\token_to_str:N #1 \c_space_tl + Comma~list~\token_to_str:N #1~ contains~the~items~(without~outer~braces): } \tl_set:Nx \l_clist_show_tl @@ -1281,6 +1375,7 @@ % Counting the items in a comma list is done using the same approach as for % other length functions: turn each entry into a \texttt{+1} then use % integer evaluation to actually do the mathematics. +%^^A todo: make a faster version avoiding \clist_map_function:nN? % \begin{macrocode} \cs_new:Npn \clist_length:N #1 { @@ -1347,11 +1442,13 @@ % \clist_set_from_seq:NN, \clist_set_from_seq:cN, % \clist_set_from_seq:Nc, \clist_set_from_seq:cc % } +% \UnitTested % \begin{macro} % { % \clist_gset_from_seq:NN, \clist_gset_from_seq:cN, % \clist_gset_from_seq:Nc, \clist_gset_from_seq:cc % } +% \UnitTested % Setting a comma list from a comma-separated list is done using a simple % mapping. We wrap each item with braces, \cs{exp_not:n}, and a comma. The % first comma must be removed, except in the case of an empty comma-list. @@ -1372,7 +1469,7 @@ \seq_if_empty:NTF #2 { \clist_gclear:N #1 } { - \seq_push_item_def:n { , \exp_not:n {##1} } + \seq_push_item_def:n { , \exp_not:n {{##1}} } \tl_gset:Nx #1 { \exp_after:wN \use_none:n \tex_romannumeral:D -`\0 #2 } \seq_pop_item_def: @@ -1391,6 +1488,7 @@ % Deprecated on 2011-05-27, for removal by 2011-08-31. % % \begin{macro}{\clist_top:NN, \clist_top:cN} +% \UnitTested % These are old stack functions. % \begin{macrocode} \cs_new_eq:NN \clist_top:NN \clist_get:NN @@ -1398,15 +1496,14 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\clist_remove_element:Nn} -% \begin{macro}{\clist_gremove_element:Nn} +% \begin{macro}{\clist_remove_element:Nn,\clist_gremove_element:Nn} +% \UnitTested % An older name for \cs{clist_remove_all:Nn}. % \begin{macrocode} \cs_new_eq:NN \clist_remove_element:Nn \clist_remove_all:Nn \cs_new_eq:NN \clist_gremove_element:Nn \clist_gremove_all:Nn % \end{macrocode} % \end{macro} -% \end{macro} % % \begin{macro}{\clist_display:N, \clist_display:c} % An older name for \cs{clist_show:N}. @@ -1415,6 +1512,26 @@ \cs_new_eq:NN \clist_display:c \clist_show:c % \end{macrocode} % \end{macro} +% +% Deprecated on 2011-09-05, for removal by 2012-09-04. +% +% \begin{macro} +% { +% \clist_trim_spaces:N, \clist_trim_spaces:c, +% \clist_gtrim_spaces:N, \clist_gtrim_spaces:c +% } +% Since clist items are now always stripped from their surrounding +% spaces, it is redundant to provide these functions. +% \begin{macrocode} +\cs_new_protected:Npn \clist_trim_spaces:N #1 + { \tl_set:Nx #1 { \exp_args:No \clist_trim_spaces:n #1 } } +\cs_new_protected:Npn \clist_gtrim_spaces:N #1 + { \tl_gset:Nx #1 { \exp_args:No \clist_trim_spaces:n #1 } } +\cs_generate_variant:Nn \clist_trim_spaces:N { c } +\cs_generate_variant:Nn \clist_gtrim_spaces:N { c } +% \end{macrocode} +% \end{macro} +% % % \begin{macrocode} %</initex|package> |