summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2012-07-23 17:15:00 +0000
committerKarl Berry <karl@freefriends.org>2012-07-23 17:15:00 +0000
commit134349701bddf7cbbacf6030c6b9f9838aff96fa (patch)
treeec1140c46e1c0347a671a6fa3cf8af5a79e95f93 /Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
parentf7855c12c18bb97b7b9e49ab685ee558d8c0b47b (diff)
l3kernel 3990 (17jul12)
git-svn-id: svn://tug.org/texlive/trunk@27108 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3tl.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3tl.dtx1450
1 files changed, 672 insertions, 778 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
index 51fcddc242e..08d2630523d 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
@@ -35,8 +35,8 @@
%
%<*driver|package>
\RequirePackage{l3names}
-\GetIdInfo$Id: l3tl.dtx 3490 2012-03-04 01:00:53Z bruno $
- {L3 Experimental token lists}
+\GetIdInfo$Id: l3tl.dtx 3986 2012-07-15 19:23:51Z joseph $
+ {L3 Token lists}
%</driver|package>
%<*driver>
\documentclass[full]{l3doc}
@@ -148,10 +148,23 @@
% \tl_gset_eq:NN, \tl_gset_eq:cN, \tl_gset_eq:Nc, \tl_gset_eq:cc
% }
% \begin{syntax}
-% \cs{tl_set_eq:NN} \meta{tl~var1} \meta{tl~var2}
+% \cs{tl_set_eq:NN} \meta{tl~var_1} \meta{tl~var_2}
% \end{syntax}
-% Sets the content of \meta{tl~var1} equal to that of
-% \meta{tl~var2}.
+% Sets the content of \meta{tl~var_1} equal to that of
+% \meta{tl~var_2}.
+% \end{function}
+%
+% \begin{function}[added = 2012-05-18]
+% {
+% \tl_concat:NNN, \tl_concat:ccc,
+% \tl_gconcat:NNN, \tl_gconcat:ccc
+% }
+% \begin{syntax}
+% \cs{tl_concat:NNN} \meta{tl~var_1} \meta{tl~var_2} \meta{tl~var_3}
+% \end{syntax}
+% Concatenates the content of \meta{tl~var_2} and \meta{tl~var_3}
+% together and saves the result in \meta{tl~var_1}. The \meta{tl~var_2}
+% will be placed at the left side of the new token list.
% \end{function}
%
% \begin{function}[EXP, pTF, added=2012-03-03]{\tl_if_exist:N, \tl_if_exist:c}
@@ -363,23 +376,21 @@
% (\emph{i.e.}~contains no tokens at all).
% \end{function}
%
-% \begin{function}[EXP,pTF]
-% {\tl_if_empty:n, \tl_if_empty:V, \tl_if_empty:o, \tl_if_empty:x}
+% \begin{function}[added = 2012-05-24, updated = 2012-06-05, EXP,pTF]
+% {\tl_if_empty:n, \tl_if_empty:V, \tl_if_empty:o}
% \begin{syntax}
% \cs{tl_if_empty_p:n} \Arg{token list}
% \cs{tl_if_empty:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
% \end{syntax}
% Tests if the \meta{token list} is entirely empty
% (\emph{i.e.}~contains no tokens at all).
-% All versions of these functions are fully expandable
-% (including those involving an \texttt{x}-type expansion).
% \end{function}
%
% \begin{function}[EXP,pTF]
% {\tl_if_eq:NN, \tl_if_eq:Nc, \tl_if_eq:cN, \tl_if_eq:cc}
% \begin{syntax}
-% \cs{tl_if_eq_p:NN} \Arg{tl var1} \Arg{tl var2}
-% \cs{tl_if_eq:NNTF} \Arg{tl var1} \Arg{tl var2} \Arg{true code} \Arg{false code}
+% \cs{tl_if_eq_p:NN} \Arg{tl var_1} \Arg{tl var_2}
+% \cs{tl_if_eq:NNTF} \Arg{tl var_1} \Arg{tl var_2} \Arg{true code} \Arg{false code}
% \end{syntax}
% Compares the content of two \meta{token list variables} and
% is logically \texttt{true} if the two contain the same list of
@@ -395,9 +406,9 @@
%
% \begin{function}[TF]{\tl_if_eq:nn}
% \begin{syntax}
-% \cs{tl_if_eq:nnTF} \meta{token list1} \Arg{token list2} \Arg{true code} \Arg{false code}
+% \cs{tl_if_eq:nnTF} \meta{token list_1} \Arg{token list_2} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if \meta{token list1} and \meta{token list2} are equal, both in
+% Tests if \meta{token list_1} and \meta{token list_2} are equal, both in
% respect of character codes and category codes.
% \end{function}
%
@@ -414,9 +425,9 @@
% \begin{function}[TF]
% {\tl_if_in:nn, \tl_if_in:Vn, \tl_if_in:on, \tl_if_in:no}
% \begin{syntax}
-% \cs{tl_if_in:nnTF} \Arg{token list1} \Arg{token list2} \Arg{true code} \Arg{false code}
+% \cs{tl_if_in:nnTF} \Arg{token list_1} \Arg{token list_2} \Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if <token list2> is found inside <token list1>.
+% Tests if <token list_2> is found inside <token list_1>.
% The \meta{token list} cannot contain the tokens |{|, |}| or |#|
% (assuming the usual \TeX{} category codes apply).
% \end{function}
@@ -430,8 +441,8 @@
% Tests if the content of the \meta{tl~var} consists of a single item,
% \emph{i.e.}~is either a single normal token (excluding spaces,
% and brace tokens) or a single brace group, surrounded by optional
-% spaces on both sides. In other words, such a token list has length
-% $1$ according to \cs{tl_length:N}.
+% spaces on both sides. In other words, such a token list has token count
+% $1$ according to \cs{tl_count:N}.
% \end{function}
%
% \begin{function}[updated = 2011-08-13, EXP,pTF]{\tl_if_single:n}
@@ -442,22 +453,33 @@
% Tests if the token list has exactly one item, \emph{i.e.}~is either
% a single normal token or a single brace group, surrounded by
% optional spaces on both sides. In other words, such a token list
-% has length $1$ according to \cs{tl_length:n}.
+% has token count $1$ according to \cs{tl_count:n}.
% \end{function}
%
-% \begin{function}[added = 2011-08-11,EXP,pTF]{\tl_if_single_token:n}
+% \begin{function}[added = 2012-06-03, EXP]{\tl_case:Nnn, \tl_case:cnn}
% \begin{syntax}
-% \cs{tl_if_single_token_p:n} \Arg{token list}
-% \cs{tl_if_single_token:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \cs{tl_case:Nnn} \meta{test token list variable} \\
+% ~~"{" \\
+% ~~~~\meta{token list variable case_1} \Arg{code case_1} \\
+% ~~~~\meta{token list variable case_2} \Arg{code case_2} \\
+% ~~~~\ldots \\
+% ~~~~\meta{token list variable case_n} \Arg{code case_n} \\
+% ~~"}" \\
+% ~~\Arg{else code}
% \end{syntax}
-% Tests if the token list consists of exactly one token, \emph{i.e.}~is
-% either a single space character or a single \enquote{normal} token.
-% Token groups (|{|\ldots|}|) are not single tokens.
+% This function compares the \meta{test token list variable} in turn
+% with each of the \meta{token list variable cases}. If the two
+% are equal (as described for
+% \cs{tl_if_eq:nnTF}
+% then the associated \meta{code} is left in the input
+% stream. If none of the tests are \texttt{true} then the
+% \texttt{else code} will be left in the input stream.
% \end{function}
%
% \section{Mapping to token lists}
%
-% \begin{function}[rEXP]{\tl_map_function:NN, \tl_map_function:cN}
+% \begin{function}[updated = 2012-06-29, rEXP]
+% {\tl_map_function:NN, \tl_map_function:cN}
% \begin{syntax}
% \cs{tl_map_function:NN} \meta{tl~var} \meta{function}
% \end{syntax}
@@ -468,7 +490,7 @@
% \texttt{n}-type arguments. See also \cs{tl_map_function:nN}.
% \end{function}
%
-% \begin{function}[rEXP]{\tl_map_function:nN}
+% \begin{function}[updated = 2012-06-29, rEXP]{\tl_map_function:nN}
% \begin{syntax}
% \cs{tl_map_function:nN} \meta{token list} \meta{function}
% \end{syntax}
@@ -479,7 +501,8 @@
% \texttt{n}-type arguments. See also \cs{tl_map_function:NN}.
% \end{function}
%
-% \begin{function}{\tl_map_inline:Nn, \tl_map_inline:cn}
+% \begin{function}[updated = 2012-06-29]
+% {\tl_map_inline:Nn, \tl_map_inline:cn}
% \begin{syntax}
% \cs{tl_map_inline:Nn} \meta{tl~var} \Arg{inline function}
% \end{syntax}
@@ -489,7 +512,7 @@
% inside another. See also \cs{tl_map_function:Nn}.
% \end{function}
%
-% \begin{function}{\tl_map_inline:nn}
+% \begin{function}[updated = 2012-06-29]{\tl_map_inline:nn}
% \begin{syntax}
% \cs{tl_map_inline:nn} \meta{token list} \Arg{inline function}
% \end{syntax}
@@ -499,7 +522,8 @@
% inside another. See also \cs{tl_map_function:nn}.
% \end{function}
%
-% \begin{function}{\tl_map_variable:NNn, \tl_map_variable:cNn}
+% \begin{function}[updated = 2012-06-29]
+% {\tl_map_variable:NNn, \tl_map_variable:cNn}
% \begin{syntax}
% \cs{tl_map_variable:NNn} \meta{tl~var} \meta{variable} \Arg{function}
% \end{syntax}
@@ -510,7 +534,7 @@
% \cs{tl_map_inline:Nn}.
% \end{function}
%
-% \begin{function}{\tl_map_variable:nNn}
+% \begin{function}[updated = 2012-06-29]{\tl_map_variable:nNn}
% \begin{syntax}
% \cs{tl_map_variable:nNn} \meta{token list} \meta{variable} \Arg{function}
% \end{syntax}
@@ -521,7 +545,7 @@
% \cs{tl_map_inline:nn}.
% \end{function}
%
-% \begin{function}[rEXP]{\tl_map_break:}
+% \begin{function}[updated = 2012-06-29, rEXP]{\tl_map_break:}
% \begin{syntax}
% \cs{tl_map_break:}
% \end{syntax}
@@ -540,6 +564,40 @@
% \end{verbatim}
% Use outside of a \cs{tl_map_\ldots} scenario will lead low
% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted by the
+% 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}[updated = 2012-06-29, rEXP]{\tl_map_break:n}
+% \begin{syntax}
+% \cs{tl_map_break:n} \Arg{tokens}
+% \end{syntax}
+% Used to terminate a \cs{tl_map_\ldots} function before all
+% entries in the \meta{token list variable} have been processed, inserting
+% the \meta{tokens} after the mapping has ended. This will
+% normally take place within a conditional statement, for example
+% \begin{verbatim}
+% \tl_map_inline:Nn \l_my_tl
+% {
+% \str_if_eq:nnTF { #1 } { bingo }
+% { \tl_map_break:n { <tokens> } }
+% {
+% % Do something useful
+% }
+% }
+% \end{verbatim}
+% Use outside of a \cs{tl_map_\ldots} scenario will lead to low
+% level \TeX{} errors.
+% \begin{texnote}
+% When the mapping is broken, additional tokens may be inserted by the
+% 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}
%
% \section{Using token lists}
@@ -564,7 +622,8 @@
% in the input stream. Note that this function requires only a single
% expansion.
% \begin{texnote}
-% This is the \eTeX{} primitive \tn{detokenize}.
+% This is the \eTeX{} primitive \tn{detokenize}. Hence its argument
+% \emph{must} be given within braces.
% \end{texnote}
% \end{function}
%
@@ -580,28 +639,28 @@
%
% \section{Working with the content of token lists}
%
-% \begin{function}[updated = 2011-08-13, EXP]
-% {\tl_length:n, \tl_length:V, \tl_length:o}
+% \begin{function}[added = 2012-05-13, EXP]
+% {\tl_count:n, \tl_count:V, \tl_count:o}
% \begin{syntax}
-% \cs{tl_length:n} \Arg{tokens}
+% \cs{tl_count:n} \Arg{tokens}
% \end{syntax}
% Counts the number of \meta{items} in \meta{tokens} and leaves this
% information in the input stream. Unbraced tokens count as one
% element as do each token group (|{|\ldots|}|). This process will
% ignore any unprotected spaces within \meta{tokens}. See also
-% \cs{tl_length:N}. This function requires three expansions,
+% \cs{tl_count:N}. This function requires three expansions,
% giving an \meta{integer denotation}.
% \end{function}
%
-% \begin{function}[updated = 2011-08-13, EXP]{\tl_length:N, \tl_length:c}
+% \begin{function}[added = 2012-05-13, EXP]{\tl_count:N, \tl_count:c}
% \begin{syntax}
-% \cs{tl_length:N} \Arg{tl~var}
+% \cs{tl_count:N} \Arg{tl~var}
% \end{syntax}
% Counts the number of token groups in the \meta{tl~var}
% and leaves this information in the input stream. Unbraced tokens
% count as one element as do each token group (|{|\ldots|}|). This
% process will ignore any unprotected spaces within \meta{tokens}.
-% See also \cs{tl_length:n}. This function requires three expansions,
+% See also \cs{tl_count:n}. This function requires three expansions,
% giving an \meta{integer denotation}.
% \end{function}
%
@@ -611,8 +670,8 @@
% \cs{tl_reverse:n} \Arg{token list}
% \end{syntax}
% Reverses the order of the \meta{items} in the \meta{token list},
-% so that \meta{item1}\meta{item2}\meta{item3} \ldots \meta{item$_n$}
-% becomes \meta{item$_n$}\ldots \meta{item3}\meta{item2}\meta{item1}.
+% so that \meta{item_1}\meta{item_2}\meta{item_3} \ldots \meta{item_n}
+% becomes \meta{item_n}\ldots \meta{item_3}\meta{item_2}\meta{item_1}.
% This process will preserve unprotected space within the
% \meta{token list}. Tokens are not reversed within braced token
% groups, which keep their outer set of braces.
@@ -633,8 +692,8 @@
% \cs{tl_reverse:N} \Arg{tl~var}
% \end{syntax}
% Reverses the order of the \meta{items} stored in \meta{tl~var}, so
-% that \meta{item1}\meta{item2}\meta{item3} \ldots \meta{item$_n$}
-% becomes \meta{item$_n$}\ldots \meta{item3}\meta{item2}\meta{item1}.
+% that \meta{item_1}\meta{item_2}\meta{item_3} \ldots \meta{item_n}
+% becomes \meta{item_n}\ldots \meta{item_3}\meta{item_2}\meta{item_1}.
% This process will preserve unprotected spaces within the
% \meta{token list variable}. Braced token groups are copied without
% reversing the order of tokens, but keep the outer set of braces.
@@ -646,8 +705,8 @@
% \cs{tl_reverse_items:n} \Arg{token list}
% \end{syntax}
% Reverses the order of the \meta{items} stored in \meta{tl~var},
-% so that \Arg{item_1}\Arg{item_2}\Arg{item_3} \ldots \Arg{item$_n$}
-% becomes \Arg{item$_n$} \ldots{} \Arg{item_3}\Arg{item_2}\Arg{item_1}.
+% so that \Arg{item_1}\Arg{item_2}\Arg{item_3} \ldots \Arg{item_n}
+% becomes \Arg{item_n} \ldots{} \Arg{item_3}\Arg{item_2}\Arg{item_1}.
% This process will remove any unprotected space within the
% \meta{token list}. Braced token groups are copied without
% reversing the order of tokens, and keep the outer set of braces.
@@ -662,14 +721,14 @@
% \end{texnote}
% \end{function}
%
-% \begin{function}[added = 2011-07-09, updated = 2011-08-13, EXP]
+% \begin{function}[added = 2011-07-09, updated = 2012-06-25, EXP]
% {\tl_trim_spaces:n}
% \begin{syntax}
% \cs{tl_trim_spaces:n} \meta{token list}
% \end{syntax}
% Removes any leading and trailing explicit space characters
% from the \meta{token list} and leaves the result in the input
-% stream. This process requires two expansions.
+% stream.
% \begin{texnote}
% The result is returned within the \tn{unexpanded}
% primitive (\cs{exp_not:n}), which means that the token
@@ -793,78 +852,75 @@
% nothing is left in the input stream.
% \end{function}
%
-% \begin{function}[updated = 2011-08-10, EXP,pTF]{\tl_if_head_eq_catcode:nN}
+% \begin{function}[updated = 2012-07-09, EXP, pTF]{\tl_if_head_eq_catcode:nN}
% \begin{syntax}
% \cs{tl_if_head_eq_catcode_p:nN} \Arg{token list} \meta{test token}
% \cs{tl_if_head_eq_catcode:nNTF} \Arg{token list} \meta{test token}
% ~~\Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if the first \meta{token} in the \meta{token list} has the same
-% category code as the \meta{test token}. In the case where
-% \meta{token list} is empty, its head is considered to be \cs{q_nil},
-% and the test will be true if \meta{test token} is a control sequence.
+% Tests if the first \meta{token} in the \meta{token list} has the
+% same category code as the \meta{test token}. In the case where the
+% \meta{token list} is empty, the test will always be \texttt{false}.
% \end{function}
%
-% \begin{function}[updated = 2011-08-10, EXP,pTF]
+% \begin{function}[updated = 2012-07-09, EXP, pTF]
% {\tl_if_head_eq_charcode:nN, \tl_if_head_eq_charcode:fN}
% \begin{syntax}
% \cs{tl_if_head_eq_charcode_p:nN} \Arg{token list} \meta{test token}
% \cs{tl_if_head_eq_charcode:nNTF} \Arg{token list} \meta{test token}
% ~~\Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if the first \meta{token} in the \meta{token list} has the same
-% character code as the \meta{test token}. In the case where
-% \meta{token list} is empty, its head is considered to be \cs{q_nil},
-% and the test will be true if \meta{test token} is a control sequence.
+% Tests if the first \meta{token} in the \meta{token list} has the
+% same character code as the \meta{test token}. In the case where the
+% \meta{token list} is empty, the test will always be \texttt{false}.
% \end{function}
%
-% \begin{function}[updated = 2011-08-10, EXP,pTF]{\tl_if_head_eq_meaning:nN}
+% \begin{function}[updated = 2012-07-09, EXP, pTF]{\tl_if_head_eq_meaning:nN}
% \begin{syntax}
% \cs{tl_if_head_eq_meaning_p:nN} \Arg{token list} \meta{test token}
% \cs{tl_if_head_eq_meaning:nNTF} \Arg{token list} \meta{test token}
% ~~\Arg{true code} \Arg{false code}
% \end{syntax}
-% Tests if the first \meta{token} in the \meta{token list} has the same
-% meaning as the \meta{test token}. In the case where \meta{token list}
-% is empty, its head is considered to be \cs{q_nil}, and the test will
-% be true if \meta{test token} has the same meaning as \cs{q_nil}.
+% Tests if the first \meta{token} in the \meta{token list} has the
+% same meaning as the \meta{test token}. In the case where
+% \meta{token list} is empty, the test will always be \texttt{false}.
% \end{function}
%
-% \begin{function}[updated = 2011-08-11, EXP,pTF]{\tl_if_head_group:n}
+% \begin{function}[added = 2012-07-08, EXP, pTF]{\tl_if_head_is_group:n}
% \begin{syntax}
-% \cs{tl_if_head_group_p:n} \Arg{token list}
-% \cs{tl_if_head_group:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \cs{tl_if_head_is_group_p:n} \Arg{token list}
+% \cs{tl_if_head_is_group:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
% \end{syntax}
% Tests if the first \meta{token} in the \meta{token list}
% is an explicit begin-group character (with category code~1
% and any character code), in other words, if the \meta{token list}
-% starts with a brace group. In particular, the test is false
+% starts with a brace group. In particular, the test is \texttt{false}
% if the \meta{token list} starts with an implicit token such as
% \cs{c_group_begin_token}, or if it empty.
% This function is useful to implement actions on token lists on
% a token by token basis.
% \end{function}
%
-% \begin{function}[added = 2011-08-11,EXP,pTF]{\tl_if_head_N_type:n}
+% \begin{function}[added = 2012-07-08, EXP, pTF]{\tl_if_head_is_N_type:n}
% \begin{syntax}
-% \cs{tl_if_head_N_type_p:n} \Arg{token list}
-% \cs{tl_if_head_N_type:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \cs{tl_if_head_is_N_type_p:n} \Arg{token list}
+% \cs{tl_if_head_is_N_type:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
% \end{syntax}
% Tests if the first \meta{token} in the \meta{token list}
% is a normal \texttt{N}-type argument. In other words,
% it is neither an explicit space character (with category code~10
% and character code~32) nor an explicit begin-group character
% (with category code~1 and any character code). An empty
-% argument yields false, as it does not have a \enquote{normal}
+% argument yields \texttt{false}, as it does not have a \enquote{normal}
% first token.
% This function is useful to implement actions on token lists on
% a token by token basis.
% \end{function}
%
-% \begin{function}[updated = 2011-08-11,EXP,pTF]{\tl_if_head_space:n}
+% \begin{function}[updated = 2012-07-08, EXP, pTF]{\tl_if_head_is_space:n}
% \begin{syntax}
-% \cs{tl_if_head_space_p:n} \Arg{token list}
-% \cs{tl_if_head_space:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \cs{tl_if_head_is_space_p:n} \Arg{token list}
+% \cs{tl_if_head_is_space:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
% \end{syntax}
%^^A We need to add a discussion of
%^^A explicit vs implicit tokens somewhere in the doc.
@@ -872,7 +928,7 @@
% is an explicit space character (with category code~$10$
% and character code~$32$). If \meta{token list} starts with
% an implicit token such as \cs{c_space_token}, the test
-% will yield false, as well as if the argument is empty.
+% will yield \texttt{false}, as well as if the argument is empty.
% This function is useful to implement actions on token lists on
% a token by token basis.
% \begin{texnote}
@@ -942,89 +998,22 @@
% code and so should only be used for short-term storage.
% \end{variable}
%
-% \section{Experimental token list functions}
-%
-% \begin{function}[added = 2012-01-08, EXP]{\tl_reverse_tokens:n}
-% \begin{syntax}
-% \cs{tl_reverse_tokens:n} \Arg{tokens}
-% \end{syntax}
-% This function, which works directly on \TeX{} tokens, reverses
-% the order of the \meta{tokens}: the first will be the last and
-% the last will become first. Spaces are preserved. The reversal
-% also operates within brace groups, but the braces themselves
-% are not exchanged, as this would lead to an unbalanced token
-% list. For instance, \cs{tl_reverse_tokens:n} |{a~{b()}}|
-% leaves |{)(b}~a| in the input stream. This function requires
-% two steps of expansion.
-% \begin{texnote}
-% The result is returned within the \tn{unexpanded}
-% primitive (\cs{exp_not:n}), which means that the token
-% list will not expand further when appearing in an x-type
-% argument expansion.
-% \end{texnote}
-% \end{function}
-%
-% \begin{function}[added = 2011-08-11, EXP]{\tl_length_tokens:n}
-% \begin{syntax}
-% \cs{tl_length_tokens:n} \Arg{tokens}
-% \end{syntax}
-% Counts the number of \TeX{} tokens in the \meta{tokens} and leaves
-% this information in the input stream. Every token, including spaces and
-% braces, contributes one to the total; thus for instance, the length of
-% |a~{bc}| is $6$.
-% This function requires three expansions,
-% giving an \meta{integer denotation}.
-% \end{function}
-%
-% \begin{function}[added = 2012-01-08, EXP]
-% {\tl_expandable_uppercase:n,\tl_expandable_lowercase:n}
-% \begin{syntax}
-% \cs{tl_expandable_uppercase:n} \Arg{tokens}
-% \cs{tl_expandable_lowercase:n} \Arg{tokens}
-% \end{syntax}
-% The \cs{tl_expandable_uppercase:n} function works through all of
-% the \meta{tokens}, replacing characters in the range |a|--|z|
-% (with arbitrary category code) by the corresponding letter
-% in the range |A|--|Z|, with category code $11$ (letter). Similarly,
-% \cs{tl_expandable_lowercase:n} replaces characters in the range
-% |A|--|Z| by letters in the range |a|--|z|, and leaves other tokens
-% unchanged. This function requires two steps of expansion.
-% \begin{texnote}
-% Begin-group and end-group characters are normalized and become
-% |{| and |}|, respectively.
-% The result is returned within the \tn{unexpanded}
-% primitive (\cs{exp_not:n}), which means that the token
-% list will not expand further when appearing in an x-type
-% argument expansion.
-% \end{texnote}
-% \end{function}
+% \section{Internal functions}
%
-% \begin{function}[added = 2011-11-21, updated = 2012-01-08, EXP]
-% {\tl_item:nn, \tl_item:Nn, \tl_item:cn}
+% \begin{function}{\__tl_trim_spaces:nn}
% \begin{syntax}
-% \cs{tl_item:nn} \Arg{token list} \Arg{integer expression}
+% \cs{__tl_trim_spaces:nn} |{ \q_mark| \meta{token list} |}| \Arg{continuation}
% \end{syntax}
-% Indexing items in the \meta{token list} from $0$ on the left, this
-% function will evaluate the \meta{integer expression} and leave the
-% appropriate item from the \meta{token list} in the input stream.
-% If the \meta{integer expression} is negative, indexing occurs from
-% the right of the token list, starting at $-1$ for the right-most item.
-% If the index is out of bounds, then thr function expands 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}
+% This function removes all leading and trailing explicit space
+% characters from the \meta{token list}, and expands to the
+% \meta{continuation}, followed by a brace group containing
+% \cs{use_none:n} \cs{q_mark} \meta{trimmed token list}. For
+% instance, \cs{tl_trim_spaces:n} is implemented by taking the
+% \meta{continuation} to be \cs{exp_not:o}, and the \texttt{o}-type
+% expansion removes the \cs{q_mark}. This function is also used in
+% \pkg{l3clist}.
% \end{function}
%
-% \section{Internal functions}
-%
-% \begin{variable}{\q_tl_act_mark,\q_tl_act_stop}
-% Quarks which are only used for the particular purposes of
-% \cs{tl_act_...} functions.
-% \end{variable}
-%
% \end{documentation}
%
% \begin{implementation}
@@ -1036,10 +1025,14 @@
% \end{macrocode}
%
% \begin{macrocode}
+%<@@=tl>
+% \end{macrocode}
+%
+% \begin{macrocode}
%<*package>
\ProvidesExplPackage
{\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
-\package_check_loaded_expl:
+\__expl_package_check:
%</package>
% \end{macrocode}
%
@@ -1055,7 +1048,7 @@
% \begin{macrocode}
\cs_new_protected:Npn \tl_new:N #1
{
- \chk_if_free_cs:N #1
+ \__chk_if_free_cs:N #1
\cs_gset_eq:NN #1 \c_empty_tl
}
\cs_generate_variant:Nn \tl_new:N { c }
@@ -1067,12 +1060,12 @@
% \begin{macrocode}
\cs_new_protected:Npn \tl_const:Nn #1#2
{
- \chk_if_free_cs:N #1
+ \__chk_if_free_cs:N #1
\cs_gset_nopar:Npx #1 { \exp_not:n {#2} }
}
\cs_new_protected:Npn \tl_const:Nx #1#2
{
- \chk_if_free_cs:N #1
+ \__chk_if_free_cs:N #1
\cs_gset_nopar:Npx #1 {#2}
}
\cs_generate_variant:Nn \tl_const:Nn { c }
@@ -1134,6 +1127,20 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\tl_concat:NNN, \tl_concat:ccc}
+% \begin{macro}{\tl_gconcat:NNN, \tl_gconcat:ccc}
+% Concatenating token lists is easy.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_concat:NNN #1#2#3
+ { \tl_set:Nx #1 { \exp_not:o {#2} \exp_not:o {#3} } }
+\cs_new_protected:Npn \tl_gconcat:NNN #1#2#3
+ { \tl_gset:Nx #1 { \exp_not:o {#2} \exp_not:o {#3} } }
+\cs_generate_variant:Nn \tl_concat:NNN { ccc }
+\cs_generate_variant:Nn \tl_gconcat:NNN { ccc }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
% \begin{macro}[pTF]{\tl_if_exist:N, \tl_if_exist:c}
% Copies of the \texttt{cs} functions defined in \pkg{l3basics}.
% \begin{macrocode}
@@ -1148,6 +1155,37 @@
% \end{macrocode}
% \end{macro}
%
+% \subsection{Constant token lists}
+%
+% \begin{variable}{\c_job_name_tl}
+% Inherited from the \LaTeX3 name for the primitive: this needs to
+% actually contain the text of the job name rather than the name of
+% the primitive, of course. \LuaTeX{} does not quote file names containing
+% spaces, whereas \pdfTeX{} and \XeTeX{} do. So there may be a correction to
+% make in the \LuaTeX{} case.
+% \begin{macrocode}
+%<*initex>
+\tex_everyjob:D \exp_after:wN
+ {
+ \tex_the:D \tex_everyjob:D
+ \luatex_if_engine:T
+ {
+ \lua_now:x
+ { dofile ( assert ( kpse.find_file ("lualatexquotejobname.lua" ) ) ) }
+ }
+ }
+%</initex>
+\tl_const:Nx \c_job_name_tl { \tex_jobname:D }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_space_tl}
+% A space as a token list (as opposed to as a character).
+% \begin{macrocode}
+\tl_const:Nn \c_space_tl { ~ }
+% \end{macrocode}
+% \end{variable}
+%
% \subsection{Adding to token list variables}
%
% \begin{macro}
@@ -1273,7 +1311,7 @@
%
% \subsection{Reassigning token list category codes}
%
-% \begin{variable}{\c_tl_rescan_marker_tl}
+% \begin{variable}{\c_@@_rescan_marker_tl}
% The rescanning code needs a special token list containing the same
% character with two different category codes. This is set up here,
% while the detail is described below.
@@ -1286,7 +1324,7 @@
\tex_lowercase:D
{
\group_end:
- \tl_const:Nn \c_tl_rescan_marker_tl { A B }
+ \tl_const:Nn \c_@@_rescan_marker_tl { A B }
}
% \end{macrocode}
% \end{variable}
@@ -1302,8 +1340,8 @@
% \tl_gset_rescan:cnn, \tl_gset_rescan:cno, \tl_gset_rescan:cnx
% }
% \begin{macro}{\tl_rescan:nn}
-% \begin{macro}[aux]{\tl_set_rescan_aux:NNnn}
-% \begin{macro}[aux]{\tl_rescan_aux:w}
+% \begin{macro}[aux]{\@@_set_rescan:NNnn}
+% \begin{macro}[aux]{\@@_rescan:w}
% The idea here is to deal cleanly with the problem that
% \tn{scantokens} treats the argument as a file, and without
% the correct settings a \TeX{} error occurs:
@@ -1322,15 +1360,15 @@
% \enquote{unprintable}.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \tl_set_rescan:Nnn
- { \tl_set_rescan_aux:NNnn \tl_set:Nn }
+ { \@@_set_rescan:NNnn \tl_set:Nn }
\cs_new_protected_nopar:Npn \tl_gset_rescan:Nnn
- { \tl_set_rescan_aux:NNnn \tl_gset:Nn }
+ { \@@_set_rescan:NNnn \tl_gset:Nn }
\cs_new_protected_nopar:Npn \tl_rescan:nn
- { \tl_set_rescan_aux:NNnn \prg_do_nothing: \use:n }
-\cs_new_protected:Npn \tl_set_rescan_aux:NNnn #1#2#3#4
+ { \@@_set_rescan:NNnn \prg_do_nothing: \use:n }
+\cs_new_protected:Npn \@@_set_rescan:NNnn #1#2#3#4
{
\group_begin:
- \exp_args:No \etex_everyeof:D { \c_tl_rescan_marker_tl \exp_not:N }
+ \exp_args:No \etex_everyeof:D { \c_@@_rescan_marker_tl \exp_not:N }
\tex_endlinechar:D \c_minus_one
\tex_newlinechar:D \c_minus_one
#3
@@ -1339,7 +1377,7 @@
\group_end:
#1 \exp_not:N #2
{
- \exp_after:wN \tl_rescan_aux:w
+ \exp_after:wN \@@_rescan:w
\exp_after:wN \prg_do_nothing:
\etex_scantokens:D {#4}
}
@@ -1347,8 +1385,8 @@
}
\use:x
{
- \cs_new:Npn \exp_not:N \tl_rescan_aux:w ##1
- \c_tl_rescan_marker_tl
+ \cs_new:Npn \exp_not:N \@@_rescan:w ##1
+ \c_@@_rescan_marker_tl
{ \exp_not:N \exp_not:o { ##1 } }
}
\cs_generate_variant:Nn \tl_set_rescan:Nnn { Nno , Nnx }
@@ -1380,21 +1418,21 @@
% \begin{macro}{\tl_greplace_all:Nnn, \tl_greplace_all:cnn}
% \begin{macro}{\tl_replace_once:Nnn, \tl_replace_once:cnn}
% \begin{macro}{\tl_greplace_once:Nnn, \tl_greplace_once:cnn}
-% \begin{macro}[aux]{\tl_replace_aux:NNNnn, \tl_replace_aux_ii:w}
-% \begin{macro}[aux]{\tl_replace_all_aux:, \tl_replace_once_aux:}
-% \begin{macro}[aux]{\tl_replace_once_aux_end:w}
-% All of the replace functions are based on \cs{tl_replace_aux:NNNnn},
+% \begin{macro}[aux]{\@@_replace:NNNnn, \@@_replace:w}
+% \begin{macro}[aux]{\@@_replace_all:, \@@_replace_once:}
+% \begin{macro}[aux]{\@@_replace_once_end:w}
+% All of the replace functions are based on \cs{@@_replace:NNNnn},
% whose arguments are: \meta{function}, \cs{tl_(g)set:Nx}, \meta{tl~var},
% \meta{search tokens}, \meta{replacement tokens}.
% \begin{macrocode}
\cs_new_protected_nopar:Npn \tl_replace_once:Nnn
- { \tl_replace_aux:NNNnn \tl_replace_once_aux: \tl_set:Nx }
+ { \@@_replace:NNNnn \@@_replace_once: \tl_set:Nx }
\cs_new_protected_nopar:Npn \tl_greplace_once:Nnn
- { \tl_replace_aux:NNNnn \tl_replace_once_aux: \tl_gset:Nx }
+ { \@@_replace:NNNnn \@@_replace_once: \tl_gset:Nx }
\cs_new_protected_nopar:Npn \tl_replace_all:Nnn
- { \tl_replace_aux:NNNnn \tl_replace_all_aux: \tl_set:Nx }
+ { \@@_replace:NNNnn \@@_replace_all: \tl_set:Nx }
\cs_new_protected_nopar:Npn \tl_greplace_all:Nnn
- { \tl_replace_aux:NNNnn \tl_replace_all_aux: \tl_gset:Nx }
+ { \@@_replace:NNNnn \@@_replace_all: \tl_gset:Nx }
\cs_generate_variant:Nn \tl_replace_once:Nnn { c }
\cs_generate_variant:Nn \tl_greplace_once:Nnn { c }
\cs_generate_variant:Nn \tl_replace_all:Nnn { c }
@@ -1402,34 +1440,34 @@
% \end{macrocode}
% The idea is easier to understand by considering the case of
% \cs{tl_replace_all:Nnn}. The replacement happens within an
-% \texttt{x}-type expansion. We use an auxiliary function \cs{tl_tmp:w},
+% \texttt{x}-type expansion. We use an auxiliary function \cs{@@_tmp:w},
% which essentially replaces the next \meta{search tokens} by
% \meta{replacement tokens}. To avoid runaway arguments,
-% we expand something like \cs{tl_tmp:w} \meta{token list} \cs{q_mark}
+% we expand something like \cs{@@_tmp:w} \meta{token list} \cs{q_mark}
% \meta{search tokens} \cs{q_stop}, repeating until the end. How do we
% detect that we have reached the last occurrence of \meta{search tokens}?
% The last replacement is characterized by the fact that the argument of
-% \cs{tl_tmp:w} contains \cs{q_mark}. In the code below,
-% \cs{tl_replace_aux_ii:w} takes an argument delimited by \cs{q_mark},
+% \cs{@@_tmp:w} contains \cs{q_mark}. In the code below,
+% \cs{@@_replace:w} takes an argument delimited by \cs{q_mark},
% and removes the following token. Before we reach the end, this gobbles
% \cs{q_mark} \cs{use_none_delimit_by_q_stop:w} which appear in the
-% definition of \cs{tl_tmp:w}, and leaves the \meta{replacement tokens},
+% definition of \cs{@@_tmp:w}, and leaves the \meta{replacement tokens},
% passed to \cs{exp_not:n}, to be included in the \texttt{x}-expanding
% definition. At the end, the first \cs{q_mark} is within the argument
-% of \cs{tl_tmp:w}, and \cs{tl_replace_aux_ii:w} gobbles the second
+% of \cs{@@_tmp:w}, and \cs{@@_replace:w} gobbles the second
% \cs{q_mark} as well, leaving \cs{use_none_delimit_by_q_stop:w},
% which ends the recursion cleanly.
% \begin{macrocode}
-\cs_new_protected:Npn \tl_replace_aux:NNNnn #1#2#3#4#5
+\cs_new_protected:Npn \@@_replace:NNNnn #1#2#3#4#5
{
\tl_if_empty:nTF {#4}
{
- \msg_kernel_error:nnx { tl } { empty-search-pattern }
+ \__msg_kernel_error:nnx { kernel } { empty-search-pattern }
{ \tl_to_str:n {#5} }
}
{
\group_align_safe_begin:
- \cs_set:Npx \tl_tmp:w ##1##2 #4
+ \cs_set:Npx \@@_tmp:w ##1##2 #4
{
##2
\exp_not:N \q_mark
@@ -1445,12 +1483,12 @@
}
}
}
-\cs_new:Npn \tl_replace_aux_ii:w #1 \q_mark #2 { \exp_not:o {#1} }
+\cs_new:Npn \@@_replace:w #1 \q_mark #2 { \exp_not:o {#1} }
% \end{macrocode}
-% The first argument of \cs{tl_tmp:w} is responsible for repeating
+% The first argument of \cs{@@_tmp:w} is responsible for repeating
% the replacement in the case of \texttt{replace_all}, and stopping
% it early for \texttt{replace_once}. Note also that we build
-% \cs{tl_tmp:w} within an \texttt{x}-expansion so that the
+% \cs{@@_tmp:w} within an \texttt{x}-expansion so that the
% \meta{replacement tokens} can contain |#|. The second
% \cs{exp_not:n} ensures that the \meta{replacement tokens}
% are not expanded by \cs{tl_(g)set:Nx}.
@@ -1460,17 +1498,17 @@
% ensure that we don't lose braces in case the tokens between two
% occurrences of the \meta{search tokens} form a brace group.
% \begin{macrocode}
-\cs_new:Npn \tl_replace_all_aux:
+\cs_new_nopar:Npn \@@_replace_all:
{
- \exp_after:wN \tl_replace_aux_ii:w
- \tl_tmp:w \tl_replace_all_aux: \prg_do_nothing:
+ \exp_after:wN \@@_replace:w
+ \@@_tmp:w \@@_replace_all: \prg_do_nothing:
}
-\cs_new_nopar:Npn \tl_replace_once_aux:
+\cs_new_nopar:Npn \@@_replace_once:
{
- \exp_after:wN \tl_replace_aux_ii:w
- \tl_tmp:w { \tl_replace_once_aux_end:w \prg_do_nothing: } \prg_do_nothing:
+ \exp_after:wN \@@_replace:w
+ \@@_tmp:w { \@@_replace_once_end:w \prg_do_nothing: } \prg_do_nothing:
}
-\cs_new:Npn \tl_replace_once_aux_end:w #1 \q_mark #2 \q_stop
+\cs_new:Npn \@@_replace_once_end:w #1 \q_mark #2 \q_stop
{ \exp_not:o {#1} }
% \end{macrocode}
% \end{macro}
@@ -1511,7 +1549,7 @@
% \subsection{Token list conditionals}
%
% \begin{macro}[pTF]{\tl_if_blank:n,\tl_if_blank:V,\tl_if_blank:o}
-% \begin{macro}[aux]{\tl_if_blank_p_aux:NNw}
+% \begin{macro}[aux]{\@@_if_blank_p:NNw}
% \TeX{} skips spaces when reading a non-delimited arguments. Thus,
% a \meta{token list} is blank if and only if \cs{use_none:n}
% \meta{token list} |?| is empty. For performance reasons, we hard-code
@@ -1525,7 +1563,7 @@
% while \tn{escapechar} is a space or is unprintable.
% \begin{macrocode}
\prg_new_conditional:Npnn \tl_if_blank:n #1 { p , T , F , TF }
- { \tl_if_empty_return:o { \use_none:n #1 ? } }
+ { \@@_if_empty_return:o { \use_none:n #1 ? } }
\cs_generate_variant:Nn \tl_if_blank_p:n { V }
\cs_generate_variant:Nn \tl_if_blank:nT { V }
\cs_generate_variant:Nn \tl_if_blank:nF { V }
@@ -1561,14 +1599,15 @@
% \begin{macro}[pTF]{\tl_if_empty:n,\tl_if_empty:V}
% It would be tempting to just use |\if_meaning:w \q_nil #1 \q_nil| as
% a test since this works really well. However, it fails on a token
-% list starting with |\q_nil| of course but more troubling is the
-% case where argument is a complete conditional such as |\if_true:|
-% a |\else:| b |\fi:| because then |\if_true:| is used by
-% |\if_meaning:w|, the test turns out false, the |\else:| executes
-% the false branch, the |\fi:| ends it and the |\q_nil| at the end
+% list starting with \cs{q_nil} of course but more troubling is the
+% case where argument is a complete conditional such as \cs{if_true:}
+% a \cs{else:} b \cs{fi:} because then \cs{if_true:} is used by
+% \cs{if_meaning:w}, the test turns out \texttt{false}, the \cs{else:}
+% executes the \texttt{false} branch, the \cs{fi:} ends it and the
+% \cs{q_nil} at the end
% starts executing\dots{} A safer route is to convert the entire
% token list into harmless characters first and then compare
-% that. This way the test will even accept |\q_nil| as the first
+% that. This way the test will even accept \cs{q_nil} as the first
% token.
% \begin{macrocode}
\prg_new_conditional:Npnn \tl_if_empty:n #1 { p , TF , T , F }
@@ -1587,8 +1626,8 @@
% \end{macro}
%
% \begin{macro}[pTF]{\tl_if_empty:o}
-% \begin{macro}[EXP,aux]{\tl_if_empty_return:o}
-% The auxiliary function \cs{tl_if_empty_return:o} is for use
+% \begin{macro}[EXP,aux]{\@@_if_empty_return:o}
+% The auxiliary function \cs{@@_if_empty_return:o} is for use
% in conditionals on token lists, which mostly reduce to testing
% if a given token list is empty after applying a simple function
% to it.
@@ -1598,7 +1637,7 @@
% Note that this works because \cs{tl_to_str:n} expands tokens
% that follow until reading a catcode $1$ (begin-group) token.
% \begin{macrocode}
-\cs_new:Npn \tl_if_empty_return:o #1
+\cs_new:Npn \@@_if_empty_return:o #1
{
\exp_after:wN \if_meaning:w \exp_after:wN \q_nil
\tl_to_str:n \exp_after:wN {#1} \q_nil
@@ -1608,7 +1647,7 @@
\fi:
}
\prg_new_conditional:Npnn \tl_if_empty:o #1 { p , TF , T , F }
- { \tl_if_empty_return:o {#1} }
+ { \@@_if_empty_return:o {#1} }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1670,10 +1709,10 @@
%
% \begin{macro}[TF]{\tl_if_in:nn, \tl_if_in:Vn, \tl_if_in:on, \tl_if_in:no}
% Once more, the test relies on \cs{tl_to_str:n} for robustness.
-% The function \cs{tl_tmp:w} removes tokens until the first occurrence
+% The function \cs{@@_tmp:w} removes tokens until the first occurrence
% of |#2|. If this does not appear in |#1|, then the final |#2| is removed,
% leaving an empty token list. Otherwise some tokens remain, and the
-% test is false. See \cs{tl_if_empty:n(TF)} for details on
+% test is \texttt{false}. See \cs{tl_if_empty:n(TF)} for details on
% the emptyness test.
%
% Special care is needed to treat correctly cases like
@@ -1685,8 +1724,8 @@
% \begin{macrocode}
\prg_new_protected_conditional:Npnn \tl_if_in:nn #1#2 { T , F , TF }
{
- \cs_set:Npn \tl_tmp:w ##1 #2 { }
- \tl_if_empty:oTF { \tl_tmp:w #1 {} {} #2 }
+ \cs_set:Npn \@@_tmp:w ##1 #2 { }
+ \tl_if_empty:oTF { \@@_tmp:w #1 {} {} #2 }
{ \prg_return_false: } { \prg_return_true: }
}
\cs_generate_variant:Nn \tl_if_in:nnT { V , o , no }
@@ -1695,27 +1734,73 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}[EXP,pTF]{\tl_if_single:N}
+% Expand the token list and feed it to \cs{tl_if_single:n}.
+% \begin{macrocode}
+\cs_new:Npn \tl_if_single_p:N { \exp_args:No \tl_if_single_p:n }
+\cs_new:Npn \tl_if_single:NT { \exp_args:No \tl_if_single:nT }
+\cs_new:Npn \tl_if_single:NF { \exp_args:No \tl_if_single:nF }
+\cs_new:Npn \tl_if_single:NTF { \exp_args:No \tl_if_single:nTF }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP,pTF]{\tl_if_single:n}
+% A token list has exactly one item if it is either a single
+% token surrounded by optional explicit spaces, or a single brace
+% group surrounded by optional explicit spaces. The naive
+% version of this test would do \cs{use_none:n} |#1|, and
+% test if the result is empty. However, this will fail when
+% the token list is empty. Furthermore, it does not allow optional
+% trailing spaces.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_single:n #1 { p , T , F , TF }
+ { \__str_if_eq_x_return:nn { \exp_not:o { \use_none:nn #1 ?? } } {?} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\tl_case:Nnn, \tl_case:cnn}
+% \begin{macro}[aux, EXP]{\@@_case:Nw}
+% \begin{macro}[aux, EXP]{\@@_case_end:nw}
+% \begin{macrocode}
+\cs_new:Npn \tl_case:Nnn #1#2#3
+ {
+ \tex_romannumeral:D
+ \@@_case:Nw #1 #2 #1 {#3} \q_recursion_stop
+ }
+\cs_new:Npn \@@_case:Nw #1#2#3
+ {
+ \tl_if_eq:NNTF #1 #2
+ { \@@_case_end:nw {#3} }
+ { \@@_case:Nw #1 }
+ }
+\cs_generate_variant:Nn \tl_case:Nnn { c }
+\cs_new_eq:NN \@@_case_end:nw \__prg_case_end:nw
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
% \subsection{Mapping to token lists}
%
% \begin{macro}{\tl_map_function:nN}
% \begin{macro}{\tl_map_function:NN, \tl_map_function:cN}
-% \begin{macro}[aux]{\tl_map_function_aux:Nn}
+% \begin{macro}[aux]{\@@_map_function:Nn}
% Expandable loop macro for token lists. These have the advantage of not
% needing to test if the argument is empty, because if it is, the stop
% marker will be read immediately and the loop terminated.
% \begin{macrocode}
\cs_new:Npn \tl_map_function:nN #1#2
{
- \tl_map_function_aux:Nn #2 #1
+ \@@_map_function:Nn #2 #1
\q_recursion_tail
- \prg_break_point:n { }
+ \__prg_break_point:Nn \tl_map_break: { }
}
\cs_new_nopar:Npn \tl_map_function:NN
{ \exp_args:No \tl_map_function:nN }
-\cs_new:Npn \tl_map_function_aux:Nn #1#2
+\cs_new:Npn \@@_map_function:Nn #1#2
{
- \quark_if_recursion_tail_break:n {#2}
- #1 {#2} \tl_map_function_aux:Nn #1
+ \__quark_if_recursion_tail_break:nN {#2} \tl_map_break:
+ #1 {#2} \@@_map_function:Nn #1
}
\cs_generate_variant:Nn \tl_map_function:NN { c }
% \end{macrocode}
@@ -1726,19 +1811,18 @@
% \begin{macro}{\tl_map_inline:nn}
% \begin{macro}{\tl_map_inline:Nn, \tl_map_inline:cn}
% The inline functions are straight forward by now. We use a little
-% trick with the counter \cs{g_prg_map_int} to make
-% them nestable. We can also make use of \cs{tl_map_function_aux:Nn}
+% trick with the counter \cs{g__prg_map_int} to make
+% them nestable. We can also make use of \cs{@@_map_function:Nn}
% from before.
% \begin{macrocode}
\cs_new_protected:Npn \tl_map_inline:nn #1#2
{
- \int_gincr:N \g_prg_map_int
- \cs_gset:cpn { tl_map_inline_ \int_use:N \g_prg_map_int :n }
- ##1 {#2}
- \exp_args:Nc \tl_map_function_aux:Nn
- { tl_map_inline_ \int_use:N \g_prg_map_int :n }
+ \int_gincr:N \g__prg_map_int
+ \cs_gset:cpn { __prg_map_ \int_use:N \g__prg_map_int :w } ##1 {#2}
+ \exp_args:Nc \@@_map_function:Nn
+ { __prg_map_ \int_use:N \g__prg_map_int :w }
#1 \q_recursion_tail
- \prg_break_point:n { \int_gdecr:N \g_prg_map_int }
+ \__prg_break_point:Nn \tl_map_break: { \int_gdecr:N \g__prg_map_int }
}
\cs_new_protected:Npn \tl_map_inline:Nn
{ \exp_args:No \tl_map_inline:nn }
@@ -1749,25 +1833,25 @@
%
% \begin{macro}{\tl_map_variable:nNn}
% \begin{macro}{\tl_map_variable:NNn, \tl_map_variable:cNn}
-% \begin{macro}[aux]{\tl_map_variable_aux:Nnn}
+% \begin{macro}[aux]{\@@_map_variable:Nnn}
% \cs{tl_map_variable:nNn} \meta{token list} \meta{temp} \meta{action}
% assigns
% \meta{temp} to each element and executes \meta{action}.
% \begin{macrocode}
\cs_new_protected:Npn \tl_map_variable:nNn #1#2#3
{
- \tl_map_variable_aux:Nnn #2 {#3} #1
+ \@@_map_variable:Nnn #2 {#3} #1
\q_recursion_tail
- \prg_break_point:n { }
+ \__prg_break_point:Nn \tl_map_break: { }
}
\cs_new_protected_nopar:Npn \tl_map_variable:NNn
{ \exp_args:No \tl_map_variable:nNn }
-\cs_new_protected:Npn \tl_map_variable_aux:Nnn #1#2#3
+\cs_new_protected:Npn \@@_map_variable:Nnn #1#2#3
{
\tl_set:Nn #1 {#3}
- \quark_if_recursion_tail_break:N #1
+ \__quark_if_recursion_tail_break:NN #1 \tl_map_break:
\use:n {#2}
- \tl_map_variable_aux:Nnn #1 {#2}
+ \@@_map_variable:Nnn #1 {#2}
}
\cs_generate_variant:Nn \tl_map_variable:NNn { c }
% \end{macrocode}
@@ -1777,10 +1861,12 @@
%
% \begin{macro}{\tl_map_break:}
% \begin{macro}{\tl_map_break:n}
-% The break statements are simply copies.
+% The break statements use the general \cs{__prg_map_break:Nn}.
% \begin{macrocode}
-\cs_new_eq:NN \tl_map_break: \prg_map_break:
-\cs_new_eq:NN \tl_map_break:n \prg_map_break:n
+\cs_new_nopar:Npn \tl_map_break:
+ { \__prg_map_break:Nn \tl_map_break: { } }
+\cs_new_nopar:Npn \tl_map_break:n
+ { \__prg_map_break:Nn \tl_map_break: }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1811,7 +1897,7 @@
\cs_new:Npn \tl_use:N #1
{
\tl_if_exist:NTF #1 {#1}
- { \msg_expandable_kernel_error:nnn { kernel } { bad-var } {#1} }
+ { \__msg_kernel_expandable_error:nnn { kernel } { bad-variable } {#1} }
}
\cs_generate_variant:Nn \tl_use:N { c }
% \end{macrocode}
@@ -1819,54 +1905,54 @@
%
% \subsection{Working with the contents of token lists}
%
-% \begin{macro}{\tl_length:n, \tl_length:V, \tl_length:o}
-% \begin{macro}{\tl_length:N, \tl_length:c}
-% \begin{macro}[aux]{\tl_length_aux:n}
+% \begin{macro}{\tl_count:n, \tl_count:V, \tl_count:o}
+% \begin{macro}{\tl_count:N, \tl_count:c}
+% \begin{macro}[aux]{\@@_count:n}
% Count number of elements within a token list or token list
% variable. Brace groups within the list are read as a single
% element. Spaces are ignored.
-% \cs{tl_length_aux:n} grabs the element and replaces it by |+1|.
+% \cs{@@_count:n} grabs the element and replaces it by |+1|.
% The |0| to ensure it works on an empty list.
% \begin{macrocode}
-\cs_new:Npn \tl_length:n #1
+\cs_new:Npn \tl_count:n #1
{
\int_eval:n
- { 0 \tl_map_function:nN {#1} \tl_length_aux:n }
+ { 0 \tl_map_function:nN {#1} \@@_count:n }
}
-\cs_new:Npn \tl_length:N #1
+\cs_new:Npn \tl_count:N #1
{
\int_eval:n
- { 0 \tl_map_function:NN #1 \tl_length_aux:n }
+ { 0 \tl_map_function:NN #1 \@@_count:n }
}
-\cs_new:Npn \tl_length_aux:n #1 { + \c_one }
-\cs_generate_variant:Nn \tl_length:n { V , o }
-\cs_generate_variant:Nn \tl_length:N { c }
+\cs_new:Npn \@@_count:n #1 { + \c_one }
+\cs_generate_variant:Nn \tl_count:n { V , o }
+\cs_generate_variant:Nn \tl_count:N { c }
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tl_reverse_items:n}
-% \begin{macro}[aux]{\tl_reverse_items_aux:nwNwn}
-% \begin{macro}[aux]{\tl_reverse_items_aux:wn}
+% \begin{macro}[aux]{\@@_reverse_items:nwNwn}
+% \begin{macro}[aux]{\@@_reverse_items:wn}
% Reversal of a token list is done by taking one item at a time
% and putting it after \cs{q_stop}.
% \begin{macrocode}
\cs_new:Npn \tl_reverse_items:n #1
{
- \tl_reverse_items_aux:nwNwn #1 ?
- \q_mark \tl_reverse_items_aux:nwNwn
- \q_mark \tl_reverse_items_aux:wn
+ \@@_reverse_items:nwNwn #1 ?
+ \q_mark \@@_reverse_items:nwNwn
+ \q_mark \@@_reverse_items:wn
\q_stop { }
}
-\cs_new:Npn \tl_reverse_items_aux:nwNwn #1 #2 \q_mark #3 #4 \q_stop #5
+\cs_new:Npn \@@_reverse_items:nwNwn #1 #2 \q_mark #3 #4 \q_stop #5
{
#3 #2
- \q_mark \tl_reverse_items_aux:nwNwn
- \q_mark \tl_reverse_items_aux:wn
+ \q_mark \@@_reverse_items:nwNwn
+ \q_mark \@@_reverse_items:wn
\q_stop { {#1} #5 }
}
-\cs_new:Npn \tl_reverse_items_aux:wn #1 \q_stop #2
+\cs_new:Npn \@@_reverse_items:wn #1 \q_stop #2
{ \exp_not:o { \use_none:nn #2 } }
% \end{macrocode}
% \end{macro}
@@ -1879,78 +1965,237 @@
% \tl_trim_spaces:N, \tl_trim_spaces:c,
% \tl_gtrim_spaces:N, \tl_gtrim_spaces:c
% }
+% Trimming spaces from around the input is deferred to an internal
+% function whose first argument is the token list to trim, augmented
+% by an initial \cs{q_mark}, and whose second argument is a
+% \meta{continuation}, which will receive as a braced argument
+% \cs{use_none:n} \cs{q_mark} \meta{trimmed token list}. In the case
+% at hand, we take \cs{exp_not:o} as our continuation, so that space
+% trimming will behave correctly within an \texttt{x}-type expansion.
+% \begin{macrocode}
+\cs_new:Npn \tl_trim_spaces:n #1
+ { \@@_trim_spaces:nn { \q_mark #1 } \exp_not:o }
+\cs_new_protected:Npn \tl_trim_spaces:N #1
+ { \tl_set:Nx #1 { \exp_args:No \tl_trim_spaces:n {#1} } }
+\cs_new_protected:Npn \tl_gtrim_spaces:N #1
+ { \tl_gset:Nx #1 { \exp_args:No \tl_trim_spaces:n {#1} } }
+\cs_generate_variant:Nn \tl_trim_spaces:N { c }
+\cs_generate_variant:Nn \tl_gtrim_spaces:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[int]{\@@_trim_spaces:nn}
% \begin{macro}[aux]
% {
-% \tl_trim_spaces_aux_i:w, \tl_trim_spaces_aux_ii:w
-% \tl_trim_spaces_aux_iii:w, \tl_trim_spaces_aux_iv:w
+% \@@_trim_spaces_i:w, \@@_trim_spaces_ii:w
+% \@@_trim_spaces_iii:w, \@@_trim_spaces_iv:w
% }
% Trimming spaces from around the input is done using delimited
% arguments and quarks, and to get spaces at odd places in the
-% definitions, we nest those in \cs{tl_tmp:w}, which then receives
+% definitions, we nest those in \cs{@@_tmp:w}, which then receives
% a single space as its argument: |#1| is \verb*+ +.
-% Removing leading spaces is done with \cs{tl_trim_spaces_aux_i:w},
+% Removing leading spaces is done with \cs{@@_trim_spaces_i:w},
% which loops until \cs{q_mark}\verb*+ + matches the end of the token
% list: then |##1| is the token list and |##3| is
-% \cs{tl_trim_spaces_aux_ii:w}. This hands the relevant tokens to the
-% loop \cs{tl_trim_spaces_aux_iii:w}, responsible for trimming
+% \cs{@@_trim_spaces_ii:w}. This hands the relevant tokens to the
+% loop \cs{@@_trim_spaces_iii:w}, responsible for trimming
% trailing spaces. The end is reached when \verb*+ + \cs{q_nil}
% matches the one present in the definition of \cs{tl_trim_spacs:n}.
-% Then \cs{tl_trim_spaces_aux_iv:w} puts the token list into a group,
-% as the argument of the initial \tn{unexpanded}.
-% The \tn{unexpanded} here is used so that space trimming will
-% behave correctly within an \texttt{x}-type expansion.
-%
-% Some of the auxiliaries used in this code are also used
-% in the \pkg{l3clist} module. Change with care.
+% Then \cs{@@_trim_spaces_iv:w} puts the token list into a group,
+% with \cs{use_none:n} placed there to gobble a lingering \cs{q_mark},
+% and feeds this to the \meta{continuation}.
% \begin{macrocode}
-\cs_set:Npn \tl_tmp:w #1
+\cs_set:Npn \@@_tmp:w #1
{
- \cs_new:Npn \tl_trim_spaces:n ##1
+ \cs_new:Npn \@@_trim_spaces:nn ##1
{
- \etex_unexpanded:D
- \tl_trim_spaces_aux_i:w
- \q_mark
+ \@@_trim_spaces_i:w
##1
\q_nil
\q_mark #1 { }
- \q_mark \tl_trim_spaces_aux_ii:w
- \tl_trim_spaces_aux_iii:w
+ \q_mark \@@_trim_spaces_ii:w
+ \@@_trim_spaces_iii:w
#1 \q_nil
- \tl_trim_spaces_aux_iv:w
- \q_stop
+ \@@_trim_spaces_iv:w
+ \q_stop
}
- \cs_new:Npn \tl_trim_spaces_aux_i:w ##1 \q_mark #1 ##2 \q_mark ##3
+ \cs_new:Npn \@@_trim_spaces_i:w ##1 \q_mark #1 ##2 \q_mark ##3
{
##3
- \tl_trim_spaces_aux_i:w
+ \@@_trim_spaces_i:w
\q_mark
##2
\q_mark #1 {##1}
}
- \cs_new:Npn \tl_trim_spaces_aux_ii:w ##1 \q_mark \q_mark ##2
+ \cs_new:Npn \@@_trim_spaces_ii:w
+ \@@_trim_spaces_i:w \q_mark \q_mark ##1
{
- \tl_trim_spaces_aux_iii:w
- ##2
+ \@@_trim_spaces_iii:w
+ ##1
}
- \cs_new:Npn \tl_trim_spaces_aux_iii:w ##1 #1 \q_nil ##2
+ \cs_new:Npn \@@_trim_spaces_iii:w ##1 #1 \q_nil ##2
{
##2
##1 \q_nil
- \tl_trim_spaces_aux_iii:w
+ \@@_trim_spaces_iii:w
}
- \cs_new:Npn \tl_trim_spaces_aux_iv:w ##1 \q_nil ##2 \q_stop
- { \exp_after:wN { \use_none:n ##1 } }
+ \cs_new:Npn \@@_trim_spaces_iv:w ##1 \q_nil ##2 \q_stop ##3
+ { ##3 { \use_none:n ##1 } }
}
-\tl_tmp:w { ~ }
-\cs_new_protected:Npn \tl_trim_spaces:N #1
- { \tl_set:Nx #1 { \exp_after:wN \tl_trim_spaces:n \exp_after:wN {#1} } }
-\cs_new_protected:Npn \tl_gtrim_spaces:N #1
- { \tl_gset:Nx #1 { \exp_after:wN \tl_trim_spaces:n \exp_after:wN {#1} } }
-\cs_generate_variant:Nn \tl_trim_spaces:N { c }
-\cs_generate_variant:Nn \tl_gtrim_spaces:N { c }
+\@@_tmp:w { ~ }
% \end{macrocode}
% \end{macro}
% \end{macro}
+%
+% \subsection{Token by token changes}
+%
+% \begin{variable}{\q__@@_act_mark,\q__@@_act_stop}
+% The \cs{tl_act} functions may be applied to any token list.
+% Hence, we use two private quarks, to allow any token, even quarks,
+% in the token list.^^A in particular critical for future \::e.
+% Only \cs{q__@@_act_mark} and \cs{q__@@_act_stop} may not appear
+% in the token lists manipulated by \cs{@@_act:NNNnn} functions. The quarks
+% are effectively defined in \pkg{l3quark}.
+% \end{variable}
+%
+% \begin{macro}[EXP,int]{\@@_act:NNNnn}
+% \begin{macro}[EXP,aux]{\@@_act_output:n, \@@_act_reverse_output:n}
+% \begin{macro}[EXP,aux]{\@@_act_loop:w}
+% \begin{macro}[EXP,aux]{\@@_act_normal:NwnNNN}
+% \begin{macro}[EXP,aux]{\@@_act_group:nwnNNN}
+% \begin{macro}[EXP,aux]{\@@_act_space:wwnNNN}
+% \begin{macro}[EXP,aux]{\@@_act_end:w}
+% To help control the expansion, \cs{@@_act:NNNnn} should always
+% be proceeded by \tn{romannumeral} and ends by producing \cs{c_zero}
+% once the result has been obtained. Then loop over tokens,
+% groups, and spaces in |#5|. The marker \cs{q__@@_act_mark}
+% is used both to avoid losing outer braces and to detect the
+% end of the token list more easily. The result is stored
+% as an argument for the dummy function \cs{@@_act_result:n}.
+% \begin{macrocode}
+\cs_new:Npn \@@_act:NNNnn #1#2#3#4#5
+ {
+ \group_align_safe_begin:
+ \@@_act_loop:w #5 \q__@@_act_mark \q__@@_act_stop
+ {#4} #1 #2 #3
+ \@@_act_result:n { }
+ }
+% \end{macrocode}
+% In the loop, we check how the token list begins and act
+% accordingly. In the \enquote{normal} case, we may have
+% reached \cs{q__@@_act_mark}, the end of the list. Then
+% leave \cs{c_zero} and the result in the input stream,
+% to terminate the expansion of \tn{romannumeral}.
+% Otherwise, apply the relevant function to the
+% \enquote{arguments}, |#3|
+% and to the head of the token list. Then repeat the loop.
+% The scheme is the same if the token list starts with a
+% group or with a space. Some extra work is needed to
+% make \cs{@@_act_space:wwnNNN} gobble the space.
+% \begin{macrocode}
+\cs_new:Npn \@@_act_loop:w #1 \q__@@_act_stop
+ {
+ \tl_if_head_is_N_type:nTF {#1}
+ { \@@_act_normal:NwnNNN }
+ {
+ \tl_if_head_is_group:nTF {#1}
+ { \@@_act_group:nwnNNN }
+ { \@@_act_space:wwnNNN }
+ }
+ #1 \q__@@_act_stop
+ }
+\cs_new:Npn \@@_act_normal:NwnNNN #1 #2 \q__@@_act_stop #3#4
+ {
+ \if_meaning:w \q__@@_act_mark #1
+ \exp_after:wN \@@_act_end:wn
+ \fi:
+ #4 {#3} #1
+ \@@_act_loop:w #2 \q__@@_act_stop
+ {#3} #4
+ }
+\cs_new:Npn \@@_act_end:wn #1 \@@_act_result:n #2
+ { \group_align_safe_end: \c_zero #2 }
+\cs_new:Npn \@@_act_group:nwnNNN #1 #2 \q__@@_act_stop #3#4#5
+ {
+ #5 {#3} {#1}
+ \@@_act_loop:w #2 \q__@@_act_stop
+ {#3} #4 #5
+ }
+\exp_last_unbraced:NNo
+ \cs_new:Npn \@@_act_space:wwnNNN \c_space_tl #1 \q__@@_act_stop #2#3#4#5
+ {
+ #5 {#2}
+ \@@_act_loop:w #1 \q__@@_act_stop
+ {#2} #3 #4 #5
+ }
+% \end{macrocode}
+% Typically, the output is done to the right of what was already output,
+% using \cs{@@_act_output:n}, but for the \cs{@@_act_reverse} functions,
+% it should be done to the left.
+% \begin{macrocode}
+\cs_new:Npn \@@_act_output:n #1 #2 \@@_act_result:n #3
+ { #2 \@@_act_result:n { #3 #1 } }
+\cs_new:Npn \@@_act_reverse_output:n #1 #2 \@@_act_result:n #3
+ { #2 \@@_act_result:n { #1 #3 } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\tl_reverse:n, \tl_reverse:o, \tl_reverse:V}
+% \begin{macro}[EXP,aux]{\@@_reverse_normal:nN}
+% \begin{macro}[EXP,aux]{\@@_reverse_group_preserve:nn}
+% \begin{macro}[EXP,aux]{\@@_reverse_space:n}
+% The goal here is to reverse without losing spaces nor braces.
+% This is done using the general internal function \cs{@@_act:NNNnn}.
+% Spaces and \enquote{normal} tokens are output on the left of the current
+% output. Grouped tokens are output to the left but without any reversal
+% within the group. All of the internal functions here drop one argument:
+% this is needed by \cs{@@_act:NNNnn} when changing case (to record
+% which direction the change is in), but not when reversing the tokens.
+% \begin{macrocode}
+\cs_new:Npn \tl_reverse:n #1
+ {
+ \etex_unexpanded:D \exp_after:wN
+ {
+ \tex_romannumeral:D
+ \@@_act:NNNnn
+ \@@_reverse_normal:nN
+ \@@_reverse_group_preserve:nn
+ \@@_reverse_space:n
+ { }
+ {#1}
+ }
+ }
+\cs_generate_variant:Nn \tl_reverse:n { o , V }
+\cs_new:Npn \@@_reverse_normal:nN #1#2
+ { \@@_act_reverse_output:n {#2} }
+\cs_new:Npn \@@_reverse_group_preserve:nn #1#2
+ { \@@_act_reverse_output:n { {#2} } }
+\cs_new:Npn \@@_reverse_space:n #1
+ { \@@_act_reverse_output:n { ~ } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_reverse:N, \tl_reverse:c, \tl_greverse:N, \tl_greverse:c}
+% This reverses the list, leaving \cs{exp_stop_f:} in front,
+% which stops the \texttt{f}-expansion.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_reverse:N #1
+ { \tl_set:Nx #1 { \exp_args:No \tl_reverse:n { #1 } } }
+\cs_new_protected:Npn \tl_greverse:N #1
+ { \tl_gset:Nx #1 { \exp_args:No \tl_reverse:n { #1 } } }
+\cs_generate_variant:Nn \tl_reverse:N { c }
+\cs_generate_variant:Nn \tl_greverse:N { c }
+% \end{macrocode}
% \end{macro}
%
% \subsection{The first token from a token list}
@@ -1959,6 +2204,7 @@
% \begin{macro}{\tl_head:w}
% \begin{macro}{\tl_tail:N, \tl_tail:n, \tl_tail:V, \tl_tail:v, \tl_tail:f}
% \begin{macro}{\tl_tail:w}
+% \begin{macro}[aux]{\@@_tail:w}
% These functions pick up either the head or the tail of a list. The
% empty brace groups in \cs{tl_head:n} and \cs{tl_tail:n} ensure that
% a blank argument gives an empty result. The result is returned within
@@ -1969,8 +2215,8 @@
\cs_new:Npn \tl_head:n #1
{ \etex_unexpanded:D \exp_after:wN { \tl_head:w #1 { } \q_stop } }
\cs_new:Npn \tl_tail:n #1
- { \etex_unexpanded:D \tl_tail_aux:w #1 \q_mark { } \q_mark \q_stop }
-\cs_new:Npn \tl_tail_aux:w #1 #2 \q_mark #3 \q_stop { {#2} }
+ { \etex_unexpanded:D \@@_tail:w #1 \q_mark { } \q_mark \q_stop }
+\cs_new:Npn \@@_tail:w #1 #2 \q_mark #3 \q_stop { {#2} }
\cs_new_nopar:Npn \tl_head:N { \exp_args:No \tl_head:n }
\cs_generate_variant:Nn \tl_head:n { V , v , f }
\cs_new_nopar:Npn \tl_tail:N { \exp_args:No \tl_tail:n }
@@ -1980,46 +2226,47 @@
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
%
% \begin{macro}{\str_head:n, \str_tail:n}
-% \begin{macro}[aux]{\str_head_aux:w}
-% \begin{macro}[aux]{\str_tail_aux:w}
+% \begin{macro}[aux]{\__str_head:w}
+% \begin{macro}[aux]{\__str_tail:w}
% After \cs{tl_to_str:n}, we have a list of character tokens,
% all with category code 12, except the space, which has category
% code 10. Directly using \cs{tl_head:w} would thus lose leading spaces.
% Instead, we take an argument delimited by an explicit space, and
% then only use \cs{tl_head:w}. If the string started with a
-% space, then the argument of \cs{str_head_aux:w} is empty, and
+% space, then the argument of \cs{__str_head:w} is empty, and
% the function correctly returns a space character. Otherwise,
% it returns the first token of |#1|, which is the first token
% of the string. If the string is empty, we return an empty result.
%
% To remove the first character of \cs{tl_to_str:n} |{#1}|,
% we test it using \cs{if_charcode:w} \cs{scan_stop:},
-% always false for characters. If the argument was non-empty,
-% then \cs{str_tail_aux:w} returns everything until the first
+% always \texttt{false} for characters. If the argument was non-empty,
+% then \cs{__str_tail:w} returns everything until the first
% \texttt{X} (with category code letter, no risk of confusing
% with the user input). If the argument was empty, the first
% \texttt{X} is taken by \cs{if_charcode:w}, and nothing
% is returned. We use \texttt{X} as a \meta{marker}, rather than
% a quark because the test \cs{if_charcode:w} \cs{scan_stop:}
-% \meta{marker} has to be false.
+% \meta{marker} has to be \texttt{false}.
% \begin{macrocode}
\cs_new:Npn \str_head:n #1
{
- \exp_after:wN \str_head_aux:w
+ \exp_after:wN \__str_head:w
\tl_to_str:n {#1}
{ { } } ~ \q_stop
}
-\cs_new:Npn \str_head_aux:w #1 ~ %
+\cs_new:Npn \__str_head:w #1 ~ %
{ \tl_head:w #1 { ~ } }
\cs_new:Npn \str_tail:n #1
{
- \exp_after:wN \str_tail_aux:w
+ \exp_after:wN \__str_tail:w
\reverse_if:N \if_charcode:w
\scan_stop: \tl_to_str:n {#1} X X \q_stop
}
-\cs_new:Npn \str_tail_aux:w #1 X #2 \q_stop { \fi: #1 }
+\cs_new:Npn \__str_tail:w #1 X #2 \q_stop { \fi: #1 }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -2029,32 +2276,39 @@
% \begin{macro}[pTF]{\tl_if_head_eq_charcode:nN}
% \begin{macro}[pTF]{\tl_if_head_eq_charcode:fN}
% \begin{macro}[pTF]{\tl_if_head_eq_catcode:nN}
-% Accessing the first token of a token list is tricky in two cases:
-% when it has category code $1$ (begin-group token), or when it is
-% an explicit space, with category code $10$ and character code $32$.
-%
-% Forgetting temporarily about this issue we would use the
-% following test in \cs{tl_if_head_eq_charcode:nN}. Here,
-% an empty |#1| argument yields \cs{q_nil}, otherwise the
-% first token of the token list.
+% Accessing the first token of a token list is tricky in three cases:
+% when it has category code $1$ (begin-group token), when it is an
+% explicit space, with category code $10$ and character code $32$, or
+% when the token list is empty (obviously).
+%
+% Forgetting temporarily about this issue we would use the following
+% test in \cs{tl_if_head_eq_charcode:nN}. Here, \cs{tl_head:w} yields
+% the first token of the token list, then passed to \cs{exp_not:N}.
% \begin{verbatim}
% \if_charcode:w
% \exp_after:wN \exp_not:N \tl_head:w #1 \q_nil \q_stop
% \exp_not:N #2
% \end{verbatim}
-% The special cases are detected using \cs{tl_if_head_N_type:n}
-% (the extra |?| takes care of empty arguments).
-% In those cases, the first token is a character, and
-% since we only care about its character code, we can
-% use \cs{str_head:n} to access it (this works even if
-% it is a space character).
+% The two first special cases are detected by testing if the token
+% list starts with an \texttt{N}-type token (the extra |?| sends empty
+% token lists to the \texttt{true} branch of this test). In those
+% cases, the first token is a character, and since we only care about
+% its character code, we can use \cs{str_head:n} to access it (this
+% works even if it is a space character). An empty argument will
+% result in \cs{tl_head:w} leaving two tokens: |?| which is taken in
+% the \cs{if_charcode:w} test, and \cs{use_none:nn}, which ensures
+% that \cs{prg_return_false:} is returned regardless of whether the
+% charcode test was \texttt{true} or \texttt{false}.
% \begin{macrocode}
\prg_new_conditional:Npnn \tl_if_head_eq_charcode:nN #1#2 { p , T , F , TF }
{
\if_charcode:w
\exp_not:N #2
- \tl_if_head_N_type:nTF { #1 ? }
- { \exp_after:wN \exp_not:N \tl_head:w #1 \q_nil \q_stop }
+ \tl_if_head_is_N_type:nTF { #1 ? }
+ {
+ \exp_after:wN \exp_not:N
+ \tl_head:w #1 { ? \use_none:nn } \q_stop
+ }
{ \str_head:n {#1} }
\prg_return_true:
\else:
@@ -2066,20 +2320,26 @@
\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNT { f }
\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNF { f }
% \end{macrocode}
-% For \cs{tl_if_head_eq_catcode:nN}, again we detect special
-% cases with a \cs{tl_if_head_N_type}. Then we need to test
-% if the first token is a begin-group token or an explicit
-% space token, and produce the relevant token, either
-% \cs{c_group_begin_token} or \cs{c_space_token}.
+% For \cs{tl_if_head_eq_catcode:nN}, again we detect special cases
+% with a \cs{tl_if_head_is_N_type:n}. Then we need to test if the
+% first token is a begin-group token or an explicit space token, and
+% produce the relevant token, either \cs{c_group_begin_token} or
+% \cs{c_space_token}. Again, for an empty argument, a hack is used,
+% removing \cs{prg_return_true:} and \cs{else:} with \cs{use_none:nn}
+% in case the catcode test with the (arbitrarily chosen) |?| is
+% \texttt{true}.
% \begin{macrocode}
\prg_new_conditional:Npnn \tl_if_head_eq_catcode:nN #1 #2 { p , T , F , TF }
{
\if_catcode:w
\exp_not:N #2
- \tl_if_head_N_type:nTF { #1 ? }
- { \exp_after:wN \exp_not:N \tl_head:w #1 \q_nil \q_stop }
+ \tl_if_head_is_N_type:nTF { #1 ? }
{
- \tl_if_head_group:nTF {#1}
+ \exp_after:wN \exp_not:N
+ \tl_head:w #1 { ? \use_none:nn } \q_stop
+ }
+ {
+ \tl_if_head_is_group:nTF {#1}
{ \c_group_begin_token }
{ \c_space_token }
}
@@ -2089,29 +2349,34 @@
\fi:
}
% \end{macrocode}
-% For \cs{tl_if_head_eq_meaning:nN}, again, detect special cases.
-% In the normal case, use \cs{tl_head:w}, with no \cs{exp_not:N}
-% this time, since \cs{if_meaning:w} causes no expansion.
+% For \cs{tl_if_head_eq_meaning:nN}, again, detect special cases. In
+% the normal case, use \cs{tl_head:w}, with no \cs{exp_not:N} this
+% time, since \cs{if_meaning:w} causes no expansion. With an empty
+% argument, the test is \texttt{true}, and \cs{use_none:nnn} removes
+% |#2| and the usual \cs{prg_return_true:} and \cs{else:}.
% In the special cases, we know that the first token is a character,
% hence \cs{if_charcode:w} and \cs{if_catcode:w} together are enough.
% We combine them in some order, hopefully faster than the reverse.
+% Tests are not nested because the arguments may contain unmatched
+% primitive conditionals.
% \begin{macrocode}
\prg_new_conditional:Npnn \tl_if_head_eq_meaning:nN #1#2 { p , T , F , TF }
{
- \tl_if_head_N_type:nTF { #1 ? }
- { \tl_if_head_eq_meaning_aux_normal:nN }
- { \tl_if_head_eq_meaning_aux_special:nN }
+ \tl_if_head_is_N_type:nTF { #1 ? }
+ { \@@_if_head_eq_meaning_normal:nN }
+ { \@@_if_head_eq_meaning_special:nN }
{#1} #2
}
-\cs_new:Npn \tl_if_head_eq_meaning_aux_normal:nN #1 #2
+\cs_new:Npn \@@_if_head_eq_meaning_normal:nN #1 #2
{
- \exp_after:wN \if_meaning:w \tl_head:w #1 \q_nil \q_stop #2
+ \exp_after:wN \if_meaning:w
+ \tl_head:w #1 { ?? \use_none:nnn } \q_stop #2
\prg_return_true:
\else:
\prg_return_false:
\fi:
}
-\cs_new:Npn \tl_if_head_eq_meaning_aux_special:nN #1 #2
+\cs_new:Npn \@@_if_head_eq_meaning_special:nN #1 #2
{
\if_charcode:w \str_head:n {#1} \exp_not:N #2
\exp_after:wN \use:n
@@ -2121,7 +2386,7 @@
\fi:
{
\if_catcode:w \exp_not:N #2
- \tl_if_head_group:nTF {#1}
+ \tl_if_head_is_group:nTF {#1}
{ \c_group_begin_token }
{ \c_space_token }
\prg_return_true:
@@ -2136,7 +2401,7 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}[pTF]{\tl_if_head_N_type:n}
+% \begin{macro}[pTF]{\tl_if_head_is_N_type:n}
% The first token of a token list can be either an N-type argument,
% a begin-group token (catcode 1), or an explicit space token
% (catcode 10 and charcode 32). These two cases are characterized
@@ -2145,16 +2410,16 @@
% string representation). The extra brace group covers the case of
% an empty argument, whose head is not \enquote{normal}.
% \begin{macrocode}
-\prg_new_conditional:Npnn \tl_if_head_N_type:n #1 { p , T , F , TF }
+\prg_new_conditional:Npnn \tl_if_head_is_N_type:n #1 { p , T , F , TF }
{
- \str_if_eq_return:xx
+ \__str_if_eq_x_return:nn
{ \exp_not:o { \use:n #1 { } } }
{ \exp_not:n { #1 { } } }
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[EXP,pTF]{\tl_if_head_group:n}
+% \begin{macro}[EXP,pTF]{\tl_if_head_is_group:n}
% Pass the first token of |#1| through \cs{token_to_str:N},
% then check for the brace balance. The extra \texttt{?}
% caters for an empty argument.\footnote{Bruno: this could
@@ -2163,7 +2428,7 @@
% to happen in one step of expansion, keeping the token
% list brace balanced at all times.}
% \begin{macrocode}
-\prg_new_conditional:Npnn \tl_if_head_group:n #1 { p , T , F , TF }
+\prg_new_conditional:Npnn \tl_if_head_is_group:n #1 { p , T , F , TF }
{
\if_catcode:w *
\exp_after:wN \use_none:n
@@ -2181,22 +2446,22 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[EXP,pTF]{\tl_if_head_space:n}
-% \begin{macro}[EXP,aux]{\tl_if_head_space_aux:w}
+% \begin{macro}[EXP,pTF]{\tl_if_head_is_space:n}
+% \begin{macro}[EXP,aux]{\@@_if_head_is_space:w}
% If the first token of the token list is an explicit space, i.e.,
% a character token with character code $32$ and category code $10$,
-% then this test will be \meta{true}. It is \meta{false} if the token
+% then this test will be \texttt{true}. It is \texttt{false} if the token
% list is empty, if the first token is an implicit space token,
% such as \cs{c_space_token}, or any token other than an explicit space.
% The slightly convoluted approach with \tn{romannumeral} ensures that
% each expansion step gives a balanced token list.
% \begin{macrocode}
-\prg_new_conditional:Npnn \tl_if_head_space:n #1 { p , T , F , TF }
+\prg_new_conditional:Npnn \tl_if_head_is_space:n #1 { p , T , F , TF }
{
\tex_romannumeral:D \if_false: { \fi:
- \tl_if_head_space_aux:w ? #1 ? ~ }
+ \@@_if_head_is_space:w ? #1 ? ~ }
}
-\cs_new:Npn \tl_if_head_space_aux:w #1 ~
+\cs_new:Npn \@@_if_head_is_space:w #1 ~
{
\tl_if_empty:oTF { \use_none:n #1 }
{ \exp_after:wN \c_zero \exp_after:wN \prg_return_true: }
@@ -2225,37 +2490,6 @@
% \end{macrocode}
%\end{macro}
%
-% \subsection{Constant token lists}
-%
-% \begin{variable}{\c_job_name_tl}
-% Inherited from the \LaTeX3 name for the primitive: this needs to
-% actually contain the text of the job name rather than the name of
-% the primitive, of course. \LuaTeX{} does not quote file names containing
-% spaces, whereas \pdfTeX{} and \XeTeX{} do. So there may be a correction to
-% make in the \LuaTeX{} case.
-% \begin{macrocode}
-%<*initex>
-\tex_everyjob:D \exp_after:wN
- {
- \tex_the:D \tex_everyjob:D
- \luatex_if_engine:T
- {
- \lua_now:x
- { dofile ( assert ( kpse.find_file ("lualatexquotejobname.lua" ) ) ) }
- }
- }
-%</initex>
-\tl_const:Nx \c_job_name_tl { \tex_jobname:D }
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{variable}{\c_space_tl}
-% A space as a token list (as opposed to as a character).
-% \begin{macrocode}
-\tl_const:Nn \c_space_tl { ~ }
-% \end{macrocode}
-% \end{variable}
-%
% \subsection{Scratch token lists}
%
% \begin{variable}{\g_tmpa_tl, \g_tmpb_tl}
@@ -2279,398 +2513,6 @@
% \end{macrocode}
% \end{variable}
%
-% \subsection{Experimental functions}
-%
-% \begin{macro}[EXP]{\str_if_eq_return:xx}
-% It turns out that we often need to compare a token list
-% with the result of applying some function to it, and
-% return with \cs{prg_return_true/false:}. This test is
-% similar to \cs{str_if_eq:nnTF}, but hard-coded for speed.
-% \begin{macrocode}
-\cs_new:Npn \str_if_eq_return:xx #1 #2
- {
- \if_int_compare:w \pdftex_strcmp:D {#1} {#2} = \c_zero
- \prg_return_true:
- \else:
- \prg_return_false:
- \fi:
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP,pTF]{\tl_if_single:N}
-% Expand the token list and feed it to \cs{tl_if_single:n}.
-% \begin{macrocode}
-\cs_new:Npn \tl_if_single_p:N { \exp_args:No \tl_if_single_p:n }
-\cs_new:Npn \tl_if_single:NT { \exp_args:No \tl_if_single:nT }
-\cs_new:Npn \tl_if_single:NF { \exp_args:No \tl_if_single:nF }
-\cs_new:Npn \tl_if_single:NTF { \exp_args:No \tl_if_single:nTF }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP,pTF]{\tl_if_single:n}
-% A token list has exactly one item if it is either a single
-% token surrounded by optional explicit spaces, or a single brace
-% group surrounded by optional explicit spaces. The naive
-% version of this test would do \cs{use_none:n} |#1|, and
-% test if the result is empty. However, this will fail when
-% the token list is empty. Furthermore, it does not allow optional
-% trailing spaces.
-% \begin{macrocode}
-\prg_new_conditional:Npnn \tl_if_single:n #1 { p , T , F , TF }
- { \str_if_eq_return:xx { \exp_not:o { \use_none:nn #1 ?? } } {?} }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP,pTF]{\tl_if_single_token:n}
-% There are four cases: empty token list, token list starting with
-% a normal token, with a brace group, or with a space token.
-% If the token list starts with a normal token, remove it
-% and check for emptyness. Otherwise, compare with a single
-% space, only case where we have a single token.
-% \begin{macrocode}
-\prg_new_conditional:Npnn \tl_if_single_token:n #1 { p , T , F , TF }
- {
- \tl_if_head_N_type:nTF {#1}
- { \str_if_eq_return:xx { \exp_not:o { \use_none:n #1 } } { } }
- { \str_if_eq_return:xx { \exp_not:n {#1} } { ~ } }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{variable}{\q_tl_act_mark,\q_tl_act_stop}
-% The \cs{tl_act} functions may be applied to any token list.
-% Hence, we use two private quarks, to allow any token, even quarks,
-% in the token list.^^A in particular critical for future \::e.
-% Only \cs{q_tl_act_mark} and \cs{q_tl_act_stop} may not appear
-% in the token lists manipulated by \cs{tl_act} functions. The quarks
-% are effectively defined in \pkg{l3quark}.
-% \end{variable}
-%
-% \begin{macro}[EXP]{\tl_act:NNNnn,\tl_act_aux:NNNnn}
-% \begin{macro}[EXP]{\tl_act_output:n,\tl_act_reverse_output:n,
-% \tl_act_group_recurse:Nnn}
-% \begin{macro}[EXP,aux]{\tl_act_loop:w,\tl_act_normal:NwnNNN,
-% \tl_act_group:nwnNNN,\tl_act_space:wwnNNN,\tl_act_end:w}
-% To help control the expansion, \cs{tl_act:NNNnn} starts with
-% \tn{romannumeral} and ends by producing \cs{c_zero}
-% once the result has been obtained. Then loop over tokens,
-% groups, and spaces in |#5|. The marker \cs{q_tl_act_mark}
-% is used both to avoid losing outer braces and to detect the
-% end of the token list more easily. The result is stored
-% as an argument for the dummy function \cs{tl_act_result:n}.
-% \begin{macrocode}
-\cs_new:Npn \tl_act:NNNnn { \tex_romannumeral:D \tl_act_aux:NNNnn }
-\cs_new:Npn \tl_act_aux:NNNnn #1 #2 #3 #4 #5
- {
- \group_align_safe_begin:
- \tl_act_loop:w #5 \q_tl_act_mark \q_tl_act_stop
- {#4} #1 #2 #3
- \tl_act_result:n { }
- }
-% \end{macrocode}
-% In the loop, we check how the token list begins and act
-% accordingly. In the \enquote{normal} case, we may have
-% reached \cs{q_tl_act_mark}, the end of the list. Then
-% leave \cs{c_zero} and the result in the input stream,
-% to terminate the expansion of \tn{romannumeral}.
-% Otherwise, apply the relevant function to the
-% \enquote{arguments}, |#3|
-% and to the head of the token list. Then repeat the loop.
-% The scheme is the same if the token list starts with a
-% group or with a space. Some extra work is needed to
-% make \cs{tl_act_space:wwnNNN} gobble the space.
-% \begin{macrocode}
-\cs_new:Npn \tl_act_loop:w #1 \q_tl_act_stop
- {
- \tl_if_head_N_type:nTF {#1}
- { \tl_act_normal:NwnNNN }
- {
- \tl_if_head_group:nTF {#1}
- { \tl_act_group:nwnNNN }
- { \tl_act_space:wwnNNN }
- }
- #1 \q_tl_act_stop
- }
-\cs_new:Npn \tl_act_normal:NwnNNN #1 #2 \q_tl_act_stop #3#4
- {
- \if_meaning:w \q_tl_act_mark #1
- \exp_after:wN \tl_act_end:wn
- \fi:
- #4 {#3} #1
- \tl_act_loop:w #2 \q_tl_act_stop
- {#3} #4
- }
-\cs_new:Npn \tl_act_end:wn #1 \tl_act_result:n #2
- { \group_align_safe_end: \c_zero #2 }
-\cs_new:Npn \tl_act_group:nwnNNN #1 #2 \q_tl_act_stop #3#4#5
- {
- #5 {#3} {#1}
- \tl_act_loop:w #2 \q_tl_act_stop
- {#3} #4 #5
- }
-\exp_last_unbraced:NNo
- \cs_new:Npn \tl_act_space:wwnNNN \c_space_tl #1 \q_tl_act_stop #2#3#4#5
- {
- #5 {#2}
- \tl_act_loop:w #1 \q_tl_act_stop
- {#2} #3 #4 #5
- }
-% \end{macrocode}
-% Typically, the output is done to the right of what was already output,
-% using \cs{tl_act_output:n}, but for the \cs{tl_act_reverse} functions,
-% it should be done to the left.
-% \begin{macrocode}
-\cs_new:Npn \tl_act_output:n #1 #2 \tl_act_result:n #3
- { #2 \tl_act_result:n { #3 #1 } }
-\cs_new:Npn \tl_act_reverse_output:n #1 #2 \tl_act_result:n #3
- { #2 \tl_act_result:n { #1 #3 } }
-% \end{macrocode}
-% In many applications of \cs{tl_act:NNNnn}, we need to recursively
-% apply some transformation within brace groups, then output. In this
-% code, |#1| is the output function, |#2| is the transformation,
-% which should expand in two steps, and |#3| is the group.
-% \begin{macrocode}
-\cs_new:Npn \tl_act_group_recurse:Nnn #1#2#3
- {
- \exp_args:Nf #1
- { \exp_after:wN \exp_after:wN \exp_after:wN { #2 {#3} } }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\tl_reverse_tokens:n}
-% \begin{macro}[EXP,aux]{\tl_act_reverse_normal:nN,
-% \tl_act_reverse_group:nn, \tl_act_reverse_space:n}
-% The goal is to reverse a token list. This is done by feeding
-% \cs{tl_act_aux:NNNnn} three functions, an empty fourth argument
-% (we don't use it for \cs{tl_act_reverse_tokens:n}), and as
-% a fifth argument the token list to be reversed.
-% Spaces and normal tokens are output to the left of the current
-% output. For groups, we must recursively apply
-% \cs{tl_act_reverse_tokens:n} to the group, and output, still
-% on the left. Note that in all three cases, we throw one argument
-% away: this \meta{parameter} is where for instance the
-% upper/lowercasing action stores the information of whether it
-% is uppercasing or lowercasing.
-% \begin{macrocode}
-\cs_new:Npn \tl_reverse_tokens:n #1
- {
- \etex_unexpanded:D \exp_after:wN
- {
- \tex_romannumeral:D
- \tl_act_aux:NNNnn
- \tl_act_reverse_normal:nN
- \tl_act_reverse_group:nn
- \tl_act_reverse_space:n
- { }
- {#1}
- }
- }
-\cs_new:Npn \tl_act_reverse_space:n #1
- { \tl_act_reverse_output:n {~} }
-\cs_new:Npn \tl_act_reverse_normal:nN #1 #2
- { \tl_act_reverse_output:n {#2} }
-\cs_new:Npn \tl_act_reverse_group:nn #1
- {
- \tl_act_group_recurse:Nnn
- \tl_act_reverse_output:n
- { \tl_reverse_tokens:n }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\tl_reverse:n,\tl_reverse:o,\tl_reverse:V}
-% \begin{macro}[EXP,aux]{\tl_reverse_group_preserve:nn}
-% The goal here is to reverse without losing spaces nor braces.
-% The only difference with \cs{tl_reverse_tokens:n} is that
-% we now simply output groups without entering them.
-% \begin{macrocode}
-\cs_new:Npn \tl_reverse:n #1
- {
- \etex_unexpanded:D \exp_after:wN
- {
- \tex_romannumeral:D
- \tl_act_aux:NNNnn
- \tl_act_reverse_normal:nN
- \tl_act_reverse_group_preserve:nn
- \tl_act_reverse_space:n
- { }
- {#1}
- }
- }
-\cs_new:Npn \tl_act_reverse_group_preserve:nn #1 #2
- { \tl_act_reverse_output:n { {#2} } }
-\cs_generate_variant:Nn \tl_reverse:n { o , V }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\tl_reverse:N, \tl_reverse:c, \tl_greverse:N, \tl_greverse:c}
-% This reverses the list, leaving \cs{exp_stop_f:} in front,
-% which stops the \texttt{f}-expansion.
-% \begin{macrocode}
-\cs_new_protected:Npn \tl_reverse:N #1
- { \tl_set:Nx #1 { \exp_args:No \tl_reverse:n { #1 } } }
-\cs_new_protected:Npn \tl_greverse:N #1
- { \tl_gset:Nx #1 { \exp_args:No \tl_reverse:n { #1 } } }
-\cs_generate_variant:Nn \tl_reverse:N { c }
-\cs_generate_variant:Nn \tl_greverse:N { c }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}[EXP]{\tl_length_tokens:n}
-% \begin{macro}[EXP,aux]{\tl_act_length_normal:nN,
-% \tl_act_length_group:nn,\tl_act_length_space:n}
-% The length is computed through an \cs{int_eval:n} construction.
-% Each \texttt{1+} is output to the \emph{left}, into the integer
-% expression, and the sum is ended by the \cs{c_zero} inserted by
-% \cs{tl_act_end:wn}. Somewhat a hack.
-% \begin{macrocode}
-\cs_new:Npn \tl_length_tokens:n #1
- {
- \int_eval:n
- {
- \tl_act_aux:NNNnn
- \tl_act_length_normal:nN
- \tl_act_length_group:nn
- \tl_act_length_space:n
- { }
- {#1}
- }
- }
-\cs_new:Npn \tl_act_length_normal:nN #1 #2 { 1 + }
-\cs_new:Npn \tl_act_length_space:n #1 { 1 + }
-\cs_new:Npn \tl_act_length_group:nn #1 #2
- { 2 + \tl_length_tokens:n {#2} + }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{variable}{\c_tl_act_uppercase_tl, \c_tl_act_lowercase_tl}
-% These constants contain the correspondance between lowercase
-% and uppercase letters, in the form |aAbBcC...| and |AaBbCc...|
-% respectively.
-% \begin{macrocode}
-\tl_const:Nn \c_tl_act_uppercase_tl
- {
- aA bB cC dD eE fF gG hH iI jJ kK lL mM
- nN oO pP qQ rR sS tT uU vV wW xX yY zZ
- }
-\tl_const:Nn \c_tl_act_lowercase_tl
- {
- Aa Bb Cc Dd Ee Ff Gg Hh Ii Jj Kk Ll Mm
- Nn Oo Pp Qq Rr Ss Tt Uu Vv Ww Xx Yy Zz
- }
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{macro}[EXP]{\tl_expandable_uppercase:n,\tl_expandable_lowercase:n}
-% \begin{macro}[EXP,aux]{\tl_act_case_normal:nN,
-% \tl_act_case_group:nn,\tl_act_case_space:n}
-% The only difference between uppercasing and lowercasing is
-% the table of correspondance that is used. As for other
-% token list actions, we feed \cs{tl_act_aux:NNNnn} three
-% functions, and this time, we use the \meta{parameters}
-% argument to carry which case-changing we are applying.
-% A space is simply output. A normal token is compared
-% to each letter in the alphabet using \cs{str_if_eq:nn}
-% tests, and converted if necessary to upper/lowercase,
-% before being output. For a group, we must perform the
-% conversion within the group (the \cs{exp_after:wN} trigger
-% \tn{romannumeral}, which expands fully to give the
-% converted group), then output.
-% \begin{macrocode}
-\cs_new:Npn \tl_expandable_uppercase:n #1
- {
- \etex_unexpanded:D \exp_after:wN
- {
- \tex_romannumeral:D
- \tl_act_case_aux:nn { \c_tl_act_uppercase_tl } {#1}
- }
- }
-\cs_new:Npn \tl_expandable_lowercase:n #1
- {
- \etex_unexpanded:D \exp_after:wN
- {
- \tex_romannumeral:D
- \tl_act_case_aux:nn { \c_tl_act_lowercase_tl } {#1}
- }
- }
-\cs_new:Npn \tl_act_case_aux:nn
- {
- \tl_act_aux:NNNnn
- \tl_act_case_normal:nN
- \tl_act_case_group:nn
- \tl_act_case_space:n
- }
-\cs_new:Npn \tl_act_case_space:n #1 { \tl_act_output:n {~} }
-\cs_new:Npn \tl_act_case_normal:nN #1 #2
- {
- \exp_args:Nf \tl_act_output:n
- {
- \exp_args:NNo \prg_case_str:nnn #2 {#1}
- { \exp_stop_f: #2 }
- }
- }
-\cs_new:Npn \tl_act_case_group:nn #1 #2
- {
- \exp_after:wN \tl_act_output:n \exp_after:wN
- { \exp_after:wN { \tex_romannumeral:D \tl_act_case_aux:nn {#1} {#2} } }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\tl_item:nn, \tl_item:Nn, \tl_item:cn}
-% \begin{macro}[aux]{\tl_item_aux:nn}
-% 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 \cs{quark_if_recursion_tail_stop:n} terminates the loop, and returns
-% nothing at all.
-% \begin{macrocode}
-\cs_new:Npn \tl_item:nn #1#2
- {
- \exp_args:Nf \tl_item_aux:nn
- {
- \int_eval:n
- {
- \int_compare:nNnT {#2} < \c_zero
- { \tl_length:n {#1} + }
- #2
- }
- }
- #1
- \q_recursion_tail
- \prg_break_point:n { }
- }
-\cs_new:Npn \tl_item_aux:nn #1#2
- {
- \quark_if_recursion_tail_break:n {#2}
- \int_compare:nNnTF {#1} = \c_zero
- { \tl_map_break:n { \exp_not:n {#2} } }
- { \exp_args:Nf \tl_item_aux:nn { \int_eval:n { #1 - 1 } } }
- }
-\cs_new_nopar:Npn \tl_item:Nn { \exp_args:No \tl_item:nn }
-\cs_generate_variant:Nn \tl_item:Nn { c }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}[pTF]{\tl_if_empty:x}
-% We can test expandably the emptyness of an expanded token list
-% thanks to the primitive \tn{pdfstrcmp} which expands its argument:
-% a token list is empty if and only if its string representation is
-% empty.
-% \begin{macrocode}
-\prg_new_conditional:Npnn \tl_if_empty:x #1 { p , T , F , TF }
- { \str_if_eq_return:xx { } {#1} }
-% \end{macrocode}
-% \end{macro}
-%
% \subsection{Deprecated functions}
%
% \begin{macro}{\tl_new:Nn, \tl_new:cn, \tl_new:Nx}
@@ -2751,11 +2593,11 @@
% Another renaming job.
% \begin{macrocode}
%<*deprecated>
-\cs_new_eq:NN \tl_elt_count:n \tl_length:n
-\cs_new_eq:NN \tl_elt_count:V \tl_length:V
-\cs_new_eq:NN \tl_elt_count:o \tl_length:o
-\cs_new_eq:NN \tl_elt_count:N \tl_length:N
-\cs_new_eq:NN \tl_elt_count:c \tl_length:c
+\cs_new_eq:NN \tl_elt_count:n \tl_count:n
+\cs_new_eq:NN \tl_elt_count:V \tl_count:V
+\cs_new_eq:NN \tl_elt_count:o \tl_count:o
+\cs_new_eq:NN \tl_elt_count:N \tl_count:N
+\cs_new_eq:NN \tl_elt_count:c \tl_count:c
%</deprecated>
% \end{macrocode}
% \end{macro}
@@ -2782,6 +2624,58 @@
% \end{macro}
% \end{macro}
%
+% Deprecated on 2012-05-13 for removal by 2012-08-31.
+%
+% \begin{macro}{\tl_length_tokens:n}
+% \begin{macrocode}
+\cs_new_eq:NN \tl_length_tokens:n \tl_count_tokens:n
+% \end{macrocode}
+% \end{macro}
+%
+% Deprecated 2012-05-13 for removal by 2012-11-31.
+%
+% \begin{macro}
+% {\tl_length:N, \tl_length:c, \tl_length:n, \tl_length:V, \tl_length:o}
+% Renames.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_length:N \tl_count:N
+\cs_new_eq:NN \tl_length:c \tl_count:c
+\cs_new_eq:NN \tl_length:n \tl_count:n
+\cs_new_eq:NN \tl_length:V \tl_count:V
+\cs_new_eq:NN \tl_length:o \tl_count:o
+% \end{macrocode}
+% \end{macro}
+%
+% Deprecated 2012-06-05 for removal after 2012-12-31.
+%
+% \begin{macro}[pTF]{\tl_if_empty:x}
+% We can test expandably the emptiness of an expanded token list
+% thanks to the primitive \tn{pdfstrcmp} which expands its argument:
+% a token list is empty if and only if its string representation is
+% empty.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_empty:x #1 { p , T , F , TF }
+ { \__str_if_eq_x_return:nn { } {#1} }
+% \end{macrocode}
+% \end{macro}
+%
+% Deprecated 2012-07-08 for removal after 2012-10-31.
+%
+% \begin{macro}[EXP, pTF]{\tl_if_head_group:n}
+% \begin{macro}[EXP, pTF]{\tl_if_head_N_type:n}
+% \begin{macro}[EXP, pTF]{\tl_if_head_space:n}
+% \begin{macrocode}
+\prg_new_eq_conditional:NNn \tl_if_head_group:n \tl_if_head_is_group:n
+ { p , T , F , TF }
+\prg_new_eq_conditional:NNn \tl_if_head_N_type:n \tl_if_head_is_N_type:n
+ { p , T , F , TF }
+\prg_new_eq_conditional:NNn \tl_if_head_space:n \tl_if_head_is_space:n
+ { p , T , F , TF }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
% \begin{macrocode}
%</initex|package>
% \end{macrocode}