diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3seq.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/l3kernel/l3seq.dtx | 1411 |
1 files changed, 564 insertions, 847 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx index d8dd80c75ed..d4a3688a068 100644 --- a/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx +++ b/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx @@ -35,8 +35,8 @@ % %<*driver|package> \RequirePackage{l3names} -\GetIdInfo$Id: l3seq.dtx 3490 2012-03-04 01:00:53Z bruno $ - {L3 Experimental sequences and stacks} +\GetIdInfo$Id: l3seq.dtx 3986 2012-07-15 19:23:51Z joseph $ + {L3 Sequences and stacks} %</driver|package> %<*driver> \documentclass[full]{l3doc} @@ -109,14 +109,17 @@ % \seq_gset_eq:NN, \seq_gset_eq:cN, \seq_gset_eq:Nc, \seq_gset_eq:cc % } % \begin{syntax} -% \cs{seq_set_eq:NN} \meta{sequence1} \meta{sequence2} +% \cs{seq_set_eq:NN} \meta{sequence_1} \meta{sequence_2} % \end{syntax} -% Sets the content of \meta{sequence1} equal to that of -% \meta{sequence2}. +% Sets the content of \meta{sequence_1} equal to that of +% \meta{sequence_2}. % \end{function} % -% \begin{function}[added = 2011-08-15, updated = 2011-12-07] -% {\seq_set_split:Nnn, \seq_gset_split:Nnn} +% \begin{function}[added = 2011-08-15, updated = 2012-07-02] +% { +% \seq_set_split:Nnn , \seq_set_split:NnV , +% \seq_gset_split:Nnn, \seq_gset_split:NnV +% } % \begin{syntax} % \cs{seq_set_split:Nnn} \meta{sequence} \Arg{delimiter} \Arg{token list} % \end{syntax} @@ -137,11 +140,11 @@ % \begin{function} % {\seq_concat:NNN, \seq_concat:ccc, \seq_gconcat:NNN, \seq_gconcat:ccc} % \begin{syntax} -% \cs{seq_concat:NNN} \meta{sequence1} \meta{sequence2} \meta{sequence3} +% \cs{seq_concat:NNN} \meta{sequence_1} \meta{sequence_2} \meta{sequence_3} % \end{syntax} -% Concatenates the content of \meta{sequence2} and \meta{sequence3} -% together and saves the result in \meta{sequence1}. The items in -% \meta{sequence2} will be placed at the left side of the new sequence. +% Concatenates the content of \meta{sequence_2} and \meta{sequence_3} +% together and saves the result in \meta{sequence_1}. The items in +% \meta{sequence_2} will be placed at the left side of the new sequence. % \end{function} % % \begin{function}[EXP, pTF, added=2012-03-03] @@ -197,27 +200,29 @@ % \meta{token list variable} used with \cs{tl_set:Nn} and \emph{never} % \cs{tl_gset:Nn}. % -% \begin{function}{\seq_get_left:NN, \seq_get_left:cN} +% \begin{function}[updated = 2012-05-14]{\seq_get_left:NN, \seq_get_left:cN} % \begin{syntax} % \cs{seq_get_left:NN} \meta{sequence} \meta{token list variable} % \end{syntax} % Stores the left-most item from a \meta{sequence} in the % \meta{token list variable} without removing it from the % \meta{sequence}. The \meta{token list variable} is assigned locally. -% If \meta{sequence} is empty an error will be raised. +% If \meta{sequence} is empty the \meta{token list variable} will +% contain the special marker \cs{q_no_value}. % \end{function} % -% \begin{function}{\seq_get_right:NN, \seq_get_right:cN} +% \begin{function}[updated = 2012-05-19]{\seq_get_right:NN, \seq_get_right:cN} % \begin{syntax} % \cs{seq_get_right:NN} \meta{sequence} \meta{token list variable} % \end{syntax} % Stores the right-most item from a \meta{sequence} in the % \meta{token list variable} without removing it from the % \meta{sequence}. The \meta{token list variable} is assigned locally. -% If \meta{sequence} is empty an error will be raised. +% If \meta{sequence} is empty the \meta{token list variable} will +% contain the special marker \cs{q_no_value}. % \end{function} % -% \begin{function}{\seq_pop_left:NN, \seq_pop_left:cN} +% \begin{function}[updated = 2012-05-14]{\seq_pop_left:NN, \seq_pop_left:cN} % \begin{syntax} % \cs{seq_pop_left:NN} \meta{sequence} \meta{token list variable} % \end{syntax} @@ -225,10 +230,11 @@ % \meta{token list variable}, \emph{i.e.}~removes the item from the % sequence and stores it in the \meta{token list variable}. % Both of the variables are assigned locally. If \meta{sequence} is -% empty an error will be raised. +% empty the \meta{token list variable} will +% contain the special marker \cs{q_no_value}. % \end{function} % -% \begin{function}{\seq_gpop_left:NN, \seq_gpop_left:cN} +% \begin{function}[updated = 2012-05-14]{\seq_gpop_left:NN, \seq_gpop_left:cN} % \begin{syntax} % \cs{seq_gpop_left:NN} \meta{sequence} \meta{token list variable} % \end{syntax} @@ -237,10 +243,11 @@ % sequence and stores it in the \meta{token list variable}. % The \meta{sequence} is modified globally, while the assignment of % the \meta{token list variable} is local. -% If \meta{sequence} is empty an error will be raised. +% If \meta{sequence} is empty the \meta{token list variable} will +% contain the special marker \cs{q_no_value}. % \end{function} % -% \begin{function}{\seq_pop_right:NN, \seq_pop_right:cN} +% \begin{function}[updated = 2012-05-19]{\seq_pop_right:NN, \seq_pop_right:cN} % \begin{syntax} % \cs{seq_pop_right:NN} \meta{sequence} \meta{token list variable} % \end{syntax} @@ -248,10 +255,11 @@ % \meta{token list variable}, \emph{i.e.}~removes the item from the % sequence and stores it in in the \meta{token list variable}. % Both of the variables are assigned locally. If \meta{sequence} is -% empty an error will be raised. +% empty the \meta{token list variable} will +% contain the special marker \cs{q_no_value}. % \end{function} % -% \begin{function}{\seq_gpop_right:NN, \seq_gpop_right:cN} +% \begin{function}[updated = 2012-05-19]{\seq_gpop_right:NN, \seq_gpop_right:cN} % \begin{syntax} % \cs{seq_gpop_right:NN} \meta{sequence} \meta{token list variable} % \end{syntax} @@ -260,7 +268,104 @@ % sequence and stores it in the \meta{token list variable}. % The \meta{sequence} is modified globally, while the assignment of % the \meta{token list variable} is local. -% If \meta{sequence} is empty an error will be raised. +% If \meta{sequence} is empty the \meta{token list variable} will +% contain the special marker \cs{q_no_value}. +% \end{function} +% +% \section{Recovering values from sequences with branching} +% +% The functions in this section combine tests for non-empty sequences +% with recovery of an item from the sequence. They offer increased readability +% and performance over separate testing and recovery phases. +% +% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19] +% {\seq_get_left:NN, \seq_get_left:cN} +% \begin{syntax} +% \cs{seq_get_left:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code} +% \end{syntax} +% If the \meta{sequence} is empty, leaves the \meta{false code} in the +% input stream. The value of the \meta{token list variable} is +% not defined in this case and should not be relied upon. If the +% \meta{sequence} is non-empty, stores the left-most item from a +% \meta{sequence} +% in the \meta{token list variable} without removing it from a +% \meta{sequence}. +% The \meta{token list variable} is assigned locally. +% \end{function} +% +% \begin{function}[TF, added = 2012-05-19] +% {\seq_get_right:NN, \seq_get_right:cN} +% \begin{syntax} +% \cs{seq_get_right:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code} +% \end{syntax} +% If the \meta{sequence} is empty, leaves the \meta{false code} in the +% input stream. The value of the \meta{token list variable} is +% not defined in this case and should not be relied upon. If the +% \meta{sequence} is non-empty, stores the right-most item from a +% \meta{sequence} +% in the \meta{token list variable} without removing it from a +% \meta{sequence}. +% The \meta{token list variable} is assigned locally. +% \end{function} +% +% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19] +% {\seq_pop_left:NN, \seq_pop_left:cN} +% \begin{syntax} +% \cs{seq_pop_left:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code} +% \end{syntax} +% If the \meta{sequence} is empty, leaves the \meta{false code} in the +% input stream. The value of the \meta{token list variable} is +% not defined in this case and should not be relied upon. If the +% \meta{sequence} is non-empty, pops the left-most item from a +% \meta{sequence} +% in the \meta{token list variable}, \emph{i.e.}~removes the item from a +% \meta{sequence}. +% Both the \meta{sequence} and the \meta{token list variable} are assigned +% locally. +% \end{function} +% +% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19] +% {\seq_gpop_left:NN, \seq_gpop_left:cN} +% \begin{syntax} +% \cs{seq_gpop_left:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code} +% \end{syntax} +% If the \meta{sequence} is empty, leaves the \meta{false code} in the +% input stream. The value of the \meta{token list variable} is +% not defined in this case and should not be relied upon. If the +% \meta{sequence} is non-empty, pops the left-most item from a \meta{sequence} +% in the \meta{token list variable}, \emph{i.e.}~removes the item from a +% \meta{sequence}. +% The \meta{sequence} is modified globally, while the \meta{token list variable} +% is assigned locally. +% \end{function} +% +% \begin{function}[TF, added = 2012-05-19] +% {\seq_pop_right:NN, \seq_pop_right:cN} +% \begin{syntax} +% \cs{seq_pop_right:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code} +% \end{syntax} +% If the \meta{sequence} is empty, leaves the \meta{false code} in the +% input stream. The value of the \meta{token list variable} is +% not defined in this case and should not be relied upon. If the +% \meta{sequence} is non-empty, pops the right-most item from a \meta{sequence} +% in the \meta{token list variable}, \emph{i.e.}~removes the item from a +% \meta{sequence}. +% Both the \meta{sequence} and the \meta{token list variable} are assigned +% locally. +% \end{function} +% +% \begin{function}[TF, added = 2012-05-19] +% {\seq_gpop_right:NN, \seq_gpop_right:cN} +% \begin{syntax} +% \cs{seq_gpop_right:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code} +% \end{syntax} +% If the \meta{sequence} is empty, leaves the \meta{false code} in the +% input stream. The value of the \meta{token list variable} is +% not defined in this case and should not be relied upon. If the +% \meta{sequence} is non-empty, pops the right-most item from a \meta{sequence} +% in the \meta{token list variable}, \emph{i.e.}~removes the item from a +% \meta{sequence}. The \meta{sequence} is modified globally, while the +% \meta{token list variable} is assigned locally. % \end{function} % % \section{Modifying sequences} @@ -324,7 +429,8 @@ % % \section{Mapping to sequences} % -% \begin{function}[rEXP]{\seq_map_function:NN, \seq_map_function:cN} +% \begin{function}[rEXP, updated = 2012-06-29] +% {\seq_map_function:NN, \seq_map_function:cN} % \begin{syntax} % \cs{seq_map_function:NN} \meta{sequence} \meta{function} % \end{syntax} @@ -336,7 +442,8 @@ % One mapping may be nested inside another. % \end{function} % -% \begin{function}{\seq_map_inline:Nn, \seq_map_inline:cn} +% \begin{function}[updated = 2012-06-29] +% {\seq_map_inline:Nn, \seq_map_inline:cn} % \begin{syntax} % \cs{seq_map_inline:Nn} \meta{sequence} \Arg{inline function} % \end{syntax} @@ -347,10 +454,11 @@ % are returned from left to right. % \end{function} % -% \begin{function}{ -% \seq_map_variable:NNn, \seq_map_variable:Ncn, -% \seq_map_variable:cNn, \seq_map_variable:ccn -% } +% \begin{function}[updated = 2012-06-29] +% { +% \seq_map_variable:NNn, \seq_map_variable:Ncn, +% \seq_map_variable:cNn, \seq_map_variable:ccn +% } % \begin{syntax} % \cs{seq_map_variable:NNn} \meta{sequence} \meta{tl~var.} \Arg{function using tl~var.} % \end{syntax} @@ -362,7 +470,7 @@ % are returned from left to right. % \end{function} % -% \begin{function}[rEXP]{\seq_map_break:} +% \begin{function}[rEXP, updated = 2012-06-29]{\seq_map_break:} % \begin{syntax} % \cs{seq_map_break:} % \end{syntax} @@ -383,13 +491,13 @@ % level \TeX{} errors. % \begin{texnote} % When the mapping is broken, additional tokens may be inserted by the -% internal macro \cs{prg_break_point:n} before further items are taken +% internal macro \cs{__prg_break_point:Nn} before further items are taken % from the input stream. This will depend on the design of the mapping % function. % \end{texnote} % \end{function} % -% \begin{function}[rEXP]{\seq_map_break:n} +% \begin{function}[rEXP, updated = 2012-06-29]{\seq_map_break:n} % \begin{syntax} % \cs{seq_map_break:n} \Arg{tokens} % \end{syntax} @@ -411,12 +519,22 @@ % level \TeX{} errors. % \begin{texnote} % When the mapping is broken, additional tokens may be inserted by the -% internal macro \cs{prg_break_point:n} before the \meta{tokens} are +% internal macro \cs{__prg_break_point:Nn} before the \meta{tokens} are % inserted into the input stream. % This will depend on the design of the mapping function. % \end{texnote} % \end{function} % +% \begin{function}[EXP, added = 2012-07-13]{\seq_count:N, \seq_count:c} +% \begin{syntax} +% \cs{seq_count:N} \meta{sequence} +% \end{syntax} +% Leaves the number of items in the \meta{sequence} in the input +% stream as an \meta{integer denotation}. The total number of items +% in a \meta{sequence} will include those which are empty and duplicates, +% \emph{i.e.}~every item in a \meta{sequence} is unique. +% \end{function} +% % \section{Sequences as stacks} % % Sequences can be used as stacks, where data is pushed to and popped @@ -426,322 +544,147 @@ % in the previous section: a sequence should either be used as an % ordered data type or as a stack, but not in both ways. % -% \begin{function}{\seq_get:NN, \seq_get:cN} +% \begin{function}[updated = 2012-05-14]{\seq_get:NN, \seq_get:cN} % \begin{syntax} % \cs{seq_get:NN} \meta{sequence} \meta{token list variable} % \end{syntax} % Reads the top item from a \meta{sequence} into the % \meta{token list variable} without removing it from the % \meta{sequence}. The \meta{token list variable} is assigned locally. -% If \meta{sequence} is empty an error will be raised. +% If \meta{sequence} is empty the \meta{token list variable} will +% contain the special marker \cs{q_no_value}. % \end{function} % -% \begin{function}{\seq_pop:NN, \seq_pop:cN} +% \begin{function}[updated = 2012-05-14]{\seq_pop:NN, \seq_pop:cN} % \begin{syntax} % \cs{seq_pop:NN} \meta{sequence} \meta{token list variable} % \end{syntax} % Pops the top item from a \meta{sequence} into the % \meta{token list variable}. Both of the variables are assigned -% locally. If \meta{sequence} is empty an error will be raised. +% locally. If \meta{sequence} is empty the \meta{token list variable} will +% contain the special marker \cs{q_no_value}. % \end{function} % -% \begin{function}{\seq_gpop:NN, \seq_gpop:cN} +% \begin{function}[updated = 2012-05-14]{\seq_gpop:NN, \seq_gpop:cN} % \begin{syntax} % \cs{seq_gpop:NN} \meta{sequence} \meta{token list variable} % \end{syntax} % Pops the top item from a \meta{sequence} into the % \meta{token list variable}. The \meta{sequence} is modified globally, % while the \meta{token list variable} is assigned locally. If -% \meta{sequence} is empty an error will be raised. -% \end{function} -% -% \begin{function} -% { -% \seq_push:Nn, \seq_push:NV, \seq_push:Nv, \seq_push:No, \seq_push:Nx, -% \seq_push:cn, \seq_push:cV, \seq_push:cv, \seq_push:co, \seq_push:cx, -% \seq_gpush:Nn, \seq_gpush:NV, \seq_gpush:Nv, -% \seq_gpush:No, \seq_gpush:Nx, -% \seq_gpush:cn, \seq_gpush:cV, \seq_gpush:cv, -% \seq_gpush:co, \seq_gpush:cx -% } -% \begin{syntax} -% \cs{seq_push:Nn} \meta{sequence} \Arg{item} -% \end{syntax} -% Adds the \Arg{item} to the top of the \meta{sequence}. -% \end{function} -% -% \section{Viewing sequences} -% -% \begin{function}{\seq_show:N, \seq_show:c} -% \begin{syntax} -% \cs{seq_show:N} \meta{sequence} -% \end{syntax} -% Displays the entries in the \meta{sequence} in the terminal. -% \end{function} -% -% \section{Experimental sequence functions} -% -% This section contains functions which may or may not be retained, depending -% on how useful they are found to be. -% -% \begin{function}[TF]{\seq_get_left:NN, \seq_get_left:cN} -% \begin{syntax} -% \cs{seq_get_left:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code} -% \end{syntax} -% If the \meta{sequence} is empty, leaves the \meta{false code} in the -% input stream and leaves the \meta{token list variable} unchanged. If the -% \meta{sequence} is non-empty, stores the left-most item from a -% \meta{sequence} -% in the \meta{token list variable} without removing it from a -% \meta{sequence}. -% The \meta{token list variable} is assigned locally. -% \end{function} -% -% \begin{function}[TF]{\seq_get_right:NN, \seq_get_right:cN} -% \begin{syntax} -% \cs{seq_get_right:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code} -% \end{syntax} -% If the \meta{sequence} is empty, leaves the \meta{false code} in the -% input stream and leaves the \meta{token list variable} unchanged. If the -% \meta{sequence} is non-empty, stores the right-most item from a -% \meta{sequence} -% in the \meta{token list variable} without removing it from a -% \meta{sequence}. -% The \meta{token list variable} is assigned locally. -% \end{function} -% -% \begin{function}[TF]{\seq_pop_left:NN, \seq_pop_left:cN} -% \begin{syntax} -% \cs{seq_pop_left:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code} -% \end{syntax} -% If the \meta{sequence} is empty, leaves the \meta{false code} in the -% input stream and leaves the \meta{token list variable} unchanged. If the -% \meta{sequence} is non-empty, pops the left-most item from a -% \meta{sequence} -% in the \meta{token list variable}, \emph{i.e.}~removes the item from a -% \meta{sequence}. -% Both the \meta{sequence} and the \meta{token list variable} are assigned -% locally. +% \meta{sequence} is empty the \meta{token list variable} will +% contain the special marker \cs{q_no_value}. % \end{function} % -% \begin{function}[TF]{\seq_gpop_left:NN, \seq_gpop_left:cN} +% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]{\seq_get:NN, \seq_get:cN} % \begin{syntax} -% \cs{seq_gpop_left:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code} +% \cs{seq_get:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code} % \end{syntax} % If the \meta{sequence} is empty, leaves the \meta{false code} in the -% input stream and leaves the \meta{token list variable} unchanged. If the -% \meta{sequence} is non-empty, pops the left-most item from a \meta{sequence} -% in the \meta{token list variable}, \emph{i.e.}~removes the item from a -% \meta{sequence}. -% The \meta{sequence} is modified globally, while the \meta{token list variable} -% is assigned locally. +% input stream. The value of the \meta{token list variable} is +% not defined in this case and should not be relied upon. If the +% \meta{sequence} is non-empty, stores the top item from a +% \meta{sequence} in the \meta{token list variable} without removing it from +% the \meta{sequence}. The \meta{token list variable} is assigned locally. % \end{function} % -% \begin{function}[TF]{\seq_pop_right:NN, \seq_pop_right:cN} +% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]{\seq_pop:NN, \seq_pop:cN} % \begin{syntax} -% \cs{seq_pop_right:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code} +% \cs{seq_pop:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code} % \end{syntax} % If the \meta{sequence} is empty, leaves the \meta{false code} in the -% input stream and leaves the \meta{token list variable} unchanged. If the -% \meta{sequence} is non-empty, pops the right-most item from a \meta{sequence} -% in the \meta{token list variable}, \emph{i.e.}~removes the item from a -% \meta{sequence}. -% Both the \meta{sequence} and the \meta{token list variable} are assigned -% locally. +% input stream. The value of the \meta{token list variable} is +% not defined in this case and should not be relied upon. If the +% \meta{sequence} is non-empty, pops the top item from the +% \meta{sequence} in the \meta{token list variable}, \emph{i.e.}~removes the +% item from the \meta{sequence}. Both the \meta{sequence} and the +% \meta{token list variable} are assigned locally. % \end{function} % -% \begin{function}[TF]{\seq_gpop_right:NN, \seq_gpop_right:cN} +% \begin{function}[TF, added = 2012-05-14, updated = 2012-05-19]{\seq_gpop:NN, \seq_gpop:cN} % \begin{syntax} -% \cs{seq_gpop_right:NNTF} \meta{sequence} \meta{token list variable} -% ~~\Arg{true code} \Arg{false code} +% \cs{seq_gpop:NNTF} \meta{sequence} \meta{token list variable} \Arg{true code} \Arg{false code} % \end{syntax} % If the \meta{sequence} is empty, leaves the \meta{false code} in the -% input stream and leaves the \meta{token list variable} unchanged. If the -% \meta{sequence} is non-empty, pops the right-most item from a \meta{sequence} -% in the \meta{token list variable}, \emph{i.e.}~removes the item from a -% \meta{sequence}. -% The \meta{sequence} is modified globally, while the \meta{token list variable} -% is assigned locally. -% \end{function} -% -% \begin{function}[EXP]{\seq_length:N, \seq_length:c} -% \begin{syntax} -% \cs{seq_length:N} \meta{sequence} -% \end{syntax} -% Leaves the number of items in the \meta{sequence} in the input -% stream as an \meta{integer denotation}. The total number of items -% in a \meta{sequence} will include those which are empty and duplicates, -% \emph{i.e.}~every item in a \meta{sequence} is unique. -% \end{function} -% -% \begin{function}[EXP, updated = 2012-01-08]{\seq_item:Nn, \seq_item:cn} -% \begin{syntax} -% \cs{seq_item:Nn} \meta{sequence} \Arg{integer expression} -% \end{syntax} -% Indexing items in the \meta{sequence} from $0$ at the top (left), this -% function will evaluate the \meta{integer expression} and leave the -% appropriate item from the sequence in the input stream. If the -% \meta{integer expression} is negative, indexing occurs from the -% bottom (right) of the sequence. When the \meta{integer expression} -% is larger than the number of items in the \meta{sequence} (as -% calculated by \cs{seq_length:N}) then the function will expand to -% nothing. -% \begin{texnote} -% The result is returned within the \tn{unexpanded} -% primitive (\cs{exp_not:n}), which means that the \meta{item} -% will not expand further when appearing in an x-type -% argument expansion. -% \end{texnote} -% \end{function} -% -% \begin{function}[rEXP]{\seq_use:N, \seq_use:c} -% \begin{syntax} -% \cs{seq_use:N} \meta{sequence} -% \end{syntax} -% Places each \meta{item} in the \meta{sequence} in turn in the input stream. -% This occurs in an expandable fashion, and is implemented as a mapping. -% This means that the process may be prematurely terminated using -% \cs{seq_map_break:} or \cs{seq_map_break:n}. The \meta{items} in the -% \meta{sequence} will be used from left (top) to right (bottom). -% \end{function} -% -% \begin{function}[rEXP] -% { -% \seq_mapthread_function:NNN, \seq_mapthread_function:NcN, -% \seq_mapthread_function:cNN, \seq_mapthread_function:ccN -% } -% \begin{syntax} -% \cs{seq_mapthread_function:NNN} \meta{seq1} \meta{seq2} \meta{function} -% \end{syntax} -% Applies \meta{function} to every pair of items -% \meta{seq1-item}--\meta{seq2-item} from the two sequences, returning -% items from both sequences from left to right. The \meta{function} will -% receive two \texttt{n}-type arguments for each iteration. The mapping -% will terminate when -% the end of either sequence is reached (\emph{i.e.}~whichever sequence has -% fewer items determines how many iterations -% occur). +% input stream. The value of the \meta{token list variable} is +% not defined in this case and should not be relied upon. If the +% \meta{sequence} is non-empty, pops the top item from the \meta{sequence} +% in the \meta{token list variable}, \emph{i.e.}~removes the item from the +% \meta{sequence}. The \meta{sequence} is modified globally, while the +% \meta{token list variable} is assigned locally. % \end{function} % % \begin{function} % { -% \seq_set_from_clist:NN, \seq_set_from_clist:cN, -% \seq_set_from_clist:Nc, \seq_set_from_clist:cc, -% \seq_set_from_clist:Nn, \seq_set_from_clist:cn, -% \seq_gset_from_clist:NN, \seq_gset_from_clist:cN, -% \seq_gset_from_clist:Nc, \seq_gset_from_clist:cc, -% \seq_gset_from_clist:Nn, \seq_gset_from_clist:cn +% \seq_push:Nn, \seq_push:NV, \seq_push:Nv, \seq_push:No, \seq_push:Nx, +% \seq_push:cn, \seq_push:cV, \seq_push:cv, \seq_push:co, \seq_push:cx, +% \seq_gpush:Nn, \seq_gpush:NV, \seq_gpush:Nv, +% \seq_gpush:No, \seq_gpush:Nx, +% \seq_gpush:cn, \seq_gpush:cV, \seq_gpush:cv, +% \seq_gpush:co, \seq_gpush:cx % } % \begin{syntax} -% \cs{seq_set_from_clist:NN} \meta{sequence} \meta{comma-list} +% \cs{seq_push:Nn} \meta{sequence} \Arg{item} % \end{syntax} -% Sets the \meta{sequence} within the current \TeX{} group to be equal -% to the content of the \meta{comma-list}. +% Adds the \Arg{item} to the top of the \meta{sequence}. % \end{function} % -% \begin{function}[added = 2011-11-22, updated = 2011-11-24] -% {\seq_reverse:N, \seq_greverse:N} -% \begin{syntax} -% \cs{seq_reverse:N} \meta{sequence} -% \end{syntax} -% Reverses the order of items in the \meta{sequence}, and -% assigns the result to \meta{sequence}, locally or globally -% according to the variant chosen. -% \end{function} +% \section{Constant and scratch sequences} % -% \begin{function}[added = 2011-12-22] -% {\seq_set_filter:NNn, \seq_gset_filter:NNn} -% \begin{syntax} -% \cs{seq_set_filter:NNn} \meta{sequence1} \meta{sequence2} \Arg{inline boolexpr} -% \end{syntax} -% Evaluates the \meta{inline boolexpr} for every \meta{item} stored -% within the \meta{sequence2}. The \meta{inline boolexpr} will -% receive the \meta{item} as |#1|. The sequence of all \meta{items} -% for which the \meta{inline boolexpr} evaluated to \texttt{true} -% is assigned to \meta{sequence1}. -% \begin{texnote} -% Contrarily to other mapping functions, \cs{seq_map_break:} cannot -% be used in this function, and will lead to low-level \TeX{} errors. -% \end{texnote} -% \end{function} +% \begin{variable}[added = 2012-07-02]{\c_empty_seq} +% Constant that is always empty. +% \end{variable} % -% \begin{function}[added = 2011-12-22] -% {\seq_set_map:NNn, \seq_gset_map:NNn} -% \begin{syntax} -% \cs{seq_set_map:NNn} \meta{sequence1} \meta{sequence2} \Arg{inline function} -% \end{syntax} -% Applies \meta{inline function} to every \meta{item} stored -% within the \meta{sequence2}. The \meta{inline function} should -% consist of code which will receive the \meta{item} as |#1|. -% The sequence resulting from \texttt{x}-expanding -% \meta{inline function} applied to each \meta{item} -% is assigned to \meta{sequence1}. As such, the code -% in \meta{inline function} should be expandable. -% \begin{texnote} -% Contrarily to other mapping functions, \cs{seq_map_break:} cannot -% be used in this function, and will lead to low-level \TeX{} errors. -% \end{texnote} -% \end{function} +% \begin{variable}[added = 2012-04-26]{\l_tmpa_seq, \l_tmpb_seq} +% Scratch sequences for local assignment. These are never used by +% the kernel code, and so are safe for use with any \LaTeX3-defined +% function. However, they may be overwritten by other non-kernel +% code and so should only be used for short-term storage. +% \end{variable} % -% \section{Internal sequence functions} +% \begin{variable}[added = 2012-04-26]{\g_tmpa_seq, \g_tmpb_seq} +% Scratch sequences for global assignment. These are never used by +% the kernel code, and so are safe for use with any \LaTeX3-defined +% function. However, they may be overwritten by other non-kernel +% code and so should only be used for short-term storage. +% \end{variable} +% +% \section{Viewing sequences} % -% \begin{function}{\seq_if_empty_err_break:N} +% \begin{function}{\seq_show:N, \seq_show:c} % \begin{syntax} -% \cs{seq_if_empty_err_break:N} \meta{sequence} +% \cs{seq_show:N} \meta{sequence} % \end{syntax} -% Tests if the \meta{sequence} is empty, and if so issues an error -% message before skipping over any tokens up to \cs{prg_break_point:n}. -% This function is used to avoid more serious errors which would -% otherwise occur if some internal functions were applied to an -% empty \meta{sequence}. +% Displays the entries in the \meta{sequence} in the terminal. % \end{function} % -% \begin{function}[EXP]{\seq_item:n} +% \section{Internal sequence functions} +% +% \begin{function}[EXP]{\__seq_item:n} % \begin{syntax} -% \cs{seq_item:n} \meta{item} +% \cs{__seq_item:n} \meta{item} % \end{syntax} % The internal token used to begin each sequence entry. If expanded % outside of a mapping or manipulation function, an error will be % raised. The definition should always be set globally. % \end{function} % -% \begin{function}{\seq_push_item_def:n, \seq_push_item_def:x} +% \begin{function}{\__seq_push_item_def:n, \__seq_push_item_def:x} % \begin{syntax} -% \cs{seq_push_item_def:n} \Arg{code} +% \cs{__seq_push_item_def:n} \Arg{code} % \end{syntax} -% Saves the definition of \cs{seq_item:n} and redefines it to +% Saves the definition of \cs{__seq_item:n} and redefines it to % accept one parameter and expand to \meta{code}. This function -% should always be balanced by use of \cs{seq_pop_item_def:}. -% \end{function} -% -% \begin{function}{\seq_pop_item_def:} -% \begin{syntax} -% \cs{seq_pop_item_def:} -% \end{syntax} -% Restores the definition of \cs{seq_item:n} most recently saved by -% \cs{seq_push_item_def:n}. This function should always be used in -% a balanced pair with \cs{seq_push_item_def:n}. +% should always be balanced by use of \cs{__seq_pop_item_def:}. % \end{function} % -% \begin{function}[EXP]{\seq_break:} +% \begin{function}{\__seq_pop_item_def:} % \begin{syntax} -% \cs{seq_break:} +% \cs{__seq_pop_item_def:} % \end{syntax} -% Used to terminate sequence functions by gobbling all tokens -% up to \cs{prg_break_point:n}. This function is a copy of -% \cs{seq_map_break:}, but is used in situations which are -% not mappings. -% \end{function} -% -% \begin{function}[EXP]{\seq_break:n} -% \begin{syntax} -% \cs{seq_break:n} \Arg{tokens} -% \end{syntax} -% Used to terminate sequence functions by gobbling all tokens -% up to \cs{prg_break_point:n}, then inserting the \meta{tokens} -% before continuing reading the input stream. This function is a copy -% of \cs{seq_map_break:n}, but is used in situations which are -% not mappings. +% Restores the definition of \cs{__seq_item:n} most recently saved by +% \cs{__seq_push_item_def:n}. This function should always be used in +% a balanced pair with \cs{__seq_push_item_def:n}. % \end{function} % % \end{documentation} @@ -757,41 +700,52 @@ % \end{macrocode} % % \begin{macrocode} +%<@@=seq> +% \end{macrocode} +% +% \begin{macrocode} %<*package> \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} -\package_check_loaded_expl: +\__expl_package_check: %</package> % \end{macrocode} % % A sequence is a control sequence whose top-level expansion is of -% the form \enquote{\cs{seq_item:n} \marg{item$_0$} -% \ldots \cs{seq_item:n} \marg{item$_{n-1}$}}. An earlier implementation -% used the structure \enquote{\cs{seq_elt:w} \meta{item$_1$} -% \cs{seq_elt_end:} \ldots \cs{seq_elt:w} \meta{item$_n$} +% the form \enquote{\cs{@@_item:n} \marg{item_1} +% \ldots \cs{@@_item:n} \marg{item_n}}. An earlier implementation +% used the structure \enquote{\cs{seq_elt:w} \meta{item_1} +% \cs{seq_elt_end:} \ldots \cs{seq_elt:w} \meta{item_n} % \cs{seq_elt_end:}}. This allows rapid searching using a delimited % function, but is not suitable for items containing |{|, |}| and |#| % tokens, and also leads to the loss of surrounding braces % around items. % -% \begin{macro}[int]{\seq_item:n} +% \begin{macro}[int]{\@@_item:n} % The delimiter is always defined, but when used incorrectly simply % removes its argument and hits an undefined control sequence to % raise an error. % \begin{macrocode} -\cs_new:Npn \seq_item:n +\cs_new:Npn \@@_item:n { - \msg_expandable_kernel_error:nn { seq } { misused } + \__msg_kernel_expandable_error:nn { kernel } { misused-sequence } \use_none:n } % \end{macrocode} % \end{macro} % -% \begin{variable}{\l_seq_internal_a_tl, \l_seq_internal_b_tl} +% \begin{variable}{\l_@@_internal_a_tl, \l_@@_internal_b_tl} % Scratch space for various internal uses. % \begin{macrocode} -\tl_new:N \l_seq_internal_a_tl -\tl_new:N \l_seq_internal_b_tl +\tl_new:N \l_@@_internal_a_tl +\tl_new:N \l_@@_internal_b_tl +% \end{macrocode} +% \end{variable} +% +% \begin{variable}{\c_empty_seq} +% Simply copy the empty token list. +% \begin{macrocode} +\cs_new_eq:NN \c_empty_seq \c_empty_tl % \end{macrocode} % \end{variable} % @@ -853,25 +807,29 @@ % \end{macro} % \end{macro} % -% \begin{macro}{\seq_set_split:Nnn,\seq_gset_split:Nnn} -% \begin{macro}[aux]{\seq_set_split_aux:NNnn} +% \begin{macro} +% { +% \seq_set_split:Nnn , \seq_set_split:NnV , +% \seq_gset_split:Nnn, \seq_gset_split:NnV +% } +% \begin{macro}[aux]{\@@_set_split:NNnn} % \begin{macro}[aux] % { -% \seq_set_split_aux_i:w, \seq_set_split_aux_ii:w, -% \seq_set_split_aux_end: +% \@@_set_split_i:w, \@@_set_split_ii:w, +% \@@_set_split_end: % } % The goal is to split a given token list at a marker, % strip spaces from each item, and remove one set of % outer braces if after removing leading and trailing % spaces the item is enclosed within braces. After -% \cs{tl_replace_all:Nnn}, the token list \cs{l_seq_internal_a_tl} +% \cs{tl_replace_all:Nnn}, the token list \cs{l_@@_internal_a_tl} % is a repetition of the pattern -% \cs{seq_set_split_aux_i:w} \cs{prg_do_nothing:} -% \meta{item with spaces} \cs{seq_set_split_aux_end:}. -% Then, \texttt{x}-expansion causes \cs{seq_set_split_aux_i:w} +% \cs{@@_set_split_i:w} \cs{prg_do_nothing:} +% \meta{item with spaces} \cs{@@_set_split_end:}. +% Then, \texttt{x}-expansion causes \cs{@@_set_split_i:w} % to trim spaces, and leaves its result as -% \cs{seq_set_split_aux_ii:w} \meta{trimmed item} -% \cs{seq_set_split_aux_end:}. This is then converted +% \cs{@@_set_split_ii:w} \meta{trimmed item} +% \cs{@@_set_split_end:}. This is then converted % to the \pkg{l3seq} internal structure by another % \texttt{x}-expansion. In the first step, we insert % \cs{prg_do_nothing:} to avoid losing braces too early: @@ -880,37 +838,39 @@ % braces which are outermost after space trimming. % \begin{macrocode} \cs_new_protected_nopar:Npn \seq_set_split:Nnn - { \seq_set_split_aux:NNnn \tl_set:Nx } + { \@@_set_split:NNnn \tl_set:Nx } \cs_new_protected_nopar:Npn \seq_gset_split:Nnn - { \seq_set_split_aux:NNnn \tl_gset:Nx } -\cs_new_protected:Npn \seq_set_split_aux:NNnn #1 #2 #3 #4 + { \@@_set_split:NNnn \tl_gset:Nx } +\cs_new_protected:Npn \@@_set_split:NNnn #1 #2 #3 #4 { \tl_if_empty:nTF {#3} - { #1 #2 { \tl_map_function:nN {#4} \seq_wrap_item:n } } + { #1 #2 { \tl_map_function:nN {#4} \@@_wrap_item:n } } { - \tl_set:Nn \l_seq_internal_a_tl + \tl_set:Nn \l_@@_internal_a_tl { - \seq_set_split_aux_i:w \prg_do_nothing: + \@@_set_split_i:w \prg_do_nothing: #4 - \seq_set_split_aux_end: + \@@_set_split_end: } - \tl_replace_all:Nnn \l_seq_internal_a_tl { #3 } + \tl_replace_all:Nnn \l_@@_internal_a_tl { #3 } { - \seq_set_split_aux_end: - \seq_set_split_aux_i:w \prg_do_nothing: + \@@_set_split_end: + \@@_set_split_i:w \prg_do_nothing: } - \tl_set:Nx \l_seq_internal_a_tl { \l_seq_internal_a_tl } - #1 #2 { \l_seq_internal_a_tl } + \tl_set:Nx \l_@@_internal_a_tl { \l_@@_internal_a_tl } + #1 #2 { \l_@@_internal_a_tl } } } -\cs_new:Npn \seq_set_split_aux_i:w #1 \seq_set_split_aux_end: +\cs_new:Npn \@@_set_split_i:w #1 \@@_set_split_end: { - \exp_not:N \seq_set_split_aux_ii:w + \exp_not:N \@@_set_split_ii:w \exp_args:No \tl_trim_spaces:n {#1} - \exp_not:N \seq_set_split_aux_end: + \exp_not:N \@@_set_split_end: } -\cs_new:Npn \seq_set_split_aux_ii:w #1 \seq_set_split_aux_end: - { \seq_wrap_item:n {#1} } +\cs_new:Npn \@@_set_split_ii:w #1 \@@_set_split_end: + { \@@_wrap_item:n {#1} } +\cs_generate_variant:Nn \seq_set_split:Nnn { NnV } +\cs_generate_variant:Nn \seq_gset_split:Nnn { NnV } % \end{macrocode} % \end{macro} % \end{macro} @@ -965,9 +925,9 @@ % The code here is just a wrapper for adding to token lists. % \begin{macrocode} \cs_new_protected:Npn \seq_put_left:Nn #1#2 - { \tl_put_left:Nn #1 { \seq_item:n {#2} } } + { \tl_put_left:Nn #1 { \@@_item:n {#2} } } \cs_new_protected:Npn \seq_put_right:Nn #1#2 - { \tl_put_right:Nn #1 { \seq_item:n {#2} } } + { \tl_put_right:Nn #1 { \@@_item:n {#2} } } \cs_generate_variant:Nn \seq_put_left:Nn { NV , Nv , No , Nx } \cs_generate_variant:Nn \seq_put_left:Nn { c , cV , cv , co , cx } \cs_generate_variant:Nn \seq_put_right:Nn { NV , Nv , No , Nx } @@ -991,9 +951,9 @@ % The same for global addition. % \begin{macrocode} \cs_new_protected:Npn \seq_gput_left:Nn #1#2 - { \tl_gput_left:Nn #1 { \seq_item:n {#2} } } + { \tl_gput_left:Nn #1 { \@@_item:n {#2} } } \cs_new_protected:Npn \seq_gput_right:Nn #1#2 - { \tl_gput_right:Nn #1 { \seq_item:n {#2} } } + { \tl_gput_right:Nn #1 { \@@_item:n {#2} } } \cs_generate_variant:Nn \seq_gput_left:Nn { NV , Nv , No , Nx } \cs_generate_variant:Nn \seq_gput_left:Nn { c , cV , cv , co , cx } \cs_generate_variant:Nn \seq_gput_right:Nn { NV , Nv , No , Nx } @@ -1004,18 +964,18 @@ % % \subsection{Modifying sequences} % -% \begin{macro}[aux]{\seq_wrap_item:n} +% \begin{macro}[aux]{\@@_wrap_item:n} % This function converts its argument to a proper sequence item % in an \texttt{x}-expansion context. % \begin{macrocode} -\cs_new:Npn \seq_wrap_item:n #1 { \exp_not:n { \seq_item:n {#1} } } +\cs_new:Npn \@@_wrap_item:n #1 { \exp_not:n { \@@_item:n {#1} } } % \end{macrocode} % \end{macro} % -% \begin{variable}{\l_seq_internal_remove_seq} +% \begin{variable}{\l_@@_remove_seq} % An internal sequence for the removal routines. % \begin{macrocode} -\seq_new:N \l_seq_internal_remove_seq +\seq_new:N \l_@@_remove_seq % \end{macrocode} % \end{variable} % @@ -1023,22 +983,22 @@ % \UnitTested % \begin{macro}{\seq_gremove_duplicates:N, \seq_gremove_duplicates:c} % \UnitTested -% \begin{macro}[aux]{\seq_remove_duplicates_aux:NN} +% \begin{macro}[aux]{\@@_remove_duplicates:NN} % Removing duplicates means making a new list then copying it. % \begin{macrocode} \cs_new_protected:Npn \seq_remove_duplicates:N - { \seq_remove_duplicates_aux:NN \seq_set_eq:NN } + { \@@_remove_duplicates:NN \seq_set_eq:NN } \cs_new_protected:Npn \seq_gremove_duplicates:N - { \seq_remove_duplicates_aux:NN \seq_gset_eq:NN } -\cs_new_protected:Npn \seq_remove_duplicates_aux:NN #1#2 + { \@@_remove_duplicates:NN \seq_gset_eq:NN } +\cs_new_protected:Npn \@@_remove_duplicates:NN #1#2 { - \seq_clear:N \l_seq_internal_remove_seq + \seq_clear:N \l_@@_remove_seq \seq_map_inline:Nn #2 { - \seq_if_in:NnF \l_seq_internal_remove_seq {##1} - { \seq_put_right:Nn \l_seq_internal_remove_seq {##1} } + \seq_if_in:NnF \l_@@_remove_seq {##1} + { \seq_put_right:Nn \l_@@_remove_seq {##1} } } - #1 #2 \l_seq_internal_remove_seq + #1 #2 \l_@@_remove_seq } \cs_generate_variant:Nn \seq_remove_duplicates:N { c } \cs_generate_variant:Nn \seq_gremove_duplicates:N { c } @@ -1051,11 +1011,11 @@ % \UnitTested % \begin{macro}{\seq_gremove_all:Nn, \seq_gremove_all:cn} % \UnitTested -% \begin{macro}[aux]{\seq_remove_all_aux:NNn} +% \begin{macro}[aux]{\@@_remove_all_aux:NNn} % The idea of the code here is to avoid a relatively expensive addition of % items one at a time to an intermediate sequence. % The approach taken is therefore similar to -% that in \cs{seq_pop_right_aux_ii:NNN}, using a \enquote{flexible} +% that in \cs{@@_pop_right_aux_ii:NNN}, using a \enquote{flexible} % \texttt{x}-type expansion to do most of the work. As \cs{tl_if_eq:nnT} % is not expandable, a two-part strategy is needed. First, the % \texttt{x}-type expansion uses \cs{str_if_eq:nnT} to find potential @@ -1068,28 +1028,28 @@ % lost. % \begin{macrocode} \cs_new_protected:Npn \seq_remove_all:Nn - { \seq_remove_all_aux:NNn \tl_set:Nx } + { \@@_remove_all_aux:NNn \tl_set:Nx } \cs_new_protected:Npn \seq_gremove_all:Nn - { \seq_remove_all_aux:NNn \tl_gset:Nx } -\cs_new_protected:Npn \seq_remove_all_aux:NNn #1#2#3 + { \@@_remove_all_aux:NNn \tl_gset:Nx } +\cs_new_protected:Npn \@@_remove_all_aux:NNn #1#2#3 { - \seq_push_item_def:n + \@@_push_item_def:n { \str_if_eq:nnT {##1} {#3} { \if_false: { \fi: } - \tl_set:Nn \l_seq_internal_b_tl {##1} + \tl_set:Nn \l_@@_internal_b_tl {##1} #1 #2 { \if_false: } \fi: \exp_not:o {#2} - \tl_if_eq:NNT \l_seq_internal_a_tl \l_seq_internal_b_tl + \tl_if_eq:NNT \l_@@_internal_a_tl \l_@@_internal_b_tl { \use_none:nn } } - \seq_wrap_item:n {##1} + \@@_wrap_item:n {##1} } - \tl_set:Nn \l_seq_internal_a_tl {#3} + \tl_set:Nn \l_@@_internal_a_tl {#3} #1 #2 {#2} - \seq_pop_item_def: + \@@_pop_item_def: } \cs_generate_variant:Nn \seq_remove_all:Nn { c } \cs_generate_variant:Nn \seq_gremove_all:Nn { c } @@ -1117,33 +1077,35 @@ % \seq_if_in:cn, \seq_if_in:cV, \seq_if_in:cv, \seq_if_in:co, \seq_if_in:cx % } % \UnitTested -% \begin{macro}[aux]{\seq_if_in_aux:} -% The approach here is to define \cs{seq_item:n} to compare its +% \begin{macro}[aux]{\@@_if_in:} +% The approach here is to define \cs{@@_item:n} to compare its % argument with the test sequence. If the two items are equal, the -% mapping is terminated and \cs{prg_return_true:} is inserted. On the +% mapping is terminated and \cs{group_end:} \cs{prg_return_true:} +% is inserted after skipping over the rest of the recursion. On the % other hand, if there is no match then the loop will break returning -% \cs{prg_return_false:}. In either case, \cs{prg_break_point:n} -% ensures that the group ends before the logical value is returned. -% Everything is inside a group so that \cs{seq_item:n} is preserved +% \cs{prg_return_false:}. +% Everything is inside a group so that \cs{@@_item:n} is preserved % in nested situations. % \begin{macrocode} \prg_new_protected_conditional:Npnn \seq_if_in:Nn #1#2 { T , F , TF } { \group_begin: - \tl_set:Nn \l_seq_internal_a_tl {#2} - \cs_set_protected:Npn \seq_item:n ##1 + \tl_set:Nn \l_@@_internal_a_tl {#2} + \cs_set_protected:Npn \@@_item:n ##1 { - \tl_set:Nn \l_seq_internal_b_tl {##1} - \if_meaning:w \l_seq_internal_a_tl \l_seq_internal_b_tl - \exp_after:wN \seq_if_in_aux: + \tl_set:Nn \l_@@_internal_b_tl {##1} + \if_meaning:w \l_@@_internal_a_tl \l_@@_internal_b_tl + \exp_after:wN \@@_if_in: \fi: } #1 - \seq_break:n { \prg_return_false: } - \prg_break_point:n { \group_end: } + \group_end: + \prg_return_false: + \__prg_break_point: } -\cs_new_nopar:Npn \seq_if_in_aux: { \seq_break:n { \prg_return_true: } } +\cs_new_nopar:Npn \@@_if_in: + { \__prg_break:n { \group_end: \prg_return_true: } } \cs_generate_variant:Nn \seq_if_in:NnT { NV , Nv , No , Nx } \cs_generate_variant:Nn \seq_if_in:NnT { c , cV , cv , co , cx } \cs_generate_variant:Nn \seq_if_in:NnF { NV , Nv , No , Nx } @@ -1156,21 +1118,50 @@ % % \subsection{Recovering data from sequences} % +% \begin{macro}[int]{\@@_pop:NNNN, \@@_pop_TF:NNNN} +% The two \texttt{pop} functions share their emptiness tests. We also +% use a common emptiness test for all branching \texttt{get} and +% \texttt{pop} functions. +% \begin{macrocode} +\cs_new_protected:Npn \@@_pop:NNNN #1#2#3#4 + { + \if_meaning:w #3 \c_empty_seq + \tl_set:Nn #4 { \q_no_value } + \else: + #1#2#3#4 + \fi: + } +\cs_new_protected:Npn \@@_pop_TF:NNNN #1#2#3#4 + { + \if_meaning:w #3 \c_empty_seq + % \tl_set:Nn #4 { \q_no_value } + \prg_return_false: + \else: + #1#2#3#4 + \prg_return_true: + \fi: + } +% \end{macrocode} +% \end{macro} +% % \begin{macro}{\seq_get_left:NN, \seq_get_left:cN} % \UnitTested -% \begin{macro}[aux]{\seq_get_left_aux:NnwN} +% \begin{macro}[aux]{\@@_get_left:NnwN} % Getting an item from the left of a sequence is pretty easy: just -% trim off the first item after removing the \cs{seq_item:n} at -% the start. +% trim off the first item after removing the \cs{@@_item:n} at +% the start. We first append a \cs{q_no_value} item to cover the case +% of an empty sequence % \begin{macrocode} \cs_new_protected:Npn \seq_get_left:NN #1#2 { - \seq_if_empty_err_break:N #1 - \exp_after:wN \seq_get_left_aux:NnwN #1 \q_stop #2 - \prg_break_point:n { } + \tl_set:Nx #2 + { + \exp_after:wN \@@_get_left:Nnw + #1 \@@_item:n { \q_no_value } \q_stop + } } -\cs_new_protected:Npn \seq_get_left_aux:NnwN \seq_item:n #1#2 \q_stop #3 - { \tl_set:Nn #3 {#1} } +\cs_new:Npn \@@_get_left:Nnw \@@_item:n #1#2 \q_stop + { \exp_not:n {#1} } \cs_generate_variant:Nn \seq_get_left:NN { c } % \end{macrocode} % \end{macro} @@ -1180,24 +1171,19 @@ % \UnitTested % \begin{macro}{\seq_gpop_left:NN, \seq_gpop_left:cN} % \UnitTested -% \begin{macro}[aux]{\seq_pop_left_aux:NNN} -% \begin{macro}[aux]{\seq_pop_left_aux:NnwNNN} +% \begin{macro}[aux]{\@@_pop_left:NNN, \@@_pop_left:NnwNNN} % The approach to popping an item is pretty similar to that to get % an item, with the only difference being that the sequence itself has % to be redefined. This makes it more sensible to use an auxiliary % function for the local and global cases. % \begin{macrocode} \cs_new_protected_nopar:Npn \seq_pop_left:NN - { \seq_pop_left_aux:NNN \tl_set:Nn } + { \@@_pop:NNNN \@@_pop_left:NNN \tl_set:Nn } \cs_new_protected_nopar:Npn \seq_gpop_left:NN - { \seq_pop_left_aux:NNN \tl_gset:Nn } -\cs_new_protected:Npn \seq_pop_left_aux:NNN #1#2#3 - { - \seq_if_empty_err_break:N #2 - \exp_after:wN \seq_pop_left_aux:NnwNNN #2 \q_stop #1#2#3 - \prg_break_point:n { } - } -\cs_new_protected:Npn \seq_pop_left_aux:NnwNNN \seq_item:n #1#2 \q_stop #3#4#5 + { \@@_pop:NNNN \@@_pop_left:NNN \tl_gset:Nn } +\cs_new_protected:Npn \@@_pop_left:NNN #1#2#3 + { \exp_after:wN \@@_pop_left:NnwNNN #2 \q_stop #1#2#3 } +\cs_new_protected:Npn \@@_pop_left:NnwNNN \@@_item:n #1#2 \q_stop #3#4#5 { #3 #4 {#2} \tl_set:Nn #5 {#1} @@ -1208,94 +1194,84 @@ % \end{macro} % \end{macro} % \end{macro} -% \end{macro} % % \begin{macro}{\seq_get_right:NN, \seq_get_right:cN} % \UnitTested -% \begin{macro}[aux]{\seq_get_right_aux:NN} -% \begin{macro}[aux]{\seq_get_right_loop:nn} -% The idea here is to remove the very first \cs{seq_item:n} from the -% sequence, leaving a token list starting with the first braced entry. -% Two arguments at a time are then grabbed: apart from the right-hand end of -% the sequence, this will be a brace group followed by \cs{seq_item:n}. The -% set up code means that these all disappear. At the end of the sequence, -% the assignment is placed in front of the very last entry in the sequence, -% before a tidying-up step takes place to remove the loop and reset the -% meaning of \cs{seq_item:n}. +% \begin{macro}[aux]{\@@_get_right_loop:nn} +% First prepend \cs{q_no_value}, then take two arguments at a time. +% Apart from the right-hand end of the sequence, this be a brace group +% followed by \cs{@@_item:n}. The \cs{use_none:nn} removes both of +% those. At the end of the sequence, the two question marks are taken +% by \cs{use_none:nn}, and the assignment is placed before the +% right-most item. The \tn{afterassignment} primitive places +% \cs{use_none:n} to get rid of a trailing \cs{@@_get_right_loop:nn}. % \begin{macrocode} \cs_new_protected:Npn \seq_get_right:NN #1#2 { - \seq_if_empty_err_break:N #1 - \seq_get_right_aux:NN #1#2 - \prg_break_point:n { } + \exp_after:wN \@@_get_right_loop:nn + \exp_after:wN \q_no_value + #1 + { + ?? + \tex_afterassignment:D \use_none:n + \tl_set:Nn #2 + } } -\cs_new_protected:Npn \seq_get_right_aux:NN #1#2 - { - \seq_push_item_def:n { } - \exp_after:wN \exp_after:wN \exp_after:wN \seq_get_right_loop:nn - \exp_after:wN \use_none:n #1 - { \tl_set:Nn #2 } - { } - { - \seq_pop_item_def: - \seq_break: - } -} -\cs_new:Npn \seq_get_right_loop:nn #1#2 +\cs_new_protected:Npn \@@_get_right_loop:nn #1#2 { - #2 {#1} - \seq_get_right_loop:nn + \use_none:nn #2 {#1} + \@@_get_right_loop:nn } \cs_generate_variant:Nn \seq_get_right:NN { c } % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} % % \begin{macro}{\seq_pop_right:NN, \seq_pop_right:cN} % \UnitTested % \begin{macro}{\seq_gpop_right:NN, \seq_gpop_right:cN} % \UnitTested -% \begin{macro}[aux]{\seq_pop_right_aux:NNN, \seq_pop_right_aux_ii:NNN} +% \begin{macro}[aux]{\@@_pop_right_aux:NNN, \@@_pop_right_loop:nn} % The approach to popping from the right is a bit more involved, but does % use some of the same ideas as getting from the right. What is needed is a % \enquote{flexible length} way to set a token list variable. This is -% supplied by the |{ \if_false:} \fi:| \ldots +% supplied by the |{ \if_false: } \fi:| \ldots % |\if_false: { \fi: }| construct. Using an \texttt{x}-type -% expansion and a \enquote{non-expanding} definition for \cs{seq_item:n}, +% expansion and a \enquote{non-expanding} definition for \cs{@@_item:n}, % the left-most $n - 1$ entries in a sequence of $n$ items will be stored % back in the sequence. That needs a loop of unknown length, hence using the % strange \cs{if_false:} way of including brackets. When the last item % of the sequence is reached, the closing bracket for the assignment is -% inserted, and |\tl_set:Nn #3| is inserted in front of the final entry. -% This therefore does the pop assignment, then a final loop clears up the -% code. +% inserted, and |\tl_set:Nn #3| is inserted in front of the final +% entry. This therefore does the pop assignment. The trailing +% looping macro is removed by placing a \cs{use_none:n} using the +% \tn{afterassignment} primitive. % \begin{macrocode} \cs_new_protected_nopar:Npn \seq_pop_right:NN - { \seq_pop_right_aux:NNN \tl_set:Nx } + { \@@_pop:NNNN \@@_pop_right_aux:NNN \tl_set:Nx } \cs_new_protected_nopar:Npn \seq_gpop_right:NN - { \seq_pop_right_aux:NNN \tl_gset:Nx } -\cs_new_protected:Npn \seq_pop_right_aux:NNN #1#2#3 - { - \seq_if_empty_err_break:N #2 - \seq_pop_right_aux_ii:NNN #1 #2 #3 - \prg_break_point:n { } - } -\cs_new_protected:Npn \seq_pop_right_aux_ii:NNN #1#2#3 + { \@@_pop:NNNN \@@_pop_right_aux:NNN \tl_gset:Nx } +\cs_new_protected:Npn \@@_pop_right_aux:NNN #1#2#3 { - \seq_push_item_def:n { \seq_wrap_item:n {##1} } - #1 #2 { \if_false: } \fi: - \exp_after:wN \exp_after:wN \exp_after:wN \seq_get_right_loop:nn - \exp_after:wN \use_none:n #2 + \cs_set_eq:NN \seq_tmp:w \@@_item:n + \cs_set_eq:NN \@@_item:n \scan_stop: + #1 #2 + { \if_false: } \fi: + \exp_after:wN \exp_after:wN + \exp_after:wN \@@_pop_right_loop:nn + \exp_after:wN \use_none:n + #2 { \if_false: { \fi: } - \tl_set:Nn #3 - } - { } - { - \seq_pop_item_def: - \seq_break: + \tex_afterassignment:D \use_none:n + \tl_set:Nx #3 } + \cs_set_eq:NN \@@_item:n \seq_tmp:w + } +\cs_new:Npn \@@_pop_right_loop:nn #1#2 + { + #2 { \exp_not:n {#1} } + \@@_pop_right_loop:nn } \cs_generate_variant:Nn \seq_pop_right:NN { c } \cs_generate_variant:Nn \seq_gpop_right:NN { c } @@ -1304,99 +1280,130 @@ % \end{macro} % \end{macro} % +% \begin{macro}[TF]{\seq_get_left:NN, \seq_get_left:cN} +% \begin{macro}[TF]{\seq_get_right:NN, \seq_get_right:cN} +% Getting from the left or right with a check on the results. The +% first argument to \cs{@@_pop_TF:NNNN} is left unused. +% \begin{macrocode} +\prg_new_protected_conditional:Npnn \seq_get_left:NN #1#2 { T , F , TF } + { \@@_pop_TF:NNNN \prg_do_nothing: \seq_get_left:NN #1#2 } +\prg_new_protected_conditional:Npnn \seq_get_right:NN #1#2 { T , F , TF } + { \@@_pop_TF:NNNN \prg_do_nothing: \seq_get_right:NN #1#2 } +\cs_generate_variant:Nn \seq_get_left:NNT { c } +\cs_generate_variant:Nn \seq_get_left:NNF { c } +\cs_generate_variant:Nn \seq_get_left:NNTF { c } +\cs_generate_variant:Nn \seq_get_right:NNT { c } +\cs_generate_variant:Nn \seq_get_right:NNF { c } +\cs_generate_variant:Nn \seq_get_right:NNTF { c } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}[TF]{\seq_pop_left:NN, \seq_pop_left:cN} +% \begin{macro}[TF]{\seq_gpop_left:NN, \seq_gpop_left:cN} +% \begin{macro}[TF]{\seq_pop_right:NN, \seq_pop_right:cN} +% \begin{macro}[TF]{\seq_gpop_right:NN, \seq_gpop_right:cN} +% More or less the same for popping. +% \begin{macrocode} +\prg_new_protected_conditional:Npnn \seq_pop_left:NN #1#2 { T , F , TF } + { \@@_pop_TF:NNNN \@@_pop_left:NNN \tl_set:Nn #1 #2 } +\prg_new_protected_conditional:Npnn \seq_gpop_left:NN #1#2 { T , F , TF } + { \@@_pop_TF:NNNN \@@_pop_left:NNN \tl_gset:Nn #1 #2 } +\prg_new_protected_conditional:Npnn \seq_pop_right:NN #1#2 { T , F , TF } + { \@@_pop_TF:NNNN \@@_pop_right_aux:NNN \tl_set:Nx #1 #2 } +\prg_new_protected_conditional:Npnn \seq_gpop_right:NN #1#2 { T , F , TF } + { \@@_pop_TF:NNNN \@@_pop_right_aux:NNN \tl_gset:Nx #1 #2 } +\cs_generate_variant:Nn \seq_pop_left:NNT { c } +\cs_generate_variant:Nn \seq_pop_left:NNF { c } +\cs_generate_variant:Nn \seq_pop_left:NNTF { c } +\cs_generate_variant:Nn \seq_gpop_left:NNT { c } +\cs_generate_variant:Nn \seq_gpop_left:NNF { c } +\cs_generate_variant:Nn \seq_gpop_left:NNTF { c } +\cs_generate_variant:Nn \seq_pop_right:NNT { c } +\cs_generate_variant:Nn \seq_pop_right:NNF { c } +\cs_generate_variant:Nn \seq_pop_right:NNTF { c } +\cs_generate_variant:Nn \seq_gpop_right:NNT { c } +\cs_generate_variant:Nn \seq_gpop_right:NNF { c } +\cs_generate_variant:Nn \seq_gpop_right:NNTF { c } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% % \subsection{Mapping to sequences} % % \begin{macro}{\seq_map_break:} % \UnitTested % \begin{macro}{\seq_map_break:n} % \UnitTested -% \begin{macro}[int]{\seq_break:} -% \begin{macro}[int]{\seq_break:n} -% To break a function, the special token \cs{prg_break_point:n} is +% To break a function, the special token \cs{__prg_break_point:Nn} is % used to find the end of the code. Any ending code is then inserted % before the return value of \cs{seq_map_break:n} is inserted. -% Semantically-logical copies of the break functions for use inside -% mappings. % \begin{macrocode} -\cs_new_eq:NN \seq_break: \prg_map_break: -\cs_new_eq:NN \seq_break:n \prg_map_break:n -\cs_new_eq:NN \seq_map_break: \prg_map_break: -\cs_new_eq:NN \seq_map_break:n \prg_map_break:n +\cs_new_nopar:Npn \seq_map_break: + { \__prg_map_break:Nn \seq_map_break: { } } +\cs_new_nopar:Npn \seq_map_break:n + { \__prg_map_break:Nn \seq_map_break: } % \end{macrocode} % \end{macro} % \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}[int]{\seq_if_empty_err_break:N} -% A function to check that sequences really have some content. This -% is optimised for speed, hence the direct primitive use. -% \begin{macrocode} -\cs_new_protected:Npn \seq_if_empty_err_break:N #1 - { - \if_meaning:w #1 \c_empty_tl - \msg_kernel_error:nnx { seq } { empty-sequence } { \token_to_str:N #1 } - \exp_after:wN \seq_break: - \fi: - } -% \end{macrocode} -% \end{macro} % % \begin{macro}{\seq_map_function:NN, \seq_map_function:cN} % \UnitTested -% \begin{macro}[aux]{\seq_map_function_aux:NNn} +% \begin{macro}[aux]{\@@_map_function:NNn} % The idea here is to apply the code of |#2| to each item in the -% sequence without altering the definition of \cs{seq_item:n}. This +% sequence without altering the definition of \cs{@@_item:n}. This % is done as by noting that every odd token in the sequence must be -% \cs{seq_item:n}, which can be gobbled by \cs{use_none:n}. At the end of +% \cs{@@_item:n}, which can be gobbled by \cs{use_none:n}. At the end of % the loop, |#2| is instead |? \seq_map_break:|, which therefore breaks the % loop without needing to do a (relatively-expensive) quark test. % \begin{macrocode} \cs_new:Npn \seq_map_function:NN #1#2 { - \exp_after:wN \seq_map_function_aux:NNn \exp_after:wN #2 #1 + \exp_after:wN \@@_map_function:NNn \exp_after:wN #2 #1 { ? \seq_map_break: } { } - \prg_break_point:n { } + \__prg_break_point:Nn \seq_map_break: { } } -\cs_new:Npn \seq_map_function_aux:NNn #1#2#3 +\cs_new:Npn \@@_map_function:NNn #1#2#3 { \use_none:n #2 #1 {#3} - \seq_map_function_aux:NNn #1 + \@@_map_function:NNn #1 } \cs_generate_variant:Nn \seq_map_function:NN { c } % \end{macrocode} % \end{macro} % \end{macro} % -% \begin{macro}[int]{\seq_push_item_def:n, \seq_push_item_def:x} -% \begin{macro}[aux]{\seq_push_item_def_aux:} -% \begin{macro}[int]{\seq_pop_item_def:} -% The definition of \cs{seq_item:n} needs to be saved and restored at +% \begin{macro}[int]{\@@_push_item_def:n, \@@_push_item_def:x} +% \begin{macro}[aux]{\@@_push_item_def:} +% \begin{macro}[int]{\@@_pop_item_def:} +% The definition of \cs{@@_item:n} needs to be saved and restored at % various points within the mapping and manipulation code. That is handled % here: as always, this approach uses global assignments. % \begin{macrocode} -\cs_new_protected:Npn \seq_push_item_def:n +\cs_new_protected:Npn \@@_push_item_def:n { - \seq_push_item_def_aux: - \cs_gset:Npn \seq_item:n ##1 + \@@_push_item_def: + \cs_gset:Npn \@@_item:n ##1 } -\cs_new_protected:Npn \seq_push_item_def:x +\cs_new_protected:Npn \@@_push_item_def:x { - \seq_push_item_def_aux: - \cs_gset:Npx \seq_item:n ##1 + \@@_push_item_def: + \cs_gset:Npx \@@_item:n ##1 } -\cs_new_protected:Npn \seq_push_item_def_aux: +\cs_new_protected:Npn \@@_push_item_def: { - \cs_gset_eq:cN { seq_item_ \int_use:N \g_prg_map_int :n } - \seq_item:n - \int_gincr:N \g_prg_map_int + \int_gincr:N \g__prg_map_int + \cs_gset_eq:cN { __prg_map_ \int_use:N \g__prg_map_int :w } + \@@_item:n } -\cs_new_protected_nopar:Npn \seq_pop_item_def: +\cs_new_protected_nopar:Npn \@@_pop_item_def: { - \int_gdecr:N \g_prg_map_int - \cs_gset_eq:Nc \seq_item:n - { seq_item_ \int_use:N \g_prg_map_int :n } + \cs_gset_eq:Nc \@@_item:n + { __prg_map_ \int_use:N \g__prg_map_int :w } + \int_gdecr:N \g__prg_map_int } % \end{macrocode} % \end{macro} @@ -1405,15 +1412,15 @@ % % \begin{macro}{\seq_map_inline:Nn, \seq_map_inline:cn} % \UnitTested -% The idea here is that \cs{seq_item:n} is already \enquote{applied} to +% The idea here is that \cs{@@_item:n} is already \enquote{applied} to % each item in a sequence, and so an in-line mapping is just a case of -% redefining \cs{seq_item:n}. +% redefining \cs{@@_item:n}. % \begin{macrocode} \cs_new_protected:Npn \seq_map_inline:Nn #1#2 { - \seq_push_item_def:n {#2} + \@@_push_item_def:n {#2} #1 - \prg_break_point:n { \seq_pop_item_def: } + \__prg_break_point:Nn \seq_map_break: { \@@_pop_item_def: } } \cs_generate_variant:Nn \seq_map_inline:Nn { c } % \end{macrocode} @@ -1431,18 +1438,38 @@ % \begin{macrocode} \cs_new_protected:Npn \seq_map_variable:NNn #1#2#3 { - \seq_push_item_def:x + \@@_push_item_def:x { \tl_set:Nn \exp_not:N #2 {##1} \exp_not:n {#3} } #1 - \prg_break_point:n { \seq_pop_item_def: } + \__prg_break_point:Nn \seq_map_break: { \@@_pop_item_def: } } \cs_generate_variant:Nn \seq_map_variable:NNn { Nc } \cs_generate_variant:Nn \seq_map_variable:NNn { c , cc } % \end{macrocode} % \end{macro} +% +% \begin{macro}{\seq_count:N, \seq_count:c} +% \begin{macro}[aux]{\@@_count:n} +% Counting the items in a sequence is done using the same approach as for +% other count functions: turn each entry into a \texttt{+1} then use +% integer evaluation to actually do the mathematics. +% \begin{macrocode} +\cs_new:Npn \seq_count:N #1 + { + \int_eval:n + { + 0 + \seq_map_function:NN #1 \@@_count:n + } + } +\cs_new:Npn \@@_count:n #1 { + \c_one } +\cs_generate_variant:Nn \seq_count:N { c } +% \end{macrocode} +% \end{macro} +% \end{macro} % % \subsection{Sequence stacks} % @@ -1504,379 +1531,50 @@ % \end{macro} % \end{macro} % +% \begin{macro}[TF]{\seq_get:NN, \seq_get:cN} +% \begin{macro}[TF]{\seq_pop:NN, \seq_pop:cN} +% \begin{macro}[TF]{\seq_gpop:NN, \seq_gpop:cN} +% More copies. +% \begin{macrocode} +\prg_new_eq_conditional:NNn \seq_get:NN \seq_get_left:NN { T , F , TF } +\prg_new_eq_conditional:NNn \seq_get:cN \seq_get_left:cN { T , F , TF } +\prg_new_eq_conditional:NNn \seq_pop:NN \seq_pop_left:NN { T , F , TF } +\prg_new_eq_conditional:NNn \seq_pop:cN \seq_pop_left:cN { T , F , TF } +\prg_new_eq_conditional:NNn \seq_gpop:NN \seq_gpop_left:NN { T , F , TF } +\prg_new_eq_conditional:NNn \seq_gpop:cN \seq_gpop_left:cN { T , F , TF } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% % \subsection{Viewing sequences} % % \begin{macro}{\seq_show:N, \seq_show:c} % \UnitTested -% Apply the general \cs{msg_aux_show:Nnx}. +% Apply the general \cs{__msg_show_variable:Nnn}. % \begin{macrocode} \cs_new_protected:Npn \seq_show:N #1 { - \msg_aux_show:Nnx + \__msg_show_variable:Nnn #1 { seq } - { \seq_map_function:NN #1 \msg_aux_show:n } + { \seq_map_function:NN #1 \__msg_show_item:n } } \cs_generate_variant:Nn \seq_show:N { c } % \end{macrocode} % \end{macro} % -% \subsection{Experimental functions} +% \subsection{Scratch sequences} % -% \begin{macro}[aux]{\seq_if_empty_break_return_false:N} -% The name says it all: of the sequence is empty, returns logical -% \texttt{false}. +% \begin{variable}{\l_tmpa_seq, \l_tmpb_seq, \g_tmpa_seq, \g_tmpb_seq} +% Temporary comma list variables. % \begin{macrocode} -\cs_new:Npn \seq_if_empty_break_return_false:N #1 - { - \if_meaning:w #1 \c_empty_tl - \prg_return_false: - \exp_after:wN \seq_break: - \fi: - } +\seq_new:N \l_tmpa_seq +\seq_new:N \l_tmpb_seq +\seq_new:N \g_tmpa_seq +\seq_new:N \g_tmpb_seq % \end{macrocode} -% \end{macro} -% -% \begin{macro}[TF]{\seq_get_left:NN, \seq_get_left:cN} -% \begin{macro}[TF]{\seq_get_right:NN, \seq_get_right:cN} -% Getting from the left or right with a check on the results. -% \begin{macrocode} -\prg_new_protected_conditional:Npnn \seq_get_left:NN #1 #2 { T , F , TF } - { - \seq_if_empty_break_return_false:N #1 - \exp_after:wN \seq_get_left_aux:Nw #1 \q_stop #2 - \prg_return_true: - \seq_break: - \prg_break_point:n { } - } -\prg_new_protected_conditional:Npnn \seq_get_right:NN #1#2 { T , F , TF } - { - \seq_if_empty_break_return_false:N #1 - \seq_get_right_aux:NN #1#2 - \prg_return_true: \seq_break: - \prg_break_point:n { } - } -\cs_generate_variant:Nn \seq_get_left:NNT { c } -\cs_generate_variant:Nn \seq_get_left:NNF { c } -\cs_generate_variant:Nn \seq_get_left:NNTF { c } -\cs_generate_variant:Nn \seq_get_right:NNT { c } -\cs_generate_variant:Nn \seq_get_right:NNF { c } -\cs_generate_variant:Nn \seq_get_right:NNTF { c } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}[TF]{\seq_pop_left:NN, \seq_pop_left:cN} -% \begin{macro}[TF]{\seq_gpop_left:NN, \seq_gpop_left:cN} -% \begin{macro}[TF]{\seq_pop_right:NN, \seq_pop_right:cN} -% \begin{macro}[TF]{\seq_gpop_right:NN, \seq_gpop_right:cN} -% More or less the same for popping. -% \begin{macrocode} -\prg_new_protected_conditional:Npnn \seq_pop_left:NN #1#2 { T , F , TF } - { - \seq_if_empty_break_return_false:N #1 - \exp_after:wN \seq_pop_left_aux:NnwNNN #1 \q_stop \tl_set:Nn #1#2 - \prg_return_true: \seq_break: - \prg_break_point:n { } - } -\prg_new_protected_conditional:Npnn \seq_gpop_left:NN #1#2 { T , F , TF } - { - \seq_if_empty_break_return_false:N #1 - \exp_after:wN \seq_pop_left_aux:NnwNNN #1 \q_stop \tl_gset:Nn #1#2 - \prg_return_true: \seq_break: - \prg_break_point:n { } - } -\prg_new_protected_conditional:Npnn \seq_pop_right:NN #1#2 { T , F , TF } - { - \seq_if_empty_break_return_false:N #1 - \seq_pop_right_aux_ii:NNN \tl_set:Nx #1 #2 - \prg_return_true: \seq_break: - \prg_break_point:n { } - } -\prg_new_protected_conditional:Npnn \seq_gpop_right:NN #1#2 { T , F , TF } - { - \seq_if_empty_break_return_false:N #1 - \seq_pop_right_aux_ii:NNN \tl_gset:Nx #1 #2 - \prg_return_true: \seq_break: - \prg_break_point:n { } - } -\cs_generate_variant:Nn \seq_pop_left:NNT { c } -\cs_generate_variant:Nn \seq_pop_left:NNF { c } -\cs_generate_variant:Nn \seq_pop_left:NNTF { c } -\cs_generate_variant:Nn \seq_gpop_left:NNT { c } -\cs_generate_variant:Nn \seq_gpop_left:NNF { c } -\cs_generate_variant:Nn \seq_gpop_left:NNTF { c } -\cs_generate_variant:Nn \seq_pop_right:NNT { c } -\cs_generate_variant:Nn \seq_pop_right:NNF { c } -\cs_generate_variant:Nn \seq_pop_right:NNTF { c } -\cs_generate_variant:Nn \seq_gpop_right:NNT { c } -\cs_generate_variant:Nn \seq_gpop_right:NNF { c } -\cs_generate_variant:Nn \seq_gpop_right:NNTF { c } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\seq_length:N, \seq_length:c} -% \begin{macro}[aux]{\seq_length_aux:n} -% Counting the items in a sequence 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. -% \begin{macrocode} -\cs_new:Npn \seq_length:N #1 - { - \int_eval:n - { - 0 - \seq_map_function:NN #1 \seq_length_aux:n - } - } -\cs_new:Npn \seq_length_aux:n #1 { +1 } -\cs_generate_variant:Nn \seq_length:N { c } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\seq_item:Nn, \seq_item:cn} -% \begin{macro}[aux]{\seq_item_aux:nnn} -% The idea here is to find the offset of the item from the left, then use -% a loop to grab the correct item. If the resulting offset is too large, -% then the stop code |{ ? \seq_break: } { }| will be used by the auxiliary, -% terminating the loop and returning nothing at all. -% \begin{macrocode} -\cs_new:Npn \seq_item:Nn #1#2 - { - \exp_last_unbraced:Nfo \seq_item_aux:nnn - { - \int_eval:n - { - \int_compare:nNnT {#2} < \c_zero - { \seq_length:N #1 + } - #2 - } - } - #1 - { ? \seq_break: } - { } - \prg_break_point:n { } - } -\cs_new:Npn \seq_item_aux:nnn #1#2#3 - { - \use_none:n #2 - \int_compare:nNnTF {#1} = \c_zero - { \seq_break:n { \exp_not:n {#3} } } - { \exp_args:Nf \seq_item_aux:nnn { \int_eval:n { #1 - 1 } } } - } -\cs_generate_variant:Nn \seq_item:Nn { c } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\seq_use:N, \seq_use:c} -% A simple short cut for a mapping. -% \begin{macrocode} -\cs_new:Npn \seq_use:N #1 { \seq_map_function:NN #1 \use:n } -\cs_generate_variant:Nn \seq_use:N { c } -% \end{macrocode} -% \end{macro} -% -% \begin{macro} -% { -% \seq_mapthread_function:NNN, \seq_mapthread_function:NcN, -% \seq_mapthread_function:cNN, \seq_mapthread_function:ccN -% } -% \begin{macro}[aux]{\seq_mapthread_function_aux:NN} -% \begin{macro}[aux]{\seq_mapthread_function_aux:Nnnwnn} -% The idea here is to first expand both of the sequences, adding the usual -% |{ ? \seq_break: } { }| to the end of each on. This is most conveniently -% done in two steps using an auxiliary function. The mapping then throws -% away the first token of |#2| and |#5|, which for items in the sequences -% will both be \cs{seq_item:n}. The function to be mapped will then be -% applied to the two entries. When the code hits the end of one of the -% sequences, the break material will stop the entire loop and tidy up. This -% avoids needing to find the length of the two sequences, or worrying about -% which is longer. -% \begin{macrocode} -\cs_new:Npn \seq_mapthread_function:NNN #1#2#3 - { - \exp_after:wN \seq_mapthread_function_aux:NN - \exp_after:wN #3 - \exp_after:wN #1 - #2 - { ? \seq_break: } { } - \prg_break_point:n { } - } -\cs_new:Npn \seq_mapthread_function_aux:NN #1#2 - { - \exp_after:wN \seq_mapthread_function_aux:Nnnwnn - \exp_after:wN #1 - #2 - { ? \seq_break: } { } - \q_stop - } -\cs_new:Npn \seq_mapthread_function_aux:Nnnwnn #1#2#3#4 \q_stop #5#6 - { - \use_none:n #2 - \use_none:n #5 - #1 {#3} {#6} - \seq_mapthread_function_aux:Nnnwnn #1 #4 \q_stop - } -\cs_generate_variant:Nn \seq_mapthread_function:NNN { Nc } -\cs_generate_variant:Nn \seq_mapthread_function:NNN { c , cc } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro} -% { -% \seq_set_from_clist:NN, \seq_set_from_clist:cN, -% \seq_set_from_clist:Nc, \seq_set_from_clist:cc, -% \seq_set_from_clist:Nn, \seq_set_from_clist:cn -% } -% \begin{macro} -% { -% \seq_gset_from_clist:NN, \seq_gset_from_clist:cN, -% \seq_gset_from_clist:Nc, \seq_gset_from_clist:cc, -% \seq_gset_from_clist:Nn, \seq_gset_from_clist:cn -% } -% Setting a sequence from a comma-separated list is done using a simple -% mapping. -% \begin{macrocode} -\cs_new_protected:Npn \seq_set_from_clist:NN #1#2 - { - \tl_set:Nx #1 - { \clist_map_function:NN #2 \seq_wrap_item:n } - } -\cs_new_protected:Npn \seq_set_from_clist:Nn #1#2 - { - \tl_set:Nx #1 - { \clist_map_function:nN {#2} \seq_wrap_item:n } - } -\cs_new_protected:Npn \seq_gset_from_clist:NN #1#2 - { - \tl_gset:Nx #1 - { \clist_map_function:NN #2 \seq_wrap_item:n } - } -\cs_new_protected:Npn \seq_gset_from_clist:Nn #1#2 - { - \tl_gset:Nx #1 - { \clist_map_function:nN {#2} \seq_wrap_item:n } - } -\cs_generate_variant:Nn \seq_set_from_clist:NN { Nc } -\cs_generate_variant:Nn \seq_set_from_clist:NN { c , cc } -\cs_generate_variant:Nn \seq_set_from_clist:Nn { c } -\cs_generate_variant:Nn \seq_gset_from_clist:NN { Nc } -\cs_generate_variant:Nn \seq_gset_from_clist:NN { c , cc } -\cs_generate_variant:Nn \seq_gset_from_clist:Nn { c } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro} -% {\seq_reverse:N, \seq_reverse:c, \seq_greverse:N, \seq_greverse:c} -% \begin{macro}[aux]{\seq_reverse_aux:NN} -% \begin{macro}[aux]{\seq_reverse_aux_item:nwn} -% Previously, \cs{seq_reverse:N} was coded by collecting the items -% in reverse order after an \cs{exp_stop_f:} marker. -% \begin{verbatim} -% \cs_new_protected:Npn \seq_reverse:N #1 -% { -% \cs_set_eq:NN \seq_item:n \seq_reverse_aux_item:nw -% \tl_set:Nf #2 { #2 \exp_stop_f: } -% } -% \cs_new:Npn \seq_reverse_aux_item:nw #1 #2 \exp_stop_f: -% { -% #2 \exp_stop_f: -% \seq_item:n {#1} -% } -% \end{verbatim} -% At first, this seems optimal, since we can forget about each item -% as soon as it is placed after \cs{exp_stop_f:}. Unfortunately, -% \TeX{}'s usual tail recursion does not take place in this case: -% since the following \cs{seq_reverse_aux_item:nw} only reads -% tokens until \cs{exp_stop_f:}, and never reads the -% |\seq_item:n {#1}| left by the previous call, \TeX{} cannot -% remove that previous call from the stack, and in particular -% must retain the various macro paramters in memory, until the -% end of the replacement text is reached. The stack is thus -% only flushed after all the \cs{seq_reverse_aux_item:nw} are -% expanded. Keeping track of the arguments of all those calls -% uses up a memory quadratic in the length of the sequence. -% \TeX{} can then not cope with more than a few thousand items. -% -% Instead, we collect the items in the argument -% of \cs{exp_not:n}. The previous calls are cleanly removed -% from the stack, and the memory consumption becomes linear. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \seq_tmp:w { } -\cs_new_protected_nopar:Npn \seq_reverse:N - { \seq_reverse_aux:NN \tl_set:Nx } -\cs_new_protected_nopar:Npn \seq_greverse:N - { \seq_reverse_aux:NN \tl_gset:Nx } -\cs_new_protected:Npn \seq_reverse_aux:NN #1 #2 - { - \cs_set_eq:NN \seq_tmp:w \seq_item:n - \cs_set_eq:NN \seq_item:n \seq_reverse_aux_item:nwn - #1 #2 { #2 \exp_not:n { } } - \cs_set_eq:NN \seq_item:n \seq_tmp:w - } -\cs_new:Npn \seq_reverse_aux_item:nwn #1 #2 \exp_not:n #3 - { - #2 - \exp_not:n { \seq_item:n {#1} #3 } - } -\cs_generate_variant:Nn \seq_reverse:N { c } -\cs_generate_variant:Nn \seq_greverse:N { c } -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\seq_set_filter:NNn, \seq_gset_filter:NNn} -% \begin{macro}[aux]{\seq_set_filter_aux:NNNn} -% Similar to \cs{seq_map_inline:Nn}, without a -% \cs{prg_break_point:n} because the user's code -% is performed within the evaluation of a boolean expression, -% and skipping out of that would break horribly. -% The \cs{seq_wrap_item:n} function inserts the relevant -% \cs{seq_item:n} without expansion in the input stream, -% hence in the \texttt{x}-expanding assignment. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \seq_set_filter:NNn - { \seq_set_filter_aux:NNNn \tl_set:Nx } -\cs_new_protected_nopar:Npn \seq_gset_filter:NNn - { \seq_set_filter_aux:NNNn \tl_gset:Nx } -\cs_new_protected:Npn \seq_set_filter_aux:NNNn #1#2#3#4 - { - \seq_push_item_def:n { \bool_if:nT {#4} { \seq_wrap_item:n {##1} } } - #1 #2 { #3 \prg_break_point:n { } } - \seq_pop_item_def: - } -% \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\seq_set_map:NNn,\seq_gset_map:NNn} -% \begin{macro}[aux]{\seq_set_map_aux:NNNn} -% Very similar to \cs{seq_set_filter:NNn}. We could actually -% merge the two within a single function, but it would have weird -% semantics. -% \begin{macrocode} -\cs_new_protected_nopar:Npn \seq_set_map:NNn - { \seq_set_map_aux:NNNn \tl_set:Nx } -\cs_new_protected_nopar:Npn \seq_gset_map:NNn - { \seq_set_map_aux:NNNn \tl_gset:Nx } -\cs_new_protected:Npn \seq_set_map_aux:NNNn #1#2#3#4 - { - \seq_push_item_def:n { \exp_not:N \seq_item:n {#4} } - #1 #2 { #3 } - \seq_pop_item_def: - } -% \end{macrocode} -% \end{macro} -% \end{macro} +% \end{variable} % % \subsection{Deprecated interfaces} % @@ -1904,6 +1602,25 @@ % \end{macrocode} % \end{macro} % +% Deprecated 2012-05-13 for removal by 2012-11-30. +% +% \begin{macro}{\seq_length:N, \seq_length:c} +% \begin{macrocode} +\cs_new_eq:NN \seq_length:N \seq_count:N +\cs_new_eq:NN \seq_length:c \seq_count:c +% \end{macrocode} +% \end{macro} +% +% Deprecated 2012-05-23 for removal by 2012-08-30. +% +% \begin{macro}{\seq_use:N, \seq_use:c} +% A simple short cut for a mapping. +% \begin{macrocode} +\cs_new:Npn \seq_use:N #1 { \seq_map_function:NN #1 \use:n } +\cs_generate_variant:Nn \seq_use:N { c } +% \end{macrocode} +% \end{macro} +% % \begin{macrocode} %</initex|package> % \end{macrocode} |