summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3clist.dtx
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2011-09-07 23:33:27 +0000
committerKarl Berry <karl@freefriends.org>2011-09-07 23:33:27 +0000
commitf1cddb2ae051713a3d0b9efa1251d8f85d8131fc (patch)
tree47b6a38de15329b2ffd3a196e7d85e7ad1e93032 /Master/texmf-dist/source/latex/l3kernel/l3clist.dtx
parentea06cd2704b8ed1c5278b20798ab9e3811e0ca4e (diff)
l3kernel 2729 (5sep11)
git-svn-id: svn://tug.org/texlive/trunk@23865 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3clist.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3clist.dtx517
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>