% \iffalse %% File: l3tlp.dtx Copyright (C) 1990-1998 LaTeX3 project % %<*dtx> \ProvidesFile{l3tlp.dtx} % %\NeedsTeXFormat{LaTeX2e} %\ProvidesPackage{l3tlp} % \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} % % \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" "{" "}" % \end{syntax} % Defines to be a new variable (or constant) of type token % list pointer. is the initial value of % . 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" "{" "}" % \end{syntax} % Defines to hold the token list . Global % variants of this command assign the value globally the other variants % expand the up to a certain level before the assignment % or interpret the 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" % \end{syntax} % The is locally or globally cleared. The "c" variants will % generate a control sequence name which is then interpreted as % before clearing. % \end{function} % % \begin{function}{% % \tlp_clear_new:N | % \tlp_clear_new:c | % } % \begin{syntax} % "\tlp_clear_new:N" % \end{syntax} % These functions check if 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" "{" "}" % \end{syntax} % These functions will append to the left or right of % . Assigment is done either locally or globally and 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" % \end{syntax} % Fast form for % \begin{syntax} % "\tlp_set:No" "{" "}" % \end{syntax} % when 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" % \end{syntax} % This function returns the token list kept in 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" % \end{syntax} % This predicate returns `true' if is `empty' i.e., doesn't % contain any tokens. % \end{function} % % \begin{function}{\tlp_empty:NF| % \tlp_empty:NTF} % \begin{syntax} % "\tlp_empty:NF" "{""}" % \end{syntax} % Execute if is empty. % contain any tokens. % \end{function} % % \begin{function}{\tlp_eq:NNF} % \begin{syntax} % "\tlp_eq:NNF" "{""}" % \end{syntax} % Execute if doesn't hold the same token list as % . % \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} %\RequirePackage{l3basics}\par %\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> \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>\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>\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> \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 % } % \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} % % \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> \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} % %<*showmemory> \showMemUsage % % \end{macrocode} %