% \iffalse
%% File: l3tlp.dtx Copyright (C) 1990-1998 LaTeX3 project
%
%<*dtx>
          \ProvidesFile{l3tlp.dtx}
%</dtx>
%<package>\NeedsTeXFormat{LaTeX2e}
%<package>\ProvidesPackage{l3tlp}
%<driver> \ProvidesFile{l3tlp.drv}
% \fi
%         \ProvidesFile{l3tlp.dtx}
          [1998/04/20 v1.0d L3 Experimental Token List Pointers]
%
% \iffalse
%<*driver>
\documentclass{l3doc}

\begin{document}
\DocInput{l3tlp.dtx}
\end{document}
%</driver>
% \fi
%
%
% \GetFileInfo{l3tlp.dtx}
% \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.
% 
% \subsection{Functions}
% 
% \begin{function}{\tlp_new:Nn}
% \begin{syntax}
%    "\tlp_new:Nn" <tlp> "{" <initial token list> "}"
% \end{syntax}
% Defines <varible> 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.
% \end{function}
% 
% \begin{function}{%
%                  \tlp_set:Nn |
%                  \tlp_set:Nc |
%                  \tlp_set:No |
%                  \tlp_set:Nx |
%                  \tlp_gset:Nn |
%                  \tlp_gset:Nc |
%                  \tlp_gset:No |
%                  \tlp_gset:Nx}
% \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 <tokenlist> 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 |
% }
% \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_gput_left:Nn |
%                  \tlp_gput_left:No |
%                  \tlp_put_right:Nn |
%                  \tlp_put_right:cc |
%                  \tlp_gput_right:Nn |
%                  \tlp_gput_right:No
% }
% \begin{syntax}
%   "\tlp_put_left:Nn" <tlp> "{" <token list> "}"
% \end{syntax}
% These functions will append <token list> to the left or right of
% <tlp>. Assigment is done either locally or globally and <token
% list> might be subject to expansion before assigment.
% \end{function}
% 
% \begin{function}{%
%                  \tlp_set_eq:NN |
%                  \tlp_gset_eq:NN
% }
% \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_empty_p:N}
% \begin{syntax}
%   "\tlp_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_empty:NF|
%                  \tlp_empty:NTF}
% \begin{syntax}
%   "\tlp_empty:NF" <tlp> "{"<false code>"}"
% \end{syntax}
% Execute <false code> if <tlp> is empty.
% contain any tokens.
% \end{function}
% 
% \begin{function}{\tlp_eq:NNF}
% \begin{syntax}
%   "\tlp_eq:NNF" <tlp1> <tlp2> "{"<false code>"}"
% \end{syntax}
% Execute <false code> if <tlp1> doesn't hold the same token list as
% <tlp2>.
% \end{function}
% 
% \subsection{Variable 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{function}{\tlp_put_left:aux}
% Used by "\tlp_put_left:Nn" and its variants.
% \end{function}
% 
% \begin{function}{\tlp_to_str:aux}
% Function used to implement "\tlp_to_str:N".
% \end{function}
% 
% \StopEventually{}
%
%    \section{The code}
%    
%    We start by ensuring that the required packages are loaded.
%    \begin{macrocode}
%<package&!check>\RequirePackage{l3basics}\par
%<package&check>\RequirePackage{l3chk}\par
%<*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.)
%
% We don't implement a |\tlp_use:n| function. Execution is done by
% calling the list.
%
%
% \begin{macro}{\tlp_new:Nn}
% \begin{macro}{\tlp_clear:N}
% \begin{macro}{\tlp_gclear:N}
%    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}
%<*check>
\def_long_new:Npn \tlp_new:Nn #1#2{
      \chk_new_cs:N #1
      \chk_var_or_const:N #1
%    \end{macrocode}
%    The next line contains the token list assignments without any
%    checking for variable types etc.\ since we want to allow to
%    update constants here.
%    \begin{macrocode}
      \gdef:Npn #1{#2}}
%</check>
%<-check> \let_new:NN\tlp_new:Nn\gdef:Npn
\def_long_new:Npn \tlp_clear:N #1{\tlp_set_eq:NN #1\c_empty_tlp}
\def_long_new:Npn \tlp_gclear:N #1{\tlp_gset_eq:NN #1\c_empty_tlp}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tlp_clear:c}
% \begin{macro}{\tlp_gclear:c}
%    We also define the variants that construct the token list name
%    from a string.
%    \begin{macrocode}
\def_new:Npn \tlp_clear:c {\exp_args:Nc \tlp_clear:N}
\def_new:Npn \tlp_gclear:c {\exp_args:Nc \tlp_gclear:N}
%    \end{macrocode}
% \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_long_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_long_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_long_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_long_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_gput_left:Nn}
% \begin{macro}{\tlp_gput_left:No}
% \begin{macro}{\tlp_put_left:aux}
%    We can add tokens to the left (either globally or locally).
%    \begin{macrocode}
\def_long_new:Npn \tlp_put_left:Nn #1{\exp_after:NN
%    \end{macrocode}
%    We need expanding over a brace to ensure that if |#1| contains
%    just one token within braces the braces are preserved.
%    \begin{macrocode}
        \tlp_put_left:aux\exp_after:NN{#1}#1}
\def_new:Npn\tlp_put_left:No{\exp_args:NNo\tlp_put_left:Nn}
\def_long_new:Npn \tlp_gput_left:Nn {
%<*check>
   \pref_global_chk:
%</check>
%<-check> \pref_global:D
   \tlp_put_left:Nn}
\def_new:Npn\tlp_gput_left:No{\exp_args:NNo\tlp_gput_left:Nn}
\def_long_new:Npn \tlp_put_left:aux #1#2#3{\def:Npn #2{#3#1}
%    \end{macrocode}
%    We check the type afterwards to avoid conflicts with the use of
%    |\pref_global:D|.
%    \begin{macrocode}
%<*check>
        \chk_local_or_pref_global:N #2
%</check>
}
%    \end{macrocode}
% \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: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:No #1{#1#2}}
\def_long_new:Npn \tlp_gput_right:Nn #1#2{\tlp_gset:No #1{#1#2}}
\def_new:Npn \tlp_gput_right:No {\exp_args:NNo \tlp_gput_right:Nn}
\def_new:Npn \tlp_gput_right:Nx {\exp_args:NNx \tlp_gput_right:Nn}
\def_new:Npn \tlp_put_right:cc {\exp_args:Ncc \tlp_put_right:Nn}
\def_new:Npn \tlp_put_right:No {\exp_args:NNo \tlp_put_right:Nn}
\def_new:Npn \tlp_put_right:Nx {\exp_args:Nnx \tlp_put_right:Nn}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
% \begin{macro}{\tlp_set:Nn}
% \begin{macro}{\tlp_set:No}
% \begin{macro}{\tlp_set:Nx}
% \begin{macro}{\tlp_gset:Nn}
% \begin{macro}{\tlp_gset:No}
% \begin{macro}{\tlp_gset:Nx}
% \begin{macro}{\tlp_set_eq:NN}
% \begin{macro}{\tlp_gset_eq:NN}
%    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|
%    (which is not implemented). 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 builtin.
%    \begin{macrocode}
        \chk_local_or_pref_global:N #1}
\def_long_new:Npn \tlp_set:No {
        \exp_args:NNo \tlp_set:Nn}
\def_long_new:Npn \tlp_set:Nx #1#2{
        \chk_exist_cs:N #1
        \def:Npx #1{#2}\chk_local:N #1}
\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:No {
        \exp_args:NNo \tlp_gset:Nn}
\def_long_new:Npn \tlp_gset:Nx #1#2{
        \chk_exist_cs:N #1
        \gdef:Npx #1{#2}\chk_global:N #1}
\def_long_new:Npn \tlp_set_eq:NN #1#2{
        \chk_exist_cs:N #1
        \let:NwN #1#2
        \chk_local_or_pref_global:N #1\chk_var_or_const:N #2}
\def_long_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}
%    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_new:Npn\tlp_set:Nn#1#2{\def:Npn#1{#2}}
%<-check> \def_new:Npn\tlp_set:Nx#1#2{\def:Npx#1{#2}}
%<-check> \def_new:Npn\tlp_gset:Nn#1#2{\gdef:Npn#1{#2}}
%<-check> \def_new:Npn\tlp_gset:Nx#1#2{\gdef:Npx#1{#2}}
%<-check> \let_new:NN\tlp_set:No\def:No
%<-check> \let_new:NN\tlp_gset:No\gdef:No
%<-check> \let_new:NN\tlp_set_eq:NN\let:NwN
%<-check> \let_new:NN\tlp_gset_eq:NN\glet:NN
%    \end{macrocode}
% \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_empty_p:N}
%   Returns |\c_true| iff the token list in the argument is empty.
%    \begin{macrocode}
\def_new:Npn \tlp_empty_p:N #1{
  \if_meaning:NN#1\c_empty_tlp \c_true \else: \c_false \fi:}
%    \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\tlp_empty:NF}
% \begin{macro}{\tlp_empty:NTF}
%    These functions check whether the token list in the argument is 
%    empty and execute the proper code from their argument(s).
%    \begin{macrocode}
\def_new:Npn \tlp_empty:NF #1{
 \if_meaning:NN#1\c_empty_tlp
    \exp_after:NN\use_none:nn
 \fi:
 \use:n}
\def_new:Npn \tlp_empty:NTF #1{
 \if_meaning:NN#1\c_empty_tlp
    \exp_after:NN\use_choice_i:nn
 \else:
    \exp_after:NN\use_choice_ii:nn
 \fi:}
%    \end{macrocode}
% \end{macro}
% \end{macro}
%
% \begin{macro}{\tlp_eq:NNF}
%    This function test whether the token lists that are in its first
%    two arguments are equal; if they are not |#3| is executed.
%    \begin{macrocode}
\def_new:Npn \tlp_eq:NNF #1#2{
 \if_meaning:NN#1#2
    \exp_after:NN\use_none:nn
 \fi:
 \use:n}
%    \end{macrocode}
% \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}
%    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
    \token_to_meaning:N}
\def_new:Npn \tlp_to_str:aux #1>{}
\def_new:Npn\tlp_to_str:c{\exp_args:Nc\tlp_to_str:N}
%    \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
%
%    Show token usage:
%    \begin{macrocode}
%</package>
%<*showmemory>
\showMemUsage
%</showmemory>
%    \end{macrocode}
%
