summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2011-07-31 18:27:06 +0000
committerKarl Berry <karl@freefriends.org>2011-07-31 18:27:06 +0000
commitdac945b204407dae96f70ec228206516093156d7 (patch)
tree02ca182689947e45dec95e17ba08b503c959bd17 /Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
parentc1840548792cfbc7c9f746da1d53d89b94406e72 (diff)
l3kernel (5jun11)
git-svn-id: svn://tug.org/texlive/trunk@23282 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.dtx2268
1 files changed, 2268 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
new file mode 100644
index 00000000000..a7f292d14c7
--- /dev/null
+++ b/Master/texmf-dist/source/latex/l3kernel/l3tl.dtx
@@ -0,0 +1,2268 @@
+% \iffalse meta-comment
+%
+%% File: l3tl.dtx Copyright (C) 1990-2011 The LaTeX3 Project
+%%
+%% It may be distributed and/or modified under the conditions of the
+%% LaTeX Project Public License (LPPL), either version 1.3c of this
+%% license or (at your option) any later version. The latest version
+%% of this license is in the file
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% This file is part of the "expl3 bundle" (The Work in LPPL)
+%% and all files in that bundle must be distributed together.
+%%
+%% The released version of this bundle is available from CTAN.
+%%
+%% -----------------------------------------------------------------------
+%%
+%% The development version of the bundle can be found at
+%%
+%% http://www.latex-project.org/svnroot/experimental/trunk/
+%%
+%% for those people who are interested.
+%%
+%%%%%%%%%%%
+%% NOTE: %%
+%%%%%%%%%%%
+%%
+%% Snapshots taken from the repository represent work in progress and may
+%% not work or may contain conflicting material! We therefore ask
+%% people _not_ to put them into distributions, archives, etc. without
+%% prior consultation with the LaTeX3 Project.
+%%
+%% -----------------------------------------------------------------------
+%
+%<*driver|package>
+\RequirePackage{l3names}
+\GetIdInfo$Id: l3tl.dtx 2498 2011-07-09 17:51:47Z joseph $
+ {L3 Experimental token lists}
+%</driver|package>
+%<*driver>
+\documentclass[full]{l3doc}
+\begin{document}
+ \DocInput{\jobname.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% The \pkg{l3tl} package\\ Token lists^^A
+% \thanks{This file describes v\ExplFileVersion,
+% last revised \ExplFileDate.}^^A
+% }
+%
+% \author{^^A
+% The \LaTeX3 Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \date{Released \ExplFileDate}
+%
+% \maketitle
+%
+% \begin{documentation}
+%
+% \LaTeX3 stores lists of token in variables also called \enquote{token lists}.
+% Variables of this type get the suffix |tl| and functions of this type
+% have the prefix |tl|. To use a token list variable you simply call
+% the corresponding variable.
+%
+% Often you find yourself with not a token list variable but an
+% arbitrary token list which has to undergo certain tests. We will \emph{also}
+% prefix these functions with |tl|. While token list variables are
+% always single tokens, token lists are always surrounded by
+% braces. Many of the functions for token lists and token list variables
+% are very similar, and so are grouped together here.
+%
+% \section{Creating and initialising token list variables}
+%
+% \begin{function}{\tl_new:N, \tl_new:c}
+% \begin{syntax}
+% \cs{tl_new:N} \meta{tl~var}
+% \end{syntax}
+% Creates a new \meta{tl~var} or raises an error if the
+% name is already taken. The declaration is global. The
+% \meta{tl~var} will initially be empty.
+% \end{function}
+%
+% \begin{function}{\tl_const:Nn, \tl_const:Nx, \tl_const:cn, \tl_const:cx}
+% \begin{syntax}
+% \cs{tl_const:Nn} \meta{tl~var} \Arg{token list}
+% \end{syntax}
+% Creates a new constant \meta{tl~var} or raises an error
+% if the name is already taken. The value of the
+% \meta{tl~var} will be set globally to the
+% \meta{token list}.
+% \end{function}
+%
+% \begin{function}{\tl_clear:N, \tl_clear:c}
+% \begin{syntax}
+% \cs{tl_clear:N} \meta{tl~var}
+% \end{syntax}
+% Clears all entries from the \meta{tl~var} within the scope of
+% the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\tl_gclear:N, \tl_gclear:c}
+% \begin{syntax}
+% \cs{tl_gclear:N} \meta{tl~var}
+% \end{syntax}
+% Clears all entries from the \meta{tl~var} globally.
+% \end{function}
+%
+% \begin{function}{\tl_clear_new:N, \tl_clear_new:c}
+% \begin{syntax}
+% \cs{tl_clear_new:N} \meta{tl~var}
+% \end{syntax}
+% If the \meta{tl~var} already exists, clears it within the scope
+% of the current \TeX{} group. If the \meta{tl~var} is not defined,
+% it will be created (using \cs{tl_new:N}). Thus the sequence is
+% guaranteed to be available and clear within the current \TeX{}
+% group. The \meta{tl~var} will exist globally, but the content
+% outside of the current \TeX{} group is not specified.
+% \end{function}
+%
+% \begin{function}{\tl_gclear_new:N, \tl_gclear_new:c}
+% \begin{syntax}
+% \cs{tl_gclear_new:N} \meta{tl~var}
+% \end{syntax}
+% If the \meta{tl~var} already exists, clears it globally. If the
+% \meta{tl~var} is not defined, it will be created (using
+% \cs{tl_new:N}). Thus the sequence is guaranteed to be available
+% and globally clear.
+% \end{function}
+%
+% \begin{function}{\tl_set_eq:NN, \tl_set_eq:cN, \tl_set_eq:Nc, \tl_set_eq:cc}
+% \begin{syntax}
+% \cs{tl_set_eq:NN} \meta{tl~var1} \meta{tl~var2}
+% \end{syntax}
+% Sets the content of \meta{tl~var1} equal to that of
+% \meta{tl~var2}. This assignment is restricted to the current
+% \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {\tl_gset_eq:NN, \tl_gset_eq:cN, \tl_gset_eq:Nc, \tl_gset_eq:cc}
+% \begin{syntax}
+% \cs{tl_gset_eq:NN} \meta{tl~var1} \meta{tl~var2}
+% \end{syntax}
+% Sets the content of \meta{tl~var1} equal to that of
+% \meta{tl~var2}. This assignment is global and so is not
+% limited by the current \TeX{} group level.
+% \end{function}
+%
+% \section{Adding data to token list variables}
+%
+% \begin{function}
+% {
+% \tl_set:Nn, \tl_set:NV, \tl_set:Nv, \tl_set:No, \tl_set:Nf, \tl_set:Nx,
+% \tl_set:cn, \tl_set:NV, \tl_set:Nv, \tl_set:co, \tl_set:cf, \tl_set:cx
+% }
+% \begin{syntax}
+% \cs{tl_set:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Sets \meta{tl~var} to contain \meta{tokens},
+% removing any previous content from the variable. This assignment
+% is restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}
+% {
+% \tl_gset:Nn, \tl_gset:NV, \tl_gset:Nv,
+% \tl_gset:No, \tl_gset:Nf, \tl_gset:Nx,
+% \tl_gset:cn, \tl_gset:cV, \tl_gset:cv,
+% \tl_gset:co, \tl_gset:cf, \tl_gset:cx
+% }
+% \begin{syntax}
+% \cs{tl_gset:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Sets \meta{tl~var} to contain \meta{tokens},
+% removing any previous content from the variable. This assignment
+% is global and is not limited to the current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \tl_put_left:Nn, \tl_put_left:NV, \tl_put_left:No, \tl_put_left:Nx,
+% \tl_put_left:cn, \tl_put_left:cV, \tl_put_left:co, \tl_put_left:cx
+% }
+% \begin{syntax}
+% \cs{tl_put_left:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Appends \meta{tokens} to the left side of the current content of
+% \meta{tl~var}. This modification is restricted to the
+% current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \tl_gput_left:Nn, \tl_gput_left:NV, \tl_gput_left:No, \tl_gput_left:Nx,
+% \tl_gput_left:cn, \tl_gput_left:cV, \tl_gput_left:co, \tl_gput_left:cx
+% }
+% \begin{syntax}
+% \cs{tl_gput_left:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Globally appends \meta{tokens} to the left side of the current
+% content of \meta{tl~var}. This modification is not
+% limited by \TeX{} grouping.
+% \end{function}
+%
+% \begin{function}
+% {
+% \tl_put_right:Nn, \tl_put_right:NV, \tl_put_right:No, \tl_put_right:Nx,
+% \tl_put_right:cn, \tl_put_right:cV, \tl_put_right:co, \tl_put_right:cx
+% }
+% \begin{syntax}
+% \cs{tl_put_right:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Appends \meta{tokens} to the right side of the current content of
+% \meta{tl~var}. This modification is restricted to the
+% current \TeX{} group level.
+% \end{function}
+%
+% \begin{function}
+% {
+% \tl_gput_right:Nn, \tl_gput_right:NV, \tl_gput_right:No,
+% \tl_gput_right:Nx,
+% \tl_gput_right:cn, \tl_gput_right:cV, \tl_gput_right:co,
+% \tl_gput_right:cx
+% }
+% \begin{syntax}
+% \cs{tl_gput_right:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Globally appends \meta{tokens} to the right side of the current
+% content of \meta{tl~var}. This modification is not
+% limited by \TeX{} grouping.
+% \end{function}
+%
+% \section{Modifying token list variables}
+%
+% \begin{function}{\tl_replace_once:Nnn, \tl_replace_once:cnn}
+% \begin{syntax}
+% \cs{tl_replace_once:Nnn} \meta{tl~var} \Arg{old tokens}
+% ~~\Arg{new tokens}
+% \end{syntax}
+% Replaces the first (leftmost) occurrence of \meta{old tokens} in the
+% \meta{tl~var} with \meta{new tokens}. \meta{Old tokens}
+% cannot contain |{|, |}| or |#|
+% (assuming normal \TeX{} category codes). The assignment is
+% restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\tl_greplace_once:Nnn, \tl_greplace_once:cnn}
+% \begin{syntax}
+% \cs{tl_greplace_once:Nnn} \meta{tl~var} \Arg{old tokens}
+% ~~\Arg{new tokens}
+% \end{syntax}
+% Replaces the first (leftmost) occurrence of \meta{old tokens} in the
+% \meta{tl~var} with \meta{new tokens}. \meta{Old tokens}
+% cannot contain |{|, |}| or |#|
+% (assuming normal \TeX{} category codes). The assignment is
+% applied globally.
+% \end{function}
+%
+% \begin{function}{\tl_replace_all:Nnn, \tl_replace_all:cnn}
+% \begin{syntax}
+% \cs{tl_replace_all:Nnn} \meta{tl~var} \Arg{old tokens}
+% ~~\Arg{new tokens}
+% \end{syntax}
+% Replaces all occurrences of \meta{old tokens} in the
+% \meta{tl~var} with \meta{new tokens}. \meta{Old tokens}
+% cannot contain |{|, |}| or |#|
+% (assuming normal \TeX{} category codes). The assignment is
+% restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\tl_greplace_all:Nnn, \tl_greplace_all:cnn}
+% \begin{syntax}
+% \cs{tl_greplace_all:Nnn} \meta{tl~var} \Arg{old tokens}
+% ~~\Arg{new tokens}
+% \end{syntax}
+% Replaces all occurrences of \meta{old tokens} in the
+% \meta{tl~var} with \meta{new tokens}. \meta{Old tokens}
+% cannot contain |{|, |}| or |#|
+% (assuming normal \TeX{} category codes). The assignment is
+% applied globally.
+% \end{function}
+%
+% \begin{function}{\tl_remove_once:Nn, \tl_remove_once:cn}
+% \begin{syntax}
+% \cs{tl_remove_once:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Removes the first (leftmost) occurrence of \meta{tokens} from the
+% \meta{tl~var}. \meta{Tokens} cannot contain |{|, |}| or
+% |#| (assuming normal \TeX{} category codes). The assignment is
+% restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\tl_gremove_once:Nn, \tl_gremove_once:cn}
+% \begin{syntax}
+% \cs{tl_gremove_once:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Removes the first (leftmost) occurrence of \meta{tokens} from the
+% \meta{tl~var}. \meta{Tokens} cannot contain |{|, |}| or
+% |#| (assuming normal \TeX{} category codes). The assignment is
+% applied globally.
+% \end{function}
+%
+% \begin{function}{\tl_remove_all:Nn, \tl_remove_all:cn}
+% \begin{syntax}
+% \cs{tl_remove_all:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Removes all occurrences of \meta{tokens} from the
+% \meta{tl~var}. \meta{Tokens} cannot contain |{|, |}| or
+% |#| (assuming normal \TeX{} category codes). The assignment is
+% restricted to the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\tl_gremove_all:Nn, \tl_gremove_all:cn}
+% \begin{syntax}
+% \cs{tl_gremove_all:Nn} \meta{tl~var} \Arg{tokens}
+% \end{syntax}
+% Removes all occurrences of \meta{tokens} from the
+% \meta{tl~var}. \meta{Tokens} cannot contain |{|, |}| or
+% |#| (assuming normal \TeX{} category codes). The assignment is
+% applied globally.
+% \end{function}
+%
+% \section{Reassigning token list category codes}
+%
+% \begin{function}
+% {
+% \tl_set_rescan:Nnn, \tl_set_rescan:Nno, \tl_set_rescan:Nnx,
+% \tl_set_rescan:cnn, \tl_set_rescan:cno, \tl_set_rescan:cnx,
+% }
+% \begin{syntax}
+% \cs{tl_set_rescan:Nnn} \meta{tl~var} \Arg{setup}
+% ~~\Arg{tokens}
+% \end{syntax}
+% Sets \meta{tl~var} to contain \meta{tokens},
+% applying the category code regim{\'e} specified in the
+% \meta{setup} before carrying out the assignment. This allows the
+% \meta{tl~var} to contain material with category codes
+% other than those that apply when \meta{tokens} are absorbed. The
+% assignment is local to the current \TeX{} group. See also
+% \cs{tl_rescan:nn}.
+% \end{function}
+%
+% \begin{function}
+% {
+% \tl_gset_rescan:Nnn, \tl_gset_rescan:Nno, \tl_gset_rescan:Nnx,
+% \tl_gset_rescan:cnn, \tl_gset_rescan:cno, \tl_gset_rescan:cnx,
+% }
+% \begin{syntax}
+% \cs{tl_gset_rescan:Nnn} \meta{tl~var} \Arg{setup}
+% ~~\Arg{tokens}
+% \end{syntax}
+% Sets \meta{tl~var} to contain \meta{tokens},
+% applying the category code regim{\'e} specified in the
+% \meta{setup} before carrying out the assignment. This allows the
+% \meta{tl~var} to contain material with category codes
+% other than those that apply when \meta{tokens} are absorbed. The
+% assignment is global. See also \cs{tl_rescan:nn}.
+% \end{function}
+%
+% \begin{function}{\tl_rescan:nn}
+% \begin{syntax}
+% \cs{tl_rescan:nn} \Arg{setup} \Arg{tokens}
+% \end{syntax}
+% Rescans \meta{tokens} applying the category code regim{\'e} specified
+% in the \meta{setup}, and leaves the resulting tokens in the input
+% stream. See also \cs{tl_set_rescan:Nnn}.
+% \end{function}
+%
+% \section{Reassigning token list character codes}
+%
+% \begin{function}{\tl_to_lowercase:n}
+% \begin{syntax}
+% \cs{tl_to_lowercase:n} \Arg{tokens}
+% \end{syntax}
+% Works through all of the \meta{tokens}, replacing each character
+% with the lower case equivalent as defined by \cs{char_set_lccode:nn}.
+% Characters with no defined lower case character code are left
+% unchanged. This process does not alter the category code assigned
+% to the \meta{tokens}.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{lowercase} renamed.
+% As a result, this function takes place on execution and
+% not on expansion.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\tl_to_uppercase:n}
+% \begin{syntax}
+% \cs{tl_to_uppercase:n} \Arg{tokens}
+% \end{syntax}
+% Works through all of the \meta{tokens}, replacing each character
+% with the upper case equivalent as defined by \cs{char_set_uccode:nn}.
+% Characters with no defined lower case character code are left
+% unchanged. This process does not alter the category code assigned
+% to the \meta{tokens}.
+% \begin{texnote}
+% This is the \TeX{} primitive \cs{uppercase} renamed..
+% As a result, this function takes place on execution and
+% not on expansion.
+% \end{texnote}
+% \end{function}
+%
+% \section{Token list conditionals}
+%
+% \begin{function}[EXP,pTF]{\tl_if_blank:n, \tl_if_blank:V, \tl_if_blank:o}
+% \begin{syntax}
+% \cs{tl_if_blank_p:n} \Arg{token list}
+% \cs{tl_if_blank:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list} consists only of blank spaces. The
+% test is \texttt{true} if \meta{token list} is empty or consists
+% entirely of explicit tokens of character code $32$
+% and category code $10$, and is \texttt{false}
+% otherwise. The branching versions then leave either \meta{true code}
+% or \meta{false code} in the input stream, as appropriate to the
+% truth of the test and the variant of the function chosen. The logical
+% truth of the test is left in the input stream by the predicate
+% version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_empty:N, \tl_if_empty:c}
+% \begin{syntax}
+% \cs{tl_if_empty_p:N} \meta{tl var}
+% \cs{tl_if_empty:NTF} \meta{tl var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list variable} is entirely empty
+% (\emph{i.e.}~contains no tokens at all). The branching versions then
+% leave either \meta{true code} or \meta{false code} in the input
+% stream, as appropriate to the truth of the test and the variant of
+% the function chosen. The logical truth of the test is left in the
+% input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[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). The branching versions then
+% leave either \meta{true code} or \meta{false code} in the input
+% stream, as appropriate to the truth of the test and the variant of
+% the function chosen. The logical truth of the test is left in the
+% input stream by the predicate version.
+% \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}
+% \end{syntax}
+% Compares the content of two \meta{token list variables} and
+% is logically \texttt{true} if the two contain the same list of
+% tokens (\emph{i.e.}~identical in both the list of characters they
+% contain and the category codes of those characters). Thus for example
+% \begin{verbatim}
+% \tl_set:Nn \l_tmpa_tl { abc }
+% \tl_set:Nx \l_tmpb_tl { \tl_to_str:n { abc } }
+% \tl_if_eq_p:NN \l_tmpa_tl \l_tmpb_tl
+% \end{verbatim}
+% is logically \texttt{false}. The branching versions then leave either
+% \meta{true code} or \meta{false code} in the input stream, as
+% appropriate to the truth of the test and the variant of the function
+% chosen. The logical truth of the test is left in the input stream by
+% the predicate version.
+% \end{function}
+%
+% \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}
+% \end{syntax}
+% Tests if \meta{token list1} and \meta{token list2} are equal, both in
+% respect of character codes and category codes. Either the
+% \meta{true code} or \meta{false code} in the input stream, as
+% appropriate to the truth of the test and the variant of the function
+% chosen.
+% \end{function}
+%
+% \begin{function}[TF]{\tl_if_in:Nn, \tl_if_in:cn}
+% \begin{syntax}
+% \cs{tl_if_in:NnTF} \meta{tl~var} \Arg{token list} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list} is found in the content of the
+% \meta{token list variable}. The \meta{token list} cannot contain
+% the tokens |{|, |}| or |#| (assuming the usual \TeX{} category
+% codes apply). Either the \meta{true code} or \meta{false code}
+% is left in the
+% input stream, as appropriate to the truth of the test and the variant
+% of the function chosen.
+% \end{function}
+%
+% \begin{function}[TF]
+% {\tl_if_in:nn, \tl_if_in:Vn, \tl_if_in:on, \tl_if_in:on}
+% \begin{syntax}
+% \cs{tl_if_in:nnTF} \meta{token list1} \Arg{token list2} \Arg{true code}
+% ~~\Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list1} is found inside \meta{token list2}.
+% The \meta{token list} cannot contain the tokens |{|, |}| or |#|
+% (assuming the usual \TeX{} category codes apply). Either the
+% \meta{true code} or \meta{false code} is left in the input stream, as
+% appropriate to the truth of the test and the variant of the function
+% chosen.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_single:N, \tl_if_single:c}
+% \begin{syntax}
+% \cs{tl_if_single_p:N} \Arg{tl~var}
+% \cs{tl_if_single:nTF} \Arg{tl~var} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the content of the \meta{tl~var} consists of a
+% single token or token group. The test is \texttt{true} if
+% \meta{token list} contains exactly one token, if it consists
+% entirely of explicit tokens of character code $32$ and category
+% code $10$, or if it contains one braced token group (optionally
+% preceeded by spaces), and it is \texttt{false} otherwise. The branching
+% versions then leave either \meta{true code} or \meta{false code}
+% in the input stream, as appropriate to the truth of the test and the
+% variant of the function chosen. The logical truth of the test is left
+% in the input stream by the predicate version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_single:n}
+% \begin{syntax}
+% \cs{tl_if_single_p:n} \Arg{token list}
+% \cs{tl_if_single:nTF} \Arg{token list} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{token list} consists of a single token
+% or token group. The test is \texttt{true} if \meta{token list}
+% contains exactly one token, or if it consists entirely of
+% explicit tokens of character code $32$ and category code $10$,
+% or if it contains a braced token group (optionally preceeded by blank
+% spaces), and it is
+% \texttt{false} otherwise. The branching versions then leave
+% either \meta{true code} or \meta{false code} in the input stream, as
+% appropriate to the truth of the test and the variant of the function
+% chosen. The logical truth of the test is left in the input stream by
+% the predicate version.
+% \end{function}
+%
+% \section{Mapping to token lists}
+%
+% \begin{function}[EXP]{\tl_map_function:NN, \tl_map_function:cN}
+% \begin{syntax}
+% \cs{tl_map_function:NN} \meta{tl~var} \meta{function}
+% \end{syntax}
+% Applies \meta{function} to every \meta{token group} stored in the
+% \meta{tl~var}. The \meta{function}
+% will receive one argument for each iteration. This may be a number
+% of tokens if the \meta{token group} was an item stored within
+% braces. Hence the \meta{function} should anticipate receiving
+% \texttt{n}-type arguments. See also \cs{tl_map_function:nN}.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_map_function:nN}
+% \begin{syntax}
+% \cs{tl_map_function:nN} \meta{token list} \meta{function}
+% \end{syntax}
+% Applies \meta{function} to every \meta{token group} in the
+% \meta{token list}. The \meta{function}
+% will receive one argument for each iteration. This may be a number
+% of tokens if the \meta{token group} was an item stored within
+% braces. Hence the \meta{function} should anticipate receiving
+% \texttt{n}-type arguments. See also \cs{tl_map_function:NN}.
+% \end{function}
+%
+% \begin{function}{\tl_map_inline:Nn, \tl_map_inline:cn}
+% \begin{syntax}
+% \cs{tl_map_inline:Nn} \meta{tl~var} \Arg{inline function}
+% \end{syntax}
+% Applies the \meta{inline function} to every \meta{token group} stored
+% within the \meta{tl~var}. The \meta{inline function}
+% should consist of code which will receive the \meta{token group} as
+% |#1|. One in line mapping can be nested inside another. See also
+% \cs{tl_map_function:Nn}.
+% \end{function}
+%
+% \begin{function}{\tl_map_inline:nn}
+% \begin{syntax}
+% \cs{tl_map_inline:nn} \meta{token list} \Arg{inline function}
+% \end{syntax}
+% Applies the \meta{inline function} to every \meta{token group} stored
+% within the \meta{token list}. The \meta{inline function} should
+% consist of code which will receive the \meta{token group} as
+% |#1|. One in line mapping can be nested inside another. See also
+% \cs{tl_map_function:nn}.
+% \end{function}
+%
+% \begin{function}{\tl_map_variable:NNn, \tl_map_variable:cNn}
+% \begin{syntax}
+% \cs{tl_map_variable:NNn} \meta{tl~var} \meta{variable} \Arg{function}
+% \end{syntax}
+% Applies the \meta{function} to every \meta{token group} stored
+% within the \meta{tl~var}. The \meta{function} should consist of code
+% which will receive the \meta{token group} stored in the \meta{variable}.
+% One variable mapping can be nested inside another. See also
+% \cs{tl_map_inline:Nn}.
+% \end{function}
+%
+% \begin{function}{\tl_map_variable:nNn}
+% \begin{syntax}
+% \cs{tl_map_variable:nNn} \meta{token list} \meta{variable} \Arg{function}
+% \end{syntax}
+% Applies the \meta{function} to every \meta{token group} stored
+% within the \meta{token list}. The \meta{function} should consist of code
+% which will receive the \meta{token group} stored in the \meta{variable}.
+% One variable mapping can be nested inside another. See also
+% \cs{tl_map_inline:nn}.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_map_break:}
+% \begin{syntax}
+% \cs{tl_map_break:}
+% \end{syntax}
+% Used to terminate a \cs{tl_map_\ldots} function before all
+% entries in the \meta{token list variable} have been processed. 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: }
+% {
+% % Do something useful
+% }
+% }
+% \end{verbatim}
+% Use outside of a \cs{tl_map_\ldots} scenario will lead low
+% level \TeX{} errors.
+% \end{function}
+%
+% \section{Using token lists}
+%
+% \begin{function}[EXP]{\tl_to_str:N, \tl_to_str:c}
+% \begin{syntax}
+% \cs{tl_to_str:N} \meta{tl~var}
+% \end{syntax}
+% Converts the content of the \meta{tl~var} into a series of characters
+% with category code $12$ (other) with the exception of spaces, which
+% retain category code $10$ (space). This \meta{string} is then left
+% in the input stream.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_to_str:n}
+% \begin{syntax}
+% \cs{tl_to_str:n} \Arg{tokens}
+% \end{syntax}
+% Converts the given \meta{tokens} into a series of characters with
+% category code $12$ (other) with the exception of spaces, which
+% retain category code $10$ (space). This \meta{string} is then left
+% in the input stream. Note that this function requires only a single
+% expansion.
+% \begin{texnote}
+% This is the \eTeX{} primitive \cs{detokenize}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_use:N, \tl_use:c}
+% \begin{syntax}
+% \cs{tl_use:N} \meta{tl~var}
+% \end{syntax}
+% Recovers the content of a \meta{tl~var} and places it
+% directly in the input stream. An error will be raised if the variable
+% does not exist or if it is invalid. Note that it is possible to use
+% a \meta{tl~var} directly without an accessor function.
+% \end{function}
+%
+% \section{Working with the content of token lists}
+%
+% \begin{function}[EXP]{\tl_length:n, \tl_length:V, \tl_length:o}
+% \begin{syntax}
+% \cs{tl_length:n} \Arg{tokens}
+% \end{syntax}
+% Counts the number of token groups 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,
+% giving an \meta{integer denotation}.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_length:N, \tl_length:c}
+% \begin{syntax}
+% \cs{tl_length: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,
+% giving an \meta{integer denotation}.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_reverse:n, \tl_reverse:V, \tl_reverse:o}
+% \begin{syntax}
+% \cs{tl_reverse:n} \Arg{tokens}
+% \end{syntax}
+% Reverses the order of the \meta{tokens}, so that
+% \meta{token1}\meta{token2}\meta{token3} \ldots \meta{token$_n$}
+% becomes \meta{token$_n$}\ldots
+% \meta{token3}\meta{token2}\meta{token1}. This process will remove
+% any unprotected space within the \meta{tokens}. Tokens are not reversed
+% within braced token groups, which lose their outer set of braces.
+% See also \cs{tl_reverse:N}.
+% \end{function}
+%
+% \begin{function}{\tl_reverse:N, \tl_reverse:c}
+% \begin{syntax}
+% \cs{tl_reverse:N} \Arg{tl~var}
+% \end{syntax}
+% Reverses the order of the \meta{tokens} stored in
+% \meta{tl~var}, so that
+% \meta{token1}\meta{token2}\meta{token3} \ldots \meta{token$_n$}
+% becomes \meta{token$_n$}\ldots
+% \meta{token3}\meta{token2}\meta{token1}. This process will
+% remove any unprotected spaces within the
+% \meta{token list variable}. Braced token groups are copied without
+% reversing the order of tokens, and the outer set of braces is removed.
+% The reversal is local to the current
+% \TeX{} group. See also \cs{tl_reverse:n}.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_trim_spaces:n}
+% \begin{syntax}
+% \cs{tl_trim_spaces:n} \meta{token list}
+% \end{syntax}
+% Removes any leading and trailing spaces from the \meta{token list}
+% and leaves the result in the input stream. This process requires
+% two expansions.
+% \end{function}
+%
+% \begin{function}{\tl_trim_spaces:N, \tl_trim_spaces:c}
+% \begin{syntax}
+% \cs{tl_trim_spaces:N} \meta{tl~var}
+% \end{syntax}
+% Removes any leading and trailing spaces from the content of the
+% \meta{tl~var} within the current \TeX{} group.
+% \end{function}
+%
+% \begin{function}{\tl_gtrim_spaces:N, \tl_gtrim_spaces:c}
+% \begin{syntax}
+% \cs{tl_gtrim_spaces:N} \meta{tl~var}
+% \end{syntax}
+% Removes any leading and trailing spaces from the content of the
+% \meta{tl~var} globally.
+% \end{function}
+%
+% \section{The first token from a token list}
+%
+% Functions which deal with either onlt the very first token of a
+% token list or everything except the first token.
+%
+% \begin{function}[EXP]{\tl_head:n, \tl_head:V, \tl_head:v, \tl_head:f}
+% \begin{syntax}
+% \cs{tl_head:n} \Arg{tokens}
+% \end{syntax}
+% Leaves only the first \meta{token} in \meta{tokens} in the input
+% stream, discarding the remainder.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_head:w}
+% \begin{syntax}
+% \cs{tl_head:w} \Arg{tokens} \cs{q_stop}
+% \end{syntax}
+% Leaves only the first \meta{token} in \meta{tokens} in the input
+% stream, discarding the remainder. This function requires only a
+% single expansion, and so is suitable for use inside an
+% \texttt{o}-type expansion. In general \cs{tl_head:n} should be
+% preferred.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_tail:n, \tl_tail:V, \tl_tail:v, \tl_tail:f}
+% \begin{syntax}
+% \cs{tl_tail:n} \Arg{tokens}
+% \end{syntax}
+% Discards the first \meta{token} of the \meta{tokens} and leaves the
+% remainder in the input stream.
+% \end{function}
+%
+% \begin{function}[EXP]{\tl_tail:w}
+% \begin{syntax}
+% \cs{tl_tail:w} \Arg{tokens} \cs{q_stop}
+% \end{syntax}
+% Discards the first \meta{token} of the \meta{tokens} and leaves the
+% remainder in the input stream. This function requires only a
+% single expansion, and so is suitable for use inside an
+% \texttt{o}-type expansion. In general \cs{tl_tail:n} should be
+% preferred.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_head_eq_catcode:nN}
+% \begin{syntax}
+% \cs{tl_if_head_eq_catcode_p:n} \Arg{token list} \meta{test token}
+% \cs{tl_if_head_eq_catcode:nTF} \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}. The branching versions then
+% leave either \meta{true code} or \meta{false code} in the input
+% stream, as appropriate to the truth of the test and the variant of
+% the function chosen. The logical truth of the test is left in the
+% input stream by the predicate
+% version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]
+% {\tl_if_head_eq_charcode:nN, \tl_if_head_eq_charcode:fN}
+% \begin{syntax}
+% \cs{tl_if_head_eq_charcode_p:n} \Arg{token list} \meta{test token}
+% \cs{tl_if_head_eq_charcode:nTF} \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}. The branching versions then
+% leave either \meta{true code} or \meta{false code} in the input
+% stream, as appropriate to the truth of the test and the variant of
+% the function chosen. The logical truth of the test is left in the
+% input stream by the predicate
+% version.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_head_eq_meaning:nN}
+% \begin{syntax}
+% \cs{tl_if_head_eq_meaning_p:n} \Arg{token list} \meta{test token}
+% \cs{tl_if_head_eq_meaning:nTF} \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}. The branching versions then
+% leave either \meta{true code} or \meta{false code} in the input
+% stream, as appropriate to the truth of the test and the variant of
+% the function chosen. The logical truth of the test is left in the
+% input stream by the predicate
+% version.
+% \end{function}
+%
+% \section{Viewing token lists}
+%
+% \begin{function}{\tl_show:N, \tl_show:c}
+% \begin{syntax}
+% \cs{tl_show:N} \meta{tl~var}
+% \end{syntax}
+% Displays the content of the \meta{tl~var} on the terminal.
+% \begin{texnote}
+% \cs{tl_show:N} is the \TeX{} primitive \cs{show}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\tl_show:n}
+% \begin{syntax}
+% \cs{tl_show:n} \meta{token list}
+% \end{syntax}
+% Displays the \meta{token list} on the terminal.
+% \begin{texnote}
+% \cs{tl_show:n} is the \eTeX{} primitive \cs{showtokens}.
+% \end{texnote}
+% \end{function}
+%
+% \section{Constant token lists}
+%
+% \begin{variable}{\c_job_name_tl}
+% Constant that gets the \enquote{job name} assigned when \TeX{} starts.
+% \begin{texnote}
+% This is the new name for the primitive \cs{jobname}. It is a constant
+% that is set by \TeX{} and should not be overwritten by the package.
+% \end{texnote}
+% \end{variable}
+%
+% \begin{variable}{\c_empty_tl}
+% Constant that is always empty.
+% \end{variable}
+%
+% \begin{variable}{\c_space_tl}
+% A space token contained in a token list (compare this with
+% \cs{c_space_token}). For use where an explicit space is required.
+% \end{variable}
+%
+% \section{Scratch token lists}
+%
+% \begin{variable}{\l_tmpa_tl, \l_tmpb_tl}
+% Scratch token lists 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}
+%
+% \begin{variable}{\g_tmpa_tl, \g_tmpb_tl}
+% Scratch token lists 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{Experimental token list functions}
+%
+% \begin{function}[EXP,pTF]{\tl_if_single_item:n}
+% \begin{syntax}
+% \cs{tl_if_single_item_p:n} \Arg{token list}
+% \cs{tl_if_single_item:nTF} \Arg{token list}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the token list has exactly one item, 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}. The branching
+% versions then leave either \meta{true code} or \meta{false code}
+% in the input stream, as appropriate to the truth of the test and
+% the variant of the function chosen. The logical truth of the test
+% is left in the input stream by the predicate.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_head_begin_group:n}
+% \begin{syntax}
+% \cs{tl_if_head_begin_group_p:n} \Arg{token list}
+% \cs{tl_if_head_begin_group:nTF} \Arg{token list}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the first \meta{token} in the \meta{token list}
+% has catcode~1, i.e., is a begin-group character. This conditional
+% is mainly intended to be used in combination with
+% \cs{tl_if_head_eq_space:n} to check if grabbing an undelimited
+% argument from the token list is safe. The branching
+% versions leave either \meta{true code} or \meta{false code}
+% in the input stream, as appropriate to the truth of the test and
+% the variant of the function chosen. The logical truth of the test
+% is left in the input stream by the predicate.
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_head_eq_space:n}
+% \begin{syntax}
+% \cs{tl_if_head_eq_space_p:n} \Arg{token list}
+% \cs{tl_if_head_eq_space:nTF} \Arg{token list}
+% ~~\Arg{true code} \Arg{false code}
+% \end{syntax}
+%^^A Needs rewriting. We need to add a discussion of
+%^^A explicit vs implicit tokens somewhere in the doc.
+% Tests if the first token of the token list is an explicit space,
+% i.e., a token which matches \verb*+ + both in character code and
+% in category code. In the case of an implicit space token, such as
+% \cs{c_space_token}, the test will return \meta{false}.
+% This conditional is mainly intended to be used in combination with
+% \cs{tl_if_head_begin_group:n} to test if grabbing an undelimited
+% argument is safe (see \cs{tl_if_single_token:n} for an example.
+% The branching versions leave either \meta{true code} or
+% \meta{false code} in the input stream, as appropriate to the truth
+% of the test and the variant of the function chosen. The logical
+% truth of the test is left in the input stream by the predicate.
+% \begin{texnote}
+% When \TeX{}'s reads a character of category code $10$ for the
+% first time, it is converted to an explicit space token, with
+% character code $32$, regardless of the initial character code.
+% ``Funny'' spaces with a different category code, can be produced
+% using \cs{tex_lowercase:D}. Explicit spaces are also produced
+% as a result of \cs{token_to_str:N}, \cs{tl_to_str:n}, etc.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}[EXP,pTF]{\tl_if_single_token:n}
+% \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}
+% \end{syntax}
+% Tests if the token list consists of exactly one token, i.e.,
+% is either a single space character or a single ``normal'' token.
+% Token groups are not single tokens. The branching
+% versions leaves either \meta{true code} or \meta{false code}
+% in the input stream, as appropriate to the truth of the test and
+% the variant of the function chosen. The logical truth of the test
+% is left in the input stream by the predicate.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{\pkg{l3tl} implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<*package>
+\ProvidesExplPackage
+ {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
+\package_check_loaded_expl:
+%</package>
+% \end{macrocode}
+%
+% A token list variable is a \TeX{} macro that holds tokens. By using the
+% \eTeX{} primitive \cs{unexpanded} inside a \TeX{} \cs{edef} it is
+% possible to store any tokens, including |#|, in this way.
+%
+% \subsection{Functions}
+%
+% \begin{macro}{\tl_new:N, \tl_new:c}
+% Creating new token list variables is a case of checking for an
+% existing definition and if free doing the definition.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_new:N #1
+ {
+ \chk_if_free_cs:N #1
+ \cs_gset_eq:NN #1 \c_empty_tl
+ }
+\cs_generate_variant:Nn \tl_new:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_const:Nn, \tl_const:Nx, \tl_const:cn, \tl_const:cx}
+% Constants are also easy to generate.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_const:Nn #1#2
+ {
+ \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
+ \cs_gset_nopar:Npx #1 {#2}
+ }
+\cs_generate_variant:Nn \tl_const:Nn { c }
+\cs_generate_variant:Nn \tl_const:Nx { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_clear:N, \tl_clear:c}
+% \begin{macro}{\tl_gclear:N, \tl_gclear:c}
+% Clearing a token list variable means setting it to an empty value.
+% Error checking will be sorted out by the parent function.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_clear:N #1
+ { \tl_set_eq:NN #1 \c_empty_tl }
+\cs_new_protected_nopar:Npn \tl_gclear:N #1
+ { \tl_gset_eq:NN #1 \c_empty_tl }
+\cs_generate_variant:Nn \tl_clear:N { c }
+\cs_generate_variant:Nn \tl_gclear:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_clear_new:N, \tl_clear_new:c}
+% \begin{macro}{\tl_gclear_new:N, \tl_gclear_new:c}
+% Clearing a token list variable means setting it to an empty value.
+% Error checking will be sorted out by the parent function.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_clear_new:N #1
+ { \cs_if_exist:NTF #1 { \tl_clear:N #1 } { \tl_new:N #1 } }
+\cs_new_protected_nopar:Npn \tl_gclear_new:N #1
+ { \cs_if_exist:NTF #1 { \tl_gclear:N #1 } { \tl_new:N #1 } }
+\cs_generate_variant:Nn \tl_clear_new:N { c }
+\cs_generate_variant:Nn \tl_gclear_new:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_set_eq:NN, \tl_set_eq:Nc, \tl_set_eq:cN, \tl_set_eq:cc}
+% \begin{macro}{\tl_gset_eq:NN, \tl_gset_eq:Nc, \tl_gset_eq:cN, \tl_gset_eq:cc}
+% For setting token list variables equal to each other.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_set_eq:NN \cs_set_eq:NN
+\cs_new_eq:NN \tl_set_eq:cN \cs_set_eq:cN
+\cs_new_eq:NN \tl_set_eq:Nc \cs_set_eq:Nc
+\cs_new_eq:NN \tl_set_eq:cc \cs_set_eq:cc
+\cs_new_eq:NN \tl_gset_eq:NN \cs_gset_eq:NN
+\cs_new_eq:NN \tl_gset_eq:cN \cs_gset_eq:cN
+\cs_new_eq:NN \tl_gset_eq:Nc \cs_gset_eq:Nc
+\cs_new_eq:NN \tl_gset_eq:cc \cs_gset_eq:cc
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Adding to token list variables}
+%
+% \begin{macro}
+% {
+% \tl_set:Nn, \tl_set:NV, \tl_set:Nv, \tl_set:No, \tl_set:Nf, \tl_set:Nx,
+% \tl_set:cn, \tl_set:NV, \tl_set:Nv, \tl_set:co, \tl_set:cf, \tl_set:cx
+% }
+% \begin{macro}
+% {
+% \tl_gset:Nn, \tl_gset:NV, \tl_gset:Nv,
+% \tl_gset:No, \tl_gset:Nf, \tl_gset:Nx,
+% \tl_gset:cn, \tl_gset:NV, \tl_gset:Nv,
+% \tl_gset:co, \tl_gset:cf, \tl_gset:cx
+% }
+% By using \cs{exp_not:n} token list variables can contain |#| tokens,
+% which makes the token list registers provided by \TeX{}
+% more or less redundant. The \cs{tl_set:No} version is done
+% \enquote{by hand} as it is used quite a lot.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_set:Nn #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:n {#2} } }
+\cs_new_protected:Npn \tl_set:No #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:o {#2} } }
+\cs_new_protected:Npn \tl_set:Nx #1#2
+ { \cs_set_nopar:Npx #1 {#2} }
+\cs_new_protected:Npn \tl_gset:Nn #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:n {#2} } }
+\cs_new_protected:Npn \tl_gset:No #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:o {#2} } }
+\cs_new_protected:Npn \tl_gset:Nx #1#2
+ { \cs_gset_nopar:Npx #1 {#2} }
+\cs_generate_variant:Nn \tl_set:Nn { NV , Nv , Nf }
+\cs_generate_variant:Nn \tl_set:Nx { c }
+\cs_generate_variant:Nn \tl_set:Nn { c, co , cV , cv , cf }
+\cs_generate_variant:Nn \tl_gset:Nn { NV , Nv , Nf }
+\cs_generate_variant:Nn \tl_gset:Nx { c }
+\cs_generate_variant:Nn \tl_gset:Nn { c, co , cV , cv , cf }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \tl_put_left:Nn, \tl_put_left:NV, \tl_put_left:No, \tl_put_left:Nx,
+% \tl_put_left:cn, \tl_put_left:cV, \tl_put_left:co, \tl_put_left:cx
+% }
+% \begin{macro}
+% {
+% \tl_gput_left:Nn, \tl_gput_left:NV, \tl_gput_left:No, \tl_gput_left:Nx,
+% \tl_gput_left:cn, \tl_gput_left:cV, \tl_gput_left:co, \tl_gput_left:cx
+% }
+% Adding to the left is done directly to gain a little performance.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_put_left:Nn #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:n {#2} \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_put_left:NV #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:V #2 \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_put_left:No #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:o {#2} \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_put_left:Nx #1#2
+ { \cs_set_nopar:Npx #1 { #2 \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_gput_left:Nn #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:n {#2} \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_gput_left:NV #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:V #2 \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_gput_left:No #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:o {#2} \exp_not:o #1 } }
+\cs_new_protected:Npn \tl_gput_left:Nx #1#2
+ { \cs_gset_nopar:Npx #1 { #2 \exp_not:o {#1} } }
+\cs_generate_variant:Nn \tl_put_left:Nn { c }
+\cs_generate_variant:Nn \tl_put_left:NV { c }
+\cs_generate_variant:Nn \tl_put_left:No { c }
+\cs_generate_variant:Nn \tl_put_left:Nx { c }
+\cs_generate_variant:Nn \tl_gput_left:Nn { c }
+\cs_generate_variant:Nn \tl_gput_left:NV { c }
+\cs_generate_variant:Nn \tl_gput_left:No { c }
+\cs_generate_variant:Nn \tl_gput_left:Nx { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}
+% {
+% \tl_put_right:Nn, \tl_put_right:NV, \tl_put_right:No, \tl_put_right:Nx,
+% \tl_put_right:cn, \tl_put_right:cV, \tl_put_right:co, \tl_put_right:cx
+% }
+% \begin{macro}
+% {
+% \tl_gput_right:Nn, \tl_gput_right:NV, \tl_gput_right:No,
+% \tl_gput_right:Nx,
+% \tl_gput_right:cn, \tl_gput_right:cV, \tl_gput_right:co,
+% \tl_gput_right:cx
+% }
+% The same on the right.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_put_right:Nn #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:n {#2} } }
+\cs_new_protected:Npn \tl_put_right:NV #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:V #2 } }
+\cs_new_protected:Npn \tl_put_right:No #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:o {#2} } }
+\cs_new_protected:Npn \tl_put_right:Nx #1#2
+ { \cs_set_nopar:Npx #1 { \exp_not:o #1 #2 } }
+\cs_new_protected:Npn \tl_gput_right:Nn #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:n {#2} } }
+\cs_new_protected:Npn \tl_gput_right:NV #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:V #2 } }
+\cs_new_protected:Npn \tl_gput_right:No #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:o {#2} } }
+\cs_new_protected:Npn \tl_gput_right:Nx #1#2
+ { \cs_gset_nopar:Npx #1 { \exp_not:o {#1} #2 } }
+\cs_generate_variant:Nn \tl_put_right:Nn { c }
+\cs_generate_variant:Nn \tl_put_right:NV { c }
+\cs_generate_variant:Nn \tl_put_right:No { c }
+\cs_generate_variant:Nn \tl_put_right:Nx { c }
+\cs_generate_variant:Nn \tl_gput_right:Nn { c }
+\cs_generate_variant:Nn \tl_gput_right:NV { c }
+\cs_generate_variant:Nn \tl_gput_right:No { c }
+\cs_generate_variant:Nn \tl_gput_right:Nx { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Reassigning token list category codes}
+%
+% \begin{variable}{\c_tl_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.
+% \begin{macrocode}
+\group_begin:
+ \tex_lccode:D `\A = `\@ \scan_stop:
+ \tex_lccode:D `\B = `\@ \scan_stop:
+ \tex_catcode:D `\A = 8 \scan_stop:
+ \tex_catcode:D `\B = 3 \scan_stop:
+\tex_lowercase:D
+ {
+ \group_end:
+ \tl_const:Nn \c_tl_rescan_marker_tl { A B }
+ }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_tl_rescan_tl}
+% A token list variable to actually store the material being processed.
+% \begin{macrocode}
+\tl_new:N \l_tl_rescan_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}
+% {
+% \tl_set_rescan:Nnn, \tl_set_rescan:Nno,
+% \tl_set_rescan:cnn, \tl_set_rescan:cno
+% }
+% \begin{macro}
+% {
+% \tl_gset_rescan:Nnn, \tl_gset_rescan:Nno,
+% \tl_gset_rescan:cnn, \tl_gset_rescan:cno
+% }
+% \begin{macro}[aux]{\tl_set_rescan_aux:NNnn}
+% \begin{macro}[aux]{\tl_rescan_aux:w}
+% The idea here is to deal cleanly with the problem that
+% \cs{tex_scantokens:D} treats the argument as a file, and without
+% the correct settings a \TeX{} error occurs:
+% \begin{verbatim}
+% ! File ended while scanning definition of ...
+% \end{verbatim}
+% When expanding a token list this can be handled using \cs{exp_not:N}
+% but this fails if the token list is not being expanded. So instead
+% a delimited argument is used with an end marker which cannot appear
+% within the token list which is scanned: two |@| symbols with different
+% category codes. The rescanned token list cannot contain the end marker,
+% because all |@| present in the token list are read with the same category
+% code. The setting of \cs{tex_endlinechar:D}
+% is needed to avoid introducing an extraneous space in the result.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_set_rescan:Nnn
+ { \tl_set_rescan_aux:NNnn \tl_set:Nn }
+\cs_new_protected_nopar:Npn \tl_gset_rescan:Nnn
+ { \tl_set_rescan_aux:NNnn \tl_gset:Nn }
+\cs_new_protected:Npn \tl_set_rescan_aux:NNnn #1#2#3#4
+ {
+ \group_begin:
+ \exp_args:No \etex_everyeof:D { \c_tl_rescan_marker_tl }
+ \tex_endlinechar:D \c_minus_one
+ #3
+ \tl_clear:N \l_tl_rescan_tl
+ \exp_after:wN \tl_rescan_aux:w \etex_scantokens:D {#4}
+ \exp_args:NNNo \group_end:
+ #1 #2 \l_tl_rescan_tl
+ }
+\cs_new_nopar:Npx \tl_rescan_aux:w
+ {
+ \cs_set_protected:Npn \exp_not:N \tl_rescan_aux:w ##1
+ \c_tl_rescan_marker_tl
+ { \tl_set:Nn \exp_not:N \l_tl_rescan_tl {##1} }
+ }
+\tl_rescan_aux:w
+\cs_generate_variant:Nn \tl_set_rescan:Nnn { Nno }
+\cs_generate_variant:Nn \tl_set_rescan:Nnn { c , cno }
+\cs_generate_variant:Nn \tl_gset_rescan:Nnn { Nno }
+\cs_generate_variant:Nn \tl_gset_rescan:Nnn { c , cno }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_set_rescan:Nnx, \tl_set_rescan:cnx}
+% \begin{macro}{\tl_gset_rescan:Nnx, \tl_gset_rescan:cnx}
+% \begin{macro}[aux]{\tl_set_rescan_aux:NNnx}
+% With \texttt{x}-type expansion the \cs{tex_everyoef:D} method
+% does apply and the code is simple.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_set_rescan:Nnx
+ { \tl_set_rescan_aux:NNnx \tl_set:Nn }
+\cs_new_protected_nopar:Npn \tl_gset_rescan:Nnx
+ { \tl_set_rescan_aux:NNnx \tl_gset:Nn }
+\cs_new_protected_nopar:Npn \tl_set_rescan_aux:NNnx #1#2#3#4
+ {
+ \group_begin:
+ \etex_everyeof:D { \exp_not:N }
+ \tex_endlinechar:D \c_minus_one
+ #3
+ \tl_set:Nx \l_tl_rescan_tl { \etex_scantokens:D {#4} }
+ \exp_args:NNNo \group_end:
+ #1 #2 \l_tl_rescan_tl
+ }
+\cs_generate_variant:Nn \tl_set_rescan:Nnx { c }
+\cs_generate_variant:Nn \tl_gset_rescan:Nnx { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_rescan:nn}
+% The same idea is also applied to in line token lists.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_rescan:nn #1#2
+ {
+ \group_begin:
+ \exp_args:No \etex_everyeof:D { \c_tl_rescan_marker_tl }
+ \tex_endlinechar:D \c_minus_one
+ #1
+ \exp_after:wN \tl_rescan_aux:w \etex_scantokens:D {#2}
+ \exp_args:No \group_end:
+ \l_tl_rescan_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Reassigning token list character codes}
+%
+% \begin{macro}{\tl_to_lowercase:n}
+% \begin{macro}{\tl_to_uppercase:n}
+% Just some names for a few primitives.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_to_lowercase:n \tex_lowercase:D
+\cs_new_eq:NN \tl_to_uppercase:n \tex_uppercase:D
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Modifying token list variables}
+%
+% \begin{variable}{\l_tl_replace_tl}
+% A scratch variable for doing token replacement.
+% \begin{macrocode}
+\tl_new:N \l_tl_replace_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \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_once_aux:NNnn}
+% The concept here is that only the first occurrence should be
+% replaced. The first step is to define an auxiliary which will
+% match the appropriate item, with a trailing marker. If the last token
+% is the marker there is nothing to do, otherwise replace the token
+% and clean up (hence the second use of \cs{tl_tmp:w}). To prevent
+% loosing braces or spaces there are a couple of empty groups and
+% the strange-looking \cs{use:n}. There is a \cs{q_nil} between the
+% original and the search input, to prevent cases where
+% the end of the original and the start of the search run together
+% to give an erroneous test result.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_replace_once:Nnn
+ { \tl_replace_once_aux:NNnn \tl_set_eq:NN }
+\cs_new_protected_nopar:Npn \tl_greplace_once:Nnn
+ { \tl_replace_once_aux:NNnn \tl_gset_eq:NN }
+\cs_new_protected:Npn \tl_replace_once_aux:NNnn #1#2#3#4
+ {
+ \cs_set_protected:Npx \tl_tmp:w ##1 #3 ##2 \q_stop
+ {
+ \exp_not:N \quark_if_no_value:nF {##2}
+ {
+ \tl_set:No \exp_not:N \l_tl_replace_tl { ##1 \exp_not:n{#4} }
+ \exp_not:n
+ {
+ \cs_set_protected:Npn \tl_tmp:w ##1 \q_nil #3 \q_no_value
+ { \tl_put_right:No \l_tl_replace_tl {##1} }
+ }
+ \exp_not:n { \tl_tmp:w \prg_do_nothing: } ##2
+ \exp_not:n { #1 #2 \l_tl_replace_tl }
+ }
+ }
+ \exp_after:wN \tl_tmp:w \exp_after:wN \prg_do_nothing:
+ #2 \q_nil #3 \q_no_value \q_stop
+ }
+\cs_generate_variant:Nn \tl_replace_once:Nnn { c }
+\cs_generate_variant:Nn \tl_greplace_once:Nnn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_replace_all:Nnn, \tl_replace_all:cnn}
+% \begin{macro}{\tl_greplace_all:Nnn, \tl_greplace_all:cnn}
+% \begin{macro}[aux]{\tl_replace_all_aux:NNnn}
+% A similar approach here but with a loop built in.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_replace_all:Nnn
+ { \tl_replace_all_aux:NNnn \tl_set_eq:NN }
+\cs_new_protected_nopar:Npn \tl_greplace_all:Nnn
+ { \tl_replace_all_aux:NNnn \tl_gset_eq:NN }
+\cs_new_protected:Npn \tl_replace_all_aux:NNnn #1#2#3#4
+ {
+ \tl_clear:N \l_tl_replace_tl
+ \cs_set_protected:Npx \tl_tmp:w ##1 #3 ##2 \q_stop
+ {
+ \exp_not:N \quark_if_no_value:nTF {##2}
+ {
+ \exp_not:n
+ {
+ \cs_set_protected:Npn \tl_tmp:w ##1 \q_nil ##2 \q_stop
+ { \tl_put_right:No \l_tl_replace_tl {##1} }
+ }
+ \exp_not:N \tl_tmp:w ##1 \exp_not:N \q_stop
+ }
+ {
+ \exp_not:n { \tl_put_right:No \l_tl_replace_tl }
+ { ##1 \exp_not:n{#4} }
+ \exp_not:n { \tl_tmp:w \prg_do_nothing: } ##2 \exp_not:N \q_stop
+ }
+ }
+ \exp_after:wN \tl_tmp:w \exp_after:wN \prg_do_nothing:
+ #2 \q_nil #3 \q_no_value \q_stop
+ #1 #2 \l_tl_replace_tl
+ }
+\cs_generate_variant:Nn \tl_replace_all:Nnn { c }
+\cs_generate_variant:Nn \tl_greplace_all:Nnn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_remove_once:Nn, \tl_remove_once:cn}
+% \begin{macro}{\tl_gremove_once:Nn, \tl_gremove_once:cn}
+% Removal is just a special case of replacement.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_remove_once:Nn #1#2
+ { \tl_replace_once:Nnn #1 {#2} { } }
+\cs_new_protected_nopar:Npn \tl_gremove_once:Nn #1#2
+ { \tl_greplace_once:Nnn #1 {#2} { } }
+\cs_generate_variant:Nn \tl_remove_once:Nn { c }
+\cs_generate_variant:Nn \tl_gremove_once:Nn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_remove_all:Nn, \tl_remove_all:cn}
+% \begin{macro}{\tl_gremove_all:Nn, \tl_gremove_all:cn}
+% Removal is just a special case of replacement.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_remove_all:Nn #1#2
+ { \tl_replace_all:Nnn #1 {#2} { } }
+\cs_new_protected_nopar:Npn \tl_gremove_all:Nn #1#2
+ { \tl_greplace_all:Nnn #1 {#2} { } }
+\cs_generate_variant:Nn \tl_remove_all:Nn { c }
+\cs_generate_variant:Nn \tl_gremove_all:Nn { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \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}
+% \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
+% the emptyness test done in \cs{tl_if_empty:n(TF)}: convert to harmless
+% characters with \cs{tl_to_str:n}, and then use
+% \cs{if_meaning:w} \cs{q_nil} |...| \cs{q_nil}.
+% Note that converting to a string is done after reading the delimited
+% argument for \cs{use_none:n}. The similar construction
+% \cs{exp_after:wN} \cs{use_none:n} \cs{tl_to_str:n} \Arg{token list} |?|
+% would fail if the token list contains the control sequence \cs{ },
+% while \cs{tex_escapechar:D} 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 ? } }
+\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 }
+\cs_generate_variant:Nn \tl_if_blank:nTF { V }
+\cs_generate_variant:Nn \tl_if_blank_p:n { o }
+\cs_generate_variant:Nn \tl_if_blank:nT { o }
+\cs_generate_variant:Nn \tl_if_blank:nF { o }
+\cs_generate_variant:Nn \tl_if_blank:nTF { o }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\tl_if_empty:N,\tl_if_empty:c}
+% These functions check whether the token list in the argument is
+% empty and execute the proper code from their argument(s).
+% \begin{macrocode}
+\prg_set_conditional:Npnn \tl_if_empty:N #1 { p , T , F , TF }
+ {
+ \if_meaning:w #1 \c_empty_tl
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_generate_variant:Nn \tl_if_empty_p:N { c }
+\cs_generate_variant:Nn \tl_if_empty:NT { c }
+\cs_generate_variant:Nn \tl_if_empty:NF { c }
+\cs_generate_variant:Nn \tl_if_empty:NTF { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \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
+% 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
+% token.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_empty:n #1 { p,TF,T,F} {
+ \exp_after:wN \if_meaning:w \exp_after:wN \q_nil \tl_to_str:n {#1} \q_nil
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+}
+\cs_generate_variant:Nn \tl_if_empty_p:n { V }
+\cs_generate_variant:Nn \tl_if_empty:nTF { V }
+\cs_generate_variant:Nn \tl_if_empty:nT { V }
+\cs_generate_variant:Nn \tl_if_empty:nF { V }
+% \end{macrocode}
+% \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
+% in conditionals on token lists, which mostly reduce to testing
+% if a given token list is empty after applying a simple function
+% to it.
+% The test for emptyness is based on \cs{tl_if_empty:n(TF)}, but
+% the expansion is hard-coded for efficiency, as this auxiliary
+% function is used in many places.
+% 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 {
+ \exp_after:wN \if_meaning:w \exp_after:wN \q_nil
+ \tl_to_str:n \exp_after:wN {#1} \q_nil
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+}
+\prg_new_conditional:Npnn \tl_if_empty:o #1 { p,TF,T,F}
+ { \tl_if_empty_return:o {#1} }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\tl_if_eq:NN,\tl_if_eq:Nc,\tl_if_eq:cN,\tl_if_eq:cc}
+% Returns \cs{c_true_bool} if and only if the two token list variables are
+% equal.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_eq:NN #1#2 { p , T , F , TF }
+ {
+ \if_meaning:w #1 #2
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_generate_variant:Nn \tl_if_eq_p:NN { Nc , c , cc }
+\cs_generate_variant:Nn \tl_if_eq:NNTF { Nc , c , cc }
+\cs_generate_variant:Nn \tl_if_eq:NNT { Nc , c , cc }
+\cs_generate_variant:Nn \tl_if_eq:NNF { Nc , c , cc }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[TF]{\tl_if_eq:nn}
+% \begin{variable}{\l_tl_tmpa_tl, \l_tl_tmpb_tl}
+% A simple store and compare routine.
+% \begin{macrocode}
+\prg_new_protected_conditional:Npnn \tl_if_eq:nn #1#2 { T , F , TF }
+ {
+ \group_begin:
+ \tl_set:Nn \l_tl_tmpa_tl {#1}
+ \tl_set:Nn \l_tl_tmpb_tl {#2}
+ \if_meaning:w \l_tl_tmpa_tl \l_tl_tmpb_tl
+ \group_end:
+ \prg_return_true:
+ \else:
+ \group_end:
+ \prg_return_false:
+ \fi:
+ }
+\tl_new:N \l_tl_tmpa_tl
+\tl_new:N \l_tl_tmpb_tl
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+%
+% \begin{macro}[TF]{\tl_if_in:Nn, \tl_if_in:cn}
+% See \cs{tl_if_in:nn(TF)} for further comments. Here we simply
+% expand the token list variable and pass it to \cs{tl_if_in:nn(TF)}.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_if_in:NnT { \exp_args:No \tl_if_in:nnT }
+\cs_new_protected_nopar:Npn \tl_if_in:NnF { \exp_args:No \tl_if_in:nnF }
+\cs_new_protected_nopar:Npn \tl_if_in:NnTF { \exp_args:No \tl_if_in:nnTF }
+\cs_generate_variant:Nn \tl_if_in:NnT { c }
+\cs_generate_variant:Nn \tl_if_in:NnF { c }
+\cs_generate_variant:Nn \tl_if_in:NnTF { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \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
+% 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
+% the emptyness test.
+%
+% Special care is needed to treat correctly cases like
+% |\tl_if_in:nnTF {a state}{states}|, where |#1#2| contains |#2| before
+% the end. To cater for this case, we insert |{}{}| between the two token
+% lists. This marker may not appear in |#2| because of \TeX{} limitations
+% on what can delimit a parameter, hence we are safe. Using two brace
+% groups makes the test work also for empty arguments.
+% \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 }
+ { \prg_return_false: } { \prg_return_true: }
+ }
+\cs_generate_variant:Nn \tl_if_in:nnT { V }
+\cs_generate_variant:Nn \tl_if_in:nnF { V }
+\cs_generate_variant:Nn \tl_if_in:nnTF { V }
+\cs_generate_variant:Nn \tl_if_in:nnT { o }
+\cs_generate_variant:Nn \tl_if_in:nnF { o }
+\cs_generate_variant:Nn \tl_if_in:nnTF { o }
+\cs_generate_variant:Nn \tl_if_in:nnT { no }
+\cs_generate_variant:Nn \tl_if_in:nnF { no }
+\cs_generate_variant:Nn \tl_if_in:nnTF { no }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\tl_if_single:n}
+% \begin{macro}[aux]{\tl_if_single_aux:n}
+% If the argument is a single token, or a single brace group
+% preceeded by optional (explicit) spaces, or a non-zero number
+% of spaces.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_single:n #1 { p , T , F , TF }
+ {
+ \tl_if_blank:nTF {#1}
+ { \tl_if_empty:nTF {#1} { \prg_return_false: } { \prg_return_true: } }
+ { \tl_if_single_aux:n {#1} }
+ }
+\prg_new_conditional:Npnn \tl_if_single:N #1 { p , T , F , TF }
+ {
+ \tl_if_blank:oTF #1
+ { \tl_if_empty:NTF #1 { \prg_return_false: } { \prg_return_true: } }
+ { \exp_args:No \tl_if_single_aux:n {#1} }
+ }
+\cs_new:Npn \tl_if_single_aux:n #1
+ { \tl_if_empty_return:o { \use_none:n #1 } }
+% \end{macrocode}
+% \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}
+% 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 \q_recursion_tail \q_recursion_stop }
+\cs_new_nopar:Npn \tl_map_function:NN #1#2
+ {
+ \exp_after:wN \tl_map_function_aux:Nn
+ \exp_after:wN #2 #1 \q_recursion_tail \q_recursion_stop
+ }
+\cs_new:Npn \tl_map_function_aux:Nn #1#2
+ {
+ \quark_if_recursion_tail_stop:n {#2}
+ #1 {#2} \tl_map_function_aux:Nn #1
+ }
+\cs_generate_variant:Nn \tl_map_function:NN { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_map_inline:nn}
+% \begin{macro}{\tl_map_inline:Nn, \tl_map_inline:cn}
+% \begin{macro}[aux]{\tl_map_inline_aux:n}
+% \begin{variable}{\g_tl_inline_level_int}
+% The inline functions are straight forward by now. We use a little
+% trick with the counter \cs{g_tl_inline_level_int} to make
+% them nestable. We can also make use of \cs{tl_map_function:Nn}
+% from before. (\cs{g_tl_inline_level_int} is defined in \pkg{l3int}
+% for order-of-loading reasons.)
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_map_inline:nn #1#2
+ {
+ \int_gincr:N \g_tl_inline_level_int
+ \cs_gset:cpn { tl_map_inline_ \int_use:N \g_tl_inline_level_int :n }
+ ##1 {#2}
+ \exp_args:Nc \tl_map_function_aux:Nn
+ { tl_map_inline_ \int_use:N \g_tl_inline_level_int :n }
+ #1 \q_recursion_tail \q_recursion_stop
+ \int_gdecr:N \g_tl_inline_level_int
+ }
+\cs_new_protected:Npn \tl_map_inline:Nn #1#2
+ {
+ \int_gincr:N \g_tl_inline_level_int
+ \cs_gset:cpn { tl_map_inline_ \int_use:N \g_tl_inline_level_int :n }
+ ##1 {#2}
+ \exp_last_unbraced:NcV \tl_map_function_aux:Nn
+ { tl_map_inline_ \int_use:N \g_tl_inline_level_int :n }
+ #1 \q_recursion_tail\q_recursion_stop
+ \int_gdecr:N \g_tl_inline_level_int
+ }
+\cs_generate_variant:Nn \tl_map_inline:Nn { c }
+% \end{macrocode}
+% \end{variable}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_map_variable:nNn}
+% \begin{macro}{\tl_map_variable:NNn, \tl_map_variable:cNn}
+% \begin{macro}[aux]{\tl_map_variable_aux: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 \q_recursion_tail \q_recursion_stop }
+\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
+ {
+ \tl_set:Nn #1 {#3}
+ \quark_if_recursion_tail_stop:N #1
+ #2 \tl_map_variable_aux:Nnn #1 {#2}
+ }
+\cs_generate_variant:Nn \tl_map_variable:NNn { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_map_break:}
+% The break statement.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_map_break: \use_none_delimit_by_q_recursion_stop:w
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Using token lists}
+%
+% \begin{macro}{\tl_to_str:n}
+% Another name for a primitive.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_to_str:n \etex_detokenize:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_to_str:N, \tl_to_str:c}
+% These functions return the replacement text of a token list as a
+% string.
+% \begin{macrocode}
+\cs_new_nopar:Npn \tl_to_str:N #1 { \etex_detokenize:D \exp_after:wN {#1} }
+\cs_generate_variant:Nn \tl_to_str:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_use:N, \tl_use:c}
+% \begin{macro}[aux]{\tl_error_message:}
+% Token lists which are simply not defined will give a clear \TeX{}
+% error here. No such luck for ones equal to \cs{scan_stop:} so
+% instead a test is made and if there is an issue an error is forced.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_use:N \prg_do_nothing:
+\cs_new_nopar:Npn \tl_use:c #1
+ {
+ \if_cs_exist:w #1 \cs_end:
+ \cs:w #1 \exp_after:wN \cs_end:
+ \else:
+ \exp_after:wN \tl_error_message:
+ \fi:
+ }
+\group_begin:
+\tex_catcode:D `\! = 11 \scan_stop:
+\tex_catcode:D `\ = 11\scan_stop:%
+\cs_gset_nopar:Npn\tl_error_message:{\undefined variable name!}%
+\group_end:%
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \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}
+% 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|.
+% The |0| to ensure it works on an empty list.
+% \begin{macrocode}
+\cs_new:Npn \tl_length:n #1
+ {
+ \int_eval:n
+ { 0 \tl_map_function:nN {#1} \tl_length_aux:n }
+ }
+\cs_new_nopar:Npn \tl_length:N #1
+ {
+ \int_eval:n
+ { 0 \tl_map_function:NN #1 \tl_length_aux:n }
+ }
+\cs_new:Npn \tl_length_aux:n #1 { + 1 }
+\cs_generate_variant:Nn \tl_length:n { V , o }
+\cs_generate_variant:Nn \tl_length:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_reverse:n, \tl_reverse:V, \tl_reverse:o}
+% \begin{macro}[aux]{\tl_reverse_aux:nN}
+% Reversal of a token list is done by taking one token at a time
+% and putting it in front of the ones before it.
+% \begin{macrocode}
+\cs_new:Npn \tl_reverse:n #1
+ { \tl_reverse_aux:nN { } #1 \q_recursion_tail \q_recursion_stop }
+\cs_new:Npn \tl_reverse_aux:nN #1#2
+ {
+ \quark_if_recursion_tail_stop_do:nn {#2} {#1}
+ \tl_reverse_aux:nN { #2 #1 }
+ }
+\cs_generate_variant:Nn \tl_reverse:n {V,o}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_reverse:N, \tl_reverse:c}
+% This reverses the list, leaving |\exp_stop_f:| in front, which in turn
+% is removed by the |f| expansion which comes to a halt.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_reverse:N #1
+ { \tl_set:Nf #1 { \tl_reverse:o { #1 \exp_stop_f: } } }
+\cs_generate_variant:Nn \tl_reverse:N { c }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_trim_spaces:n}
+% \begin{macro}
+% {
+% \tl_trim_spaces:N, \tl_trim_spaces:c,
+% \tl_gtrim_spaces:N, \tl_gtrim_spaces:c
+% }
+% \begin{macro}[aux]{\tl_trim_spaces_exp:n}
+% \begin{macro}[aux]{\tl_trim_spaces_aux_i:w}
+% \begin{macro}[aux]{\tl_trim_spaces_aux_ii:w}
+% Trimming spaces from around the input uses the idea of a sufficiently
+% odd token to allow for a delimited argument to do this. Here, the
+% standard approach [a |Q| with category code 3 (math toggle)] is used.
+% The \cs{etex_unexpanded:D} here is used so that space trimming will
+% behave correctly within an \texttt{x}-type expansion.
+% \begin{macrocode}
+\cs_new:Npn \tl_trim_spaces:n #1
+ {
+ \etex_unexpanded:D \exp_after:wN \exp_after:wN \exp_after:wN
+ { \tl_trim_spaces_exp:n {#1} }
+ }
+\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} } }
+\group_begin:
+ \tex_catcode:D `\Q = 3 \scan_stop:
+ \cs_new:Npn \tl_trim_spaces_exp:n #1
+ { \tex_romannumeral:D - `0 \tl_trim_spaces_aux_i:w \exp_not:N #1 Q ~ Q }
+ \cs_new:Npn \tl_trim_spaces_aux_i:w #1 ~ Q { \tl_trim_spaces_aux_ii:w #1 Q }
+ \cs_new:Npn \tl_trim_spaces_aux_ii:w #1 Q #2 {#1}
+\group_end:
+\cs_generate_variant:Nn \tl_trim_spaces:N { c }
+\cs_generate_variant:Nn \tl_gtrim_spaces:N { c }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{The first token from a token list}
+%
+% \begin{macro}{\tl_head:n, \tl_head:V, \tl_head:v, \tl_head:f}
+% \begin{macro}{\tl_head:w}
+% \begin{macro}{\tl_tail:n, \tl_tail:V, \tl_tail:v, \tl_tail:f}
+% \begin{macro}{\tl_tail:w}
+% These functions pick up either the head or the tail of a list.
+% \begin{macrocode}
+\cs_new:Npn \tl_head:n #1 { \tl_head:w #1 \q_stop }
+\cs_new:Npn \tl_tail:n #1 { \tl_tail:w #1 \q_stop }
+\cs_new:Npn \tl_head:w #1#2 \q_stop {#1}
+\cs_new:Npn \tl_tail:w #1#2 \q_stop {#2}
+\cs_generate_variant:Nn \tl_head:n { V , v , f }
+\cs_generate_variant:Nn \tl_tail:n { V , v , f }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\tl_if_head_eq_meaning:nN}
+% \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}
+% When we want to check if the first token of a list equals something
+% specific it is usually either to see if it is a control sequence or
+% a character. Hence we make two different functions as the internal
+% test is different.
+% \cs{tl_if_head_meaning_eq:nNTF} uses \cs{if_meaning:w} and will
+% consider the tokens |b|$\sb{11}$ and |b|$\sb{12}$ different.
+% \cs{tl_if_head_char_eq:nNTF} on the other hand only compares
+% character codes so would regard |b|$\sb{11}$ and |b|$\sb{12}$ as
+% equal but would also regard two primitives as equal.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_head_eq_meaning:nN #1#2 { p , T , F , TF }
+ {
+ \exp_after:wN \if_meaning:w \tl_head:w #1 \q_stop #2
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% For the charcode and catcode versions we insert |\exp_not:N| in
+% front of both tokens. If you need them to expand fully as \TeX{}
+% does itself with these you can use an |f| type expansion.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_head_eq_charcode:nN #1#2 { p , T , F , TF }
+ {
+ \exp_after:wN \if:w
+ \exp_after:wN \exp_not:N \tl_head:w #1 \q_stop \exp_not:N #2
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+\cs_generate_variant:Nn \tl_if_head_eq_charcode_p:nN { f }
+\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNTF { f }
+\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNT { f }
+\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNF { f }
+% \end{macrocode}
+% And now catcodes:
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_head_eq_catcode:nN #1#2 { p , T , F , TF }
+ {
+ \exp_after:wN \if_catcode:w \exp_after:wN \exp_not:N
+ \tl_head:w #1 \q_stop \exp_not:N #2
+ \prg_return_true: \else: \prg_return_false: \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Viewing token lists}
+%
+% \begin{macro}{\tl_show:N, \tl_show:c}
+% Showing token list variables is done directly: at the moment do not
+% worry if they are defined.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_show:N #1 { \cs_show:N #1 }
+\cs_generate_variant:Nn \tl_show:N { c }
+% \end{macrocode}
+%\end{macro}
+%
+% \begin{macro}{\tl_show:n}
+% For literal token lists, life is easy.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_show:n \etex_showtokens:D
+% \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.
+% \begin{macrocode}
+%<*package>
+\tl_const:Nx \c_job_name_tl { \tex_jobname:D }
+%</package>
+%<*initex>
+\tex_everyjob:D \exp_after:wN
+ {
+ \tex_the:D \tex_everyjob:D
+ \luatex_if_engine:TF
+ {
+ \tl_if_in:onTF { \tex_jobname:D } { ~ }
+ { \tl_const:Nx \c_job_name_tl { " \tex_jobname:D " } }
+ { \tl_const:Nx \c_job_name_tl { \tex_jobname:D } }
+ }
+ { \tl_const:Nx \c_job_name_tl { \tex_jobname:D } }
+ }
+%</initex>
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\c_empty_tl}
+% Never full.
+% \begin{macrocode}
+\tl_const:Nn \c_empty_tl { }
+% \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}
+% Global temporary token list variables.
+% They are supposed to be set and used immediately,
+% with no delay between the definition and the use because you
+% can't count on other macros not to redefine them from under you.
+% \begin{macrocode}
+\tl_new:N \g_tmpa_tl
+\tl_new:N \g_tmpb_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{\l_tmpa_tl, \l_tmpb_tl}
+% These are local temporary token list variables. Be sure not to assume
+% that the value you put into them will survive for
+% long---see discussion above.
+% \begin{macrocode}
+\tl_new:N \l_tmpa_tl
+\tl_new:N \l_tmpb_tl
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Experimental functions}
+%
+% \begin{macro}[EXP,pTF]{\tl_if_single_item: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}
+\cs_new:Npn \tl_if_single_item:nTF #1
+ { \str_if_eq:onTF { \use_ii:nn #1 {?} ? } {??} }
+\cs_new:Npn \tl_if_single_item:nT #1
+ { \str_if_eq:onT { \use_ii:nn #1 {?} ? } {??} }
+\cs_new:Npn \tl_if_single_item:nF #1
+ { \str_if_eq:onF { \use_ii:nn #1 {?} ? } {??} }
+\cs_new:Npn \tl_if_single_item_p:n #1
+ { \str_if_eq_p:on { \use_ii:nn #1 {?} ? } {??} }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP,pTF]{\tl_if_head_begin_group:n}
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_head_begin_group:n #1 { p , T , F , TF }
+ {
+ \exp_after:wN \use_none:n
+ \exp_after:wN {
+ \exp_after:wN {
+ \token_to_str:N #1 .
+ }
+ \prg_return_true: \exp_after:wN \use_none:nn \token_to_str:N
+ }
+ \prg_return_false:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP,pTF]{\tl_if_head_eq_space:n}
+% \begin{macro}[EXP,aux]{\tl_if_head_eq_space_aux: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
+% 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.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_head_eq_space:n #1 { p , T , F , TF }
+ {
+ \if_false: { \fi:
+ \tl_if_head_eq_space_aux:w \prg_do_nothing: #1 ? ~ }
+ }
+\cs_new:Npn \tl_if_head_eq_space_aux:w #1 ~ %
+ {
+ \tl_if_empty_return:o { #1 }
+ \exp_after:wN \use_none:n \exp_after:wN { \if_false: } \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[EXP,pTF]{\tl_if_single_token:n}
+% If the token list starts with a space, then it is
+% a single token if and only if its string representation
+% is exactly one space character. Otherwise, we check if removing
+% the first token group makes the token list empty. If it doesn't,
+% the token list is not a single token. If it does, then the token
+% list is either a single token or a single brace group. This is
+% tested for using \cs{tl_if_head_begin_group:n}.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \tl_if_single_token:n #1 { p , T , F , TF }
+ {
+ \tl_if_head_eq_space:nTF {#1}
+ {
+ \str_if_eq:nnTF {#1} {~}
+ \prg_return_true: \prg_return_false:
+ }
+ {
+ \str_if_eq:onTF { \use_none:n #1 ? } {?}
+ {
+ \tl_if_head_begin_group:nTF {#1}
+ \prg_return_false: \prg_return_true:
+ }
+ \prg_return_false:
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Deprecated functions}
+%
+% \begin{macro}{\tl_new:Nn, \tl_new:cn, \tl_new:Nx}
+% Use either \cs{tl_const:Nn} or \cs{tl_new:N}.
+% \begin{macrocode}
+\cs_new_protected:Npn \tl_new:Nn #1#2
+ {
+ \tl_new:N #1
+ \tl_gset:Nn #1 {#2}
+ }
+\cs_generate_variant:Nn \tl_new:Nn { c }
+\cs_generate_variant:Nn \tl_new:Nn { Nx }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tl_gset:Nc}
+% \begin{macro}{\tl_set:Nc}
+% This was useful once, but nowadays does not make much sense.
+% \begin{macrocode}
+\cs_new_protected_nopar:Npn \tl_gset:Nc
+ { \pref_global:D \tl_set:Nc }
+\cs_new_protected_nopar:Npn \tl_set:Nc #1#2
+ { \tl_set:No #1 { \cs:w #2 \cs_end: } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_replace_in:Nnn, \tl_replace_in:cnn}
+% \begin{macro}{\tl_greplace_in:Nnn, \tl_greplace_in:cnn}
+% \begin{macro}{\tl_replace_all_in:Nnn, \tl_replace_all_in:cnn}
+% \begin{macro}{\tl_greplace_all_in:Nnn, \tl_greplace_all_in:cnn}
+% These are renamed.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_replace_in:Nnn \tl_replace_once:Nnn
+\cs_new_eq:NN \tl_replace_in:cnn \tl_replace_once:cnn
+\cs_new_eq:NN \tl_greplace_in:Nnn \tl_greplace_once:Nnn
+\cs_new_eq:NN \tl_greplace_in:cnn \tl_greplace_once:cnn
+\cs_new_eq:NN \tl_replace_all_in:Nnn \tl_replace_all:Nnn
+\cs_new_eq:NN \tl_replace_all_in:cnn \tl_replace_all:cnn
+\cs_new_eq:NN \tl_greplace_all_in:Nnn \tl_greplace_all:Nnn
+\cs_new_eq:NN \tl_greplace_all_in:cnn \tl_greplace_all:cnn
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_remove_in:Nn, \tl_remove_in:cn}
+% \begin{macro}{\tl_gremove_in:Nn, \tl_gremove_in:cn}
+% \begin{macro}{\tl_remove_all_in:Nn, \tl_remove_all_in:cn}
+% \begin{macro}{\tl_gremove_all_in:Nn, \tl_gremove_all_in:cn}
+% Also renamed.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_remove_in:Nn \tl_remove_once:Nn
+\cs_new_eq:NN \tl_remove_in:cn \tl_remove_once:cn
+\cs_new_eq:NN \tl_gremove_in:Nn \tl_gremove_once:Nn
+\cs_new_eq:NN \tl_gremove_in:cn \tl_gremove_once:cn
+\cs_new_eq:NN \tl_remove_all_in:Nn \tl_remove_all:Nn
+\cs_new_eq:NN \tl_remove_all_in:cn \tl_remove_all:cn
+\cs_new_eq:NN \tl_gremove_all_in:Nn \tl_gremove_all:Nn
+\cs_new_eq:NN \tl_gremove_all_in:cn \tl_gremove_all:cn
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_elt_count:n, \tl_elt_count:V, \tl_elt_count:o}
+% \begin{macro}{\tl_elt_count:N, \tl_elt_count:c}
+% Another renaming job.
+% \begin{macrocode}
+\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
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\tl_head_i:n}
+% \begin{macro}{\tl_head_i:w}
+% \begin{macro}{\tl_head_iii:n}
+% \begin{macro}{\tl_head_iii:f}
+% \begin{macro}{\tl_head_iii:w}
+% Two renames, and a few that are rather too specialised.
+% \begin{macrocode}
+\cs_new_eq:NN \tl_head_i:n \tl_head:n
+\cs_new_eq:NN \tl_head_i:w \tl_head:w
+\cs_new:Npn \tl_head_iii:n #1 { \tl_head_iii:w #1 \q_stop }
+\cs_generate_variant:Nn \tl_head_iii:n { f }
+\cs_new:Npn \tl_head_iii:w #1#2#3#4 \q_stop {#1#2#3}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macrocode}
+%</initex|package>
+% \end{macrocode}
+%
+% \end{implementation}
+%
+% \PrintIndex