summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3seq.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3seq.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3seq.dtx1411
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}