% \iffalse
%% File: l3tlp.dtx Copyright (C) 1990-2008 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/cgi-bin/cvsweb.cgi/
%%
%% 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: l3tlp.dtx 740 2008-08-01 13:25:38Z morten $
          {L3 Experimental Token List Pointers}
%\iffalse
%<*driver>
%\fi
\ProvidesFile{\filename.\filenameext}
  [\filedate\space v\fileversion\space\filedescription]
%\iffalse
\documentclass{l3doc}
\begin{document}
\DocInput{\filename.\filenameext}
\end{document}
%</driver>
% \fi
%
%
% \title{The \textsf{l3tlp} package\thanks{This file
%         has version number \fileversion, last
%         revised \filedate.}\\
% Token List Pointers}
% \author{\Team}
% \date{\filedate}
% \maketitle
%
%
%
% \section {Token list pointers}
%
% \LaTeX3 stores token lists in so called `token list pointers'.
% Variables of this type get the suffix "tlp" and functions of this type
% have the prefix "tlp". To use a  token list pointer you simply call
% the corresponding variable.
%
% Often you find yourself with not a token list pointer but an
% arbitrary token list which has to undergo certain tests. We will
% prefix these functions with "tlist". While token list pointers are
% always single tokens, token lists are always surrounded by
% braces. Perhaps these token lists should have their own module but
% for now I decided to put them here because there is quite a bit of
% overlap with token list pointers.
%
% \subsection{Functions}
%
% \begin{function}{\tlp_new:N  |
%                  \tlp_new:c  |
%                  \tlp_new:Nn |
%                  \tlp_new:cn |
%                  \tlp_new:Nx }
% \begin{syntax}
%    "\tlp_new:Nn" <tlp> "{" <initial token list> "}"
% \end{syntax}
% Defines <tlp> to be a new variable (or constant) of type token list
% pointer. <initial token list> is the initial value of <tlp>. This
% makes it possible to assign values to a constant token list pointer.
%
% The form "\tlp_new:N" initializes the token list pointer with an empty value.
% \end{function}
%
% \begin{function}{%
%                  \tlp_use:N |
%                  \tlp_use:c
% }
% \begin{syntax}
%   "\tlp_use:N" <tlp>
% \end{syntax}
% Function that inserts the <tlp> into the processing stream. Instead of
% |\tlp_use:N| simply placing the <tlp> into the input stream is also
% supported.|\tlp_use:c| will complain is the <tlp> hasn't been declared
% previously!
% \end{function}
%
% \begin{function}{%
%                  \tlp_set:Nn |
%                  \tlp_set:Nc |
%                  \tlp_set:No |
%                  \tlp_set:Nd |
%                  \tlp_set:Nf |
%                  \tlp_set:Nx |
%                  \tlp_gset:Nn |
%                  \tlp_gset:Nc |
%                  \tlp_gset:No |
%                  \tlp_gset:Nd |
%                  \tlp_gset:Nx |
%                  \tlp_gset:cn |
%                  \tlp_gset:cx }
% \begin{syntax}
%   "\tlp_set:Nn" <tlp> "{" <token list> "}"
% \end{syntax}
% Defines <tlp> to hold the token list <token list>. Global
% variants of this command assign the value globally the other variants
% expand the <token list> up to a certain level before the assignment
% or interpret the <token list> as a character list and form a control
% sequence out of it.
% \end{function}
%
% \begin{function}{%
%                  \tlp_clear:N |
%                  \tlp_clear:c |
%                  \tlp_gclear:N |
%                  \tlp_gclear:c
% }
% \begin{syntax}
%   "\tlp_clear:N" <tlp>
% \end{syntax}
% The <tlp> is locally or globally cleared. The "c" variants will
% generate a control sequence name which is then interpreted as
% <tlp> before clearing.
% \end{function}
%
% \begin{function}{%
%                  \tlp_clear_new:N |
%                  \tlp_clear_new:c |
%                  \tlp_gclear_new:N |
%                  \tlp_gclear_new:c |
% }
% \begin{syntax}
%   "\tlp_clear_new:N" <tlp>
% \end{syntax}
% These functions check if <tlp> exists. If it does it will be cleared;
% if it doesn't it will be allocated.
% \end{function}
%
% \begin{function}{%
%                  \tlp_put_left:Nn |
%                  \tlp_put_left:No |
%                  \tlp_put_left:Nx |
%                  \tlp_gput_left:Nn |
%                  \tlp_gput_left:No |
%                  \tlp_gput_left:Nx |
%                  \tlp_put_right:Nn |
%                  \tlp_put_right:No |
%                  \tlp_put_right:Nx |
%                  \tlp_put_right:cc |
%                  \tlp_gput_right:Nn |
%                  \tlp_gput_right:No|
%                  \tlp_gput_right:Nx|
%                  \tlp_gput_right:cn|
%                  \tlp_gput_right:co|
% }
% \begin{syntax}
%   "\tlp_put_left:Nn" <tlp> "{" <token list> "}"
% \end{syntax}
% These functions will append <token list> to the left or right of
% <tlp>. Assignment is done either locally or globally and <token
% list> might be subject to expansion before assignment.
% \end{function}
%
% A word of warning is appropriate here: Token list pointers 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}
% \tlp_set:Nn \l_tmpa_tlp{##1}
% \tlp_put_right:Nn \l_tmpa_tlp{##2}
% \tlp_set:No \l_tmpb_tlp{\l_tmpa_tlp ##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}{%
%                  \tlp_set_eq:NN |
%                  \tlp_set_eq:Nc |
%                  \tlp_set_eq:cN |
%                  \tlp_set_eq:cc |
%                  \tlp_gset_eq:NN |
%                  \tlp_gset_eq:Nc |
%                  \tlp_gset_eq:cN |
%                  \tlp_gset_eq:cc |
% }
% \begin{syntax}
%    "\tlp_set_eq:NN" <tlp1> <tlp2>
% \end{syntax}
% Fast form for
% \begin{syntax}
%    "\tlp_set:No" <tlp1> "{" <tlp2> "}"
% \end{syntax}
% when <tlp2> is known to be a variable of type token list pointer.
% \end{function}
%
% \begin{function}{\tlp_to_str:N |
%                  \tlp_to_str:c
% }
% \begin{syntax}
%   "\tlp_to_str:N" <tlp>
% \end{syntax}
% This function returns the token list kept in <tlp> as a string list
% with all characters catcoded to `other'.
% \end{function}
%
% \subsection{Predicates and conditionals}
%
% \begin{function}{\tlp_if_empty_p:N|
%                  \tlp_if_empty_p:c
%                  }
% \begin{syntax}
%   "\tlp_if_empty_p:N" <tlp>
% \end{syntax}
% This predicate returns `true' if <tlp> is `empty' i.e., doesn't
% contain any tokens.
% \end{function}
%
% \begin{function}{\tlp_if_empty:NTF|
%                  \tlp_if_empty:NT|
%                  \tlp_if_empty:NF|
%                  \tlp_if_empty:cTF |
%                  \tlp_if_empty:cT  |
%                  \tlp_if_empty:cF
% }
% \begin{syntax}
%   "\tlp_if_empty:NTF" <tlp> "{"<true code>"}""{"<false code>"}"
% \end{syntax}
% Execute <true code> if <tlp> is empty and <false code> if it
% contains any tokens.
% \end{function}
%
% \begin{function}{\tlp_if_eq_p:NN |
%                  \tlp_if_eq_p:cN |
%                  \tlp_if_eq_p:Nc |
%                  \tlp_if_eq_p:cc |
%                  }
% \begin{syntax}
%   "\tlp_if_eq_p:NN" <tlp1> <tlp2> 
% \end{syntax}
% Predicate function which returns `true' if the two token list
% pointers are identical and `false' otherwise.
% \end{function}
%
% \begin{function}{
%                  \tlp_if_eq:NNTF |
%                  \tlp_if_eq:NNT |
%                  \tlp_if_eq:NNF |
%                  \tlp_if_eq:cNTF |
%                  \tlp_if_eq:cNT |
%                  \tlp_if_eq:cNF |
%                  \tlp_if_eq:NcTF |
%                  \tlp_if_eq:NcT |
%                  \tlp_if_eq:NcF |
%                  \tlp_if_eq:ccTF |
%                  \tlp_if_eq:ccT |
%                  \tlp_if_eq:ccF |
%  }
%  \begin{syntax}
%   "\tlp_if_eq:NNTF" <tlp1> <tlp2> "{"<true code>"}""{"<false code>"}"
% \end{syntax}
% Execute <true code> if <tlp1> holds the same token list as <tlp2>
% and <false code> otherwise.
% \end{function}
%
%
% \subsection{Token lists}
%
% \begin{function}{\tlist_if_eq:nnTF |
%                  \tlist_if_eq:nnT |
%                  \tlist_if_eq:nnF |
%                  \tlist_if_eq:noTF |
%                  \tlist_if_eq:noT |
%                  \tlist_if_eq:noF |
%                }
% \begin{syntax}
%   "\tlist_if_eq:nnTF" "{"<tlist1>"}" "{"<tlist2>"}" "{"<true
%     code>"}" "{"<false code>"}"
% \end{syntax}
% Execute <true code> if the two token lists <tlist1> and <tlist2> are
% identical.
% \end{function}
%
%
% \begin{function}{\tlist_if_empty_p:n |
%                  \tlist_if_empty_p:o |
%                  \tlist_if_empty:nTF |
%                  \tlist_if_empty:nT |
%                  \tlist_if_empty:nF |
%                  \tlist_if_empty:oTF |
%                  \tlist_if_empty:oT |
%                  \tlist_if_empty:oF |
%                  }
% \begin{syntax}
%   "\tlist_if_empty:nTF" "{"<tlist>"}" "{"<true code>"}" "{"<false code>"}"
% \end{syntax}
% Execute <true code> if <tlist> doesn't contain any tokens and <false
% code> otherwise.
% \end{function}
%
% \begin{function}{\tlist_if_blank_p:n |
%                  \tlist_if_blank:nTF |
%                  \tlist_if_blank:nT |
%                  \tlist_if_blank:nF |
%                  \tlist_if_blank_p:o |
%                  \tlist_if_blank:oTF |
%                  \tlist_if_blank:oT |
%                  \tlist_if_blank:oF |
%                  }
% \begin{syntax}
%   "\tlist_if_blank:nTF" "{"<tlist>"}" "{"<true code>"}" "{"<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}{\tlist_to_lowercase:n |
%                  \tlist_to_uppercase:n 
%                  }
% \begin{syntax}
%   "\tlist_to_lowercase:n" "{"<tlist>"}"
% \end{syntax}
% "\tlist_to_lowercase:n" converts all tokens in <tlist> to their
% lower case representation. Similar for "\tlist_to_uppercase:n".
% \begin{texnote}
%   These are the \TeX\ primitives \tn{lowercase} and \tn{uppercase}
%   renamed.
% \end{texnote}
% \end{function}
%
% \begin{function}{\tlist_to_str:n 
%                  }
% \begin{syntax}
%   "\tlist_to_str:n" "{"<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}{%
%                   \tlist_map_function:nN |
%                   \tlp_map_function:NN |
%                   \tlp_map_function:cN |
%  }
%  \begin{syntax}
%     "\tlist_map_function:nN" "{"<tlist>"}" <function> \\
%     "\tlp_map_function:NN" <tlp> <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}{%
%                   \tlist_map_inline:nn |
%                   \tlp_map_inline:Nn |
%                   \tlp_map_inline:cn |
%  }
%  \begin{syntax}
%     "\tlist_map_inline:nn" "{"<tlist>"}" "{"<inline~function>"}" \\
%     "\tlp_map_inline:Nn" <tlp> "{"<inline~function>"}"
%  \end{syntax}
%  Allows a syntax like "\tlist_map_inline:nn" "{"<tlist>"}"
%  "{\token_to_string:N ##1}". This renders it non-expandable though.
%  Remember to double the "#"s for each level.
%  \end{function}
%
%
%  \begin{function}{%
%                   \tlist_map_variable:nNn |
%                   \tlp_map_variable:NNn |
%                   \tlp_map_variable:cNn |
%  }
%  \begin{syntax}
%     "\tlist_map_variable:nNn" "{"<tlist>"}" <temp> "{"<action>"}" \\
%     "\tlp_map_variable:NNn" <tlp> <temp> "{"<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}{%
%                   \tlist_map_break:w |
%                   \tlp_map_break:w |
%  }
%  \begin{syntax}
%     "\tlist_map_break:w"
%  \end{syntax}
%  For breaking out of a loop. You should take note of the ":w" as
%  its usage must be precise!
%  \end{function}
%
%
%  \begin{function}{%
%                   \tlist_reverse:n |
%  }
%  \begin{syntax}
%     "\tlist_reverse:n" "{"<token$\sb1$><token$\sb2$>...<token$\sb n$>"}"
%  \end{syntax}
%  Reverse the token list to result in
%  <token$\sb n$>\dots<token$\sb2$><token$\sb1$>. Note that spaces in this
%  token list are gobbled in the process.
%  \end{function}
%
%  \begin{function}{%
%                   \tlist_elt_count:n |
%                   \tlp_elt_count:N |
%  }
%  \begin{syntax}
%     "\tlist_elt_count:n" "{"<token list>"}" \\
%     "\tlp_elt_count:N"   <tlp>
%  \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}
%
%
% \subsubsection{Internal functions}
%
%
%  \begin{function}{%
%                   \tlist_map_function_aux:Nn |
%                   \tlist_map_inline_aux:Nn |
%                   \tlist_map_variable_aux:Nnn |
%  }
%  \begin{syntax}\end{syntax}
%  Internal helper functions for the <tlist> loops.
%  \end{function}
%
%
%
% \begin{function}{\tlist_if_blank_p_aux:w 
%                  }
% \end{function}
%
%
%
% \subsection{Variables and constants}
%
% \begin{variable}{\C_job_name_tlp}
% 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 will be set by \TeX{} and can not be overwritten by the package.
% Therefore the "C"
% \end{texnote}
% \end{variable}
%
% \begin{variable}{\c_empty_tlp}
% 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_relax_tlp}
% Constant holding the token that is assigned to a newly created control
% sequence by \TeX.
% \end{variable}
%
% \begin{variable}{%
%                  \l_tmpa_tlp |
%                  \l_tmpb_tlp |
%                  \g_tmpa_tlp |
%                  \g_tmpb_tlp
% }
% Scratch register for immediate use. They are not used by conditionals
% or predicate functions.
% \end{variable}
%
%
% \subsubsection{Internal functions}
%
% \begin{variable}{%
%                  \l_replace_tlp |
% }
% Internal register used in the replace functions.
% \end{variable}
%
% \begin{variable}{%
%                  \l_testa_tlp |
%                  \l_testb_tlp |
%                  \g_testa_tlp |
%                  \g_testb_tlp |
% }
% Registers used for conditional processing if the engine doesn't
% support arbitrary string comparison.
% \end{variable}
%
%
% \begin{function}{\tlp_to_str_aux:w}
% Function used to implement "\tlp_to_str:N".
% \end{function}
%
%
% \subsection{Search and replace}
%
%
% \begin{function}{
%                  \tlp_if_in:NnTF |
%                  \tlp_if_in:cnTF |
%                  \tlp_if_in:NnT |
%                  \tlp_if_in:cnT |
%                  \tlp_if_in:NnF |
%                  \tlp_if_in:cnF |
%                  \tlist_if_in:nnTF |
%                  \tlist_if_in:onTF |
%                  }
% \begin{syntax}
%   "\tlp_if_in:NnTF" <tlp> "{" <item> "}{" <true code> "}{"
%     <false code> "}"
% \end{syntax}
% Function that tests if <item> is in <tlp>. Depending on the result
% either <true code> or <false code> is executed. Note that <item>
% cannot contain brace groups.
% \end{function}
%
% \begin{function}{
%                  \tlp_replace_in:Nnn |
%                  \tlp_replace_in:cnn |
%                  \tlp_greplace_in:Nnn |
%                  \tlp_greplace_in:cnn |
%                  }
% \begin{syntax}
%   "\tlp_replace_in:Nnn" <tlp> "{" <item1> "}{" <item2> "}"
% \end{syntax}
% Replaces the leftmost occurrence of <item1> in <tlp> with
% <item2> if present, otherwise the <tlp> is left untouched.
% \end{function}
%
% \begin{function}{
%                  \tlp_replace_all_in:Nnn |
%                  \tlp_replace_all_in:cnn |
%                  \tlp_greplace_all_in:Nnn |
%                  \tlp_greplace_all_in:cnn |
%                  }
% \begin{syntax}
%   "\tlp_replace_all_in:Nnn" <tlp> "{" <item1> "}{" <item2> "}"
% \end{syntax}
% Replaces \emph{all} occurrences of <item1> in <tlp> with
% <item2>.
% \end{function}
%
%
% \begin{function}{
%                  \tlp_remove_in:Nn |
%                  \tlp_remove_in:cn |
%                  \tlp_gremove_in:Nn |
%                  \tlp_gremove_in:cn |
%                  }
% \begin{syntax}
%   "\tlp_remove_in:Nn" <tlp> "{" <item> "}"
% \end{syntax}
% Removes the leftmost occurrence of <item> from <tlp> if present.
% \end{function}
%
%
% \begin{function}{
%                  \tlp_remove_all_in:Nn |
%                  \tlp_remove_all_in:cn |
%                  \tlp_gremove_all_in:Nn |
%                  \tlp_gremove_all_in:cn |
%                  }
% \begin{syntax}
%   "\tlp_remove_all_in:Nn" <tlp> "{" <item> "}"
% \end{syntax}
% Removes \emph{all} occurrences of <item> from <tlp>.
% \end{function}
%
%
% \subsection{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}{%
%                  \tlist_head:n |
%                  \tlist_tail:n |
%                  \tlist_head_iii:n |
%                  \tlist_head_iii:f |
%                  \tlist_head:w |
%                  \tlist_tail:w |
%                  \tlist_head_iii:w
% }
% \begin{syntax}
%   "\tlist_head:n"  "{" <token1><token2>...<token-n> "}" \\
%   "\tlist_tail:n"  "{" <token1><token2>...<token-n> "}"
% \end{syntax}
% These functions return either the head or the tail of a list, thus in
% the above example "\tlist_head:n" would return <token1> and "\tlist_tail:n"
% would return <token2>\dots<token-n>. "\tlist_head_iii:n" returns the first
% three tokens. The ":w" versions require some care as they use a
% delimited argument internally.
% \begin{texnote}
% These are the Lisp functions "car" and "cdr" but with \LaTeX3 names.
% \end{texnote}
% \end{function}
%
%
%
%
% \begin{function}{%
%                  \tlist_if_head_eq_meaning_p:nN |
%                  \tlist_if_head_eq_meaning:nNTF |
%                  \tlist_if_head_eq_meaning:nNTF |
%                  \tlist_if_head_eq_meaning:nNTF |
% }
% \begin{syntax}
%   "\tlist_if_head_eq_meaning:nNTF" "{" <token list> "}" <token>
%   "{"<true>"}""{"<false>"}"
% \end{syntax}
% Returns <true> if the first token in <token list> is equal to
% <token> and <false> otherwise. The |meaning| version compares the
% two tokens with |\if_meaning:NN|.
% \end{function}
%
% \begin{function}{%
%                  \tlist_if_head_eq_charcode_p:nN |
%                  \tlist_if_head_eq_charcode:nNTF |
%                  \tlist_if_head_eq_charcode:nNTF |
%                  \tlist_if_head_eq_charcode:nNTF |
% }
% \begin{syntax}
%   "\tlist_if_head_eq_charcode:nNTF" "{" <token list> "}" <token>
%   "{"<true>"}""{"<false>"}"
% \end{syntax}
% Returns <true> if the first token in <token list> 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 |\tlist_if_head_eq_charcode:fNTF| or similar).
% \end{function}
%
% \begin{function}{%
%                  \tlist_if_head_eq_catcode_p:nN |
%                  \tlist_if_head_eq_catcode:nNTF |
%                  \tlist_if_head_eq_catcode:nNTF |
%                  \tlist_if_head_eq_catcode:nNTF |
% }
% \begin{syntax}
%   "\tlist_if_head_eq_catcode:nNTF" "{" <token list> "}" <token>
%   "{"<true>"}""{"<false>"}"
% \end{syntax}
% Returns <true> if the first token in <token list> 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}
%
%
% \StopEventually{}
%
%    \subsection{The Implementation}
%
%    We start by ensuring that the required packages are loaded.
%    \begin{macrocode}
%<package>\ProvidesExplPackage
%<package>  {\filename}{\filedate}{\fileversion}{\filedescription}
%<package&!check>\RequirePackage{l3basics}
%<package&check>\RequirePackage{l3chk}
%    \end{macrocode}
%    \begin{macrocode}
%<*initex|package>
%    \end{macrocode}
%
% A token list pointer is a control sequence that holds tokens.  The
% interface is similar to that for token registers, but beware that
% the behavior vis \'a vis |\def:Npx| etc. \ldots{} is different.  (You
% see this comes from Denys' implementation.)
%
%
%
% \begin{macro}{\tlp_new:N}
% \begin{macro}{\tlp_new:c}
% \begin{macro}{\tlp_new:Nn}
% \begin{macro}{\tlp_new:cn}
% \begin{macro}{\tlp_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}
\def_long_new:Npn \tlp_new:Nn #1#2{
  \chk_new_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}
  \gdef:Npn #1{#2}
}
\def_new:Npn \tlp_new:cn {\exp_args:Nc \tlp_new:Nn }
\def_long_new:Npn \tlp_new:Nx #1#2{
  \chk_new_cs:N #1
%<check> \chk_var_or_const:N #1
  \gdef:Npx #1{#2}
}
\def_new:Npn \tlp_new:N #1{\tlp_new:Nn #1{}}
\def_new:Npn \tlp_new:c #1{\tlp_new:cn {#1}{}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\tlp_use:N}
% \begin{macro}{\tlp_use:c}
% Perhaps this should just be enabled when checking?
%    \begin{macrocode}
\def_new:Npn \tlp_use:N #1 {
  \if_meaning:NN #1 \scan_stop:
%    \end{macrocode}
%  If \m{tlp} equals |\scan_stop:| it is probably stemming from a
%  |\cs:w ... \cd_end:| that was created by mistake somewhere.
%    \begin{macrocode}
     \err_latex_bug:x {Token~list~pointer~ `\token_to_string:N #1'~
                       has~ an~ erroneous~ structure!}
  \else:
    \exp_after:NN #1
  \fi:
}
\def_new:Npn \tlp_use:c {\exp_args:Nc \tlp_use:N}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\tlp_set:Nn}
% \begin{macro}{\tlp_set:No}
% \begin{macro}{\tlp_set:Nd}
% \begin{macro}{\tlp_set:Nf}
% \begin{macro}{\tlp_set:Nx}
% \begin{macro}{\tlp_set:cn}
% \begin{macro}{\tlp_set:co}
% \begin{macro}{\tlp_set:cx}
% \begin{macro}{\tlp_gset:Nn}
% \begin{macro}{\tlp_gset:No}
% \begin{macro}{\tlp_gset:Nd}
% \begin{macro}{\tlp_gset:Nx}
% \begin{macro}{\tlp_gset:cn}
% \begin{macro}{\tlp_gset:cx}
%    To set token lists to a specific value to type of functions are
%    available: |\tlp_set_eq:NN| takes two token-lists as its
%    arguments assign the first the contents of the second;
%    |\tlp_set:Nn| has as its second argument a `real' list of tokens.
%    One can view |\tlp_set_eq:NN| as a special form of |\tlp_set:No|.
%    Both functions have global counterparts.
%
%    During development we check if the token list that is being
%    assigned to exists. If not, a warning will be issued.
%    \begin{macrocode}
%<*check>
\def_long_new:Npn \tlp_set:Nn #1#2{
  \chk_exist_cs:N #1  \def:Npn #1{#2}
%    \end{macrocode}
%    We use |\chk_local_or_pref_global:N| after the assignment to
%    allow constructs with |\pref_global_chk:|. But one should note
%    that this is less efficient then using the real global variant
%    since they are built-in.
%    \begin{macrocode}
  \chk_local_or_pref_global:N #1
}
\def_long_new:Npn \tlp_set:Nx #1#2{
  \chk_exist_cs:N #1  \def:Npx #1{#2}  \chk_local:N #1
}
%    \end{macrocode}
%  The the global versions.
%    \begin{macrocode}
\def_long_new:Npn \tlp_gset:Nn #1#2{
  \chk_exist_cs:N #1  \gdef:Npn #1{#2}  \chk_global:N #1
}
\def_long_new:Npn \tlp_gset:Nx #1#2{
  \chk_exist_cs:N #1  \gdef:Npx #1{#2}  \chk_global:N #1
}
%</check>
%    \end{macrocode}
%    For some functions like |\tlp_set:Nn| we need to define the
%    `non-check' version with  arguments since we want to allow
%    constructions like |\tlp_set:Nn\l_tmpa_tlp\foo| and so we can't
%    use the primitive \TeX{} command.
%    \begin{macrocode}
%<*!check>
\def_long_new:Npn\tlp_set:Nn#1#2{\def:Npn#1{#2}}
\def_long_new:Npn\tlp_set:Nx#1#2{\def:Npx#1{#2}}
\def_long_new:Npn\tlp_gset:Nn#1#2{\gdef:Npn#1{#2}}
\def_long_new:Npn\tlp_gset:Nx#1#2{\gdef:Npx#1{#2}}
%</!check>
%    \end{macrocode}
%  The remaining functions can just be defined with help from the
%  expansion module.
%    \begin{macrocode}
\def_new:Npn \tlp_set:No {\exp_args:NNo \tlp_set:Nn}
\def_new:Npn \tlp_set:Nd {\exp_args:NNd \tlp_set:Nn}
\def_new:Npn \tlp_set:Nf {\exp_args:NNf \tlp_set:Nn}
\def_new:Npn \tlp_set:cn {\exp_args:Nc  \tlp_set:Nn}
\def_new:Npn \tlp_set:co {\exp_args:Nco \tlp_set:Nn}
\def_new:Npn \tlp_set:cx {\exp_args:Nc  \tlp_set:Nx}
\def_new:Npn \tlp_gset:No {\exp_args:NNo \tlp_gset:Nn}
\def_new:Npn \tlp_gset:Nd {\exp_args:NNd \tlp_gset:Nn}
\def_new:Npn \tlp_gset:cn {\exp_args:Nc \tlp_gset:Nn}
\def_new:Npn \tlp_gset:cx {\exp_args:Nc \tlp_gset:Nx}
%    \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}{\tlp_set_eq:NN}
% \begin{macro}{\tlp_set_eq:Nc}
% \begin{macro}{\tlp_set_eq:cN}
% \begin{macro}{\tlp_set_eq:cc}
% \begin{macro}{\tlp_gset_eq:NN}
% \begin{macro}{\tlp_gset_eq:Nc}
% \begin{macro}{\tlp_gset_eq:cN}
% \begin{macro}{\tlp_gset_eq:cc}
%  For setting token list pointers equal to each other. First checking:
%    \begin{macrocode}
%<*check>
\def_new:Npn \tlp_set_eq:NN #1#2{
  \chk_exist_cs:N #1  \let:NN #1#2
  \chk_local_or_pref_global:N #1  \chk_var_or_const:N #2
}
\def_new:Npn \tlp_gset_eq:NN #1#2{
  \chk_exist_cs:N #1  \glet:NN #1#2
  \chk_global:N #1  \chk_var_or_const:N #2
}
%</check>
%    \end{macrocode}
%  Non-checking versions are easy.
%    \begin{macrocode}
%<*!check>
\let_new:NN \tlp_set_eq:NN \let:NN
\let_new:NN \tlp_gset_eq:NN \glet:NN
%</!check>
%    \end{macrocode}
%  The rest again with the expansion module.
%    \begin{macrocode}
\def_new:Npn \tlp_set_eq:Nc {\exp_args:NNc \tlp_set_eq:NN}
\def_new:Npn \tlp_set_eq:cN {\exp_args:Nc  \tlp_set_eq:NN}
\def_new:Npn \tlp_set_eq:cc {\exp_args:Ncc \tlp_set_eq:NN}
\def_new:Npn \tlp_gset_eq:Nc {\exp_args:NNc \tlp_gset_eq:NN}
\def_new:Npn \tlp_gset_eq:cN {\exp_args:Nc  \tlp_gset_eq:NN}
\def_new:Npn \tlp_gset_eq:cc {\exp_args:Ncc \tlp_gset_eq:NN}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
%
% \begin{macro}{\tlp_clear:N}
% \begin{macro}{\tlp_clear:c}
% \begin{macro}{\tlp_gclear:N}
% \begin{macro}{\tlp_gclear:c}
%    Clearing a token list pointer.
%    \begin{macrocode}
\def_new:Npn \tlp_clear:N #1{\tlp_set_eq:NN #1\c_empty_tlp}
\def_new:Npn \tlp_clear:c {\exp_args:Nc \tlp_clear:N}
\def_new:Npn \tlp_gclear:N #1{\tlp_gset_eq:NN #1\c_empty_tlp}
\def_new:Npn \tlp_gclear:c {\exp_args:Nc \tlp_gclear:N}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tlp_clear_new:N}
% \begin{macro}{\tlp_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>
\def_new:Npn \tlp_clear_new:N #1{
  \chk_var_or_const:N #1
  \if:w \cs_exist_p:N #1
    \tlp_clear:N #1
  \else:
    \tlp_new:Nn #1{}
  \fi:
}
%</check>
%<-check>\let_new:NN \tlp_clear_new:N \tlp_clear:N
\def_new:Npn \tlp_clear_new:c {\exp_args:Nc \tlp_clear_new:N}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tlp_gclear_new:N}
% \begin{macro}{\tlp_gclear_new:c}
%    These are the global versions of the above.
%    \begin{macrocode}
%<*check>
\def_new:Npn \tlp_gclear_new:N #1{
  \chk_var_or_const:N #1
  \if:w \cs_exist_p:N #1
    \tlp_gclear:N #1
  \else:
    \tlp_new:Nn #1{}
  \fi:}
%</check>
%<-check>\let_new:NN \tlp_gclear_new:N \tlp_gclear:N
\def_new:Npn \tlp_gclear_new:c {\exp_args:Nc \tlp_gclear_new:N}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tlp_put_left:Nn}
% \begin{macro}{\tlp_put_left:No}
% \begin{macro}{\tlp_put_left:Nx}
% \begin{macro}{\tlp_gput_left:Nn}
% \begin{macro}{\tlp_gput_left:No}
% \begin{macro}{\tlp_gput_left:Nx}
%   We can add tokens to the left (either globally or locally). It is
%   not quite as easy as we would like because we have to ensure the
%   assignments
% \begin{verbatim}
% \tlp_set:Nn \l_tmpa_tlp{##1abc##2def}
% \tlp_set:Nn \l_tmpb_tlp{##1abc}
% \tlp_put_right:Nn \l_tmpb_tlp {##2def}
% \end{verbatim}
%   cause |\l_tmpa_tlp| and |\l_tmpb_tlp| to be identical. The old
%   code did not succeed in doing this (it gave an error) and so we
%   use a different technique where the item(s) to be added are first
%   stored in a temporary pointer and then added using an |x| type
%   expansion combined with the appropriate level of
%   non-expansion. Putting the tokens directly into one assignment
%   does not work unless we want full expansion. Note (according to
%   the warning earlier) \TeX\ does not allow us to treat |#|s the
%   same in all cases. Tough.
%    \begin{macrocode}
\def_long_new:Npn \tlp_put_left:Nn #1#2{
  \tlp_set:Nn \l_exp_tlp{#2}
  \tlp_set:Nx #1{\exp_not:o{\l_exp_tlp}\exp_not:o{#1}}
%<check> \chk_local_or_pref_global:N #1
}
\def_long_new:Npn \tlp_put_left:No #1#2{
  \tlp_set:Nn \l_exp_tlp{#2}
  \tlp_set:Nx #1{\exp_not:d{\l_exp_tlp}\exp_not:o{#1}}
%<check> \chk_local_or_pref_global:N #1
}
\def_long_new:Npn \tlp_put_left:Nx #1#2{
  \tlp_set:Nx #1{#2\exp_not:o{#1}}
%<check> \chk_local_or_pref_global:N #1
}
\def_long_new:Npn \tlp_gput_left:Nn #1#2{
  \tlp_set:Nn \l_exp_tlp{#2}
  \tlp_gset:Nx #1{\exp_not:o{\l_exp_tlp}\exp_not:o{#1}}
%<check> \chk_local_or_pref_global:N #1
}
\def_long_new:Npn \tlp_gput_left:No #1#2{
  \tlp_set:Nn \l_exp_tlp{#2}
  \tlp_gset:Nx #1{\exp_not:d{\l_exp_tlp}\exp_not:o{#1}}
%<check> \chk_local_or_pref_global:N #1
}
\def_long_new:Npn \tlp_gput_left:Nx #1#2{
  \tlp_gset:Nx #1{#2\exp_not:o{#1}}
%<check> \chk_local_or_pref_global:N #1
}
\def_long_new:Npn \tlp_put_left:cn{\exp_args:Nc\tlp_put_left:Nn}
\def_long_new:Npn \tlp_put_left:co{\exp_args:Nc\tlp_put_left:No}
\def_long_new:Npn \tlp_put_left:cx{\exp_args:Nc\tlp_put_left:Nx}
\def_long_new:Npn \tlp_gput_left:cn{\exp_args:Nc\tlp_gput_left:Nn}
\def_long_new:Npn \tlp_gput_left:co{\exp_args:Nc\tlp_gput_left:No}
\def_long_new:Npn \tlp_gput_left:cx{\exp_args:Nc\tlp_gput_left:Nx}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tlp_put_right:Nn}
% \begin{macro}{\tlp_put_right:No}
% \begin{macro}{\tlp_put_right:Nx}
% \begin{macro}{\tlp_put_right:cc}
% \begin{macro}{\tlp_gput_right:Nn}
% \begin{macro}{\tlp_gput_right:No}
% \begin{macro}{\tlp_gput_right:cn}
% \begin{macro}{\tlp_gput_right:co}
% \begin{macro}{\tlp_gput_right:Nx}
%    These are variants of the functions above, but for adding tokens
%    to the right.
%    \begin{macrocode}
\def_long_new:Npn \tlp_put_right:Nn #1#2{
  \tlp_set:Nn \l_exp_tlp{#2}
  \tlp_set:Nx #1{\exp_not:o{#1}\exp_not:o{\l_exp_tlp}}
%<check> \chk_local_or_pref_global:N #1
}
\def_long_new:Npn \tlp_gput_right:Nn #1#2{
  \tlp_set:Nn \l_exp_tlp{#2}
  \tlp_gset:Nx #1{\exp_not:o{#1}\exp_not:o{\l_exp_tlp}}
%<check> \chk_local_or_pref_global:N #1
}
\def_long_new:Npn \tlp_put_right:No #1#2{
  \tlp_set:Nn \l_exp_tlp{#2}
  \tlp_set:Nx #1{\exp_not:o{#1}\exp_not:d{\l_exp_tlp}}
%<check> \chk_local_or_pref_global:N #1
}
\def_long_new:Npn \tlp_gput_right:No #1#2{
  \tlp_set:Nn \l_exp_tlp{#2}
  \tlp_gset:Nx #1{\exp_not:o{#1}\exp_not:d{\l_exp_tlp}}
%<check> \chk_local_or_pref_global:N #1
}
\def_long:Npn \tlp_put_right:Nx #1#2{
  \tlp_set:Nx #1{\exp_not:o{#1}#2}
%<check> \chk_local_or_pref_global:N #1
}
\def_long:Npn \tlp_gput_right:Nx #1#2{
  \tlp_gset:Nx #1{\exp_not:o{#1}#2}
%<check> \chk_local_or_pref_global:N #1
}
\def_new:Npn \tlp_gput_right:cn {\exp_args:Nc \tlp_gput_right:Nn}
\def_new:Npn \tlp_gput_right:co {\exp_args:Nc \tlp_gput_right:No}
\def_new:Npn \tlp_put_right:cc {\exp_args:Ncc \tlp_put_right:Nn}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
%
% \begin{macro}{\tlp_gset:Nc}
% \begin{macro}{\tlp_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}
\def_new:Npn \tlp_gset:Nc {
%<*check>
  \pref_global_chk:
%</check>
%<-check> \pref_global:D
  \tlp_set:Nc}
%    \end{macrocode}
%    |\pref_global_chk:| will turn the variable check in |\tlp_set:No|
%    into a  global check.
%    \begin{macrocode}
\def_new:Npn \tlp_set:Nc #1#2{\tlp_set:No #1{\cs:w#2\cs_end:}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% We also provide a few conditionals, both in expandable form (with
% |\c_true|) and in `brace-form', the latter are denoted by |TF| at the
% end, as explained elsewhere.
%
%
% \begin{macro}{\tlp_if_empty_p:N}
% \begin{macro}{\tlp_if_empty_p:c}
%   Returns |\c_true| iff the token list in the argument is empty.
%    \begin{macrocode}
\def_new:Npn \tlp_if_empty_p:N #1{
  \if_meaning:NN#1\c_empty_tlp \c_true \else: \c_false \fi:}
\def_new:Npn \tlp_if_empty_p:c {\exp_args:Nc\tlp_if_empty_p:N}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\tlp_if_empty:NTF}
% \begin{macro}{\tlp_if_empty:NT}
% \begin{macro}{\tlp_if_empty:NF}
% \begin{macro}{\tlp_if_empty:cTF}
% \begin{macro}{\tlp_if_empty:cT}
% \begin{macro}{\tlp_if_empty:cF}
%    These functions check whether the token list in the argument is
%    empty and execute the proper code from their argument(s).
%    \begin{macrocode}
\def_test_function_new:npn {tlp_if_empty:N} #1{
  \if_meaning:NN#1\c_empty_tlp}
\def_new:Npn \tlp_if_empty:cTF {\exp_args:Nc \tlp_if_empty:NTF}
\def_new:Npn \tlp_if_empty:cT {\exp_args:Nc \tlp_if_empty:NT}
\def_new:Npn \tlp_if_empty:cF {\exp_args:Nc \tlp_if_empty:NF}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tlp_if_eq_p:NN}
% \begin{macro}{\tlp_if_eq_p:Nc}
% \begin{macro}{\tlp_if_eq_p:cN}
% \begin{macro}{\tlp_if_eq_p:cc}
%   Returns |\c_true| iff the two token list pointers are equal.
%    \begin{macrocode}
\def_new:Npn \tlp_if_eq_p:NN #1#2{
  \if_meaning:NN#1#2 \c_true \else: \c_false \fi:}
\def_new:Npn \tlp_if_eq_p:Nc {\exp_args:NNc\tlp_if_empty_p:NN}
\def_new:Npn \tlp_if_eq_p:cN {\exp_args:Nc\tlp_if_empty_p:NN}
\def_new:Npn \tlp_if_eq_p:cc {\exp_args:Ncc\tlp_if_empty_p:NN}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tlp_if_eq:NNTF}
% \begin{macro}{\tlp_if_eq:NNT}
% \begin{macro}{\tlp_if_eq:NNF}
% \begin{macro}{\tlp_if_eq:NcTF}
% \begin{macro}{\tlp_if_eq:NcT}
% \begin{macro}{\tlp_if_eq:NcF}
% \begin{macro}{\tlp_if_eq:cNTF}
% \begin{macro}{\tlp_if_eq:cNT}
% \begin{macro}{\tlp_if_eq:cNF}
% \begin{macro}{\tlp_if_eq:ccTF}
% \begin{macro}{\tlp_if_eq:ccT}
% \begin{macro}{\tlp_if_eq:ccF}
%   These function tests whether the token list pointers that are in its
%   first two arguments are equal.
%    \begin{macrocode}
\def_test_function_new:npn {tlp_if_eq:NN} #1#2{\if_meaning:NN#1#2}
\def_new:Npn \tlp_if_eq:cNTF{\exp_args:Nc \tlp_if_eq:NNTF}
\def_new:Npn \tlp_if_eq:cNT {\exp_args:Nc \tlp_if_eq:NNT}
\def_new:Npn \tlp_if_eq:cNF {\exp_args:Nc \tlp_if_eq:NNF}
\def_new:Npn \tlp_if_eq:NcTF{\exp_args:NNc \tlp_if_eq:NNTF}
\def_new:Npn \tlp_if_eq:NcT {\exp_args:NNc \tlp_if_eq:NNT}
\def_new:Npn \tlp_if_eq:NcF {\exp_args:NNc \tlp_if_eq:NNF}
\def_new:Npn \tlp_if_eq:ccTF{\exp_args:Ncc \tlp_if_eq:NNTF}
\def_new:Npn \tlp_if_eq:ccT {\exp_args:Ncc \tlp_if_eq:NNT}
\def_new:Npn \tlp_if_eq:ccF {\exp_args:Ncc \tlp_if_eq:NNF}
%    \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}
%
%
%
% \begin{macro}{\c_empty_tlp}
% \begin{macro}{\c_relax_tlp}
%    Two constants which are often used.
%    \begin{macrocode}
\tlp_new:Nn \c_empty_tlp {}
\tlp_new:Nn \c_relax_tlp {\scan_stop:}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \begin{macro}{\g_tmpa_tlp}
% \begin{macro}{\g_tmpb_tlp}
%    Global temporary token list pointers.
%    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}
\tlp_new:Nn \g_tmpa_tlp{}
\tlp_new:Nn \g_tmpb_tlp{}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\l_testa_tlp}
% \begin{macro}{\l_testb_tlp}
% \begin{macro}{\g_testa_tlp}
% \begin{macro}{\g_testb_tlp}
%    Global and local temporaries.  These are the ones for test
%    routines.  This means that one can safely use other temporaries
%    when calling test routines.
%    \begin{macrocode}
\tlp_new:Nn \l_testa_tlp {}
\tlp_new:Nn \l_testb_tlp {}
\tlp_new:Nn \g_testa_tlp {}
\tlp_new:Nn \g_testb_tlp {}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\l_tmpa_tlp}
% \begin{macro}{\l_tmpb_tlp}
%    These are local temporary token list pointers.
%    \begin{macrocode}
\tlp_new:Nn \l_tmpa_tlp{}
\tlp_new:Nn \l_tmpb_tlp{}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tlp_to_str:N}
% \begin{macro}{\tlp_to_str:c}
% \begin{macro}{\tlp_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}
\def_new:Npn \tlp_to_str:N {\exp_after:NN\tlp_to_str_aux:w
  \token_to_meaning:N}
\def_new:Npn \tlp_to_str_aux:w #1>{}
\def_new:Npn\tlp_to_str:c{\exp_args:Nc\tlp_to_str:N}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
%
%
% \begin{macro}{\tlist_if_empty_p:n}
%   It would be tempting to just use "\if_meaning:NN\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:NN", 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}
\def_long_new:Npn \tlist_if_empty_p:n #1{
  \exp_after:NN\if_meaning:NN\exp_after:NN\q_nil\tlist_to_str:n{#1}\q_nil
    \c_true
  \else:
    \c_false
  \fi:
}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tlist_if_empty_p:o}
% \begin{macro}{\tlist_if_empty:nTF}
% \begin{macro}{\tlist_if_empty:nT}
% \begin{macro}{\tlist_if_empty:nF}
% \begin{macro}{\tlist_if_empty:oTF}
% \begin{macro}{\tlist_if_empty:oT}
% \begin{macro}{\tlist_if_empty:oF}
%    \begin{macrocode}
\def_new:Npn \tlist_if_empty_p:o {\exp_args:No\tlist_if_empty_p:n}
\def_long_test_function_new:npn{tlist_if_empty:n}#1{
  \if:w\tlist_if_empty_p:n{#1}}
\def_long_test_function_new:npn{tlist_if_empty:o}#1{
  \if:w\tlist_if_empty_p:o{#1}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tlist_if_blank_p:n}
% \begin{macro}{\tlist_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 |\tlist_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}
\def_long_new:Npn \tlist_if_blank_p:n #1{
  \exp_after:NN\tlist_if_blank_p_aux:w\tlist_to_str:n{#1}aa..\q_nil     
}
\def_new:Npn \tlist_if_blank_p_aux:w #1#2a#3#4\q_nil{
  \if_meaning:NN #3#4\c_true\else:\c_false\fi:}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tlist_if_blank:nTF}
% \begin{macro}{\tlist_if_blank:nT}
% \begin{macro}{\tlist_if_blank:nF}
% \begin{macro}{\tlist_if_blank_p:o}
% \begin{macro}{\tlist_if_blank:oTF}
% \begin{macro}{\tlist_if_blank:oT}
% \begin{macro}{\tlist_if_blank:oF}
% Variations on the original function above.
%    \begin{macrocode}
\def_long_test_function_new:npn{tlist_if_blank:n}#1{
  \if:w\tlist_if_blank_p:n{#1}}
\def:Npn \tlist_if_blank_p:o{\exp_args:No\tlist_if_blank_p:n}
\def_long_test_function_new:npn{tlist_if_blank:o}#1{
  \if:w\tlist_if_blank_p:o{#1}}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tlist_to_lowercase:n}
% \begin{macro}{\tlist_to_uppercase:n}
% Just some names for a few primitives.
%    \begin{macrocode}
\let_new:NN \tlist_to_lowercase:n \tex_lowercase:D
\let_new:NN \tlist_to_uppercase:n \tex_uppercase:D
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tlist_to_str:n}
%   Another name for a primitive.
%    \begin{macrocode}
\let_new:NN \tlist_to_str:n \etex_detokenize:D
%    \end{macrocode}
% \end{macro}
%
%
%  \begin{macro}{\tlist_map_function:nN}
%  \begin{macro}{\tlp_map_function:NN}
%  \begin{macro}{\tlp_map_function:cN}
%  \begin{macro}{\tlist_map_function_aux:NN}
%  Expandable loop macro for |tlist|s. 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}
\def_long_new:Npn \tlist_map_function:nN #1#2{
  \tlist_map_function_aux:Nn #2 #1 \q_recursion_tail \q_recursion_stop
}
\def_new:Npn \tlp_map_function:NN #1#2{
  \exp_after:NN \tlist_map_function_aux:Nn
  \exp_after:NN #2 #1 \q_recursion_tail \q_recursion_stop
}
\def_long_new:Npn \tlist_map_function_aux:Nn #1#2{
  \quark_if_recursion_tail_stop:n{#2} 
  #1{#2} \tlist_map_function_aux:Nn  #1 
}
\def_new:Npn\tlp_map_function:cN{\exp_args:Nc\tlp_map_function:NN}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%
%  \begin{macro}{\tlist_map_inline:nn}
%  \begin{macro}{\tlp_map_inline:Nn}
%  \begin{macro}{\tlp_map_inline:cn}
%  \begin{macro}{\tlist_map_inline_aux:n}
%  \begin{macro}{\l_tlp_inline_level_num}
%    The inline functions are straight forward by now. We use a little
%    a trick with the fake counter |\l_tlp_inline_level_num| to make
%    them nestable.\footnote{This should be a proper integer, but I
%      don't want to mess with the dependencies right now\dots} We can
%    also make use of |\tlist_map_function:Nn| from before.
%    \begin{macrocode}
\def_long_new:Npn \tlist_map_inline:nn #1#2{
  \num_incr:N \l_tlp_inline_level_num
  \def_long:cpn {tlist_map_inline_ \num_use:N \l_tlp_inline_level_num :n}
  ##1{#2}
  \exp_args:Nc \tlist_map_function_aux:Nn
  {tlist_map_inline_ \num_use:N \l_tlp_inline_level_num :n}
  #1 \q_recursion_tail\q_recursion_stop
  \num_decr:N \l_tlp_inline_level_num
}
\def_long_new:Npn \tlp_map_inline:Nn #1#2{
  \num_incr:N \l_tlp_inline_level_num
  \def_long:cpn {tlist_map_inline_ \num_use:N \l_tlp_inline_level_num :n}
  ##1{#2}
  \exp_args:NcE \tlist_map_function_aux:Nn 
  {tlist_map_inline_ \num_use:N \l_tlp_inline_level_num :n}
  #1 \q_recursion_tail\q_recursion_stop
  \num_decr:N \l_tlp_inline_level_num
}
\def_new:Npn\tlp_map_inline:cN{\exp_args:Nc\tlp_map_inline:NN}
\tlp_new:Nn \l_tlp_inline_level_num{0}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%
% \begin{macro}{\tlist_map_variable:nNn}
% \begin{macro}{\tlp_map_variable:NNn}
% \begin{macro}{\tlp_map_variable:cNn}
%    |\tlist_map:nNn| \zz{tlist} \zz{temp} \zz{action} assigns
%    \zz{temp} to each element and executes \zz{action}.
%    \begin{macrocode}
\def_long_new:Npn \tlist_map_variable:nNn #1#2#3{
  \tlist_map_variable_aux:Nnn #2 {#3} #1 \q_recursion_tail \q_recursion_stop
}
\def_new:Npn \tlp_map_variable:NNn {\exp_args:No \tlist_map_variable:nNn}
\def_new:Npn \tlp_map_variable:cNn {\exp_args:Nc \tlp_map_variable:NNn}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tlist_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}
\def_long_new:Npn \tlist_map_variable_aux:Nnn #1#2#3{
  \tlp_set:Nn #1{#3}
  \quark_if_recursion_tail_stop:N #1 
  #2 \tlist_map_variable_aux:Nnn #1{#2} 
}
%    \end{macrocode}
% \end{macro}
%
%  \begin{macro}{\tlist_map_break:w}
%  \begin{macro}{\tlp_map_break:w}
%  The break statement.
%    \begin{macrocode}
\let_new:NN \tlist_map_break:w \use_none_delimit_by_q_recursion_stop:w
\let_new:NN \tlp_map_break:w \tlist_map_break:w
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%
%  \begin{macro}{\tlist_elt_count:n}
%  \begin{macro}{\tlp_elt_count:n}
%    Count number of elements within a token list or token list
%    pointer. Brace groups within the list are read as a single
%    element.
%    "\num_elt_count:n" grabs the element and replaces it by "+1". The
%    "0" to ensure it works on an empty list.
%    \begin{macrocode}
\def_long_new:Npn \tlist_elt_count:n #1{
  \num_value:w \num_eval:w  0
  \tlist_map_function:nN {#1}\num_elt_count:n
  \num_eval_end:
}
\def_new:Npn \tlp_elt_count:N #1{
  \num_value:w \num_eval:w  0
  \tlp_map_function:NN #1 \num_elt_count:n
  \num_eval_end:
}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%
%
%
% \begin{macro}{\tlist_if_eq:nnTF}
% \begin{macro}{\tlist_if_eq:nnT}
% \begin{macro}{\tlist_if_eq:nnF}
%   Test if two token lists are identical. pdf\TeX\ contains a most
%   interesting primitive for expandable string comparison so we make
%   use of it if available. Presumable it will be in the final
%   version.
%
%   Firstly we give it an appropriate name. Note that this primitive
%   actually performs an \texttt{x} type expansion but it is still
%   expandable! Hence we must program these functions backwards to add
%   \verb|\exp_not:n|. We provide the combinations for the types
%   \texttt{n}, \texttt{o} and \texttt{x}.
%    \begin{macrocode}
\let_new:NN \tlist_compare:xx \pdfstrcmp
\def_long_new:NNn \tlist_compare:nn 2{
  \tlist_compare:xx{\exp_not:n{#1}}{\exp_not:n{#2}}
}
\def_long_new:NNn \tlist_compare:nx 1{
  \tlist_compare:xx{\exp_not:n{#1}}
}
\def_long_new:NNn \tlist_compare:xn 2{
  \tlist_compare:xx{#1}{\exp_not:n{#2}}
}
\def_long_new:NNn \tlist_compare:no 2{
  \tlist_compare:xx{\exp_not:n{#1}}{\exp_not:n\exp_after:NN{#2}}
}
\def_long_new:NNn \tlist_compare:on 2{
  \tlist_compare:xx{\exp_not:n\exp_after:NN{#1}}{\exp_not:n{#2}}
}
\def_long_new:NNn \tlist_compare:oo 2{
  \tlist_compare:xx{\exp_not:n\exp_after:NN{#1}}{\exp_not:n\exp_after:NN{#2}}
}
\def_long_new:NNn \tlist_compare:xo 2{
  \tlist_compare:xx{#1}{\exp_not:n\exp_after:NN{#2}}
}
\def_long_new:NNn \tlist_compare:ox 2{
  \tlist_compare:xx{\exp_not:n\exp_after:NN{#1}}{\exp_not:n{#2}}
}
%    \end{macrocode}
% Since we have a lot of basically identical functions to define we
% define one to define the rest. Unfortunately we aren't quite set up
% to use the new \verb|\tlist_map_inline:nn| function yet.
%    \begin{macrocode}
\def:Npn \tmp:w #1{
  \def_long_new:cNx {tlist_if_eq_p:#1} 2{
    \exp_not:N \if_num:w 
    \exp_after:NN \exp_not:N \cs:w tlist_compare:#1\cs_end:{##1}{##2}
    \exp_not:n{ =\c_zero \c_true \else: \c_false \fi: }
  }
  \def_long_test_function_new:npx{tlist_if_eq:#1}##1##2{
    \exp_not:N \if_num:w 
    \exp_after:NN \exp_not:N \cs:w tlist_compare:#1\cs_end:{##1}{##2}
    \exp_not:n{ =\c_zero }
  }
}
\tmp:w{xx}  \tmp:w{nn}  \tmp:w{oo}  \tmp:w{xn}  \tmp:w{nx}
\tmp:w{on}  \tmp:w{no}  \tmp:w{xo}  \tmp:w{ox}  
%    \end{macrocode}
% However all of this only makes sense if we actually have that
% primitive. Therefore we disable it again if it is not there and
% define \verb|\tlist_if_eq:nn| the old fashioned (and unexpandable)
% way.
%    \begin{macrocode}
\cs_if_really_free:cT{pdf_strcmp:D}{
  \def_long_test_function:npn{tlist_if_eq:nn}#1#2{
    \tlp_set:Nx \l_testa_tlp {\exp_not:n{#1}}
    \tlp_set:Nx \l_testb_tlp {\exp_not:n{#2}}
    \if_meaning:NN\l_testa_tlp \l_testb_tlp
  }
  \def_long_test_function:npn{tlist_if_eq:no}#1#2{
    \tlp_set:Nx \l_testa_tlp {\exp_not:n{#1}}
    \tlp_set:Nx \l_testb_tlp {\exp_not:o{#2}}
    \if_meaning:NN\l_testa_tlp \l_testb_tlp
  }
  \def_long_test_function:npn{tlist_if_eq:nx}#1#2{
    \tlp_set:Nx \l_testa_tlp {\exp_not:n{#1}}
    \tlp_set:Nx \l_testb_tlp {#2}
    \if_meaning:NN\l_testa_tlp \l_testb_tlp
  }
  \def_long_test_function:npn{tlist_if_eq:on}#1#2{
    \tlp_set:Nx \l_testa_tlp {\exp_not:o{#1}}
    \tlp_set:Nx \l_testb_tlp {\exp_not:n{#2}}
    \if_meaning:NN\l_testa_tlp \l_testb_tlp
  }
  \def_long_test_function:npn{tlist_if_eq:oo}#1#2{
    \tlp_set:Nx \l_testa_tlp {\exp_not:o{#1}}
    \tlp_set:Nx \l_testb_tlp {\exp_not:o{#2}}
    \if_meaning:NN\l_testa_tlp \l_testb_tlp
  }
  \def_long_test_function:npn{tlist_if_eq:ox}#1#2{
    \tlp_set:Nx \l_testa_tlp {\exp_not:o{#1}}
    \tlp_set:Nx \l_testb_tlp {#2}
    \if_meaning:NN\l_testa_tlp \l_testb_tlp
  }
  \def_long_test_function:npn{tlist_if_eq:xn}#1#2{
    \tlp_set:Nx \l_testa_tlp {#1}
    \tlp_set:Nx \l_testb_tlp {\exp_not:n{#2}}
    \if_meaning:NN\l_testa_tlp \l_testb_tlp
  }
  \def_long_test_function:npn{tlist_if_eq:xo}#1#2{
    \tlp_set:Nx \l_testa_tlp {#1}
    \tlp_set:Nx \l_testb_tlp {\exp_not:o{#2}}
    \if_meaning:NN\l_testa_tlp \l_testb_tlp
  }
  \def_long_test_function:npn{tlist_if_eq:xx}#1#2{
    \tlp_set:Nx \l_testa_tlp {#1}
    \tlp_set:Nx \l_testb_tlp {#2}
    \if_meaning:NN\l_testa_tlp \l_testb_tlp
  }
}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
%
%
% \subsubsection{Checking for and replacing tokens}
%
% \begin{macro}{\tlp_if_in:NnTF}
% \begin{macro}{\tlp_if_in:cnTF}
% \begin{macro}{\tlp_if_in:NnT}
% \begin{macro}{\tlp_if_in:cnT}
% \begin{macro}{\tlp_if_in:NnF}
% \begin{macro}{\tlp_if_in:cnF}
% \begin{macro}{\tlist_if_in:nnTF}
% \begin{macro}{\tlist_if_in:onTF}
%   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}
\def_long:Npn \tlp_if_in:NnTF #1#2{
  \def_long:Npn\tmp:w ##1 #2 ##2\q_stop{
    \quark_if_no_value:nFT{##2}
  }
  \exp_after:NN \tmp:w #1 #2 \q_no_value \q_stop
}
\def_new:Npn \tlp_if_in:cnTF {\exp_args:Nc\tlp_if_in:NnTF}
\def_long:Npn \tlp_if_in:NnT #1#2{
  \def_long:Npn\tmp:w ##1 #2 ##2\q_stop{
    \quark_if_no_value:nF{##2}
  }
  \exp_after:NN \tmp:w #1 #2 \q_no_value \q_stop
}
\def_new:Npn \tlp_if_in:cnT {\exp_args:Nc\tlp_if_in:NnT}
\def_long:Npn \tlp_if_in:NnF #1#2{
  \def_long:Npn\tmp:w ##1 #2 ##2\q_stop{
    \quark_if_no_value:nT{##2}
  }
  \exp_after:NN \tmp:w #1 #2 \q_no_value \q_stop
}
\def_new:Npn \tlp_if_in:cnF {\exp_args:Nc\tlp_if_in:NnF}
\def_long_new:Npn \tlist_if_in:nnTF #1#2{
  \def_long:Npn\tmp:w ##1 #2 ##2\q_stop{
    \quark_if_no_value:nFT{##2}
  }
  \tmp:w #1 #2 \q_no_value \q_stop
}
\def_new:Npn \tlist_if_in:onTF {\exp_args:No\tlist_if_in:nnTF}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\l_tlp_replace_tlp}
% A temp variable for the replace operations.
%    \begin{macrocode}
\tlp_new:Nn\l_tlp_replace_tlp{}
%    \end{macrocode}
% \end{macro}
%
% \begin{macro}{\tlp_replace_in:Nnn}
% \begin{macro}{\tlp_replace_in:cnn}
% \begin{macro}{\tlp_greplace_in:Nnn}
% \begin{macro}{\tlp_greplace_in:cnn}
% \begin{macro}{\tlp_replace_in_aux:NNnn}
%   Replacing the first item in a token list pointer goes like this:
%   Define a temporary function with delimited arguments containing
%   the search term and take a closer look at what is left. We append
%   the expansion of the tlp with the search term plus the quark
%   |\q_no_value|. If the search term isn't present this last one is
%   found and the following token is the quark, so we test for
%   that. If the search term is present we will have to split off the
%   |#3\q_no_value| we had, so we define yet another function with
%   delimited arguments to do this. The advantage here is that now we
%   have a special end sequence so there is no problem if the search
%   term appears more than once. Only problem left is to prevent brace
%   stripping in both ends, so we prepend the expansion of the tlp
%   with |\q_mark| later to be gobbled and also prepend the remainder
%   of the first split operation with |\q_mark| also to be gobbled
%   again later on.
%    \begin{macrocode}
\def_long_new:NNn \tlp_replace_in_aux:NNnn 4{
  \def_long:Npn \tmp:w ##1#3##2\q_stop{
    \quark_if_no_value:nF{##2}
    {
%    \end{macrocode}
% At this point |##1| starts with a |\q_mark| so remove it.
%    \begin{macrocode}
      \tlp_set:Nx\l_tlp_replace_tlp{\exp_not:o{\use_none:n##1#4}}
      \def_long:Npn \tmp:w ####1#3\q_no_value{
        \tlp_put_right:Nx \l_tlp_replace_tlp {\exp_not:o{\use_none:n ####1}}
      }
      \tmp:w \q_mark ##2
    }
%    \end{macrocode}
% Now all that is done is setting the token list pointer equal to the
% expansion of the token register.
%    \begin{macrocode}
    #1#2\l_tlp_replace_tlp
  }
%    \end{macrocode}
% Here is where we start the process. Note that the tlp might start
% with a space token so we use this little trick with |\use_arg_i:n|
% to prevent it from being removed.
%    \begin{macrocode}
  \use_arg_i:n{\exp_after:NN \tmp:w\exp_after:NN\q_mark}
  #2#3 \q_no_value\q_stop
}
%    \end{macrocode}
% Now the various versions doing the replacement either globally or
% locally.
%    \begin{macrocode}
\def_new:Npn \tlp_replace_in:Nnn {\tlp_replace_in_aux:NNnn \tlp_set_eq:NN}
\def_new:Npn \tlp_replace_in:cnn{\exp_args:Nc\tlp_replace_in:Nnn}
\def_new:Npn \tlp_greplace_in:Nnn {\tlp_replace_in_aux:NNnn \tlp_gset_eq:NN}
\def_new:Npn \tlp_greplace_in:cnn{\exp_args:Nc\tlp_greplace_in:Nnn}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tlp_replace_all_in:Nnn}
% \begin{macro}{\tlp_greplace_all_in:cnn}
% \begin{macro}{\tlp_replace_all_in:Nnn}
% \begin{macro}{\tlp_greplace_all_in:cnn}
% \begin{macro}{\tlp_replace_all_in_aux:NNnn}
%   The version for replacing \emph{all} occurrences of the search
%   term is fairly easy since we just have to keep doing the
%   replacement on the split-off part until all are
%   replaced. Otherwise it is pretty much the same as above.
%    \begin{macrocode}
\def_long:NNn \tlp_replace_all_in_aux:NNnn 4{
  \tlp_clear:N \l_tlp_replace_tlp
  \def_long:Npn \tmp:w ##1#3##2\q_stop{
    \quark_if_no_value:nTF{##2}
    { 
      \tlp_put_right:Nx \l_tlp_replace_tlp {\exp_not:o{\use_none:n##1}} 
    }
    { 
      \tlp_put_right:Nx \l_tlp_replace_tlp {\exp_not:o{\use_none:n##1 #4}} 
      \tmp:w \q_mark##2 \q_stop
    }
  }
  \use_arg_i:n{\exp_after:NN \tmp:w\exp_after:NN\q_mark} 
  #2#3 \q_no_value\q_stop
  #1#2\l_tlp_replace_tlp
}
%    \end{macrocode}
% Now the various forms.
%    \begin{macrocode}
\def_new:Npn \tlp_replace_all_in:Nnn {
  \tlp_replace_all_in_aux:NNnn \tlp_set_eq:NN}
\def_new:Npn \tlp_replace_all_in:cnn{\exp_args:Nc\tlp_replace_all_in:Nnn}
\def_new:Npn \tlp_greplace_all_in:Nnn {
  \tlp_replace_all_in_aux:NNnn \tlp_gset_eq:NN}
\def_new:Npn \tlp_greplace_all_in:cnn{\exp_args:Nc\tlp_greplace_all_in:Nnn}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
%
% \begin{macro}{\tlp_remove_in:Nn}
% \begin{macro}{\tlp_remove_in:cn}
% \begin{macro}{\tlp_gremove_in:Nn}
% \begin{macro}{\tlp_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}
\def_long_new:NNn \tlp_remove_in:Nn  2{\tlp_replace_in:Nnn #1{#2}{}}
\def_long_new:NNn \tlp_gremove_in:Nn 2{\tlp_greplace_in:Nnn #1{#2}{}}
\def_new:Npn \tlp_remove_in:cn{\exp_args:Nc\tlp_remove_in:Nn}
\def_new:Npn \tlp_gremove_in:cn{\exp_args:Nc\tlp_gremove_in:Nn}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\tlp_remove_all_in:Nn}
% \begin{macro}{\tlp_remove_all_in:Nn}
% \begin{macro}{\tlp_gremove_all_in:Nn}
% \begin{macro}{\tlp_gremove_all_in:Nn}
%   Same old, same old.
%    \begin{macrocode}
\def_long_new:Npn \tlp_remove_all_in:Nn #1#2{
  \tlp_replace_all_in:Nnn #1{#2}{}
}
\def_long_new:Npn \tlp_gremove_all_in:Nn #1#2{
  \tlp_greplace_all_in:Nnn #1{#2}{}
}
\def_new:Npn \tlp_remove_all_in:cn{\exp_args:Nc\tlp_remove_all_in:Nn}
\def_new:Npn \tlp_gremove_all_in:cn{\exp_args:Nc\tlp_gremove_all_in:Nn}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
%  \subsubsection{Heads or tails?}
%
%  \begin{macro}{\tlist_head:n}
%  \begin{macro}{\tlist_head_i:n}
%  \begin{macro}{\tlist_tail:n}
%  \begin{macro}{\tlist_tail:f}
%  \begin{macro}{\tlist_head_iii:n}
%  \begin{macro}{\tlist_head_iii:f}
%  \begin{macro}{\tlist_head:w}
%  \begin{macro}{\tlist_tail:w}
%  \begin{macro}{\tlist_head_iii:w}
%  These functions pick up either the head or the tail of a list.
%  "\tlist_head_iii:n" returns the first three items on a list.
%    \begin{macrocode}
\def_long_new:Npn \tlist_head:n #1{\tlist_head:w #1\q_nil}
\let_new:NN \tlist_head_i:n \tlist_head:n
\def_long_new:Npn \tlist_tail:n #1{\tlist_tail:w #1\q_nil}
\def_new:Npn \tlist_tail:f {\exp_args:Nf \tlist_tail:n}
\def_long_new:Npn \tlist_head_iii:n #1{\tlist_head_iii:w #1\q_nil}
\def_new:Npn \tlist_head_iii:f {\exp_args:Nf \tlist_head_iii:n}
\let_new:NN \tlist_head:w \use_arg_i_delimit_by_q_nil:nw
\def_long_new:Npn \tlist_tail:w #1#2\q_nil{#2}
\def_long_new:Npn \tlist_head_iii:w #1#2#3#4\q_nil{#1#2#3}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%  \end{macro}
%
%  \begin{macro}{\tlist_if_head_eq_meaning_p:nN}
%  \begin{macro}{\tlist_if_head_eq_meaning:nNTF}
%  \begin{macro}{\tlist_if_head_eq_meaning:nNT}
%  \begin{macro}{\tlist_if_head_eq_meaning:nNF}
%  \begin{macro}{\tlist_if_head_eq_charcode_p:nNTF}
%  \begin{macro}{\tlist_if_head_eq_charcode:nNTF}
%  \begin{macro}{\tlist_if_head_eq_charcode:nNT}
%  \begin{macro}{\tlist_if_head_eq_charcode:nNF}
%  \begin{macro}{\tlist_if_head_eq_catcode_p:nNTF}
%  \begin{macro}{\tlist_if_head_eq_catcode:nNTF}
%  \begin{macro}{\tlist_if_head_eq_catcode:nNT}
%  \begin{macro}{\tlist_if_head_eq_catcode:nNF}
%  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.
%  |\tlist_if_head_meaning_eq:nNTF| uses |\if_meaning:NN| and will
%  consider the tokens |b|$\sb{11}$ and |b|$\sb{12}$ different.
%  |\tlist_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}
\def_long_new:Npn \tlist_if_head_eq_meaning_p:nN #1#2{
  \exp_after:NN \if_meaning:NN \tlist_head:w #1\q_nil#2
    \c_true
  \else:
    \c_false
  \fi:
}
\def_long_test_function_new:npn {tlist_if_head_eq_meaning:nN}#1#2{
  \if:w \tlist_if_head_eq_meaning_p:nN{#1}#2}
%    \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}
\def_long_new:Npn \tlist_if_head_eq_charcode_p:nN #1#2{
   \exp_after:NN\if_charcode:w \exp_after:NN\exp_not:N
     \tlist_head:w #1\q_nil\exp_not:N#2
    \c_true
  \else:
    \c_false
  \fi:
}
\def_long_test_function_new:npn {tlist_if_head_eq_charcode:nN}#1#2{
  \if:w\tlist_if_head_eq_charcode_p:nN{#1}#2}
%    \end{macrocode}
% Actually the default is already an |f| type expansion.
%    \begin{macrocode}
\def_long_new:Npn \tlist_if_head_eq_charcode_p:fN #1#2{
   \exp_after:NN\if_charcode:w \tlist_head:w #1\q_nil\exp_not:N#2
    \c_true
  \else:
    \c_false
  \fi:
}
\def_long_test_function_new:npn {tlist_if_head_eq_charcode:fN}#1#2{
  \if:w\tlist_if_head_eq_charcode_p:fN{#1}#2}
\def_long_new:Npn \tlist_if_head_eq_catcode_p:nN #1#2{
   \exp_after:NN\if_charcode:w \exp_after:NN\exp_not:N
     \tlist_head:w #1\q_nil\exp_not:N#2
    \c_true
  \else:
    \c_false
  \fi:
}
\def_long_test_function_new:npn {tlist_if_head_eq_catcode:nN}#1#2{
  \if:w\tlist_if_head_eq_catcode_p:nN{#1}#2}
%    \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}
%
%
%  \begin{macro}{\tlist_reverse:n}
%  \begin{macro}{\tlist_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}
\def_long_new:Npn \tlist_reverse:n #1{
   \tlist_reverse_aux:nN {} #1 \q_recursion_tail\q_stop
}
\def_long_new:Npn \tlist_reverse_aux:nN #1#2{
  \quark_if_recursion_tail_stop_do:nn {#2}{ #1 }
  \tlist_reverse_aux:nN {#2#1}
}
%    \end{macrocode}
%  \end{macro}
%  \end{macro}
%
%
%
%  As this package relies heavily on a lot of the expansion tricks used
%  in \textsf{l3expan} we make sure to load it automatically at the end
%  when used as a package. Probably not needed but I'm just such a nice
%  guy\dots
%    \begin{macrocode}
%<package>\RequirePackage{l3expan}
%<package>\RequirePackage{l3num}\par
%    \end{macrocode}
%    Show token usage:
%    \begin{macrocode}
%</initex|package>
%<*showmemory>
\showMemUsage
%</showmemory>
%    \end{macrocode}
%
% \endinput
%
% $Log$
% Revision 1.28  2006/07/30 15:51:53  morten
% Made \tlist_map_inline:nn and variants nestable. Reimplemented
% \tlp_if_in:..., \tlp_replace_in:..., \tlp_replace_all_in:...
%
% Revision 1.27  2006/07/25 15:32:48  morten
% More \tlist_if_blank functions
%
% Revision 1.26  2006/07/06 14:58:50  morten
% Documentation touch-ups. Added more functions plus some new comparison
% functions which are dependent on a reasonably new pdfTeX.
%
% Revision 1.25  2006/06/05 14:55:14  morten
% Function for reversing a list of tokens.
%
% Revision 1.24  2006/06/03 16:31:19  morten
% Another version of \tlist_head...
%
% Revision 1.23  2006/03/20 18:26:41  braams
% Updated the copyright notice (2006) and demoted all implementation
% sections to subsections and so on to clean up the toc for source3.tex
%
% Revision 1.22  2006/01/26 14:00:42  morten
% Added a few missing functions (that were documented to be there!)
%
% Revision 1.21  2006/01/19 22:27:08  morten
% Added \tlp_replace_ and \tlp_remove_if_in functions.
%
% Revision 1.20  2006/01/17 23:07:06  morten
% Added "if_in" functions.
%
% Revision 1.19  2005/12/27 10:09:07  morten
% Changed RCS information retrieval, imported all tlist functions since
% half of them dealt with token list pointers anyway
%
% Revision 1.18  2005/07/25 19:50:40  morten
% Fixed the \long-ness aspects.
%
% Revision 1.17  2005/04/12 16:43:03  morten
% Minor updates
%
% Revision 1.16  2005/04/12 12:10:28  morten
% Rearranged and cleaned up code to avoid much doubling.
%
% Revision 1.15  2005/04/06 21:34:07  morten
% Fixed all tlp_set:XX so that they're \long. Added \tlp_set:Nf
%
% Revision 1.14  2005/03/22 23:20:43  morten
% Fixed \long versions according to Benjamin's suggestions. Slightly reorganized.
%
% Revision 1.13  2005/03/16 22:35:41  braams
% Added the tweaks necessary to be able to load with initex
%
% Revision 1.12  2005/03/11 21:43:58  braams
% Fixed the use of RCS information;
% Fixed a documentation typo
%
