summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/expl3/l3clist.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/expl3/l3clist.dtx')
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3clist.dtx988
1 files changed, 551 insertions, 437 deletions
diff --git a/Master/texmf-dist/source/latex/expl3/l3clist.dtx b/Master/texmf-dist/source/latex/expl3/l3clist.dtx
index 0155c64f394..f875b7e0cbc 100644
--- a/Master/texmf-dist/source/latex/expl3/l3clist.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3clist.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3clist.dtx Copyright (C) 2005-2006 Frank Mittelbach, LaTeX3 project
+%% File: l3clist.dtx Copyright (C) 2005-2008 Frank Mittelbach, 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3clist.dtx 745 2008-08-03 18:50:46Z morten $
+\GetIdInfo$Id: l3clist.dtx 1362 2009-05-28 20:19:21Z joseph $
{L3 Experimental comma separated lists}
%\iffalse
%<*driver>
@@ -44,7 +44,7 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
\DocInput{\filename.\filenameext}
\end{document}
@@ -61,9 +61,7 @@
% \date{\filedate}
% \maketitle
%
-%
-%
-% \section{Comma lists}
+% \begin{documentation}
%
% \LaTeX3 implements a data type called `clist (comma-lists)'. These
% are special
@@ -75,8 +73,8 @@
% part of the value). It is also possible to map functions on such
% comma-lists so that they are executed for every item of the comma-list.
%
-% All functions that return items from a comma-list in some \m{tlp} assume
-% that the \m{tlp} is local. See remarks below if you need a global
+% All functions that return items from a comma-list in some \m{tl var.}~assume
+% that the \m{tl var.}~is local. See remarks below if you need a global
% returned value.
%
% The defined functions are not orthogonal in the sense that every
@@ -89,7 +87,7 @@
% like "\clist_push:Nn" which has the same effect. Maybe one should
% therefore remove the ``left'' functions totally.
%
-% \subsection{Functions}
+% \section{Functions for creating/initialising comma-lists}
%
% \begin{function}{%
% \clist_new:N |
@@ -113,117 +111,153 @@
% These functions locally or globally clear <comma-list>.
% \end{function}
%
+% \begin{function}{ \clist_clear_new:N |
+% \clist_clear_new:c |
+% \clist_gclear_new:N |
+% \clist_gclear_new:c }
+% \begin{syntax}
+% "\clist_clear_new:N" <comma-list>
+% \end{syntax}
+% These functions locally or globally clear <comma-list> if it exists or
+% otherwise allocates it.
+% \end{function}
+%
+% \begin{function}{ \clist_set_eq:NN |
+% \clist_set_eq:cN |
+% \clist_set_eq:Nc |
+% \clist_set_eq:cc }
+% \begin{syntax}
+% "\clist_set_eq:NN" <clist1> <clist2>
+% \end{syntax}
+% Function that locally makes <clist1> identical to <clist2>.
+% \end{function}
+%
+%
+% \begin{function}{ \clist_gset_eq:NN |
+% \clist_gset_eq:cN |
+% \clist_gset_eq:Nc |
+% \clist_gset_eq:cc }
+% \begin{syntax}
+% "\clist_gset_eq:NN" <clist1> <clist2>
+% \end{syntax}
+% Function that globally makes <clist1> identical to <clist2>.
+% \end{function}
+%
+% \section{Putting data in}
+%
% \begin{function}{%
% \clist_put_left:Nn |
+% \clist_put_left:NV |
% \clist_put_left:No |
% \clist_put_left:Nx |
% \clist_put_left:cn |
-% \clist_put_right:Nn |
-% \clist_put_right:No |
-% \clist_put_right:Nx |
+% \clist_put_left:co |
+% \clist_put_left:cV |
% }
% \begin{syntax}
% "\clist_put_left:Nn" <comma-list> <token list>
% \end{syntax}
% Locally appends <token list> as a single item to the left
-% or right of <comma-list>. <token list> might get expanded before
-% appending.
+% of <comma-list>. <token list> might get expanded before
+% appending according to the variant used.
% \end{function}
%
% \begin{function}{%
-% \clist_gput_left:Nn |
-% \clist_gput_right:Nn |
-% \clist_gput_right:No |
-% \clist_gput_right:cn |
-% \clist_gput_right:co |
-% \clist_gput_right:cc |
+% \clist_put_right:Nn |
+% \clist_put_right:No |
+% \clist_put_right:NV |
+% \clist_put_right:Nx |
+% \clist_put_right:cn |
+% \clist_put_right:co |
+% \clist_put_right:cV |
% }
% \begin{syntax}
-% "\clist_gput_left:Nn" <comma-list> <token list>
+% "\clist_put_right:Nn" <comma-list> <token list>
% \end{syntax}
-% Globally appends <token list> as a single item to the left
-% or right of <comma-list>.
+% Locally appends <token list> as a single item to the right
+% of <comma-list>. <token list> might get expanded before
+% appending according to the variant used.
% \end{function}
%
% \begin{function}{%
-% \clist_get:NN |
-% \clist_get:cN |
+% \clist_gput_left:Nn |
+% \clist_gput_left:NV |
+% \clist_gput_left:No |
+% \clist_gput_left:Nx |
+% \clist_gput_left:cn |
+% \clist_gput_left:cV |
+% \clist_gput_left:co |
% }
% \begin{syntax}
-% "\clist_get:NN" <comma-list> <tlp>
+% "\clist_gput_left:Nn" <comma-list> <token list>
% \end{syntax}
-% Functions that locally assign the left-most item of <comma-list> to the
-% token list pointer <tlp>. Item is not removed from <comma-list>! If you
-% need a global return value you need to code something like this:
-% \begin{quote}
-% "\clist_get:NN" <comma-list> "\l_tmpa_tlp" \\
-% "\tlp_gset_eq:NN" <global tlp> "\l_tmpa_tlp"
-% \end{quote}
-% But if this kind of construction is used often enough a separate
-% function should be provided.
+% Globally appends <token list> as a single item to the
+% right of <comma-list>.
% \end{function}
%
% \begin{function}{%
-% \clist_set_eq:NN
+% \clist_gput_right:Nn |
+% \clist_gput_right:NV |
+% \clist_gput_right:No |
+% \clist_gput_right:Nx |
+% \clist_gput_right:cn |
+% \clist_gput_right:cV |
+% \clist_gput_right:co |
% }
% \begin{syntax}
-% "\clist_set_eq:NN" <clist1> <clist2>
+% "\clist_gput_right:Nn" <comma-list> <token list>
% \end{syntax}
-% Function that locally makes <clist1> identical to <clist2>.
+% Globally appends <token list> as a single item to the
+% right of <comma-list>.
% \end{function}
%
+% \section{Getting data out}
%
-% \begin{function}{%
-% \clist_gset_eq:NN |
-% \clist_gset_eq:cN |
-% \clist_gset_eq:Nc |
-% \clist_gset_eq:cc
-% }
+% \begin{function}{ \clist_use:N |
+% \clist_use:c }
% \begin{syntax}
-% "\clist_gset_eq:NN" <clist1> <clist2>
+% "\clist_use:N" <clist>
% \end{syntax}
-% Function that globally makes <clist1> identical to <clist2>.
+% Function that inserts the <clist> into the processing stream. Mainly
+% useful if one knows what the <clist> contains, e.g., for displaying
+% the content of template parameters.
% \end{function}
%
-%
-% \begin{function}{%
-% \clist_concat:NNN |
-% \clist_gconcat:NNN |
-% \clist_gconcat:NNc |
-% \clist_gconcat:ccc |
-% }
+% \begin{function}{ \clist_show:N |
+% \clist_show:c }
% \begin{syntax}
-% "\clist_gconcat:NNN" <clist1> <clist2> <clist3>
+% "\clist_show:N" <clist>
% \end{syntax}
-% Function that concatenates <clist2> and <clist3> and globally assigns the
-% result to <clist1>.
+% Function that pauses the compilation and displays <clist> in the terminal
+% output and in the log file. (Usually used for diagnostic purposes.)
% \end{function}
%
-%
-% \begin{function}{%
-% \clist_remove_duplicates:N |
-% \clist_gremove_duplicates:N |
-% }
+% \begin{function}{ \clist_display:N |
+% \clist_display:c }
% \begin{syntax}
-% "\clist_gremove_duplicates:N" <clist>
+% "\clist_display:N" <clist>
% \end{syntax}
-% Function that removes any duplicate entries in <clist>.
+% As with "\clist_show:N" but pretty prints the output one line per element.
% \end{function}
%
-% \begin{function}{%
-% \clist_use:N |
-% \clist_use:c
-% }
+% \begin{function}{ \clist_get:NN |
+% \clist_get:cN }
% \begin{syntax}
-% "\clist_use:N" <clist>
+% "\clist_get:NN" <comma-list> <tl var.>
% \end{syntax}
-% Function that inserts the <clist> into the processing stream. Mainly
-% useful if one knows what the <clist> contains, e.g., for displaying
-% the content of template parameters.
+% Functions that locally assign the left-most item of <comma-list> to the
+% token list variable <tl var.>. Item is not removed from <comma-list>! If you
+% need a global return value you need to code something like this:
+% \begin{quote}
+% "\clist_get:NN" <comma-list> "\l_tmpa_tl" \\
+% "\tl_gset_eq:NN" <global tl var.> "\l_tmpa_tl"
+% \end{quote}
+% But if this kind of construction is used often enough a separate
+% function should be provided.
% \end{function}
%
%
-% \subsection{Mapping functions}
+% \section{Mapping functions}
%
%
% We provide three types of mapping functions, each with their own
@@ -253,7 +287,7 @@
% \clist_map_inline:nn |
% }
% \begin{syntax}
-% "\clist_map_inline:Nn" <comma-list> "{" <inline function> "}"
+% "\clist_map_inline:Nn" <comma-list> \Arg{inline function}
% \end{syntax}
% Applies <inline function> (which should be the direct coding for a
% function with one argument (i.e.\ use "##1" as the placeholder for
@@ -269,7 +303,7 @@
% \clist_map_variable:nNn |
% }
% \begin{syntax}
-% "\clist_map_variable:NNn" <comma-list> <temp-var> "{" <action> "}"
+% "\clist_map_variable:NNn" <comma-list> <temp-var> \Arg{action}
% \end{syntax}
% Assigns <temp-var> to each element in <clist> and then executes
% <action> which should contain <temp-var>. As the
@@ -281,16 +315,16 @@
% \end{function}
%
% \begin{function}{%
-% \clist_map_break:w |
+% \clist_map_break: |
% }
% \begin{syntax}
-% "\clist_map_break:w"
+% "\clist_map_break:"
% \end{syntax}
% For breaking out of a loop. To be used inside "TF" type functions as
% in the example below.
% \begin{verbatim}
-% \def_new:Npn \test_function:n #1 {
-% \int_compare:nNnTF {#1}> 3 {\clist_map_break:w}{``#1''}
+% \cs_new_nopar:Npn \test_function:n #1 {
+% \intexpr_compare:nTF {#1 > 3} {\clist_map_break:}{``#1''}
% }
% \clist_map_function:nN {1,2,3,4,5,6,7,8}\test_function:n
% \end{verbatim}
@@ -298,9 +332,10 @@
% \end{function}
%
%
-% \subsection{Predicates and conditionals}
+% \section{Predicates and conditionals}
%
-% \begin{function}{\clist_if_empty_p:N}
+% \begin{function}{ \clist_if_empty_p:N |
+% \clist_if_empty_p:c }
% \begin{syntax}
% "\clist_if_empty_p:N" <comma-list>
% \end{syntax}
@@ -308,99 +343,87 @@
% contain any tokens.
% \end{function}
%
-% \begin{function}{%
-% \clist_if_empty:NTF |
-% \clist_if_empty:cTF |
-% \clist_if_empty:NF |
-% \clist_if_empty:cF |
-% }
+% \begin{function}{ \clist_if_empty:N / (TF)(EXP) |
+% \clist_if_empty:c / (TF)(EXP)}
% \begin{syntax}
-% "\clist_if_empty:NTF" <comma-list> "{" <true code> "}{" <false code> "}"
+% "\clist_if_empty:NTF" <comma-list> \Arg{true code} \Arg{false code}
% \end{syntax}
% Set of conditionals that test whether or not a particular <comma-list>
% is empty and if so executes either <true code> or <false code>.
% \end{function}
%
-% \begin{function}{%
-% \clist_if_eq:NNTF |
-% }
+% \begin{function}{ \clist_if_eq_p:NN / (EXP) |
+% \clist_if_eq_p:cN / (EXP) |
+% \clist_if_eq_p:Nc / (EXP) |
+% \clist_if_eq_p:cc / (EXP) }
% \begin{syntax}
-% "\clist_if_eq:NNTF" <comma-list1> <comma-list2> "{" <true code>
-% "}{" <false code> "}"
+% "\clist_if_eq_p:N" <comma-list1> <comma-list2>
+% \end{syntax}
+% This predicate returns `true' if the two comma lists are identical.
+% \end{function}
+%
+% \begin{function}{ \clist_if_eq:NN / (TF)(EXP) |
+% \clist_if_eq:cN / (TF)(EXP) |
+% \clist_if_eq:Nc / (TF)(EXP) |
+% \clist_if_eq:cc / (TF)(EXP) }
+% \begin{syntax}
+% "\clist_if_eq:NNTF" <comma-list1> <comma-list2> \Arg{true code} \Arg{false code}
% \end{syntax}
% Check if <comma-list1> and <comma-list2> are equal and execute
% either <true code> or <false code> accordingly.
% \end{function}
%
-% \begin{function}{%
-% \clist_if_in:NnTF |
-% \clist_if_in:NoTF |
-% \clist_if_in:cnTF |
-% \clist_if_in:coTF |
-% }
+% \begin{function}{ \clist_if_in:Nn / (TF) |
+% \clist_if_in:NV / (TF) |
+% \clist_if_in:No / (TF) |
+% \clist_if_in:cn / (TF) |
+% \clist_if_in:cV / (TF) |
+% \clist_if_in:co / (TF) }
% \begin{syntax}
-% "\clist_if_in:NnTF" <comma-list> "{" <item> "}{" <true code> "}{"
-% <false code> "}"
+% "\clist_if_in:NnTF" <comma-list> \Arg{item} \Arg{true code} \Arg{false code}
% \end{syntax}
% Function that tests if <item> is in <comma-list>. Depending on the result
% either <true code> or <false code> is executed.
% \end{function}
%
-% \subsection{Internal functions}
+% \section{Higher level functions}
%
-% \begin{function}{\clist_if_empty_err:N}
+% \begin{function}{ \clist_concat:NNN |
+% \clist_concat:ccc |
+% \clist_gconcat:NNN |
+% \clist_gconcat:ccc }
% \begin{syntax}
-% "\clist_if_empty_err:N" <comma-list>
+% "\clist_gconcat:NNN" <clist1> <clist2> <clist3>
% \end{syntax}
-% Signals an \LaTeX3 error if <comma-list> is empty.
+% Function that concatenates <clist2> and <clist3> and locally or globally
+% assigns the result to <clist1>.
% \end{function}
%
-% \begin{function}{\clist_pop_aux:nnNN}
+%
+% \begin{function}{ \clist_remove_duplicates:N |
+% \clist_gremove_duplicates:N }
% \begin{syntax}
-% "\clist_pop_aux:nnNN" <assign1> <assign2> <comma-list> <tlp>
+% "\clist_gremove_duplicates:N" <clist>
% \end{syntax}
-% Function that assigns the left-most item of <comma-list> to <tlp> using
-% <assign1> and assigns the tail to <comma-list> using <assign2>. This
-% function could be used to implement a global return function.
+% Function that removes any duplicate entries in <clist>.
% \end{function}
-%
-% \begin{function}{%
-% \clist_get_aux:w |
-% \clist_pop_aux:w |
-% \clist_pop_auxi:w |
-% \clist_put_aux:NNnnNn |
-% }
-% \begin{syntax}\end{syntax}
-% Functions used to implement put and get operations. They are not for
-% meant for direct use.
+%
+% \begin{function}{
+% \clist_remove_element:Nn |
+% \clist_gremove_element:Nn
+%}
+% \begin{syntax}
+% "\clist_gremove_element:Nn" <clist> <element>
+% \end{syntax}
+% Function that removes <element> from <clist>, if present.
+% \begin{texnote}
+% This is similar in concept to \cs{@removeelement}, except that the
+% syntax is clearer and the initial and final lists have the same
+% name automatically.
+% \end{texnote}
% \end{function}
%
-%
-%
-% \begin{function}{%
-% \clist_map_function_aux:Nw |
-% \clist_map_inline_aux:Nw |
-% \clist_map_variable_aux:Nnw |
-% }
-% \begin{syntax}\end{syntax}
-% Internal helper functions for the <clist> mapping functions.
-% \end{function}
-%
-%
-% \begin{function}{%
-% \clist_concat_aux:NNNN |
-% \clist_remove_duplicates_aux:NN |
-% \clist_remove_duplicates_aux:n |
-% \l_clist_remove_duplicates_clist |
-% }
-% \begin{syntax}\end{syntax}
-% Functions that help concatenate <clist>s and remove duplicate
-% elements from a <clist>.
-% \end{function}
-%
-%
-%
-% \subsection{Comma list Stacks}
+% \section{Functions for `comma-list stacks'}
%
% Special comma-lists in \LaTeX3 are `stacks' with their usual operations
% of `push', `pop', and `top'. They are internally implemented as
@@ -409,14 +432,16 @@
%
% \begin{function}{%
% \clist_push:Nn |
+% \clist_push:NV |
% \clist_push:No |
% \clist_push:cn |
% \clist_gpush:Nn |
+% \clist_gpush:NV |
% \clist_gpush:No |
% \clist_gpush:cn |
% }
% \begin{syntax}
-% "\clist_push:Nn" <stack> "{" <token list> "}"
+% "\clist_push:Nn" <stack> \Arg{token list}
% \end{syntax}
% Locally or globally pushes <token list> as a single item onto the
% <stack>. <token list> might get expanded before the operation.
@@ -429,10 +454,10 @@
% \clist_gpop:cN |
% }
% \begin{syntax}
-% "\clist_pop:NN" <stack> <tlp>
+% "\clist_pop:NN" <stack> <tl var.>
% \end{syntax}
% Functions that assign the top item of <stack> to the token
-% list pointer <tlp> and removes it from <stack>!
+% list variable <tl var.> and removes it from <stack>!
% \end{function}
%
% \begin{function}{%
@@ -440,38 +465,65 @@
% \clist_top:cN |
% }
% \begin{syntax}
-% "\clist_top:NN" <stack> <tlp>
+% "\clist_top:NN" <stack> <tl var.>
% \end{syntax}
% Functions that locally assign the top item of <stack> to the token
-% list pointer <tlp>. Item is not removed from <stack>!
+% list variable <tl var.>. Item is not removed from <stack>!
% \end{function}
%
-% \StopEventually{}
+% \section{Internal functions}
%
-% Use "clist" functions.
+% \begin{function}{\clist_if_empty_err:N}
+% \begin{syntax}
+% "\clist_if_empty_err:N" <comma-list>
+% \end{syntax}
+% Signals an \LaTeX3 error if <comma-list> is empty.
+% \end{function}
%
+% \begin{function}{\clist_pop_aux:nnNN}
+% \begin{syntax}
+% "\clist_pop_aux:nnNN" <assign1> <assign2> <comma-list> <tl var.>
+% \end{syntax}
+% Function that assigns the left-most item of <comma-list> to <tl var.> using
+% <assign1> and assigns the tail to <comma-list> using <assign2>. This
+% function could be used to implement a global return function.
+% \end{function}
%
-% \subsection {The Implementation}
+% \begin{function}{%
+% \clist_get_aux:w |
+% \clist_pop_aux:w |
+% \clist_pop_auxi:w |
+% \clist_put_aux:NNnnNn |
+% }
+% \begin{syntax}\end{syntax}
+% Functions used to implement put and get operations. They are not for
+% meant for direct use.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3clist} implementation}
%
% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
%<*package>
-\NeedsTeXFormat{LaTeX2e}
-%<!check>\RequirePackage{l3prg,l3quark}
-%<check>\RequirePackage{l3chk}
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
%</package>
%<*initex|package>
% \end{macrocode}
%
+% \subsection{Allocation and initialisation}
%
% \begin{macro}{\clist_new:N}
% \begin{macro}{\clist_new:c}
% Comma-Lists are implemented using token lists.
% \begin{macrocode}
-\def_new:Npn \clist_new:N #1{\tlp_new:Nn #1{}}
-\def_new:Npn \clist_new:c {\exp_args:Nc \clist_new:N}
+\cs_new_eq:NN \clist_new:N \tl_new:N
+\cs_generate_variant:Nn \clist_new:N {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -482,10 +534,10 @@
% \begin{macro}{\clist_gclear:c}
% Clearing a comma-list is the same as clearing a token list.
% \begin{macrocode}
-\let_new:NN \clist_clear:N \tlp_clear:N
-\let_new:NN \clist_clear:c \tlp_clear:c
-\let_new:NN \clist_gclear:N \tlp_gclear:N
-\let_new:NN \clist_gclear:c \tlp_gclear:c
+\cs_new_eq:NN \clist_clear:N \tl_clear:N
+\cs_generate_variant:Nn \clist_clear:N {c}
+\cs_new_eq:NN \clist_gclear:N \tl_gclear:N
+\cs_generate_variant:Nn \clist_gclear:N {c}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -493,24 +545,32 @@
% \end{macro}
%
%
-% \begin{macro}{\clist_set_eq:NN}
-% We can set one \meta{clist} equal to another.
+% \begin{macro}{\clist_clear_new:N}
+% \begin{macro}{\clist_clear_new:c}
+% \begin{macro}{\clist_gclear_new:N}
+% \begin{macro}{\clist_gclear_new:c}
+% Clearing a comma-list is the same as clearing a token list.
% \begin{macrocode}
-\let_new:NN \clist_set_eq:NN \let:NN
+\cs_new_eq:NN \clist_clear_new:N \tl_clear_new:N
+\cs_generate_variant:Nn \clist_clear_new:N {c}
+\cs_new_eq:NN \clist_gclear_new:N \tl_gclear_new:N
+\cs_generate_variant:Nn \clist_gclear_new:N {c}
% \end{macrocode}
% \end{macro}
-%
+% \end{macro}
+% \end{macro}
+% \end{macro}
%
% \begin{macro}{\clist_set_eq:NN}
% \begin{macro}{\clist_set_eq:cN}
% \begin{macro}{\clist_set_eq:Nc}
% \begin{macro}{\clist_set_eq:cc}
-% An of course globally which seems to be needed far more often.
+% We can set one \meta{clist} equal to another.
% \begin{macrocode}
-\let_new:NN \clist_gset_eq:NN \glet:NN
-\def_new:Npn \clist_gset_eq:cN {\exp_args:Nc \clist_gset_eq:NN}
-\def_new:Npn \clist_gset_eq:Nc {\exp_args:NNc \clist_gset_eq:NN}
-\def_new:Npn \clist_gset_eq:cc {\exp_args:Ncc \clist_gset_eq:NN}
+\cs_new_eq:NN \clist_set_eq:NN \cs_set_eq:NN
+\cs_new_eq:NN \clist_set_eq:cN \cs_set_eq:cN
+\cs_new_eq:NN \clist_set_eq:Nc \cs_set_eq:Nc
+\cs_new_eq:NN \clist_set_eq:cc \cs_set_eq:cc
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -518,33 +578,30 @@
% \end{macro}
%
%
-% \begin{macro}{\clist_if_empty_p:N}
-% A predicate which evaluates to |\c_true| iff the comma-list is empty.
-% \begin{macrocode}
-\let_new:NN \clist_if_empty_p:N \tlp_if_empty_p:N
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\clist_if_empty:NTF}
-% \begin{macro}{\clist_if_empty:NT}
-% \begin{macro}{\clist_if_empty:NF}
-% \begin{macro}{\clist_if_empty:cTF}
-% \begin{macro}{\clist_if_empty:cT}
-% \begin{macro}{\clist_if_empty:cF}
-% |\clist_if_empty:NTF|\m{clist}\m{true~case}\m{false~case} will check
-% whether the \m{clist} is empty and then select one of the other
-% arguments. |\clist_if_empty:cTF| turns its first argument into a
-% control comma-list to get the name of the comma-list.
+% \begin{macro}{\clist_gset_eq:NN}
+% \begin{macro}{\clist_gset_eq:cN}
+% \begin{macro}{\clist_gset_eq:Nc}
+% \begin{macro}{\clist_gset_eq:cc}
+% An of course globally which seems to be needed far more often.
% \begin{macrocode}
-\def_test_function_new:npn {clist_if_empty:N}#1{\if_meaning:NN#1\c_empty_tlp}
-\def_new:Npn \clist_if_empty:cTF {\exp_args:Nc\clist_if_empty:NTF}
-\def_new:Npn \clist_if_empty:cT {\exp_args:Nc\clist_if_empty:NT}
-\def_new:Npn \clist_if_empty:cF {\exp_args:Nc\clist_if_empty:NF}
+\cs_new_eq:NN \clist_gset_eq:NN \cs_gset_eq:NN
+\cs_new_eq:NN \clist_gset_eq:cN \cs_gset_eq:cN
+\cs_new_eq:NN \clist_gset_eq:Nc \cs_gset_eq:Nc
+\cs_new_eq:NN \clist_gset_eq:cc \cs_gset_eq:cc
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
+%
+% \subsection{Predicates and conditionals}
+%
+% \begin{macro}{\clist_if_empty_p:N,\clist_if_empty_p:c}
+% \begin{macro}[TF]{\clist_if_empty:N,\clist_if_empty:c}
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \clist_if_empty:N \tl_if_empty:N {p,TF,T,F}
+\prg_new_eq_conditional:NNn \clist_if_empty:c \tl_if_empty:c {p,TF,T,F}
+% \end{macrocode}
% \end{macro}
% \end{macro}
%
@@ -552,154 +609,257 @@
% \begin{macro}{\clist_if_empty_err:N}
% Signals an error if the comma-list is empty.
% \begin{macrocode}
-\def_new:Npn \clist_if_empty_err:N #1{
- \if_meaning:NN#1\c_empty_tlp
- \tlp_clear:N \l_testa_tlp % catch prefixes
- \err_latex_bug:x{Empty~comma-list~`\token_to_string:N#1'}
- \fi:}
+\cs_new_nopar:Npn \clist_if_empty_err:N #1 {
+ \if_meaning:w #1 \c_empty_tl
+ \tl_clear:N \l_testa_tl % catch prefixes
+ \msg_kernel_bug:x {Empty~comma-list~`\token_to_str:N #1'}
+ \fi:
+}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\clist_if_eq:NNTF}
-% As comma lists are token list pointers internally this is just an
-% alias.
+% \begin{macro}{\clist_if_eq_p:NN,\clist_if_eq_p:Nc,
+% \clist_if_eq_p:cN,\clist_if_eq_p:cc}
+% \begin{macro}[TF]{\clist_if_eq:NN,\clist_if_eq:cN,
+% \clist_if_eq:Nc,\clist_if_eq:cc}
+% Returns |\c_true| iff the two comma-lists are equal.
% \begin{macrocode}
-\let_new:NN \clist_if_eq:NNTF \tlp_if_eq:NNTF
+\prg_new_eq_conditional:NNn \clist_if_eq:NN \tl_if_eq:NN {p,TF,T,F}
+\prg_new_eq_conditional:NNn \clist_if_eq:cN \tl_if_eq:cN {p,TF,T,F}
+\prg_new_eq_conditional:NNn \clist_if_eq:Nc \tl_if_eq:Nc {p,TF,T,F}
+\prg_new_eq_conditional:NNn \clist_if_eq:cc \tl_if_eq:cc {p,TF,T,F}
% \end{macrocode}
-% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[TF]{\clist_if_in:Nn}
+% \begin{macro}[TF]{\clist_if_in:NV,\clist_if_in:No,\clist_if_in:cn,
+% \clist_if_in:cV,\clist_if_in:co}
+% |\clist_if_in:NnTF| \m{clist}\m{item} \m{true~case} \m{false~case}
+% will check whether \m{item} is in \m{clist} and then either execute
+% the \m{true~case} or the \m{false~case}. \m{true~case} and
+% \m{false~case} may contain incomplete |\if_charcode:w|
+% statements.
+% \begin{macrocode}
+\prg_new_conditional:Nnn \clist_if_in:Nn {TF,T,F} {
+ \cs_set:Npn \clist_tmp:w ##1,#2,##2##3 \q_stop {
+ \if_meaning:w \q_no_value ##2
+ \prg_return_false: \else: \prg_return_true: \fi:
+ }
+ \exp_last_unbraced:NNo \clist_tmp:w , #1 , #2 , \q_no_value \q_stop
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_generate_variant:Nn \clist_if_in:NnTF {NV,No,cn,cV,co}
+\cs_generate_variant:Nn \clist_if_in:NnT {NV,No,cn,cV,co}
+\cs_generate_variant:Nn \clist_if_in:NnF {NV,No,cn,cV,co}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{Retrieving data}
+%
+% \begin{macro}{\clist_use:N}
+% \begin{macro}{\clist_use:c}
+% Using a \meta{clist} is just executing it but
+% if \m{clist} equals |\scan_stop:| it is probably stemming
+% from a |\cs:w ... \cs_end:| that was created by mistake somewhere.
+% \begin{macrocode}
+\cs_new_nopar:Npn \clist_use:N #1 {
+ \if_meaning:w #1 \scan_stop:
+ \msg_kernel_bug:x {
+ Comma~list~ `\token_to_str:N #1'~ has~ an~ erroneous~ structure!}
+ \else:
+ \exp_after:wN #1
+ \fi:
+}
+\cs_generate_variant:Nn \clist_use:N {c}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
%
% \begin{macro}{\clist_get:NN}
% \begin{macro}{\clist_get:cN}
-% |\clist_get:NN |\zz{comma-list}\zz{cmd} defines \zz{cmd} to be the
-% left-most element of \zz{comma-list}.
+% \begin{macro}{\clist_get_aux:w}
+% |\clist_get:NN |\meta{comma-list}\meta{cmd} defines \meta{cmd} to be the
+% left-most element of \meta{comma-list}.
% \begin{macrocode}
-\def_new:Npn \clist_get:NN #1{
+\cs_new_nopar:Npn \clist_get:NN #1 {
\clist_if_empty_err:N #1
- \exp_after:NN\clist_get_aux:w #1,\q_stop}
+ \exp_after:wN \clist_get_aux:w #1,\q_stop
+}
% \end{macrocode}
% \begin{macrocode}
-\def_new:Npn \clist_get_aux:w #1,#2\q_stop #3{\tlp_set:Nn #3{#1}}
+\cs_new:Npn \clist_get_aux:w #1,#2\q_stop #3 { \tl_set:Nn #3{#1} }
% \end{macrocode}
% \begin{macrocode}
-\def_new:Npn \clist_get:cN {\exp_args:Nc \clist_get:NN}
+\cs_generate_variant:Nn \clist_get:NN {cN}
% \end{macrocode}
% \end{macro}
% \end{macro}
+% \end{macro}
%
% \begin{macro}{\clist_pop_aux:nnNN}
% \begin{macro}{\clist_pop_aux:w}
% \begin{macro}{\clist_pop_auxi:w}
-% |\clist_pop_aux:nnNN| \zz{def$\sb1$} \zz{def$\sb2$} \zz{comma-list}
-% \zz{cmd} assigns the left-most element of \zz{comma-list} to
-% \zz{cmd} using \zz{def$\sb2$}, and assigns the tail of
-% \zz{comma-list} to \zz{comma-list} using \zz{def$\sb1$}.
+% |\clist_pop_aux:nnNN| \meta{def$\sb1$} \meta{def$\sb2$} \meta{comma-list}
+% \meta{cmd} assigns the left-most element of \meta{comma-list} to
+% \meta{cmd} using \meta{def$\sb2$}, and assigns the tail of
+% \meta{comma-list} to \meta{comma-list} using \meta{def$\sb1$}.
% \begin{macrocode}
-\def_new:Npn \clist_pop_aux:nnNN #1#2#3{
+\cs_new:Npn \clist_pop_aux:nnNN #1#2#3 {
\clist_if_empty_err:N #3
- \exp_after:NN\clist_pop_aux:w #3,\q_nil\q_stop #1#2#3}
+ \exp_after:wN \clist_pop_aux:w #3,\q_nil\q_stop #1#2#3
+}
% \end{macrocode}
+% After the assignmnets below, if there was only one element in the original
+% clist, it now contains only |\q_nil|.
% \begin{macrocode}
-\def_new:Npn \clist_pop_aux:w #1,#2\q_stop #3#4#5#6{
- #4#6{#1}
- #3#5{#2}
+\cs_new:Npn \clist_pop_aux:w #1,#2\q_stop #3#4#5#6 {
+ #4 #6 {#1}
+ #3 #5 {#2}
+ \quark_if_nil:NTF #5 { #3 #5 {} }{ \clist_pop_auxi:w #2 #3#5 }
+}
% \end{macrocode}
-% If there was only one element in the original clist, it now contains
-% only |\q_nil|.
% \begin{macrocode}
- \quark_if_nil:NTF #5
- { #3#5{} }
- { \clist_pop_auxi:w #2 #3#5 }
-}
+\cs_new:Npn \clist_pop_auxi:w #1,\q_nil #2#3 { #2#3{#1} }
% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\clist_show:N}
+% \begin{macro}{\clist_show:c}
% \begin{macrocode}
-\def_new:Npn\clist_pop_auxi:w #1,\q_nil #2#3 {#2#3{#1}}
+\cs_new_eq:NN \clist_show:N \tl_show:N
+\cs_new_eq:NN \clist_show:c \tl_show:c
% \end{macrocode}
% \end{macro}
% \end{macro}
+%
+% \begin{macro}{\clist_display:N}
+% \begin{macro}{\clist_display:c}
+% \begin{macrocode}
+\cs_new_nopar:Npn \clist_display:N #1 {
+ \iow_term:x { Comma-list~\token_to_str:N #1~contains~
+ the~elements~(without~outer~braces): }
+ \toks_clear:N \l_tmpa_toks
+ \clist_map_inline:Nn #1 {
+ \toks_if_empty:NF \l_tmpa_toks {
+ \toks_put_right:Nx \l_tmpa_toks {^^J>~}
+ }
+ \toks_put_right:Nx \l_tmpa_toks {
+ \iow_space: \iow_char:N \{ \exp_not:n {##1} \iow_char:N \}
+ }
+ }
+ \toks_show:N \l_tmpa_toks
+}
+\cs_generate_variant:Nn \clist_display:N {c}
+% \end{macrocode}
+% \end{macro}
% \end{macro}
%
+% \subsection{Storing data}
+%
% \begin{macro}{\clist_put_aux:NNnnNn}
% The generic put function.
-% \begin{macrocode}
-\def_new:Npn \clist_put_aux:NNnnNn #1#2#3#4#5#6{
-% \end{macrocode}
% When adding we have to distinguish between an empty \meta{clist}
% and one that contains at least one item (otherwise we accumulate
% commas).
-% \begin{macrocode}
- \clist_if_empty:NTF#5 {#1 #5{#6}}
-% \end{macrocode}
+%
% MH says: Perhaps we should make sure that empty arguments don't get
% on the stack as that is probably a mistake. That's what I've
-% implemented here. Since |\tlist_if_empty:nF| is expandable prefixes
+% implemented here. Since |\tl_if_empty:nF| is expandable prefixes
% are still allowed.
% \begin{macrocode}
- { \tlist_if_empty:nF {#6}{ #2 #5{#3#6#4} } }
+\cs_new:Npn \clist_put_aux:NNnnNn #1#2#3#4#5#6 {
+ \clist_if_empty:NTF #5 { #1 #5 {#6} } {
+ \tl_if_empty:nF {#6} { #2 #5{#3#6#4} }
+ }
}
% \end{macrocode}
% \end{macro}
+%
% \begin{macro}{\clist_put_left:Nn}
+% \begin{macro}{\clist_put_left:NV}
% \begin{macro}{\clist_put_left:No}
% \begin{macro}{\clist_put_left:Nx}
% \begin{macro}{\clist_put_left:cn}
+% \begin{macro}{\clist_put_left:cV}
+% \begin{macro}{\clist_put_left:co}
% The operations for adding to the left.
% \begin{macrocode}
-\def_new:Npn \clist_put_left:Nn {
- \clist_put_aux:NNnnNn \tlp_set:Nn \tlp_put_left:Nn {} ,
+\cs_new_nopar:Npn \clist_put_left:Nn {
+ \clist_put_aux:NNnnNn \tl_set:Nn \tl_put_left:Nn {} ,
}
-\def_new:Npn \clist_put_left:cn {\exp_args:Nc \clist_put_left:Nn}
-\def_new:Npn \clist_put_left:No {\exp_args:NNo\clist_put_left:Nn}
-\def_new:Npn \clist_put_left:Nx {\exp_args:Nnx\clist_put_left:Nn}
+\cs_generate_variant:Nn \clist_put_left:Nn {NV,No,Nx,cn,cV,co}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
% \begin{macro}{\clist_gput_left:Nn}
+% \begin{macro}{\clist_gput_left:NV}
+% \begin{macro}{\clist_gput_left:No}
+% \begin{macro}{\clist_gput_left:Nx}
+% \begin{macro}{\clist_gput_left:cn}
+% \begin{macro}{\clist_gput_left:cV}
+% \begin{macro}{\clist_gput_left:co}
% Global versions.
% \begin{macrocode}
-\def_new:Npn \clist_gput_left:Nn {
- \clist_put_aux:NNnnNn \tlp_gset:Nn \tlp_gput_left:Nn {} ,
+\cs_new_nopar:Npn \clist_gput_left:Nn {
+ \clist_put_aux:NNnnNn \tl_gset:Nn \tl_gput_left:Nn {} ,
}
+\cs_generate_variant:Nn \clist_gput_left:Nn {NV,No,Nx,cn,cV,co}
% \end{macrocode}
% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
%
% \begin{macro}{\clist_put_right:Nn}
-% \begin{macro}{\clist_put_right:cn}
+% \begin{macro}{\clist_put_right:NV}
% \begin{macro}{\clist_put_right:No}
% \begin{macro}{\clist_put_right:Nx}
+% \begin{macro}{\clist_put_right:cn}
+% \begin{macro}{\clist_put_right:cV}
+% \begin{macro}{\clist_put_right:co}
% Adding something to the right side is almost the same.
% \begin{macrocode}
-\def_new:Npn \clist_put_right:Nn {
- \clist_put_aux:NNnnNn \tlp_set:Nn \tlp_put_right:Nn , {}
+\cs_new_nopar:Npn \clist_put_right:Nn {
+ \clist_put_aux:NNnnNn \tl_set:Nn \tl_put_right:Nn , {}
}
-\def_new:Npn \clist_put_right:cn {\exp_args:Nc \clist_put_right:Nn}
-\def_new:Npn \clist_put_right:No {\exp_args:Nno\clist_put_right:Nn}
-\def_new:Npn \clist_put_right:Nx {\exp_args:Nnx\clist_put_right:Nn}
+\cs_generate_variant:Nn \clist_put_right:Nn {NV,No,Nx,cn,cV,co}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
%
% \begin{macro}{\clist_gput_right:Nn}
+% \begin{macro}{\clist_gput_right:NV}
% \begin{macro}{\clist_gput_right:No}
+% \begin{macro}{\clist_gput_right:Nx}
% \begin{macro}{\clist_gput_right:cn}
+% \begin{macro}{\clist_gput_right:cV}
% \begin{macro}{\clist_gput_right:co}
-% \begin{macro}{\clist_gput_right:cc}
-% \begin{macro}{\clist_gput_right:NC}
-% An here the global variants.
+% And here the global variants.
% \begin{macrocode}
-\def_new:Npn \clist_gput_right:Nn {
- \clist_put_aux:NNnnNn \tlp_gset:Nn \tlp_gput_right:Nn , {}
+\cs_new_nopar:Npn \clist_gput_right:Nn {
+ \clist_put_aux:NNnnNn \tl_gset:Nn \tl_gput_right:Nn , {}
}
-\def_new:Npn \clist_gput_right:No {\exp_args:NNo \clist_gput_right:Nn}
-\def_new:Npn \clist_gput_right:cn {\exp_args:Nc \clist_gput_right:Nn}
-\def_new:Npn \clist_gput_right:co {\exp_args:Nco \clist_gput_right:Nn}
-\def_new:Npn \clist_gput_right:cc {\exp_args:Ncc \clist_gput_right:Nn}
-% \end{macrocode}
-% \begin{macrocode}
-\def_new:Npn \clist_gput_right:NC {\exp_args:NNC \clist_gput_right:Nn}
+\cs_generate_variant:Nn \clist_gput_right:Nn {NV,No,Nx,cn,cV,co}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -707,36 +867,42 @@
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{Mapping}
%
-% \begin{macro}{\clist_map_function:nN}
-% \begin{macro}{\clist_map_function:cN}
% \begin{macro}{\clist_map_function:NN}
-% |\clist_map_function:NN| \zz{comma-list} \zz{cmd} applies \zz{cmd} to each
-% element of \zz{comma-list}, from left to right.
+% \begin{macro}{\clist_map_function:cN}
+% \begin{macro}{\clist_map_function:nN}
+% |\clist_map_function:NN| \meta{comma-list} \meta{cmd} applies \meta{cmd} to each
+% element of \meta{comma-list}, from left to right.
% \begin{macrocode}
-\def_new:Npn \clist_map_function:NN #1#2{
- \clist_if_empty:NF #1
- {
- \exp_after:NN \clist_map_function_aux:Nw
- \exp_after:NN #2 #1 , \q_recursion_tail , \q_recursion_stop
+\cs_new_nopar:Npn \clist_map_function:NN #1#2 {
+ \clist_if_empty:NF #1 {
+ \exp_after:wN \clist_map_function_aux:Nw
+ \exp_after:wN #2 #1 , \q_recursion_tail , \q_recursion_stop
}
}
-\def_new:Npn \clist_map_function:cN{\exp_args:Nc\clist_map_function:NN}
-\def_new:Npn \clist_map_function:nN #1#2{
- \tlist_if_blank:nF {#1}
- { \clist_map_function_aux:Nw #2 #1 , \q_recursion_tail , \q_recursion_stop }
+\cs_generate_variant:Nn \clist_map_function:NN {cN}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_new:Npn \clist_map_function:nN #1#2 {
+ \tl_if_blank:nF {#1} {
+ \clist_map_function_aux:Nw #2 #1 , \q_recursion_tail , \q_recursion_stop
+ }
}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\clist_map_function_aux:Nw}
+% \begin{macro}[aux]{\clist_map_function_aux:Nw}
% The general loop. Tests if we hit the first stop marker and exits if
% we did. If we didn't, place the function "#1" in front of the
% element "#2", which is surrounded by braces.
% \begin{macrocode}
-\def_long_new:Npn \clist_map_function_aux:Nw #1#2,{
+\cs_new:Npn \clist_map_function_aux:Nw #1#2,{
\quark_if_recursion_tail_stop:n{#2}
#1{#2}
\clist_map_function_aux:Nw #1
@@ -744,11 +910,11 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\clist_map_break:w}
+% \begin{macro}{\clist_map_break:}
% The break statement is easy. Same as in other modules, gobble
% everything up to the special recursion stop marker.
% \begin{macrocode}
-\let_new:NN \clist_map_break:w \use_none_delimit_by_q_recursion_stop:w
+\cs_new_eq:NN \clist_map_break: \use_none_delimit_by_q_recursion_stop:w
% \end{macrocode}
% \end{macro}
%
@@ -769,31 +935,28 @@
% every operation globally.
% \begin{macrocode}
\int_new:N \g_clist_inline_level_int
-\def_long_new:Npn \clist_map_inline:Nn #1#2{
- \clist_if_empty:NF #1
- {
+\cs_new:Npn \clist_map_inline:Nn #1#2 {
+ \clist_if_empty:NF #1 {
\int_gincr:N \g_clist_inline_level_int
- \gdef_long:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
+ \cs_gset:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
##1{#2}
% \end{macrocode}
-% Recall that the |E| in |\exp_args:NcE| means `single token expanded
-% once and no braces added'. It is a lot more efficient to carry over
+% It is a lot more efficient to carry over
% the special function rather than constructing the same csname over
% and over again, so we just do it once. We reuse
% |\clist_map_function_aux:Nw| for the actual loop.
% \begin{macrocode}
- \exp_args:NcE \clist_map_function_aux:Nw
+ \exp_last_unbraced:NcV \clist_map_function_aux:Nw
{clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
#1 , \q_recursion_tail , \q_recursion_stop
\int_gdecr:N \g_clist_inline_level_int
}
}
-\def_new:Npn \clist_map_inline:cn{\exp_args:Nc\clist_map_inline:Nn}
-\def_long_new:Npn \clist_map_inline:nn #1#2{
- \tlist_if_empty:nF {#1}
- {
+\cs_generate_variant:Nn \clist_map_inline:Nn {c}
+\cs_new:Npn \clist_map_inline:nn #1#2 {
+ \tl_if_empty:nF {#1} {
\int_gincr:N \g_clist_inline_level_int
- \gdef_long:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
+ \cs_gset:cpn {clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
##1{#2}
\exp_args:Nc \clist_map_function_aux:Nw
{clist_map_inline_ \int_use:N \g_clist_inline_level_int :n}
@@ -810,76 +973,78 @@
% \begin{macro}{\clist_map_variable:nNn}
% \begin{macro}{\clist_map_variable:NNn}
% \begin{macro}{\clist_map_variable:cNn}
-% |\clist_map:NNn| \zz{comma-list} \zz{temp} \zz{action} assigns
-% \zz{temp} to each element and executes \zz{action}.
+% |\clist_map_variable:NNn| \meta{comma-list} \meta{temp} \meta{action} assigns
+% \meta{temp} to each element and executes \meta{action}.
% \begin{macrocode}
-\def_new:Npn \clist_map_variable:nNn #1#2#3{
- \tlist_if_empty:nF{#1}
- {
+\cs_new:Npn \clist_map_variable:nNn #1#2#3 {
+ \tl_if_empty:nF {#1} {
\clist_map_variable_aux:Nnw #2 {#3} #1
, \q_recursion_tail , \q_recursion_stop
}
}
-\def_new:Npn \clist_map_variable:NNn {\exp_args:No \clist_map_variable:nNn}
-\def_new:Npn \clist_map_variable:cNn {\exp_args:Nc \clist_map_variable:NNn}
+% \end{macrocode}
+% Something for v/V
+% \begin{macrocode}
+\cs_new_nopar:Npn \clist_map_variable:NNn {\exp_args:No \clist_map_variable:nNn}
+\cs_generate_variant:Nn\clist_map_variable:NNn {cNn}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\clist_map_variable_aux:Nnw}
+% \begin{macro}[aux]{\clist_map_variable_aux:Nnw}
% The general loop. Assign the temp variable |#1| to the current item
% |#3| and then check if that's the stop marker. If it is, break the
% loop. If not, execute the action |#2| and continue.
% \begin{macrocode}
-\def_new:Npn \clist_map_variable_aux:Nnw #1#2#3,{
- \def:Npn #1{#3}
+\cs_new:Npn \clist_map_variable_aux:Nnw #1#2#3,{
+ \cs_set_nopar:Npn #1{#3}
\quark_if_recursion_tail_stop:N #1
#2 \clist_map_variable_aux:Nnw #1{#2}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\clist_concat_aux:NNNN}
-% \begin{macro}{\clist_concat:NNN}
-% \begin{macro}{\clist_gconcat:NNN}
-% \begin{macro}{\clist_gconcat:NNc}
-% \begin{macro}{\clist_gconcat:ccc}
+% \subsection{Higher level functions}
+%
+% \begin{macro}[aux]{\clist_concat_aux:NNNN}
+% \begin{macro}{\clist_concat:NNN,\clist_concat:ccc}
+% \begin{macro}{\clist_gconcat:NNN,\clist_gconcat:ccc}
% |\clist_gconcat:NNN| \m{clist~1} \m{clist~2} \m{clist~3} will globally
% assign \m{clist~1} the concatenation of \m{clist~2} and
% \m{clist~3}.
+%
+% Again the situation is a bit more complicated because of the use
+% of commas between items, so if either list is empty we have to avoid
+% adding a comma.
% \begin{macrocode}
-\def_new:Npn \clist_concat_aux:NNNN #1#2#3#4{
+\cs_new_nopar:Npn \clist_concat_aux:NNNN #1#2#3#4 {
\toks_set:No \l_tmpa_toks {#3}
\toks_set:No \l_tmpb_toks {#4}
#1 #2 {
\toks_use:N \l_tmpa_toks
-% \end{macrocode}
-% Again the situation is a bit more complicated because of the use
-% of commas between items, so if either list is empty we have to avoid
-% adding a comma.
-% \begin{macrocode}
- \toks_if_empty:NF \l_tmpa_toks {\toks_if_empty:NF \l_tmpb_toks ,}
+ \toks_if_empty:NF \l_tmpa_toks { \toks_if_empty:NF \l_tmpb_toks , }
\toks_use:N \l_tmpb_toks
}
}
-\def_new:Npn \clist_concat:NNN {\clist_concat_aux:NNNN \tlp_set:Nx}
-\def_new:Npn \clist_gconcat:NNN {\clist_concat_aux:NNNN \tlp_gset:Nx}
+\cs_new_nopar:Npn \clist_concat:NNN { \clist_concat_aux:NNNN \tl_set:Nx }
+\cs_new_nopar:Npn \clist_gconcat:NNN { \clist_concat_aux:NNNN \tl_gset:Nx }
+\cs_generate_variant:Nn \clist_concat:NNN {ccc}
+\cs_generate_variant:Nn \clist_gconcat:NNN {ccc}
% \end{macrocode}
-% And the usual versions.
-% \begin{macrocode}
-\def_new:Npn \clist_gconcat:NNc{\exp_args:Nnnc\clist_gconcat:NNN}
-\def_new:Npn \clist_gconcat:ccc{\exp_args:Nccc\clist_gconcat:NNN}
-% \end{macrocode}
-% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
-%
+%
+% \begin{macro}[aux]{\l_clist_remove_clist}
+% A common scratch space for the removal routines.
+% \begin{macrocode}
+\clist_new:N \l_clist_remove_clist
+% \end{macrocode}
+% \end{macro}
%
-% \begin{macro}{\clist_remove_duplicates_aux:NN}
-% \begin{macro}{\clist_remove_duplicates_aux:n}
+% \begin{macro}[aux]{\clist_remove_duplicates_aux:NN}
+% \begin{macro}[aux]{\clist_remove_duplicates_aux:n}
% \begin{macro}{\clist_remove_duplicates:N}
% \begin{macro}{\clist_gremove_duplicates:N}
% Removing duplicate entries in a \meta{clist} is fairly straight
@@ -887,23 +1052,24 @@
% from left to right. For each element check if the element is
% already present in the list.
% \begin{macrocode}
-\def:Npn \clist_remove_duplicates_aux:NN #1#2 {
- \clist_clear:N \l_clist_remove_duplicates_clist
+\cs_new:Nn \clist_remove_duplicates_aux:NN {
+ \clist_clear:N \l_clist_remove_clist
\clist_map_function:NN #2 \clist_remove_duplicates_aux:n
- #1 #2 \l_clist_remove_duplicates_clist
+ #1 #2 \l_clist_remove_clist
}
-\def:Npn \clist_remove_duplicates_aux:n #1 {
- \clist_if_in:NnTF \l_clist_remove_duplicates_clist {#1} {}
- {\clist_put_right:Nn \l_clist_remove_duplicates_clist {#1}}
+\cs_new:Nn \clist_remove_duplicates_aux:n {
+ \clist_if_in:NnF \l_clist_remove_clist {#1} {
+ \clist_put_right:Nn \l_clist_remove_clist {#1}
+ }
}
% \end{macrocode}
% The high level functions are just for telling if it should be a
% local or global setting.
% \begin{macrocode}
-\def_new:Npn \clist_remove_duplicates:N {
+\cs_new_nopar:Npn \clist_remove_duplicates:N {
\clist_remove_duplicates_aux:NN \clist_set_eq:NN
}
-\def_new:Npn \clist_gremove_duplicates:N {
+\cs_new_nopar:Npn \clist_gremove_duplicates:N {
\clist_remove_duplicates_aux:NN \clist_gset_eq:NN
}
% \end{macrocode}
@@ -911,67 +1077,38 @@
% \end{macro}
% \end{macro}
% \end{macro}
-%
-% \begin{macro}{\l_clist_remove_duplicates_clist}
-% \begin{macrocode}
-\clist_new:N \l_clist_remove_duplicates_clist
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\clist_use:N}
-% \begin{macro}{\clist_use:c}
-% Using a \meta{clist} is just executing it but\dots
-% \begin{macrocode}
-\def_new:Npn \clist_use:N #1 {
- \if_meaning:NN #1 \scan_stop:
-% \end{macrocode}
-% \dots\ if \m{clist} equals |\scan_stop:| it is probably stemming
-% from a |\cs:w ... \cs_end:| that was created by mistake somewhere.
+%
+%\begin{macro}{\clist_remove_element:Nn}
+%\begin{macro}{\clist_gremove_element:Nn}
+%\begin{macro}[aux]{\clist_remove_element_aux:NNn}
+%\begin{macro}[aux]{\clist_remove_element_aux:n}
+% The same general idea is used for removing elements: the parent
+% functions just set things up for the internal ones.
% \begin{macrocode}
- \err_latex_bug:x {Comma~list~ `\token_to_string:N #1'~
- has~ an~ erroneous~ structure!}
- \else:
- \exp_after:NN #1
- \fi:
+\cs_new_nopar:Npn \clist_remove_element:Nn {
+ \clist_remove_element_aux:NNn \clist_set_eq:NN
}
-\def_new:Npn \clist_use:c {\exp_args:Nc \clist_use:N}
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\clist_if_in:NnTF}
-% \begin{macro}{\clist_if_in:NoTF}
-% \begin{macro}{\clist_if_in:cnTF}
-% \begin{macro}{\clist_if_in:coTF}
-% |\clist_if_in:NnTF| \m{clist}\m{item} \m{true~case} \m{false~case}
-% will check whether \m{item} is in \m{clist} and then either execute
-% the \m{true~case} or the \m{false~case}. \m{true~case} and
-% \m{false~case} may contain incomplete |\if_charcode:w|
-% statements.
-% \begin{macrocode}
-\def_new:Npn \clist_if_in:NnTF #1#2{
- \def:Npn \tmp:w ##1 ,#2, ##2##3\q_stop{
- \if_meaning:NN\q_no_value##2
- \exp_after:NN\use_arg_ii:nn
- \else:
- \exp_after:NN\use_arg_i:nn
- \fi:
+\cs_new_nopar:Npn \clist_gremove_element:Nn {
+ \clist_remove_element_aux:NNn \clist_gset_eq:NN
+}
+\cs_new:Nn \clist_remove_element_aux:NNn {
+ \clist_clear:N \l_clist_remove_clist
+ \cs_set:Nn \clist_remove_element_aux:n {
+ \tl_if_eq:nnF {#3} {##1} {
+ \clist_put_right:Nn \l_clist_remove_clist {##1}
+ }
}
- \exp_after:NN \tmp:w
- \exp_after:NN , #1, #2, \q_no_value \q_stop
+ \clist_map_function:NN #2 \clist_remove_element_aux:n
+ #1 #2 \l_clist_remove_clist
}
-\def_new:Npn \clist_if_in:NoTF {\exp_args:NNo \clist_if_in:NnTF}
-\def_new:Npn \clist_if_in:coTF {\exp_args:Nco \clist_if_in:NnTF}
-\def_new:Npn \clist_if_in:cnTF {\exp_args:Nc \clist_if_in:NnTF}
+\cs_new:Nn \clist_remove_element_aux:n { }
% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
%
-%
-% \subsubsection{Stack operations}
+% \subsection{Stack operations}
%
% We build stacks from comma-lists, but here we put the
% specific functions together.
@@ -979,6 +1116,7 @@
%
% \begin{macro}{\clist_push:Nn}
% \begin{macro}{\clist_push:No}
+% \begin{macro}{\clist_push:NV}
% \begin{macro}{\clist_push:cn}
% \begin{macro}{\clist_pop:NN}
% \begin{macro}{\clist_pop:cN}
@@ -986,22 +1124,25 @@
% `push' and `pop'. In most cases they are nothing more then new
% names for old functions.
% \begin{macrocode}
-\let_new:NN \clist_push:Nn \clist_put_left:Nn
-\let_new:NN \clist_push:No \clist_put_left:No
-\let_new:NN \clist_push:cn \clist_put_left:cn
-\def_new:Npn \clist_pop:NN {\clist_pop_aux:nnNN \tlp_set:Nn \tlp_set:Nn}
-\def_new:Npn \clist_pop:cN {\exp_args:Nc \clist_pop:NN}
+\cs_new_eq:NN \clist_push:Nn \clist_put_left:Nn
+\cs_new_eq:NN \clist_push:NV \clist_put_left:NV
+\cs_new_eq:NN \clist_push:No \clist_put_left:No
+\cs_new_eq:NN \clist_push:cn \clist_put_left:cn
+\cs_new_nopar:Npn \clist_pop:NN {\clist_pop_aux:nnNN \tl_set:Nn \tl_set:Nn}
+\cs_generate_variant:Nn \clist_pop:NN {cN}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
%
%
%
% \begin{macro}{\clist_gpush:Nn}
% \begin{macro}{\clist_gpush:No}
+% \begin{macro}{\clist_gpush:NV}
% \begin{macro}{\clist_gpush:cn}
% \begin{macro}{\clist_gpop:NN}
% \begin{macro}{\clist_gpop:cN}
@@ -1010,12 +1151,17 @@
% here more often. In case of |\clist_gpop:NN| the value is
% nevertheless returned locally.
% \begin{macrocode}
-\let_new:NN \clist_gpush:Nn \clist_gput_left:Nn
-\def_new:Npn \clist_gpush:No {\exp_args:NNo \clist_gpush:Nn}
-\def_new:Npn \clist_gpush:cn {\exp_args:Nc \clist_gpush:Nn}
-\def_new:Npn \clist_gpop:NN {\clist_pop_aux:nnNN \tlp_gset:Nn \tlp_set:Nn}
-\def_new:Npn \clist_gpop:cN {\exp_args:Nc \clist_gpop:NN}
+\cs_new_eq:NN \clist_gpush:Nn \clist_gput_left:Nn
+\cs_new_eq:NN \clist_gpush:NV \clist_gput_left:NV
+\cs_new_eq:NN \clist_gpush:No \clist_gput_left:No
+\cs_generate_variant:Nn \clist_gpush:Nn {cn}
% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_nopar:Npn \clist_gpop:NN {\clist_pop_aux:nnNN \tl_gset:Nn \tl_set:Nn}
+\cs_generate_variant:Nn \clist_gpop:NN {cN}
+% \end{macrocode}
+% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
@@ -1028,58 +1174,26 @@
% Looking at the top element of the stack without removing it is
% done with this operation.
% \begin{macrocode}
-\let_new:NN \clist_top:NN \clist_get:NN
-\let_new:NN \clist_top:cN \clist_get:cN
+\cs_new_eq:NN \clist_top:NN \clist_get:NN
+\cs_new_eq:NN \clist_top:cN \clist_get:cN
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-%
-% Show token usage:
% \begin{macrocode}
%</initex|package>
+% \end{macrocode}
+%
+% Show token usage:
+% \begin{macrocode}
%<*showmemory>
%\showMemUsage
%</showmemory>
% \end{macrocode}
%
+% \end{implementation}
+% \PrintIndex
%
%
-% \endinput
-%
-% $Log$
-% Revision 1.16 2006/07/30 15:45:46 morten
-% Made \clist_map_inline:Nn and variants nestable plus a little cleanup.
-%
-% Revision 1.15 2006/03/20 18:26:34 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.14 2006/01/04 01:32:09 morten
-% Minor changes to code to reflect changes in l3tlp.
-%
-% Revision 1.13 2005/12/27 09:52:51 morten
-% Minor changes plus changed RCS information retrieval
-%
-% Revision 1.12 2005/10/27 23:14:49 morten
-% Improved loops.
-%
-% Revision 1.11 2005/04/12 16:45:22 morten
-% Enabled put operations. Added function that removes duplicate entries (mostly for
-% use after concatenating to clists)
-%
-% Revision 1.10 2005/04/12 13:22:13 morten
-% Mostly cosmetic changes. \clist_gconcat:NNN reprogrammed using "proper" methods, \clist_put_right:Nn likewise.
-%
-% Revision 1.9 2005/03/22 23:26:54 morten
-% Fix error message
-%
-% Revision 1.8 2005/03/16 22:36:43 braams
-% Added the tweaks necessary to be able to load with initex
-%
-% Revision 1.7 2005/03/11 21:36:36 braams
-% Fixed the use of RCS information;
-% Fixed a few documentation typos; added \StopEventually
-% Replaced \ifx by \if_meaning:NN, \c_if_empty_toks became \c_empty_toks
-% but needs further work according to Morten
%
+% \endinput