% \iffalse
%% File: l3tl.dtx Copyright (C) 1990-2010 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 LaTeX Project Team.
%%
%% -----------------------------------------------------------------------
%
%<*driver|package>
\RequirePackage{l3names}
%</driver|package>
%\fi
\GetIdInfo$Id: l3tl.dtx 2184 2011-03-07 18:07:12Z joseph $
          {L3 Experimental Token Lists}
%\iffalse
%<*driver>
%\fi
\ProvidesFile{\filename.\filenameext}
  [\filedate\space v\fileversion\space\filedescription]
%\iffalse
\documentclass[full]{l3doc}
\begin{document}
\DocInput{l3tl.dtx}
\end{document}
%</driver>
% \fi
%
%
% \title{The \textsf{l3tl} package\thanks{This file
%         has version number \fileversion, last
%         revised \filedate.}\\
% Token Lists}
% \author{\Team}
% \date{\filedate}
% \maketitle
%
% \def\tlvar{tl var.}
% \def\tlist{token list}
%
% \begin{documentation}
%
% \LaTeX3 stores token lists in variables also called `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.
%
% \section{Functions}
%
% \begin{function}{\tl_new:N  |
%                  \tl_new:c  |
%                  \tl_new:Nn |
%                  \tl_new:cn |
%                  \tl_new:Nx }
% \begin{syntax}
%    "\tl_new:Nn" <\tlvar> \Arg{initial token list}
% \end{syntax}
% Defines <\tlvar> globally to be a new variable to store a token list.
% <initial token list> is the initial value of <\tlvar>. This
% makes it possible to assign values to a constant token list variable.
%
% The form "\tl_new:N" initializes the token list variable with an empty value.
% \end{function}
%
%
% \begin{function}{\tl_const:Nn}
% \begin{syntax}
%    "\tl_const:Nn" \meta{\tlvar} \Arg{token list}
% \end{syntax}
% Defines \meta{\tlvar} as a global constant expanding to \meta{token list}.
% The name of the constant must be free when the constant is created.
% \end{function}
%
% \begin{function}{%
%                  \tl_use:N |
%                  \tl_use:c
% }
% \begin{syntax}
%   "\tl_use:N" <\tlvar>
% \end{syntax}
% Function that inserts the <\tlvar> into the processing stream. Instead of
% |\tl_use:N| simply placing the <\tlvar> into the input stream is also
% supported. |\tl_use:c| will complain if the <\tlvar> hasn't been declared
% previously!
% \end{function}
%
% \begin{function}{\tl_show:N |
%                  \tl_show:c |
%                  \tl_show:n }
% \begin{syntax}
%   "\tl_show:N" <\tlvar>
%   "\tl_show:n" \Arg{\tlist}
% \end{syntax}
% Function that pauses the compilation and displays the <\tlvar>
% or <\tlist> on the console output and in the log file.
% \end{function}
%
% \begin{function}{%
%                  \tl_set:Nn |
%                  \tl_set:Nc |
%                  \tl_set:NV |
%                  \tl_set:No |
%                  \tl_set:Nv |
%                  \tl_set:Nf |
%                  \tl_set:Nx |
%                  \tl_set:cn |
%                  \tl_set:co |
%                  \tl_set:cV |
%                  \tl_set:cx |
%                  \tl_gset:Nn |
%                  \tl_gset:Nc |
%                  \tl_gset:No |
%                  \tl_gset:NV |
%                  \tl_gset:Nv |
%                  \tl_gset:Nx |
%                  \tl_gset:cn |
%                  \tl_gset:cx }
% \begin{syntax}
%   "\tl_set:Nn" <\tlvar> \Arg{\tlist}
% \end{syntax}
% Defines <\tlvar> to hold the token list <\tlist>. Global
% variants of this command assign the value globally the other variants
% expand the <\tlist> up to a certain level before the assignment
% or interpret the <\tlist> as a character list and form a control
% sequence out of it.
% \end{function}
%
% \begin{function}{%
%                  \tl_clear:N |
%                  \tl_clear:c |
%                  \tl_gclear:N |
%                  \tl_gclear:c
% }
% \begin{syntax}
%   "\tl_clear:N" <\tlvar>
% \end{syntax}
% The <\tlvar> is locally or globally cleared. The "c" variants will
% generate a control sequence name which is then interpreted as
% <\tlvar> before clearing.
% \end{function}
%
% \begin{function}{%
%                  \tl_clear_new:N |
%                  \tl_clear_new:c |
%                  \tl_gclear_new:N |
%                  \tl_gclear_new:c |
% }
% \begin{syntax}
%   "\tl_clear_new:N" <\tlvar>
% \end{syntax}
% These functions check if <\tlvar> exists. If it does it will be cleared;
% if it doesn't it will be allocated.
% \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 |
% }
% \begin{syntax}
%   "\tl_put_left:Nn" <\tlvar> \Arg{\tlist}
% \end{syntax}
% These functions will append <\tlist> to the left of
% <\tlvar>. <\tlist> might be subject to expansion before assignment.
% \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 |
% }
% \begin{syntax}
%   "\tl_put_right:Nn" <\tlvar> \Arg{\tlist}
% \end{syntax}
% These functions append <\tlist> to the right of
% <\tlvar>.
% \end{function}
%
% \begin{function}{%
%                  \tl_gput_left:Nn |
%                  \tl_gput_left:No |
%                  \tl_gput_left:NV |
%                  \tl_gput_left:Nx |
%                  \tl_gput_left:cn |
%                  \tl_gput_left:co |
%                  \tl_gput_left:cV |
% }
% \begin{syntax}
%   "\tl_gput_left:Nn" <\tlvar> \Arg{\tlist}
% \end{syntax}
% These functions will append <\tlist> globally to the left of
% <\tlvar>.
% \end{function}
%
% \begin{function}{%
%                  \tl_gput_right:Nn|
%                  \tl_gput_right:No|
%                  \tl_gput_right:NV|
%                  \tl_gput_right:Nx|
%                  \tl_gput_right:cn|
%                  \tl_gput_right:co|
%                  \tl_gput_right:cV|
% }
% \begin{syntax}
%   "\tl_gput_right:Nn" <\tlvar> \Arg{\tlist}
% \end{syntax}
% These functions will globally append <\tlist> to the right of
% <\tlvar>.
% \end{function}
%
% A word of warning is appropriate here: Token list variables are
% implemented as macros and as such currently inherit some of the
% peculiarities of how \TeX\ handles "#"s in the argument of
% macros. In particular, the following actions are legal
% \begin{verbatim}
% \tl_set:Nn \l_tmpa_tl{##1}
% \tl_put_right:Nn \l_tmpa_tl{##2}
% \tl_set:No \l_tmpb_tl{\l_tmpa_tl ##3}
% \end{verbatim}
% |x| type expansions where macros being expanded contain |#|s do not
% work and will not work until there is an |\expanded| primitive in
% the engine. If you want them to work you must double |#|s another
% level.
%
%
% \begin{function}{%
%                  \tl_set_eq:NN |
%                  \tl_set_eq:Nc |
%                  \tl_set_eq:cN |
%                  \tl_set_eq:cc |
%                  \tl_gset_eq:NN |
%                  \tl_gset_eq:Nc |
%                  \tl_gset_eq:cN |
%                  \tl_gset_eq:cc |
% }
% \begin{syntax}
%    "\tl_set_eq:NN" <\tlvar1> <\tlvar2>
% \end{syntax}
% Fast form for
% \begin{syntax}
%    "\tl_set:No" <\tlvar1> \Arg{\tlvar2}
% \end{syntax}
% when <\tlvar2> is known to be a variable of type "tl".
% \end{function}
%
% \begin{function}{\tl_to_str:N |
%                  \tl_to_str:c
% }
% \begin{syntax}
%   "\tl_to_str:N" <\tlvar>
% \end{syntax}
% This function returns the token list kept in <\tlvar> as a string list
% with all characters catcoded to `other'.
% \end{function}
%
% \begin{function}{ \tl_to_str:n }
% \begin{syntax}
%   "\tl_to_str:n" \Arg{\tlist}
% \end{syntax}
% This function turns its argument into a string where all characters
% have catcode `other'.
% \begin{texnote}
%   This is the \eTeX\ primitive \tn{detokenize}.
% \end{texnote}
% \end{function}
%
%
% \begin{function}{ \tl_rescan:nn }
% \begin{syntax}
% "\tl_rescan:nn" \Arg{catcode setup} \Arg{\tlist}
% \end{syntax}
% Returns the result of re-tokenising <\tlist> with the catcode setup
% (and whatever other redefinitions) specified. This is useful because
% the catcodes of characters are `frozen' when first tokenised; this allows
% their meaning to be changed even after they've been read as an argument.
% Also see "\tl_set_rescan:Nnn" below.
% \begin{texnote}
%   This is a wrapper around \eTeX's "\scantokens".
% \end{texnote}
% \end{function}
%
% \begin{function}{ \tl_set_rescan:Nnn  | \tl_set_rescan:Nno  | \tl_set_rescan:Nnx  |
%                   \tl_gset_rescan:Nnn | \tl_gset_rescan:Nno  | \tl_gset_rescan:Nnx }
% \begin{syntax}
% "\tl_set_rescan:Nnn" <\tlvar> \Arg{catcode setup} \Arg{\tlist}
% \end{syntax}
% Sets <\tlvar> to the result of re-tokenising <\tlist> with the catcode setup
% (and whatever other redefinitions) specified.
% \begin{texnote}
%   This is a wrapper around \eTeX's "\scantokens".
% \end{texnote}
% \end{function}
%
%
%
% \section{Predicates and conditionals}
%
% \begin{function}{\tl_if_empty_p:N / (EXP) |
%                  \tl_if_empty_p:c / (EXP)
%                  }
% \begin{syntax}
%   "\tl_if_empty_p:N" <\tlvar>
% \end{syntax}
% This predicate returns `true' if <\tlvar> is `empty' i.e., doesn't
% contain any tokens.
% \end{function}
%
% \begin{function}{\tl_if_empty:N / (TF)(EXP) |
%                  \tl_if_empty:c / (TF)(EXP) |
% }
% \begin{syntax}
%   "\tl_if_empty:NTF" <\tlvar> \Arg{true code} \Arg{false code}
% \end{syntax}
% Execute <true code> if <\tlvar> is empty and <false code> if it
% contains any tokens.
% \end{function}
%
% \begin{function}{\tl_if_eq_p:NN / (EXP) |
%                  \tl_if_eq_p:cN / (EXP) |
%                  \tl_if_eq_p:Nc / (EXP) |
%                  \tl_if_eq_p:cc / (EXP) |
%                  }
% \begin{syntax}
%   "\tl_if_eq_p:NN" <\tlvar1> <\tlvar2>
% \end{syntax}
% Predicate function which returns `true' if the two token list
% variables are identical and `false' otherwise.
% \end{function}
%
% \begin{function}{
%                  \tl_if_eq:NN / (TF)(EXP) |
%                  \tl_if_eq:cN / (TF)(EXP) |
%                  \tl_if_eq:Nc / (TF)(EXP) |
%                  \tl_if_eq:cc / (TF)(EXP) |
%  }
%  \begin{syntax}
%   "\tl_if_eq:NNTF" <\tlvar1> <\tlvar2> \Arg{true code} \Arg{false code}
% \end{syntax}
% Execute <true code> if <\tlvar1> holds the same token list as <\tlvar2>
% and <false code> otherwise.
% \end{function}
%
%
% \begin{function}{\tl_if_empty_p:n / (EXP) |
%                  \tl_if_empty_p:V / (EXP) |
%                  \tl_if_empty_p:o / (EXP) |
%                  \tl_if_empty:n / (TF) |
%                  \tl_if_empty:V / (TF) |
%                  \tl_if_empty:o / (TF) |
%                  }
% \begin{syntax}
%   "\tl_if_empty:nTF" \Arg{\tlist} \Arg{true code} \Arg{false code}
% \end{syntax}
% Execute <true code> if <\tlist> doesn't contain any tokens and <false
% code> otherwise.
% \end{function}
% 
%\begin{function}{ \tl_if_eq:nn / (TF) }
%  \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} 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}{\tl_if_blank_p:n / (EXP)|
%                  \tl_if_blank:n / (TF)(EXP)|
%                  \tl_if_blank_p:V / (EXP)|
%                  \tl_if_blank_p:o / (EXP)|
%                  \tl_if_blank:V / (TF)(EXP)|
%                  \tl_if_blank:o / (TF)(EXP)|
%                  }
% \begin{syntax}
%   "\tl_if_blank:nTF" \Arg{\tlist} \Arg{true code} \Arg{false code}
% \end{syntax}
% Execute <true code> if <\tlist> is blank meaning that it is either
% empty or contains only blank spaces.
% \end{function}
%
%
%
% \begin{function}{ \tl_if_single_p:n / (EXP) | \tl_if_single:n / (TF)(EXP) |
%                   \tl_if_single_p:N / (EXP) | \tl_if_single:N / (TF)(EXP) }
% \begin{syntax}
% "\tl_if_single:NTF" \Arg{\tlvar} \Arg{true code} \Arg{false code}
% "\tl_if_single:nTF" \Arg{\tlist} \Arg{true code} \Arg{false code}
% \end{syntax}
% Conditional returning true if the token list or the contents of the \tlvar\
% consists of a single token only.
%
% Note that an input of `space'\footnote{But remember any number of
% consequtive spaces are read as a single space by \TeX.} returns <true>
% from this function.
% \end{function}
%
%
% \begin{function}{\tl_to_lowercase:n |
%                  \tl_to_uppercase:n
%                  }
% \begin{syntax}
%   "\tl_to_lowercase:n" \Arg{\tlist}
% \end{syntax}
% "\tl_to_lowercase:n" converts all tokens in <\tlist> to their
% lower case representation. Similar for "\tl_to_uppercase:n".
% \begin{texnote}
%   These are the \TeX\ primitives \tn{lowercase} and \tn{uppercase}
%   renamed.
% \end{texnote}
% \end{function}
%
% \section{Working with the contents of token lists}
%
%  \begin{function}{%
%                   \tl_map_function:nN / (EXP) |
%                   \tl_map_function:NN |
%                   \tl_map_function:cN |
%  }
%  \begin{syntax}
%     "\tl_map_function:nN" \Arg{\tlist} <function> \\
%     "\tl_map_function:NN" <\tlvar> <function>
%  \end{syntax}
%  Runs through all elements in a <\tlist> from left to right and places
%  <function> in front of each element. As this function will also pick
%  up elements in brace groups, the element is returned with braces and
%  hence <function> should be a function with a |:n| suffix even though
%  it may very well only deal with a single token.
%
%  This function uses a
%  purely expandable loop function and will stay so as long as
%  <function> is expandable too.
%  \end{function}
%
%  \begin{function}{%
%                   \tl_map_inline:nn |
%                   \tl_map_inline:Nn |
%                   \tl_map_inline:cn |
%  }
%  \begin{syntax}
%     "\tl_map_inline:nn" \Arg{\tlist} \Arg{inline~function} \\
%     "\tl_map_inline:Nn" <\tlvar> \Arg{inline~function}
%  \end{syntax}
%  Allows a syntax like "\tl_map_inline:nn" \Arg{\tlist}
%  "{\token_to_str:N ##1}". This renders it non-expandable though.
%  Remember to double the "#"s for each level.
%  \end{function}
%
%
%  \begin{function}{%
%                   \tl_map_variable:nNn |
%                   \tl_map_variable:NNn |
%                   \tl_map_variable:cNn |
%  }
%  \begin{syntax}
%     "\tl_map_variable:nNn" \Arg{\tlist} <temp> \Arg{action} \\
%     "\tl_map_variable:NNn" <\tlvar> <temp> \Arg{action}
%  \end{syntax}
%  Assigns <temp> to each element on <\tlist> and executes <action>.
%  As there is an assignment in this process it is not expandable.
%  \begin{texnote}
%  This is the \LaTeX2{} function \tn{@tfor} but with a more sane syntax.
%  Also it works by tail recursion and so is faster as lists grow longer.
%  \end{texnote}
%  \end{function}
%
%  \begin{function}{%
%                   \tl_map_break: |
%  }
%  \begin{syntax}
%     "\tl_map_break:"
%  \end{syntax}
%  For breaking out of a loop. Must not be nested inside a primitive
%  "\if" structure.
%  \end{function}
%
%
%  \begin{function}{ \tl_reverse:n |
%                    \tl_reverse:V |
%                    \tl_reverse:o |
%                    \tl_reverse:N   }
%  \begin{syntax}
%     "\tl_reverse:n" "{"<token1><token2>...<token$\sb n$>"}"\\
%     "\tl_reverse:N" <\tlvar>
%  \end{syntax}
%  Reverse the token list (or the token list in the <\tlvar>) to result in
%  <token$\sb n$>\dots<token2><token1>.
%  Note that spaces in this
%  token list are gobbled in the process.
%
%  Note also that braces are lost in the process of reversing a <\tlvar>.
%  That is,\\
%  "\tl_set:Nn \l_tmpa_tl {a{bcd}e} \tl_reverse:N \l_tmpa_tl"\\
%  will result in "ebcda". This behaviour is probably more of a bug than
%  a feature.
%  \end{function}
%
%  \begin{function}{%
%                   \tl_elt_count:n  / (EXP) |
%                   \tl_elt_count:V / (EXP) |
%                   \tl_elt_count:o / (EXP) |
%                   \tl_elt_count:N / (EXP) |
%  }
%  \begin{syntax}
%     "\tl_elt_count:n" \Arg{\tlist} \\
%     "\tl_elt_count:N"   <\tlvar>
%  \end{syntax}
%  Returns the number of elements in the token list. Brace groups
%  encountered count as one element. Note that spaces in this
%  token list are gobbled in the process.
%  \end{function}
%
%
% \section{Variables and constants}
%
% \begin{variable}{\c_job_name_tl}
% Constant that gets the `job name' assigned when \TeX{} starts.
% \begin{texnote}
% This is the new name for the primitive \tn{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.
% \begin{texnote}
% This was named \tn{@empty} in \LaTeX2 and \tn{empty} in plain \TeX{}.
% \end{texnote}
% \end{variable}
% 
% \begin{variable}{\c_space_tl}
% A space token contained in a token list (compare this with
% \cs{char_space_token}). For use where an explicit space is required.
% \end{variable}
%
% \begin{variable}{%
%                  \l_tmpa_tl |
%                  \l_tmpb_tl |
%                  \g_tmpa_tl |
%                  \g_tmpb_tl
% }
% Scratch register for immediate use. They are not used by conditionals
% or predicate functions. However, it is important to note that you should
% never rely on such scratch variables unless you fully control the code used
% between setting them and retrieving their value. Calling code from other
% modules, or worse allowing arbitrary user input to interfere might result in
% them not containing what you expect. In that is the case you better define
% your own scratch variables that are tight to your code by giving them
% suitable names.
% \end{variable}
%
% \begin{variable}{%
%                  \l_tl_replace_tl |
% }
% Internal register used in the replace functions.
% \end{variable}
%
% \begin{variable}{%
%                  \l_kernel_testa_tl |
%                  \l_kernel_testb_tl |
% }
% Registers used for conditional processing if the engine doesn't
% support arbitrary string comparison. Not for use outside the kernel code!
% \end{variable}
%
% \begin{variable}{%
%                  \l_kernel_tmpa_tl |
%                  \l_kernel_tmpb_tl 
% }
% Scratch registers reserved for other places in kernel code. Not for use
% outside the kernel code!
% \end{variable}
%
% \begin{variable}{%
%                  \g_tl_inline_level_int |
% }
% Internal register used in the inline map functions.
% \end{variable}%
%
% \section{Searching for and replacing tokens}
%
% \begin{function}{
%                  \tl_if_in:Nn / (TF) |
%                  \tl_if_in:cn / (TF) |
%                  \tl_if_in:nn / (TF) |
%                  \tl_if_in:Vn / (TF) |
%                  \tl_if_in:on / (TF) |
%                  }
% \begin{syntax}
%   "\tl_if_in:NnTF" <\tlvar> \Arg{item} \Arg{true code} \Arg{false code}
% \end{syntax}
% Function that tests if <item> is in <\tlvar>. Depending on the result
% either <true code> or <false code> is executed. Note that <item>
% cannot contain brace groups nor "#"$_6$ tokens.
% \end{function}
%
% \begin{function}{
%                  \tl_replace_in:Nnn |
%                  \tl_replace_in:cnn |
%                  \tl_greplace_in:Nnn |
%                  \tl_greplace_in:cnn |
%                  }
% \begin{syntax}
%   "\tl_replace_in:Nnn" <\tlvar> \Arg{item1} \Arg{item2}
% \end{syntax}
% Replaces the leftmost occurrence of <item1> in <\tlvar> with
% <item2> if present, otherwise the <\tlvar> is left untouched.
% Note that <item1>
% cannot contain brace groups nor "#"$_6$ tokens, and <item2>
% cannot contain "#"$_6$ tokens.
% \end{function}
%
% \begin{function}{
%                  \tl_replace_all_in:Nnn |
%                  \tl_replace_all_in:cnn |
%                  \tl_greplace_all_in:Nnn |
%                  \tl_greplace_all_in:cnn |
%                  }
% \begin{syntax}
%   "\tl_replace_all_in:Nnn" <\tlvar> \Arg{item1} \Arg{item2}
% \end{syntax}
% Replaces \emph{all} occurrences of <item1> in <\tlvar> with
% <item2>.
% Note that <item1>
% cannot contain brace groups nor "#"$_6$ tokens, and <item2>
% cannot contain "#"$_6$ tokens.
% \end{function}
%
%
% \begin{function}{
%                  \tl_remove_in:Nn |
%                  \tl_remove_in:cn |
%                  \tl_gremove_in:Nn |
%                  \tl_gremove_in:cn |
%                  }
% \begin{syntax}
%   "\tl_remove_in:Nn" <\tlvar> \Arg{item}
% \end{syntax}
% Removes the leftmost occurrence of <item> from <\tlvar> if present.
% Note that <item>
% cannot contain brace groups nor "#"$_6$ tokens.
% \end{function}
%
%
% \begin{function}{
%                  \tl_remove_all_in:Nn |
%                  \tl_remove_all_in:cn |
%                  \tl_gremove_all_in:Nn |
%                  \tl_gremove_all_in:cn |
%                  }
% \begin{syntax}
%   "\tl_remove_all_in:Nn" <\tlvar> \Arg{item}
% \end{syntax}
% Removes \emph{all} occurrences of <item> from <\tlvar>. Note that <item>
% cannot contain brace groups nor "#"$_6$ tokens.
% \end{function}
%
%
% \section{Heads or tails?}
%
% Here are some functions for grabbing either the head or tail of a
% list and perform some tests on it.
%
% \begin{function}{%
%                  \tl_head:n     / (EXP) |
%                  \tl_head:V     / (EXP) |
%                  \tl_head:v     / (EXP) |
%                  \tl_tail:n     / (EXP) |
%                  \tl_tail:V     / (EXP) |
%                  \tl_tail:v     / (EXP) |
%                  \tl_tail:f     / (EXP) |
%                  \tl_head_i:n   / (EXP) |
%                  \tl_head_iii:n / (EXP) |
%                  \tl_head_iii:f / (EXP) |
%                  \tl_head:w     / (EXP) |
%                  \tl_tail:w     / (EXP) |
%                  \tl_head_i:w   / (EXP) |
%                  \tl_head_iii:w / (EXP) 
% }
% \begin{syntax}
%   "\tl_head:n"  "{" <token1><token2>...<token\,$\sb k$> "}" \\
%   "\tl_tail:n"  "{" <token1><token2>...<token\,$\sb k$> "}" \\
%   "\tl_head:w" <token1><token2>...<token\,$\sb k$> "\q_stop"
% \end{syntax}
% These functions return either the head or the tail from a list of tokens, thus in
% the above example "\tl_head:n" would return <token1> and "\tl_tail:n"
% would return <token2>\dots<token\,$\sb k$>. "\tl_head_iii:n" returns the first
% three tokens. The ":w" versions require some care as they expect the token
% list to be delimited by "\q_stop".
% \begin{texnote}
% These are the Lisp functions "car" and "cdr" but with \LaTeX3 names.
% \end{texnote}
% \end{function}
%
%
%
%
% \begin{function}{%
%                  \tl_if_head_eq_meaning_p:nN / (EXP) |
%                  \tl_if_head_eq_meaning:nN / (TF)(EXP) |
% }
% \begin{syntax}
%   "\tl_if_head_eq_meaning:nNTF" \Arg{\tlist} <token>
%   \Arg{true} \Arg{false}
% \end{syntax}
% Returns <true> if the first token in <\tlist> is equal to
% <token> and <false> otherwise. The |meaning| version compares the
% two tokens with |\if_meaning:w|.
% \end{function}
%
% \begin{function}{%
%                  \tl_if_head_eq_charcode_p:nN / (EXP) |
%                  \tl_if_head_eq_charcode_p:fN / (EXP) |
%                  \tl_if_head_eq_charcode:nN / (TF)(EXP) |
%                  \tl_if_head_eq_charcode:fN / (TF)(EXP) |
% }
% \begin{syntax}
%   "\tl_if_head_eq_charcode:nNTF" \Arg{\tlist} <token>
%   \Arg{true} \Arg{false}
% \end{syntax}
% Returns <true> if the first token in <\tlist> is equal to
% <token> and <false> otherwise. The |meaning| version compares the
% two tokens with |\if_charcode:w| but it prevents expansion of
% them. If you want them to expand, you can use an |f| type expansion
% first (define |\tl_if_head_eq_charcode:fNTF| or similar).
% \end{function}
%
% \begin{function}{%
%                  \tl_if_head_eq_catcode_p:nN / (EXP) |
%                  \tl_if_head_eq_catcode:nN / (TF)(EXP) |
% }
% \begin{syntax}
%   "\tl_if_head_eq_catcode:nNTF" \Arg{\tlist} <token>
%   \Arg{true} \Arg{false}
% \end{syntax}
% Returns <true> if the first token in <\tlist> is equal to
% <token> and <false> otherwise. This version uses |\if_catcode:w| for
% the test but is otherwise identical to the |charcode| version.
% \end{function}
%
%
% \end{documentation}
%
% \begin{implementation}
%
% \section{\pkg{l3tl} implementation}
%
%    We start by ensuring that the required packages are loaded.
%    \begin{macrocode}
%<*package>
\ProvidesExplPackage
  {\filename}{\filedate}{\fileversion}{\filedescription}
\package_check_loaded_expl:
%</package>
%    \end{macrocode}
%    \begin{macrocode}
%<*initex|package>
%    \end{macrocode}
%
% A token list variable is a control sequence that holds tokens.  The
% interface is similar to that for token registers, but beware that
% the behavior vis \'a vis |\cs_set_nopar:Npx| etc. \ldots{} is different.  (You
% see this comes from Denys' implementation.)
%
%
% \subsection{Functions}
%
% \begin{macro}{\tl_new:N}
% \begin{macro}{\tl_new:c}
% \begin{macro}{\tl_new:Nn}
% \begin{macro}{\tl_new:cn}
% \begin{macro}{\tl_new:Nx}
%    We provide one allocation function (which checks that the name is
%    not used) and two clear functions that locally or globally clear
%    the token list. The allocation function has two arguments to
%    specify an initial value. This is the only way to give values to
%    constants.
%    \begin{macrocode}
\cs_new_protected:Npn \tl_new:Nn #1#2{
  \chk_if_free_cs:N #1
%    \end{macrocode}
%  If checking we don't allow constants to be defined.
%    \begin{macrocode}
%<*check>
  \chk_var_or_const:N #1
%</check>
%    \end{macrocode}
%    Otherwise any variable type is allowed.
%    \begin{macrocode}
  \cs_gset_nopar:Npn #1{#2}
}
\cs_generate_variant:Nn \tl_new:Nn {cn}
\cs_new_protected:Npn \tl_new:Nx #1#2{
  \chk_if_free_cs:N #1
%<check> \chk_var_or_const:N #1
  \cs_gset_nopar:Npx #1{#2}
}
\cs_new_protected_nopar:Npn \tl_new:N #1{\tl_new:Nn #1{}}
\cs_new_protected_nopar:Npn \tl_new:c #1{\tl_new:cn {#1}{}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
%
%\begin{macro}{\tl_const:Nn}
% For creating constant token lists: there is not actually anything here
% that cannot be achieved using \cs{tl_new:N}  and \cs{tl_set:Nn}
%    \begin{macrocode}
\cs_new_protected:Npn \tl_const:Nn #1#2 {
  \tl_new:N   #1
  \tl_gset:Nn #1 {#2}
}
%    \end{macrocode}
%\end{macro} 
%
% \begin{macro}{\tl_use:N}
% \begin{macro}{\tl_use:c}
% Perhaps this should just be enabled when checking?
%    \begin{macrocode}
\cs_new_nopar:Npn \tl_use:N #1 {
  \if_meaning:w #1 \tex_relax:D
%    \end{macrocode}
%  If \m{\tlvar} equals |\tex_relax:D| it is probably stemming from a
%  |\cs:w|\dots|\cs_end:| that was created by mistake somewhere.
%    \begin{macrocode}
     \msg_kernel_bug:x {Token~list~variable~ `\token_to_str:N #1'~
                       has~ an~ erroneous~ structure!}
  \else:
    \exp_after:wN #1
  \fi:
}
\cs_generate_variant:Nn \tl_use:N {c}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tl_show:N,\tl_show:c,\tl_show:n}
% Showing a \meta{\tlvar} is just "\show"ing it and I don't really care
% about checking that it's malformed at this stage.
%    \begin{macrocode}
\cs_new_nopar:Npn \tl_show:N #1 { \cs_show:N #1 }
\cs_generate_variant:Nn \tl_show:N {c}
\cs_set_eq:NN \tl_show:n \etex_showtokens:D
%    \end{macrocode}
% \end{macro}
%
%\begin{macro}{\tl_set:Nn}
%\begin{macro}{\tl_set:NV}
%\begin{macro}{\tl_set:Nv}
%\begin{macro}{\tl_set:No}
%\begin{macro}{\tl_set:Nf}
%\begin{macro}{\tl_set:Nx}
%\begin{macro}{\tl_set:cn}
%\begin{macro}{\tl_set:cV}
%\begin{macro}{\tl_set:cv}
%\begin{macro}{\tl_set:co}
%\begin{macro}{\tl_set:cx}
%\begin{macro}{\tl_gset:Nn}
%\begin{macro}{\tl_gset:NV}
%\begin{macro}{\tl_gset:Nv}
%\begin{macro}{\tl_gset:No}
%\begin{macro}{\tl_gset:Nf}
%\begin{macro}{\tl_gset:Nx}
%\begin{macro}{\tl_gset:cn}
%\begin{macro}{\tl_gset:cV}
%\begin{macro}{\tl_gset:cv}
%\begin{macro}{\tl_gset:cx}
% By using \cs{exp_not:n} token list variables can contain "#" tokens.
%    \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: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:Nx #1#2 {
  \cs_gset_nopar:Npx #1 {#2}
}
\cs_generate_variant:Nn \tl_set:Nn  { NV }
\cs_generate_variant:Nn \tl_set:Nn  { Nv }
\cs_generate_variant:Nn \tl_set:Nn  { No }
\cs_generate_variant:Nn \tl_set:Nn  { Nf }
\cs_generate_variant:Nn \tl_set:Nn  { cV }
\cs_generate_variant:Nn \tl_set:Nn  { c }
\cs_generate_variant:Nn \tl_set:Nn  { cv }
\cs_generate_variant:Nn \tl_set:Nn  { co }
\cs_generate_variant:Nn \tl_set:Nx  { c }
\cs_generate_variant:Nn \tl_gset:Nn { NV }
\cs_generate_variant:Nn \tl_gset:Nn { Nv }
\cs_generate_variant:Nn \tl_gset:Nn { No }
\cs_generate_variant:Nn \tl_gset:Nn { Nf }
\cs_generate_variant:Nn \tl_gset:Nn { c }
\cs_generate_variant:Nn \tl_gset:Nn { cV }
\cs_generate_variant:Nn \tl_gset:Nn { cv }
\cs_generate_variant:Nn \tl_gset:Nx { c }
%    \end{macrocode}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%
% \begin{macro}{\tl_set_eq:NN}
% \begin{macro}{\tl_set_eq:Nc}
% \begin{macro}{\tl_set_eq:cN}
% \begin{macro}{\tl_set_eq:cc}
% \begin{macro}{\tl_gset_eq:NN}
% \begin{macro}{\tl_gset_eq:Nc}
% \begin{macro}{\tl_gset_eq:cN}
% \begin{macro}{\tl_gset_eq:cc}
%  For setting token list variables equal to each other. First checking:
%    \begin{macrocode}
%<*check>
\cs_new_protected_nopar:Npn \tl_set_eq:NN #1#2{
  \chk_exist_cs:N #1  \cs_set_eq:NN #1#2
  \chk_local_or_pref_global:N #1  \chk_var_or_const:N #2
}
\cs_new_protected_nopar:Npn \tl_gset_eq:NN #1#2{
  \chk_exist_cs:N #1  \cs_gset_eq:NN #1#2
  \chk_global:N #1  \chk_var_or_const:N #2
}
%</check>
%    \end{macrocode}
%  Non-checking versions are easy.
%    \begin{macrocode}
%<*!check>
\cs_new_eq:NN \tl_set_eq:NN  \cs_set_eq:NN
\cs_new_eq:NN \tl_gset_eq:NN \cs_gset_eq:NN
%</!check>
%    \end{macrocode}
%  The rest again with the expansion module.
%    \begin{macrocode}
\cs_generate_variant:Nn \tl_set_eq:NN {Nc,c,cc}
\cs_generate_variant:Nn \tl_gset_eq:NN {Nc,c,cc}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
%
% \begin{macro}{\tl_clear:N}
% \begin{macro}{\tl_clear:c}
% \begin{macro}{\tl_gclear:N}
% \begin{macro}{\tl_gclear:c}
%    Clearing a token list variable.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \tl_clear:N #1{\tl_set_eq:NN #1\c_empty_tl}
\cs_generate_variant:Nn \tl_clear:N {c}
\cs_new_protected_nopar:Npn \tl_gclear:N #1{\tl_gset_eq:NN #1\c_empty_tl}
\cs_generate_variant:Nn \tl_gclear:N {c}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tl_clear_new:N}
% \begin{macro}{\tl_clear_new:c}
%    These macros check whether a token list exists. If it does it
%    is cleared, if it doesn't it is allocated.
%    \begin{macrocode}
%<*check>
\cs_new_protected_nopar:Npn \tl_clear_new:N #1{
  \chk_var_or_const:N #1
  \if_predicate:w \cs_if_exist_p:N #1
    \tl_clear:N #1
  \else:
    \tl_new:N #1
  \fi:
}
%</check>
%<-check>\cs_new_eq:NN \tl_clear_new:N \tl_clear:N
\cs_generate_variant:Nn \tl_clear_new:N {c}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tl_gclear_new:N}
% \begin{macro}{\tl_gclear_new:c}
%    These are the global versions of the above.
%    \begin{macrocode}
%<*check>
\cs_new_protected_nopar:Npn \tl_gclear_new:N #1{
  \chk_var_or_const:N #1
  \if_predicate:w \cs_if_exist_p:N #1
    \tl_gclear:N #1
  \else:
    \tl_new:N #1
  \fi:}
%</check>
%<-check>\cs_new_eq:NN \tl_gclear_new:N \tl_gclear:N
\cs_generate_variant:Nn \tl_gclear_new:N {c}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%\begin{macro}{\tl_put_right:Nn}
%\begin{macro}{\tl_put_right:NV}
%\begin{macro}{\tl_put_right:Nv}
%\begin{macro}{\tl_put_right:No}
%\begin{macro}{\tl_put_right:Nx}
%\begin{macro}{\tl_put_right:cn}
%\begin{macro}{\tl_put_right:cV}
%\begin{macro}{\tl_put_right:cv}
%\begin{macro}{\tl_put_right:cx}
%\begin{macro}{\tl_gput_right:Nn}
%\begin{macro}{\tl_gput_right:NV}
%\begin{macro}{\tl_gput_right:Nv}
%\begin{macro}{\tl_gput_right:No}
%\begin{macro}{\tl_gput_right:Nx}
%\begin{macro}{\tl_gput_right:cn}
%\begin{macro}{\tl_gput_right:cV}
%\begin{macro}{\tl_gput_right:cv}
%\begin{macro}{\tl_gput_right:co}
%\begin{macro}{\tl_gput_right:cx}
% Adding to one end of a token list is done partially using 
% hand tuned functions for performance reasons. 
%    \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:Nv #1#2 {
  \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:v {#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_put_right:No #1#2 {
  \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:o {#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: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:Nv  { 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: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}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%
%\begin{macro}{\tl_put_left:Nn}
%\begin{macro}{\tl_put_left:NV}
%\begin{macro}{\tl_put_left:Nv}
%\begin{macro}{\tl_put_left:No}
%\begin{macro}{\tl_put_left:Nx}
%\begin{macro}{\tl_put_left:cn}
%\begin{macro}{\tl_put_left:cV}
%\begin{macro}{\tl_put_left:cv}
%\begin{macro}{\tl_put_left:cx}
%\begin{macro}{\tl_gput_left:Nn}
%\begin{macro}{\tl_gput_left:NV}
%\begin{macro}{\tl_gput_left:Nv}
%\begin{macro}{\tl_gput_left:No}
%\begin{macro}{\tl_gput_left:Nx}
%\begin{macro}{\tl_gput_left:cn}
%\begin{macro}{\tl_gput_left:cV}
%\begin{macro}{\tl_gput_left:cv}
%\begin{macro}{\tl_gput_left:cx}
% Adding to the left is basically the same as putting on the right.
%    \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:Nv #1#2 {
  \cs_set_nopar:Npx #1 { \exp_not:v {#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_put_left:No #1#2 {
  \cs_set_nopar:Npx #1 { \exp_not:o {#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: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:Nv  { 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:Nv { c }
\cs_generate_variant:Nn \tl_gput_left:Nx { c }
%    \end{macrocode}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%
% \begin{macro}{\tl_gset:Nc}
% \begin{macro}{\tl_set:Nc}
%    These two functions are included because they are necessary in
%    Denys' implementations. The |:Nc| convention (see the expansion
%    module) is very unusual at first sight, but it works nicely
%    over all modules, so we would like to keep it.
%
%    Construct a control sequence on the fly from |#2| and save it in
%    |#1|.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \tl_gset:Nc {
%<*check>
  \pref_global_chk:
%</check>
%<-check> \pref_global:D
  \tl_set:Nc}
%    \end{macrocode}
%    |\pref_global_chk:| will turn the variable check in |\tl_set:No|
%    into a  global check.
%    \begin{macrocode}
\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}
%
% \subsection{Variables and constants}
%
% \begin{macro}{\c_job_name_tl}
% Inherited from the expl3 name for the primitive: this needs to
% actually contain the text of the jobname rather than the name of
% the primitive, of course.
%    \begin{macrocode}
\tl_new:N \c_job_name_tl 
\tl_set:Nx \c_job_name_tl { \tex_jobname:D }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\c_empty_tl}
%    Two constants which are often used.
%    \begin{macrocode}
\tl_const:Nn \c_empty_tl { }
%    \end{macrocode}
% \end{macro}
% 
% 
%\begin{macro}{\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{macro}
%
% \begin{macro}{\g_tmpa_tl}
% \begin{macro}{\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{macro}
% \end{macro}
%
% \begin{macro}{\l_kernel_testa_tl}
% \begin{macro}{\l_kernel_testb_tl}
%    Local temporaries.  These are the ones for test
%    routines.  This means that one can safely use other temporaries
%    when calling test routines.
%    \begin{macrocode}
\tl_new:N \l_kernel_testa_tl
\tl_new:N \l_kernel_testb_tl
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\l_tmpa_tl}
% \begin{macro}{\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{macro}
% \end{macro}
%
%
% \begin{macro}{\l_kernel_tmpa_tl}
% \begin{macro}{\l_kernel_tmpb_tl}
%    These are local temporary token list variables reserved for use by the
%    kernel. They should not be used by other modules.
%    \begin{macrocode}
\tl_new:N \l_kernel_tmpa_tl
\tl_new:N \l_kernel_tmpb_tl
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \subsection{Predicates and conditionals}
%
% We also provide a few conditionals, both in expandable form (with
% |\c_true_bool|) and in `brace-form', the latter are denoted by |TF| at the
% end, as explained elsewhere.
%
%
% \begin{macro}{\tl_if_empty_p:N,\tl_if_empty_p:c}
% \begin{macro}[TF]{\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,TF,T,F} {
  \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:NTF {c}
\cs_generate_variant:Nn \tl_if_empty:NT  {c}
\cs_generate_variant:Nn \tl_if_empty:NF  {c}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tl_if_eq_p:NN,\tl_if_eq_p:Nc,\tl_if_eq_p:cN,\tl_if_eq_p:cc}
% \begin{macro}[TF]{\tl_if_eq:NN,\tl_if_eq:Nc,\tl_if_eq:cN,\tl_if_eq:cc}
%   Returns |\c_true_bool| iff the two token list variables are equal.
%    \begin{macrocode}
\prg_new_conditional:Npnn \tl_if_eq:NN #1#2 {p,TF,T,F} {
  \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}
% \end{macro}
% 
%\begin{macro}[TF]{\tl_if_eq:nn}
%\begin{macro}[aux]{\l_tl_tmpa_tl}
%\begin{macro}[aux]{\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}
    \tex_ifx:D \l_tl_tmpa_tl \l_tl_tmpb_tl
      \group_end:
      \prg_return_true:
    \tex_else:D
      \group_end:
      \prg_return_false:
    \tex_fi:D
}
\tl_new:N \l_tl_tmpa_tl
\tl_new:N \l_tl_tmpb_tl
%    \end{macrocode}
%\end{macro}
%\end{macro}
%\end{macro}
%
%
% \begin{macro}{\tl_if_empty_p:n,\tl_if_empty_p:V,\tl_if_empty_p:o}
% \begin{macro}[TF]{\tl_if_empty:n,\tl_if_empty:V,\tl_if_empty:o}
%   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}
\cs_generate_variant:Nn \tl_if_empty_p:n {o}
\cs_generate_variant:Nn \tl_if_empty:nTF {o}
\cs_generate_variant:Nn \tl_if_empty:nT  {o}
\cs_generate_variant:Nn \tl_if_empty:nF  {o}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tl_if_blank_p:n,\tl_if_blank_p:V,\tl_if_blank_p:o}
% \begin{macro}[TF]{\tl_if_blank:n,\tl_if_blank:V,\tl_if_blank:o}
% \begin{macro}[aux]{\tl_if_blank_p_aux:w}
%   This is based on the answers in ``Around the Bend No~2'' but is
%   safer as the tests listed there all have one small flaw: If the
%   input in the test is two tokens with the same meaning as the
%   internal delimiter, they will fail since one of them is mistaken
%   for the actual delimiter. In our version below we make sure to
%   pass the input through |\tl_to_str:n| which ensures that all
%   the tokens are converted to catcode 12. However we use an |a| with
%   catcode 11 as delimiter so we can \emph{never} get into the same
%   problem as the solutions in ``Around the Bend No~2''.
%    \begin{macrocode}
\prg_new_conditional:Npnn \tl_if_blank:n #1 {p,TF,T,F} {
  \exp_after:wN \tl_if_blank_p_aux:w \tl_to_str:n {#1} aa..\q_stop
}
\cs_new:Npn \tl_if_blank_p_aux:w #1#2 a #3#4 \q_stop {
  \if_meaning:w #3 #4 \prg_return_true: \else: \prg_return_false: \fi:
}
\cs_generate_variant:Nn \tl_if_blank_p:n {V}
\cs_generate_variant:Nn \tl_if_blank:nTF {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_p:n {o}
\cs_generate_variant:Nn \tl_if_blank:nTF {o}
\cs_generate_variant:Nn \tl_if_blank:nT  {o}
\cs_generate_variant:Nn \tl_if_blank:nF  {o}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}[TF]{\tl_if_single:n}
% \begin{macro}{\tl_if_single_p:n}
% If the argument is a single token. `Space' is considered `true'.
%    \begin{macrocode}
\prg_new_conditional:Nnn \tl_if_single:n {p,TF,T,F} {
  \tl_if_empty:nTF {#1}
    {\prg_return_false:}
    {
      \tl_if_blank:nTF {#1}
        {\prg_return_true:}
        {
          \_tl_if_single_aux:w #1 \q_stop
        }
    }
}
%    \end{macrocode}
% Use "\exp_after:wN" below I know what I'm doing.
% Use "\exp_args:NV" or "\exp_args_unbraced:NV"
% for more flexibility in your own code.
%    \begin{macrocode}
\prg_new_conditional:Nnn \tl_if_single:N {p,TF,T,F} {
  \tl_if_empty:NTF #1
    { \prg_return_false: }
    {
      \tl_if_blank:oTF {#1}
        { \prg_return_true: }
        { \exp_after:wN \_tl_if_single_aux:w #1 \q_stop }
    }
}
%    \end{macrocode}
%
%    \begin{macrocode}
\cs_new:Npn \_tl_if_single_aux:w #1#2 \q_stop {
  \tl_if_empty:nTF {#2} \prg_return_true: \prg_return_false:
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \subsection{Working with the contents of token lists}
%
%
% \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}
%
% \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}
% \begin{macro}{\tl_to_str:c}
% \begin{macro}[aux]{\tl_to_str_aux:w}
%    These functions return the replacement text of a token list as a
%    string list with all characters catcoded to `other'.
%    \begin{macrocode}
\cs_new_nopar:Npn \tl_to_str:N {\exp_after:wN\tl_to_str_aux:w
  \token_to_meaning:N}
\cs_new_nopar:Npn \tl_to_str_aux:w #1>{}
\cs_generate_variant:Nn \tl_to_str:N {c}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%  \begin{macro}{\tl_map_function:nN}
%  \begin{macro}{\tl_map_function:NN}
%  \begin{macro}{\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 {cN}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%
%  \begin{macro}{\tl_map_inline:nn}
%  \begin{macro}{\tl_map_inline:Nn}
%  \begin{macro}{\tl_map_inline:cn}
%  \begin{macro}[aux]{\tl_map_inline_aux:n}
%  \begin{macro}{\g_tl_inline_level_int}
%    The inline functions are straight forward by now. We use a little
%    trick with the counter |\g_tl_inline_level_int| to make
%    them nestable. We can
%    also make use of |\tl_map_function:Nn| from before.
%    \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{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%
% \begin{macro}{\tl_map_variable:nNn}
% \begin{macro}{\tl_map_variable:NNn}
% \begin{macro}{\tl_map_variable:cNn}
%    |\tl_map_variable:nNn| \meta{\tlist} \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
}
%    \end{macrocode}
%    Next really has to be v/V args
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \tl_map_variable:NNn {\exp_args:No \tl_map_variable:nNn}
\cs_generate_variant:Nn \tl_map_variable:NNn {c}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}[aux]{\tl_map_variable_aux:NnN}
%  The general loop. Assign the temp variable |#1| to the current item
%  |#3| and then check if that's the stop marker. If it is, break the
%  loop. If not, execute the action |#2| and continue.
%    \begin{macrocode}
\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}
}
%    \end{macrocode}
% \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}
%
%  \begin{macro}{\tl_reverse:n}
%  \begin{macro}{\tl_reverse:V}
%  \begin{macro}{\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}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\tl_reverse:N}
% 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: } }
}
%    \end{macrocode}
%  \end{macro}
%
%  \begin{macro}{\tl_elt_count:n}
%  \begin{macro}{\tl_elt_count:V}
%  \begin{macro}{\tl_elt_count:o}
%  \begin{macro}{\tl_elt_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.
%    \cs{tl_elt_count_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_elt_count:n #1{
  \int_eval:n {
    0 \tl_map_function:nN {#1} \tl_elt_count_aux:n
  }
}
\cs_generate_variant:Nn \tl_elt_count:n {V,o}
\cs_new_nopar:Npn \tl_elt_count:N #1{
  \int_eval:n {
    0 \tl_map_function:NN #1 \tl_elt_count_aux:n
  }
}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
% \begin{macro}[aux]{\tl_num_elt_count_aux:n}
% Helper function for counting elements in a token list.
%    \begin{macrocode}
\cs_new:Npn \tl_elt_count_aux:n #1 { + 1 }
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tl_set_rescan:Nnn, \tl_gset_rescan:Nnn}
% \begin{macro}{\tl_set_rescan:Nno, \tl_gset_rescan:Nno}
% These functions store the \marg{\tlist} in \meta{\tlvar} after
% redefining catcodes, etc., in argument "#2".
% \begin{arguments}
% \item \meta{\tlvar}
% \item \marg{catcode setup, etc.}
% \item \marg{\tlist}
% \end{arguments}
%    \begin{macrocode}
\cs_new_protected:Npn \tl_set_rescan:Nnn  { \tl_set_rescan_aux:NNnn \tl_set:Nn  }
\cs_new_protected:Npn \tl_gset_rescan:Nnn { \tl_set_rescan_aux:NNnn \tl_gset:Nn }
\cs_generate_variant:Nn \tl_set_rescan:Nnn { Nno }
\cs_generate_variant:Nn \tl_gset_rescan:Nnn { Nno }
%    \end{macrocode}
%
% \begin{macro}[aux]{\tl_set_rescan_aux:NNnn}
% This macro uses a trick to extract an unexpanded token list after it's
% rescanned with "\etex_scantokens:D". This technique was first used (as far as I
% know) by Heiko Oberdiek in his \pkg{catchfile} package, albeit for real
% files rather than the `fake' "\scantokens" one.
%
% The basic problem arises because "\etex_scantokens:D" emulates a file read, which
% inserts an EOF marker into the expansion; the simplistic\\
% "\exp_args:NNo \cs_set:Npn \tmp:w { \etex_scantokens:D {some text} }"\\
% unfortunately doesn't work, calling the error:\\
% "! File ended while scanning definition of \tmp:w."\\
% (Lua\TeX\ works around this
% problem with its "\scantextokens" primitive.)
%
% Usually, we'd define "\etex_everyeof:D" to be "\exp_not:N" to gobble the EOF
% marker, but since we're not expanding the token list, it gets left in there
% and we have the same basic problem.
%
% Instead, we define "\etex_everyeof:D" to contain a marker that's impossible
% to occur within the scanned text; that is, the same char twice with
% different catcodes. (For some reason, we \emph{don't} need to insert
% a "\exp_not:N" token after it to prevent the EOF marker to expand. Anyone
% know why?)
%
% A helper function is can be used to save the token list delimited by the
% special marker, keeping the catcode redefinitions hidden away in a group.
%
% \begin{macro}[aux]{\c_two_ats_with_two_catcodes_tl}
% A tl with two "@" characters with two different catcodes.
% Used as a special marker for delimited text.
%    \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:
\tl_to_lowercase:n {
  \group_end:
  \tl_const:Nn \c_two_ats_with_two_catcodes_tl { A B }
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{arguments}
% \item "\tl_set" function
% \item \meta{\tlvar}
% \item \marg{catcode setup, etc.}
% \item \marg{\tlist}
% \end{arguments}
% Note that if you change "\etex_everyeof:D" in "#3"
% then you'd better do it correctly!
%    \begin{macrocode}
\cs_new_protected:Npn \tl_set_rescan_aux:NNnn #1#2#3#4 {
  \group_begin:
    \toks_set:NV \etex_everyeof:D \c_two_ats_with_two_catcodes_tl
    \tex_endlinechar:D = \c_minus_one
    #3
    \exp_after:wN \tl_rescan_aux:w \etex_scantokens:D {#4}
    \exp_args:NNNV
  \group_end:
  #1 #2 \l_tmpa_tl
}
%    \end{macrocode}
%
% \begin{macro}[aux]{\tl_rescan_aux:w}
%    \begin{macrocode}
\exp_after:wN \cs_set:Npn
\exp_after:wN \tl_rescan_aux:w
\exp_after:wN #
\exp_after:wN 1 \c_two_ats_with_two_catcodes_tl {
  \tl_set:Nn \l_tmpa_tl {#1}
}
%    \end{macrocode}
%
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tl_set_rescan:Nnx,\tl_gset_rescan:Nnx}
%   These functions store the full expansion of \marg{\tlist} in
%   \meta{\tlvar} after redefining catcodes, etc., in argument "#2".
% \begin{arguments}
% \item \meta{\tlvar}
% \item \marg{catcode setup, etc.}
% \item \marg{\tlist}
% \end{arguments}
% The expanded versions are much simpler because the "\etex_scantokens:D"
% can occur within the expansion.
%    \begin{macrocode}
\cs_new_protected:Npn \tl_set_rescan:Nnx #1#2#3 {
  \group_begin:
    \etex_everyeof:D { \exp_not:N }
    \tex_endlinechar:D = \c_minus_one
    #2
    \tl_set:Nx \l_kernel_tmpa_tl { \etex_scantokens:D {#3} }
    \exp_args:NNNV
  \group_end:
  \tl_set:Nn #1 \l_kernel_tmpa_tl
}
%    \end{macrocode}
% Globally is easier again:
%    \begin{macrocode}
\cs_new_protected:Npn \tl_gset_rescan:Nnx #1#2#3 {
  \group_begin:
    \etex_everyeof:D { \exp_not:N }
    \tex_endlinechar:D = \c_minus_one
    #2
    \tl_gset:Nx #1 { \etex_scantokens:D {#3} }
  \group_end:
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tl_rescan:nn}
% The inline wrapper for "\etex_scantokens:D".
% \begin{arguments}
% \item Catcode changes (etc.)
% \item Token list to re-tokenise
% \end{arguments}
%    \begin{macrocode}
\cs_new_protected:Npn \tl_rescan:nn #1#2 {
  \group_begin:
    \toks_set:NV \etex_everyeof:D \c_two_ats_with_two_catcodes_tl
    \tex_endlinechar:D = \c_minus_one
    #1
    \exp_after:wN \tl_rescan_aux:w \etex_scantokens:D {#2}
  \exp_args:NV \group_end: 
  \l_tmpa_tl
}
%    \end{macrocode}
% \end{macro}
%
% \subsection{Checking for and replacing tokens}
%
% \begin{macro}[TF]{\tl_if_in:Nn,\tl_if_in:cn}
%   See the replace functions for further comments. In this part we
%   don't care too much about brace stripping since we are not
%   interested in passing on the tokens which are split off in the
%   process.
%    \begin{macrocode}
\prg_new_protected_conditional:Npnn \tl_if_in:Nn #1#2 {TF,T,F} {
  \cs_set:Npn \tl_tmp:w ##1 #2 ##2 \q_stop {
    \quark_if_no_value:nTF {##2} {\prg_return_false:} {\prg_return_true:}
  }
  \exp_after:wN \tl_tmp:w #1 #2 \q_no_value \q_stop
}
\cs_generate_variant:Nn \tl_if_in:NnTF {c}
\cs_generate_variant:Nn \tl_if_in:NnT  {c}
\cs_generate_variant:Nn \tl_if_in:NnF  {c}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}[TF]{\tl_if_in:nn,\tl_if_in:Vn,\tl_if_in:on}
%    \begin{macrocode}
\prg_new_protected_conditional:Npnn \tl_if_in:nn #1#2 {TF,T,F} {
  \cs_set:Npn \tl_tmp:w ##1 #2 ##2 \q_stop {
    \quark_if_no_value:nTF {##2} {\prg_return_false:} {\prg_return_true:}
  }
  \tl_tmp:w #1 #2 \q_no_value \q_stop
}
\cs_generate_variant:Nn \tl_if_in:nnTF {V}
\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 {o}
\cs_generate_variant:Nn \tl_if_in:nnT  {o}
\cs_generate_variant:Nn \tl_if_in:nnF  {o}
%    \end{macrocode}
% \end{macro}
%
%\begin{macro}{\_l_tl_replace_tl}
%\begin{macro}{\tl_replace_in:Nnn}
%\begin{macro}{\tl_replace_in:cnn}
%\begin{macro}{\tl_greplace_in:Nnn}
%\begin{macro}{\tl_greplace_in:cnn}
%\begin{macro}[aux]{\_tl_replace_in_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}.
%    \begin{macrocode}
\tl_new:N \_l_tl_replace_tl
\cs_new_protected_nopar:Npn \tl_replace_in:Nnn {
  \_tl_replace_in_aux:NNnn \tl_set_eq:NN
}
\cs_new_protected:Npn \_tl_replace_in_aux:NNnn #1#2#3#4 {
  \cs_set_protected:Npn \_tl_tmp:w ##1 #3 ##2 \q_stop
    {
      \quark_if_no_value:nF {##2}
        { 
          \tl_set:No \_l_tl_replace_tl { ##1 #4 }
          \cs_set_protected:Npn \_tl_tmp:w ####1 \q_nil #3 \q_no_value
            { \tl_put_right:No \_l_tl_replace_tl {####1} }
          \_tl_tmp:w \prg_do_nothing: ##2
          #1 #2 \_l_tl_replace_tl
        }
    }
  \use:n
    { 
      \exp_after:wN \_tl_tmp:w \exp_after:wN
        \prg_do_nothing: 
    }
  #2 \q_nil #3 \q_no_value \q_stop
}
\cs_new_protected_nopar:Npn \tl_greplace_in:Nnn {
  \_tl_replace_in_aux:NNnn \tl_gset_eq:NN
}
\cs_generate_variant:Nn \tl_replace_in:Nnn  { c }
\cs_generate_variant:Nn \tl_greplace_in:Nnn { c }
%    \end{macrocode}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%
%\begin{macro}{\tl_replace_all_in:Nnn}
%\begin{macro}{\tl_replace_all_in:Nnn}
%\begin{macro}{\tl_greplace_all_in:cnn}
%\begin{macro}{\tl_greplace_all_in:cnn}
%\begin{macro}[aux]{\_tl_replace_all_in_aux:NNnn}
% A similar approach here but with a loop built in.
%    \begin{macrocode}
\cs_new_protected_nopar:Npn \tl_replace_all_in:Nnn {
  \_tl_replace_all_in_aux:NNnn \tl_set_eq:NN
}
\cs_new_protected_nopar:Npn \tl_greplace_all_in:Nnn {
  \_tl_replace_all_in_aux:NNnn \tl_gset_eq:NN
}
\cs_new_protected:Npn \_tl_replace_all_in_aux:NNnn #1#2#3#4 {
  \tl_clear:N \_l_tl_replace_tl
  \cs_set_protected:Npn \_tl_tmp:w ##1 #3 ##2 \q_stop
    {
      \quark_if_no_value:nTF {##2}
        {
          \cs_set_protected:Npn \_tl_tmp:w ####1 \q_nil ####2 \q_stop
            { \tl_put_right:No \_l_tl_replace_tl {####1} }
          \_tl_tmp:w ##1 \q_stop
        }
        { 
          \tl_put_right:No \_l_tl_replace_tl { ##1 #4 }
          \_tl_tmp:w \prg_do_nothing: ##2 \q_stop
        }
    }
  \use:n
    { 
      \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_in:Nnn  { c }
\cs_generate_variant:Nn \tl_greplace_all_in:Nnn { c }
%    \end{macrocode}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%\end{macro}
%
%
%
% \begin{macro}{\tl_remove_in:Nn}
% \begin{macro}{\tl_remove_in:cn}
% \begin{macro}{\tl_gremove_in:Nn}
% \begin{macro}{\tl_gremove_in:cn}
%   Next comes a series of removal functions. I have just implemented
%   them as subcases of the replace functions for now (I'm lazy).
%    \begin{macrocode}
\cs_new_protected:Npn \tl_remove_in:Nn  #1#2{\tl_replace_in:Nnn #1{#2}{}}
\cs_new_protected:Npn \tl_gremove_in:Nn #1#2{\tl_greplace_in:Nnn #1{#2}{}}
\cs_generate_variant:Nn \tl_remove_in:Nn {cn}
\cs_generate_variant:Nn \tl_gremove_in:Nn {cn}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\tl_remove_all_in:Nn}
% \begin{macro}{\tl_remove_all_in:cn}
% \begin{macro}{\tl_gremove_all_in:Nn}
% \begin{macro}{\tl_gremove_all_in:cn}
%   Same old, same old.
%    \begin{macrocode}
\cs_new_protected:Npn \tl_remove_all_in:Nn #1#2{
  \tl_replace_all_in:Nnn #1{#2}{}
}
\cs_new_protected:Npn \tl_gremove_all_in:Nn #1#2{
  \tl_greplace_all_in:Nnn #1{#2}{}
}
\cs_generate_variant:Nn \tl_remove_all_in:Nn {cn}
\cs_generate_variant:Nn \tl_gremove_all_in:Nn {cn}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
%  \subsection{Heads or tails?}
%
%  \begin{macro}{\tl_head:n}
%  \begin{macro}{\tl_head:V}
%  \begin{macro}{\tl_head:v}
%  \begin{macro}{\tl_head_i:n}
%  \begin{macro}{\tl_tail:n}
%  \begin{macro}{\tl_tail:V}
%  \begin{macro}{\tl_tail:v}
%  \begin{macro}{\tl_tail:f}
%  \begin{macro}{\tl_head_iii:n}
%  \begin{macro}{\tl_head_iii:f}
%  \begin{macro}{\tl_head:w}
%  \begin{macro}{\tl_head_i:w}
%  \begin{macro}{\tl_tail:w}
%  \begin{macro}{\tl_head_iii:w}
%  These functions pick up either the head or the tail of a list.
%  "\tl_head_iii:n" returns the first three items on a list.
%    \begin{macrocode}
\cs_new:Npn \tl_head:n #1{\tl_head:w #1\q_stop}
\cs_new_eq:NN \tl_head_i:n \tl_head:n
\cs_new:Npn \tl_tail:n #1{\tl_tail:w #1\q_stop}
\cs_generate_variant:Nn \tl_tail:n {f}
\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:w #1#2\q_stop{#1}
\cs_new_eq:NN \tl_head_i:w \tl_head:w
\cs_new:Npn \tl_tail:w #1#2\q_stop{#2}
\cs_new:Npn \tl_head_iii:w #1#2#3#4\q_stop{#1#2#3}
\cs_generate_variant:Nn \tl_head:n { V }
\cs_generate_variant:Nn \tl_head:n { v }
\cs_generate_variant:Nn \tl_tail:n { V }
\cs_generate_variant:Nn \tl_tail:n { v }
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\tl_if_head_eq_meaning_p:nN}
%  \begin{macro}[TF]{\tl_if_head_eq_meaning:nN}
%  \begin{macro}{\tl_if_head_eq_charcode_p:nN}
%  \begin{macro}{\tl_if_head_eq_charcode_p:fN}
%  \begin{macro}[TF]{\tl_if_head_eq_charcode:nN}
%  \begin{macro}[TF]{\tl_if_head_eq_charcode:fN}
%  \begin{macro}{\tl_if_head_eq_catcode_p:nN}
%  \begin{macro}[TF]{\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.
%  |\tl_if_head_meaning_eq:nNTF| uses |\if_meaning:w| and will
%  consider the tokens |b|$\sb{11}$ and |b|$\sb{12}$ different.
%  |\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,TF,T,F} {
  \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,TF,T,F} {
  \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:
}
%    \end{macrocode}
% Actually the default is already an |f| type expansion.
%    \begin{macrocode}
%% \cs_new:Npn \tl_if_head_eq_charcode_p:fN #1#2{
%%    \exp_after:wN\if_charcode:w \tl_head:w #1\q_stop\exp_not:N#2
%%     \c_true_bool
%%   \else:
%%     \c_false_bool
%%   \fi:
%% }
%% \def_long_test_function_new:npn {tl_if_head_eq_charcode:fN}#1#2{
%%   \if_predicate:w \tl_if_head_eq_charcode_p:fN {#1}#2}
%    \end{macrocode}
% These ":fN" variants are broken; temporary patch:
%    \begin{macrocode}
\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,TF,T,F} {
  \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}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  
%\begin{macro}{\_tl_check_exists:N}
% When used as a package, there is an option to be picky and to
% check definitions exist. The message text for this is created later,
% as the mechanism is not yet in place.
%    \begin{macrocode}
%<*package>    
\tex_ifodd:D \@l@expl@check@declarations@bool \scan_stop:
  \cs_set_protected:Npn \_tl_check_exists:N #1 
    { 
      \cs_if_exist:NF #1 
        { 
          \msg_kernel_error:nnx { check } { non-declared-variable }
            { \token_to_str:N #1 }
        } 
    }
  \cs_set_protected:Npn \tl_set:Nn #1#2 
    {
      \_tl_check_exists:N #1
      \cs_set_nopar:Npx #1 { \exp_not:n {#2} }
    }
  \cs_set_protected:Npn \tl_set:Nx #1#2 
    {
      \_tl_check_exists:N #1
      \cs_set_nopar:Npx #1 {#2}
    }
  \cs_set_protected:Npn \tl_gset:Nn #1#2 
    {
      \_tl_check_exists:N #1
      \cs_gset_nopar:Npx #1 { \exp_not:n {#2} }
    }
  \cs_set_protected:Npn \tl_gset:Nx #1#2 
    {
      \_tl_check_exists:N #1
      \cs_gset_nopar:Npx #1 {#2}
    }
  \cs_set_protected:Npn \tl_set_eq:NN #1#2
    {
      \_tl_check_exists:N #1
      \_tl_check_exists:N #2
      \cs_set_eq:NN #1 #2
    }
  \cs_set_protected:Npn \tl_gset_eq:NN #1#2
    {
      \_tl_check_exists:N #1
      \_tl_check_exists:N #2
      \cs_gset_eq:NN #1 #2
    }
  \cs_set_protected:Npn \tl_put_right:Nn #1#2 {
    \_tl_check_exists:N #1
    \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:n {#2} }
  }
  \cs_set_protected:Npn \tl_put_right:NV #1#2 {
    \_tl_check_exists:N #1
    \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:V #2 }
  }
  \cs_set_protected:Npn \tl_put_right:Nv #1#2 {
    \_tl_check_exists:N #1
    \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:v {#2} }
  }
  \cs_set_protected:Npn \tl_put_right:No #1#2 {
    \_tl_check_exists:N #1
    \cs_set_nopar:Npx #1 { \exp_not:o #1 \exp_not:o {#2} }
  }
  \cs_set_protected:Npn \tl_put_right:Nx #1#2 {
    \_tl_check_exists:N #1
    \cs_set_nopar:Npx #1 { \exp_not:o #1 #2 }
  }
  \cs_set_protected:Npn \tl_gput_right:Nn #1#2 {
    \_tl_check_exists:N #1
    \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:n {#2} }
  }
  \cs_set_protected:Npn \tl_gput_right:NV #1#2 {
    \_tl_check_exists:N #1
    \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:V #2 }
  }
  \cs_set_protected:Npn \tl_gput_right:Nv #1#2 {
    \_tl_check_exists:N #1
    \cs_gset_nopar:Npx #1 { \exp_not:o #1 \exp_not:v {#2} }
  }
  \cs_set_protected:Npn \tl_gput_right:Nx #1#2 {
    \_tl_check_exists:N #1
    \cs_gset_nopar:Npx #1 { \exp_not:o #1 #2 }
  }
  \cs_set_protected:Npn \tl_put_left:Nn #1#2 {
    \_tl_check_exists:N #1
    \cs_set_nopar:Npx #1 { \exp_not:n {#2} \exp_not:o #1 }
  }
  \cs_set_protected:Npn \tl_put_left:NV #1#2 {
    \_tl_check_exists:N #1
    \cs_set_nopar:Npx #1 { \exp_not:V #2 \exp_not:o #1 }
  }
  \cs_set_protected:Npn \tl_put_left:Nv #1#2 {
    \_tl_check_exists:N #1
    \cs_set_nopar:Npx #1 { \exp_not:v {#2} \exp_not:o #1 }
  }
  \cs_set_protected:Npn \tl_put_left:No #1#2 {
    \_tl_check_exists:N #1
    \cs_set_nopar:Npx #1 { \exp_not:o {#2} \exp_not:o #1 }
  }
  \cs_set_protected:Npn \tl_put_left:Nx #1#2 {
    \_tl_check_exists:N #1
    \cs_set_nopar:Npx #1 { #2 \exp_not:o #1 }
  }
  \cs_set_protected:Npn \tl_gput_left:Nn #1#2 {
    \_tl_check_exists:N #1
    \cs_gset_nopar:Npx #1 { \exp_not:n {#2} \exp_not:o #1 }
  }
  \cs_set_protected:Npn \tl_gput_left:NV #1#2 {
    \_tl_check_exists:N #1
    \cs_gset_nopar:Npx #1 { \exp_not:V #2 \exp_not:o #1 }
  }
  \cs_set_protected:Npn \tl_gput_left:Nv #1#2 {
    \_tl_check_exists:N #1
    \cs_gset_nopar:Npx #1 { \exp_not:v {#2} \exp_not:o #1 }
  }
  \cs_set_protected:Npn \tl_gput_left:Nx #1#2 {
    \_tl_check_exists:N #1
    \cs_gset_nopar:Npx #1 { #2 \exp_not:o #1 }
  }
\tex_fi:D
%</package>
%    \end{macrocode}
%\end{macro}
%
%    Show token usage:
%    \begin{macrocode}
%<*showmemory>
\showMemUsage
%</showmemory>
%    \end{macrocode}
%
% \end{implementation}
% \PrintIndex
%
% \endinput
