From f4eb27d3314d15838f674a3872000159d029f88b Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Tue, 22 May 2007 17:46:23 +0000 Subject: update expl3 git-svn-id: svn://tug.org/texlive/trunk@4335 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/source/latex/expl3/l3.ins | 38 +- Master/texmf-dist/source/latex/expl3/l3alloc.dtx | 276 ++ Master/texmf-dist/source/latex/expl3/l3basics.dtx | 2942 ++++++++++++++++---- Master/texmf-dist/source/latex/expl3/l3box.dtx | 933 +++++++ Master/texmf-dist/source/latex/expl3/l3calc.dtx | 930 +++++++ Master/texmf-dist/source/latex/expl3/l3chk.dtx | 154 +- Master/texmf-dist/source/latex/expl3/l3clist.dtx | 1082 +++++++ Master/texmf-dist/source/latex/expl3/l3expan.dtx | 530 +++- Master/texmf-dist/source/latex/expl3/l3final.dtx | 129 + Master/texmf-dist/source/latex/expl3/l3format.ins | 72 + Master/texmf-dist/source/latex/expl3/l3int.dtx | 1222 +++++--- Master/texmf-dist/source/latex/expl3/l3io.dtx | 179 +- Master/texmf-dist/source/latex/expl3/l3keyval.dtx | 666 +++++ .../texmf-dist/source/latex/expl3/l3messages.dtx | 972 +++++++ Master/texmf-dist/source/latex/expl3/l3names.dtx | 446 ++- Master/texmf-dist/source/latex/expl3/l3num.dtx | 749 +++++ Master/texmf-dist/source/latex/expl3/l3precom.dtx | 228 +- Master/texmf-dist/source/latex/expl3/l3prg.dtx | 1374 +++++++++ Master/texmf-dist/source/latex/expl3/l3prop.dtx | 503 +++- Master/texmf-dist/source/latex/expl3/l3quark.dtx | 326 ++- Master/texmf-dist/source/latex/expl3/l3seq.dtx | 412 ++- Master/texmf-dist/source/latex/expl3/l3skip.dtx | 1086 ++++++++ Master/texmf-dist/source/latex/expl3/l3tlp.dtx | 1804 ++++++++++-- Master/texmf-dist/source/latex/expl3/l3token.dtx | 2004 +++++++++++++ Master/texmf-dist/source/latex/expl3/l3toks.dtx | 421 ++- Master/texmf-dist/source/latex/expl3/l3vers.dtx | 145 + Master/texmf-dist/source/latex/expl3/l3xref.dtx | 379 +++ Master/texmf-dist/source/latex/expl3/readme.txt | 224 -- Master/texmf-dist/source/latex/expl3/test1.dmp | 1 - Master/texmf-dist/source/latex/expl3/test2.dmp | 2 - Master/texmf-dist/source/latex/expl3/test3.dmp | 2 - Master/texmf-dist/source/latex/expl3/testdump.cmp | 7 - 32 files changed, 18087 insertions(+), 2151 deletions(-) create mode 100644 Master/texmf-dist/source/latex/expl3/l3alloc.dtx create mode 100644 Master/texmf-dist/source/latex/expl3/l3box.dtx create mode 100644 Master/texmf-dist/source/latex/expl3/l3calc.dtx create mode 100644 Master/texmf-dist/source/latex/expl3/l3clist.dtx create mode 100644 Master/texmf-dist/source/latex/expl3/l3final.dtx create mode 100644 Master/texmf-dist/source/latex/expl3/l3format.ins create mode 100644 Master/texmf-dist/source/latex/expl3/l3keyval.dtx create mode 100644 Master/texmf-dist/source/latex/expl3/l3messages.dtx create mode 100644 Master/texmf-dist/source/latex/expl3/l3num.dtx create mode 100644 Master/texmf-dist/source/latex/expl3/l3prg.dtx create mode 100644 Master/texmf-dist/source/latex/expl3/l3skip.dtx create mode 100644 Master/texmf-dist/source/latex/expl3/l3token.dtx create mode 100644 Master/texmf-dist/source/latex/expl3/l3vers.dtx create mode 100644 Master/texmf-dist/source/latex/expl3/l3xref.dtx delete mode 100644 Master/texmf-dist/source/latex/expl3/readme.txt delete mode 100644 Master/texmf-dist/source/latex/expl3/test1.dmp delete mode 100644 Master/texmf-dist/source/latex/expl3/test2.dmp delete mode 100644 Master/texmf-dist/source/latex/expl3/test3.dmp delete mode 100644 Master/texmf-dist/source/latex/expl3/testdump.cmp (limited to 'Master/texmf-dist/source/latex/expl3') diff --git a/Master/texmf-dist/source/latex/expl3/l3.ins b/Master/texmf-dist/source/latex/expl3/l3.ins index 786fcff9a9b..14ac72c8532 100644 --- a/Master/texmf-dist/source/latex/expl3/l3.ins +++ b/Master/texmf-dist/source/latex/expl3/l3.ins @@ -30,7 +30,7 @@ Do not distribute a modified version of this file. \generate{\file{l3basics.sty}{\from{l3basics.dtx}{package,trace}}} -% Define some basic commands That check various conditions +% Define some basic commands that check various conditions % related to defining commands eg defined/undefined global/local % Not sure how much of this really makes sense as a package, but... \generate{\file{l3chk.sty}{\from{l3chk.dtx}{package,trace}}} @@ -56,6 +56,10 @@ Do not distribute a modified version of this file. \generate{\file{l3seq.sty}{\from{l3seq.dtx}{package,trace}}} +%% LaTeX3 clists. +\generate{\file{l3clist.sty}{\from{l3clist.dtx}{package,trace}}} + + %% LaTeX3 property lists. \generate{\file{l3prop.sty}{\from{l3prop.dtx}{package,trace}}} @@ -64,14 +68,40 @@ Do not distribute a modified version of this file. \generate{\file{l3int.sty}{\from{l3int.dtx}{package,trace}}} -%% LaTeX3 precompilation -\generate{\file{l3precom.sty}{\from{l3precom.dtx}{package,precompile,trace}}} +%% LaTeX3 fake integer macros. +\generate{\file{l3num.sty}{\from{l3num.dtx}{package,trace}}} + +%% LaTeX3 skip registers. +\generate{\file{l3skip.sty}{\from{l3skip.dtx}{package,trace}}} %% LaTeX3 precompilation +\generate{\file{l3precom.sty}{\from{l3precom.dtx}{package,precompile,trace}}} + +%% LaTeX3 I/O module. \generate{\file{l3io.sty}{\from{l3io.dtx}{package,trace}}} +%% LaTeX3 program control structures (loops, booleans, ...) +\generate{\file{l3prg.sty}{\from{l3prg.dtx}{package}}} -\endbatchfile +%% LaTeX3 box module +\generate{\file{l3box.sty}{\from{l3box.dtx}{package}}} + +%% LaTeX3 messages +\generate{\file{l3messages.sty}{\from{l3messages.dtx}{package}}} + +%% LaTeX3 tokens +\generate{\file{l3token.sty}{\from{l3token.dtx}{package}}} + +%% LaTeX3 cross references +\generate{\file{l3xref.sty}{\from{l3xref.dtx}{package}}} +\generate{\file{l3xref-test.tex}{\from{l3xref.dtx}{testfile}}} +%% LaTeX3 calc module +\generate{\file{l3calc.sty}{\from{l3calc.dtx}{package}}} +%% LaTeX3 keyval module +\generate{\file{l3keyval.sty}{\from{l3keyval.dtx}{package}}} + + +\endbatchfile diff --git a/Master/texmf-dist/source/latex/expl3/l3alloc.dtx b/Master/texmf-dist/source/latex/expl3/l3alloc.dtx new file mode 100644 index 00000000000..0fa4f2aef57 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3alloc.dtx @@ -0,0 +1,276 @@ +% \iffalse +%% File: l3alloc.dtx Copyright (C) 1990-2006 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. +%% +%% ----------------------------------------------------------------------- +% +%\RequirePackage{l3names} +%<*dtx> +%\fi +\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{% + \def\fileversion{#2}% + \def\filedate{#3/#4/#5}% + \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]% +} +%\iffalse +% +%\fi +\GetIdInfo$Id: l3alloc.dtx 581 2006-12-12 12:28:27Z morten $ + {L3 Experimental register allocation}% +% \iffalse +%<*driver> +\documentclass{l3doc} + +\begin{document} +\DocInput{l3alloc.dtx} +\end{document} +% +% \fi +% +% +% \title{The \textsf{l3alloc} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Allocating registers and the like} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% \section{Allocating registers and the like} +% +% This module provides the basic mechanism for allocating \TeX's +% registers. While designing this we have to take into account the +% following characteristics: +% \begin{itemize} +% \item |\box255| is reserved for use in the output routine, so it +% should not be allocated otherwise. +% \item \TeX\ can load up 256 hyphenation patterns (registers +% |\tex_language:D| 0-255), +% \item \TeX\ can load no more than 16 math families, +% \item \TeX\ supports no more than 16 io-streams for reading +% (|\tex_read:D|) and 16 io-streams for writing (|\tex_write:D|), +% \item \TeX\ supports no more than 256 inserts, Omega supports more. +% \item The other registers (|\tex_count:D|, |\tex_dimen:D|, +% |\tex_skip:D|, |\tex_muskip:D|, |\tex_box:D|, and |\tex_toks:D| +% range from 0 to 32768, but registers numbered above 255 are +% accessed somewhat less efficient. +% \item Registers could be allocated both globally and locally; the +% use of regsiters could also be globaly or locally. Here we +% provide support for globally allocated registers for both +% gloabl and local use and for locally allocated registers for +% local use only. +% \end{itemize} +% We also need to allow for some bookkeeping: we need to know which +% register was allocated last and which registers can not be +% allocated by the standard mechanisms. +% +% \subsection{Functions} +% +% \begin{function}{\alloc_setup_type:nnn} +% \begin{syntax} +% "\alloc_setup_type:nnn" +% \end{syntax} +% Sets up the storage needed for the administration of registers of +% type .\\ +% should be a token list in braces, it can be one of +% "int", "dimen", "skip", "muskip", "box", "toks", "ior", "iow", +% "pattern", or "ins".\\ +% is the number of the first not allocated global +% register, it will be incremented by 1 when the allocation is done. +% is the number of the first not allocated local +% register, it will be decremented by 1 when the allocation is done. +% \end{function} +% +% \begin{function}{\alloc_reg:NnNN} +% \begin{syntax} +% "\alloc_reg:NnNN" +% \end{syntax} +% Performs the allocation of a register of type to copntrol +% sequence , using the command . The "g" or "l" +% indicaties whether the allocation should be global or local. +% This macro is the basic building block for the definition of the +% "\""_new:N" commands +% \end{function} +% +% \StopEventually{} +% +% \subsection{The Implementation} +% +% We start by ensuring that the required packages are loaded when +% this file is loaded as a package on top of \LaTeXe. +% +% \begin{macrocode} +%\RequirePackage{l3expan} +%\RequirePackage{l3num} +%\RequirePackage{l3seq}\par +% \end{macrocode} +% +% +% \begin{macrocode} +%<*initex|package> +% \end{macrocode} +% +% \begin{macro}{\alloc_setup_type:nnn} +% For each type of register we need to `counters' that hold the +% last allocated global or local register. We also need a sequence +% to store the `excpetions'. +% \begin{macrocode} +\def_new:Npn \alloc_setup_type:nnn #1 #2 #3{ + \num_new:c {g_ #1 _allocation_num} + \num_new:c {l_ #1 _allocation_num} + \seq_new:c {g_ #1 _allocation_seq} + \num_set:cn {g_ #1 _allocation_num}{#2} + \num_set:cn {l_ #1 _allocation_num}{#3} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\alloc_next_g:n} +% \begin{macro}{\alloc_next_l:n} +% These routines find the next free register. For globally allocated +% registers we first increment the counter that keeps track of them. +% \begin{macrocode} +\def_new:Npn \alloc_next_g:n #1 { + \num_gincr:c {g_ #1 _allocation_num} +% \end{macrocode} +% Then we need to check whether we have run out of registers. +% \begin{macrocode} + \num_compare:cNcTF {g_ #1 _allocation_num} = {l_ #1 _allocation_num} + {\io_put_term:x{We~ ran~ out~ of~ registers~ of~ type~ g_#1!}} + { +% \end{macrocode} +% We also need to check wether the value of the counter already +% occurs in the list of already allocated registers. +% \begin{macrocode} + \seq_if_in:cxTF {g_ #1 _allocation_seq} + {\num_use:c{g_ #1 _allocation_num}} + {\io_put_term:x{\num_use:c{g_ #1 _allocation_num}~Already~ allocated!} +% \end{macrocode} +% If it does, we find the next value. +% \begin{macrocode} + \alloc_next_g:n {#1} } + {\use_noop:} + } +% \end{macrocode} +% By now the |.._allocation_num| counter will contain the number of +% the register we will assign a control seuence for. +% \begin{macrocode} + } +% \end{macrocode} +% For the locally allocated registers we have a similar function. +% \begin{macrocode} +\def_new:Npn \alloc_next_l:n #1 { + \num_gdecr:c {l_ #1 _allocation_num} + \num_compare:cNcTF {g_ #1 _allocation_num} = {l_ #1 _allocation_num} + {\io_put_term:x{We~ ran~ out~ of~ registers~ of~ type~ l_#1!}} + { + \seq_if_in:cxTF {g_ #1 _allocation_seq} + {\num_use:c{l_ #1 _allocation_num}} + {\io_put_term:x{\num_use:c{l_ #1 _allocation_num}~Already~ allocated!} + \alloc_next_l:n {#1} } + {\io_put_term:x{\num_use:c{l_ #1 _allocation_num}~Free!}} + } + } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\alloc_reg:NnNN} +% This internal macro performs the actual allocation. It's first +% argument is either 'g' for a globally allocated register or `l' +% for a locally allocated register. The second argument is the +% type of register to allocate, the third argument is the command +% to use and the fourth argument is the control sequence that is to +% be defined to point to the register. +% \begin{macrocode} +\def_new:Npn \alloc_reg:NnNN #1 #2 #3 #4{ +% \end{macrocode} +% It first checks that the control sequence that is to denote the +% register does not already exist. +% \begin{macrocode} + \chk_new_cs:N #4 +% \end{macrocode} +% Next, it decides whether a prefix is needed for the allocation +% command; +% \begin{macrocode} + \if:w#1g + \exp_after:NN \pref_global:D + \fi: +% \end{macrocode} +% And finally the actual allocation takes place. +% \begin{macrocode} + #3 #4 \num_use:c{#1_ #2 _allocation_num} + %%\cs_record_meaning:N#1 +% \end{macrocode} +% All that's left to do is write a message in the log file. +% \begin{macrocode} + \io_put_log:x{ + \token_to_string:N#4=#2~register~\num_use:c{#1_ #2 _allocation_num}} +% \end{macrocode} +% Finally, it calls |\alloc_next_| to find the next free register +% number. +% \begin{macrocode} + \cs_use:c{alloc_next_#1:n} {#2} + } +% \end{macrocode} +% \end{macro} +% +% +% \begin{macrocode} +%<*showmemory> +\showMemUsage +% +% +% \end{macrocode} +% +% \endinput +% +% $Log$ +% Revision 1.6 2006/03/20 18:26:32 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.5 2006/01/15 14:02:58 braams +% Added a \SopEventually{} command +% +% Revision 1.4 2005/12/27 16:02:18 morten +% Changed RCS information retrieval +% +% Revision 1.3 2005/04/06 22:32:38 braams +% Removed the functins that belong in other modules; +% Fixed the naming conventions +% +% Revision 1.2 2005/04/05 22:12:44 braams +% First, working, version of the regsiter allocation support +% +% Revision 1.1 2005/03/16 22:50:02 braams +% Initial register allocation module +% diff --git a/Master/texmf-dist/source/latex/expl3/l3basics.dtx b/Master/texmf-dist/source/latex/expl3/l3basics.dtx index 8a4170e79cf..4181fad3182 100644 --- a/Master/texmf-dist/source/latex/expl3/l3basics.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3basics.dtx @@ -1,16 +1,49 @@ % \iffalse -%% File: l3basics.dtx Copyright (C) 1990-1998 LaTeX3 project -% +%% File: l3basics.dtx Copyright (C) 1990-2006 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. +%% +%% ----------------------------------------------------------------------- +%\RequirePackage{l3names} %<*dtx> - \ProvidesFile{l3basics.dtx} +%\fi +\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{% + \def\fileversion{#2}% + \def\filedate{#3/#4/#5}% + \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]% +} +%\iffalse % -%\NeedsTeXFormat{LaTeX2e} -%\ProvidesPackage{l3basics} -% \ProvidesFile{l3basics.drv} -% \fi -% \ProvidesFile{l3basics.dtx} - [1998/05/04 v1.0i L3 Experimental basic definitions] -% +%\fi +\GetIdInfo$Id: l3basics.dtx 583 2006-12-12 17:26:44Z morten $ + {L3 Experimental basic definitions} % \iffalse %<*driver> \documentclass{l3doc} @@ -21,7 +54,6 @@ % % \fi % -% \GetFileInfo{l3basics.dtx} % \title{The \textsf{l3basics} package\thanks{This file % has version number \fileversion, last % revised \filedate.}\\ @@ -31,109 +63,236 @@ % \maketitle % % -% We start by ensuring that the required packages are loaded. In -% this case there is a boot-strapping problem since, to use much of -% the code in this file, the `l3expan' package needs to be loaded; -% but this file must be loaded first. -% \begin{macrocode} -%\RequirePackage{l3names}\par -% \end{macrocode} -% % As the name suggest this package holds some basic definitions which % are needed by most or all other packages in this set. % -% \section{Basics} -% -% Here we describe those functions that used all over the place. +% \section{Basics} +% +% Here we describe those functions that used all over the place. With +% that we mean functions dealing with the construction and testing of +% control sequences. Furthermore the basic parts of conditional +% processing are covered; conditional processing dealing with specific +% data types is described in the modules specific for the respective +% data types. +% +% \subsection{Predicates and conditionals} % -% \subsection{Functions} +% \subsubsection{Primitive conditionals} +% +% The \eTeX\ engine itself provides many different conditionals. Some +% expand whatever comes after them and others don't. Hence the names +% for these underlying functions will often contain a |:w| part but +% higher level functions are often available. See for instance +% |\int_compare_p:nNn| which is a wrapper for |\if_num:w|. +% +% Certain conditionals deal with specific data types like boxes and +% fonts and are described there. The ones described below are either +% the universal conditionals or deal with control sequences. We will +% prefix primitive conditionals with |\if_|. % -% \begin{function}{\cs_to_str:N} +% \begin{function}{% +% \if_true: | +% \if_false: | +% \else: | +% \fi: | +% \reverse_if:N | +% } % \begin{syntax} -% "\cs_to_str:N" +% "\if_true:" "\else:" "\fi:" \\ +% "\if_false:" "\else:" "\fi:" \\ +% "\reverse_if:N" % \end{syntax} -% This function return the name of as a sequence of letters with -% the escape character removed. +% "\if_true:" always executes , while "\if_false:" always +% executes . "\reverse_if:N" reverses any two-way primitive +% conditional. "\else:" and "\fi:" delimit the branches of the conditional. % \end{function} % -% \begin{function}{\cs_gen_sym:N | -% \cs_ggen_sym:N} +% \begin{function}{% +% \if_meaning:NN | +% \if_cs_meaning_eq:NN | +% \if_token_eq:NN | +% } % \begin{syntax} -% "\cs_gen_sym:N" +% "\if_meaning:NN" "\else:" +% "\fi:" \\ +% "\if_cs_meaning_eq:NN" "\else:" +% "\fi:" \\ +% "\if_token_eq:NN" "\else:" "\fi:" % \end{syntax} -% These functions will generate a new control sequence name for use as a -% pointer, e.g.\ some tree structure like the LDB. The new unique name -% is returned locally in for further use. The names are generated -% using the roman numeral representation of some special counters -% together with a prefix of "\l*" (local) or "\g*"( global). +% "\if_meaning:NN" executes when the replacement text, +% i.e., the expansion of and are the same, otherwise it +% executes . However this name isn't really that +% good. What the \TeX\ primitive does is compare two tokens to see if +% they are equal. Hence this is actually a "token" functions. A +% similar argument applies to the situation where it is used to +% compare control sequences, where it is the meaning being compared. +% Something to be cleaned up at some point. % \end{function} -% -% -% \subsection{Predicates and conditionals} -% +% % \begin{function}{% -% \if_meaning:NN | +% \if:w | +% \if_charcode:w | +% \if_catcode:w % } % \begin{syntax} -% "\if_meaning:NN" "\else:" "\fi:" +% "\if:w" "\else:" "\fi:" \\ +% "\if_catcode:w" "\else:" "\fi:" % \end{syntax} -% This conditional executes when the replacement text, i.e., -% the expansion of and are the same, otherwise it executes -% . -% \begin{texnote} -% This is the primitive \tn{ifx}. -% \end{texnote} +% These conditionals will expand any following tokens until two +% unexpandable tokens are left. If you wish to prevent this expansion, +% prefix the token in question with "\exp_not:N". "\if_catcode:w" +% tests if the category codes of the two tokens are the same whereas +% "\if:w" tests if the character codes are +% identical. "\if_charcode:w" is an alternative name for "\if:w". +% \end{function} +% +% \begin{function}{% +% \if_cs_exist:N | +% \if_cs_exist:w +% } +% \begin{syntax} +% "\if_cs_exist:N" "\else:" "\fi:" \\ +% "\if_cs_exist:w" "\cs_end:" "\else:" "\fi:" +% \end{syntax} +% Check if appears in the hash table or if the control sequence +% that can be formed from appears in the hash table. The +% latter function does not turn the control sequence in question into +% "\scan_stop:"! This can be useful when dealing with control +% sequences which cannot be entered as a single token. % \end{function} +% +% \begin{function}{ +% \if_mode_horizontal: | +% \if_mode_vertical: | +% \if_mode_math: | +% \if_mode_inner: +% } +% \begin{syntax} +% "\if_horizontal_mode:" "\else:" "\fi:" +% \end{syntax} +% Execute if currently in horizontal mode, otherwise +% execute . Similar for the other functions. +% \end{function} +% +% \subsubsection{Non-primitive conditionals} +% % \begin{function}{% -% \cs_eq_p:NN | +% \cs_if_eq_p:NN % } % \begin{syntax} -% "\cs_eq_p:NN" +% "\cs_if_eq_p:NN" % \end{syntax} % Returns `true' if and are textually the same, i.e.\ have % the same name, otherwise it returns `false'. % \end{function} -% % % \begin{function}{% -% \cs_free_p:N | +% \cs_if_eq:NNTF | +% \cs_if_eq:NNT | +% \cs_if_eq:NNF | +% \cs_if_eq:cNTF | +% \cs_if_eq:cNT | +% \cs_if_eq:cNF | +% \cs_if_eq:NcTF | +% \cs_if_eq:NcT | +% \cs_if_eq:NcF | +% \cs_if_eq:ccTF | +% \cs_if_eq:ccT | +% \cs_if_eq:ccF % } % \begin{syntax} -% "\cs_free_p:N" +% "\cs_if_eq:NNTF" "{""}{""}" +% \end{syntax} +% These functions check if and have same meaning and then +% execute either or . +% \end{function} +% +% +% \begin{function}{% +% \cs_if_free_p:N +% } +% \begin{syntax} +% "\cs_if_free_p:N" % \end{syntax} % Returns `true' if is either undefined or equal to "\scan_stop:". % However, it returns `false' if is textually "\c_undefined" (the % constantly undefined function), or textually "\scan_stop:". % \end{function} -% +% % \begin{function}{% -% \cs_free:NTF | -% \cs_free:NF | -% \cs_free:NT | -% \cs_free:cF | -% \cs_free:cTF | +% \cs_if_free:NTF | +% \cs_if_free:NT | +% \cs_if_free:NF | +% \cs_if_free:cTF | +% \cs_if_free:cT | +% \cs_if_free:cF % } % \begin{syntax} -% "\cs_free:NTF" "{""}{""}" +% "\cs_if_free:NTF" "{""}{""}" % \end{syntax} % These functions check if is free and then execute either or . % \begin{texnote} -% The conditional "\cs_free:cTF" is the \LaTeX3 implementation of the -% \LaTeX2 function \tn{@ifundefined}. The other functions haven't been -% around before. +% The conditional "\cs_if_free:cTF" is the \LaTeX3 implementation of +% the \LaTeX2 function \tn{@ifundefined}. The other functions +% haven't been around before. % \end{texnote} % \end{function} -% +% % \begin{function}{% -% \cs_exist_p:N | +% \cs_if_really_free:cTF | +% \cs_if_really_free:cF | +% \cs_if_really_free:cT % } % \begin{syntax} -% "\cs_exist_p:N" +% "\cs_if_really_free:cTF" "{""}" "{""} {""}" % \end{syntax} -% This function does the opposite of "\cs_free_p:N". +% Similar to "\cs_if_free:cTF" but does not put anything previously +% undefined into the hash table. Useful for special control sequences +% like "\foo/bar" which cannot be entered as one token. % \end{function} -% +% +% \begin{function}{% +% \cs_if_exist_p:N +% } +% \begin{syntax} +% "\cs_if_exist_p:N" +% \end{syntax} +% This function does the opposite of "\cs_if_free_p:N". +% \end{function} +% +% \begin{function}{% +% \cs_if_exist:NTF | +% \cs_if_exist:NT | +% \cs_if_exist:NF | +% \cs_if_exist:cTF | +% \cs_if_exist:cT | +% \cs_if_exist:cF +% } +% \begin{syntax} +% "\cs_if_exist:NTF" "{""}{""}" +% \end{syntax} +% These functions check if exists and then execute either or . Exactly the opposite of "\cs_if_free:NTF". +% \end{function} +% +% \begin{function}{% +% \cs_if_really_exist:cTF | +% \cs_if_really_exist:cF | +% \cs_if_really_exist:cT +% } +% \begin{syntax} +% "\cs_if_really_exist:cTF" "{""}" "{""} {""}" +% \end{syntax} +% The opposite of "\cs_if_really_free:cTF". +% \end{function} +% +% % \begin{function}{% % \chk_new_cs:N | % } @@ -145,9 +304,10 @@ % control sequences by \TeX{} when "\cs:w" "..." "\cs_end:" is % used). % \end{function} -% +% % \begin{function}{% % \chk_exist_cs:N | +% \chk_exist_cs:c % } % \begin{syntax} % "\chk_exist_cs:N" @@ -155,14 +315,136 @@ % This function checks that is defined. If it is not an error % is generated. % \end{function} -% -% +% +% +% \begin{variable}{% +% \c_true | +% \c_false +% } +% \begin{syntax} +% \end{syntax} +% Constants that represent `true' or `false', respectively. Used to +% implement predicates. +% \end{variable} +% +% +% +% \subsection{Selecting and discarding tokens from the input stream} +% +% The conditional processing could not have been implemented without +% being able to gobble and select which tokens to use from the input +% stream. +% +% \begin{function}{% +% \use_none:n | +% \use_none:nn | +% \use_none:nnn | +% \use_none:nnnn | +% \use_none:nnnnn | +% \use_none:nnnnnn | +% \use_none:nnnnnnn | +% \use_none:nnnnnnnn | +% \use_none:nnnnnnnnn | +% } +% \begin{syntax} +% "\use_none:n" "{""}"\\ +% "\use_none:nn" "{""}{""}" +% \end{syntax} +% These functions gobble the tokens or brace groups from the input +% stream. +% \end{function} +% +% +% \begin{function}{\use_arg_i:n} +% \begin{syntax} +% "\use_arg_i:n" "{" "}" +% \end{syntax} +% Function that executes the next argument after removing the +% surrounding braces. Used to implement conditionals. +% \end{function} +% +% \begin{function}{% +% \use_arg_i:nn | +% \use_arg_ii:nn | +% } +% \begin{syntax} +% "\use_arg_i:nn" "{" "}{" "}" +% \end{syntax} +% Functions that execute the first or second argument respectively, +% after removing the surrounding braces. Primarily used to implement +% conditionals. +% \end{function} +% +% \begin{function}{% +% \use_arg_i:nnn | +% \use_arg_ii:nnn | +% \use_arg_iii:nnn | +% } +% \begin{syntax} +% "\use_arg_i:nnn" "{" "}{" "}{" "}" +% \end{syntax} +% Functions that pick up one of three arguments and execute them after +% removing the surrounding braces. Should be described somewhere else. +% \end{function} +% +% \begin{function}{% +% \use_arg_i:nnnn | +% \use_arg_ii:nnnn | +% \use_arg_iii:nnnn | +% \use_arg_iv:nnnn | +% } +% \begin{syntax} +% "\use_arg_i:nnnn" "{" "}{" "}{" "}{" "}" +% \end{syntax} +% Functions that pick up one of four arguments and execute them after +% removing the surrounding braces. +% \end{function} +% +% A different kind of functions for selecting tokens from the token +% stream are those that use delimited arguments. +% +% \begin{function}{% +% \use_none_delimit_by_q_nil:w | +% \use_none_delimit_by_q_stop:w | +% } +% \begin{syntax} +% "\use_none_delimit_by_q_nil:w" "\q_nil" +% \end{syntax} +% Gobbles . Useful in gobbling the remainder in a list +% structure. +% \end{function} +% +% \begin{function}{% +% \use_arg_i_delimit_by_q_nil:nw | +% \use_arg_i_delimit_by_q_stop:nw | +% } +% \begin{syntax} +% "\use_arg_i_delimit_by_q_nil:nw" "{""}" "\q_nil" +% \end{syntax} +% Gobbles and executes afterwards. This can also +% be used to get the first item in a token list. +% \end{function} +% +% +% \begin{function}{% +% \use_arg_i_after_fi:nw | +% \use_arg_i_after_else:nw | +% \use_arg_i_after_or:nw +% } +% \begin{syntax} +% "\use_arg_i_after_fi:nw" "{""}" "\fi:" +% "\use_arg_i_after_else:nw" "{""}" "\else:" "\fi:" +% "\use_arg_i_after_or:nw" "{""}" "\or:" "\fi:" +% \end{syntax} +% Executes after executing closing out "\fi:". +% \end{function} +% % \subsection{Internal functions} -% +% % \begin{function}{% % \cs:w | -% \cs_end: | -% } +% \cs_end: +% } % \begin{syntax} % "\cs:w" "\cs_end:" % \end{syntax} @@ -175,10 +457,11 @@ % "\cs_end:". % \end{texnote} % \end{function} -% +% % \begin{function}{\pref_global:D | % \pref_long:D | -% } +% \pref_protected:D | +% } % \begin{syntax} % "\pref_global:D" "\def:Npn" % \end{syntax} @@ -186,61 +469,55 @@ % functions (namely \ldots). The result of prefixing a function % definition with "\pref_global:D" makes the definition global, % "\pref_long:D" change the argument scanning mechanism so that it -% allows "\par" tokens in the argument of the prefixed function. -% +% allows "\par" tokens in the argument of the prefixed function, +% and "\pref_protected:D" makes the definition robust in "\write"s etc. +% +% % None of these internal functions should be used by a programmer since % the necessary combinations are all available as separate function, % e.g., "\def_long:Npn" is internally implemented as "\pref_long:D" -% "\def_long:Npn". +% "\def:Npn". % \begin{texnote} -% These prefixes are the primitives \tn{global}, \tn{long}. -% The \tn{outer} isn't used at all within \LaTeX3 -% because \ldots +% These prefixes are the primitives \tn{global}, \tn{long}, and +% \tn{protected}. The \tn{outer} isn't used at all within \LaTeX3 +% because \ldots % \end{texnote} % \end{function} -% -% \subsection{Choice functions} % -% \begin{function}{% -% \use_choice_i:nn | -% \use_choice_ii:nn | -% } -% \begin{syntax} -% "\use_choice_i:nn" "{" "}{" "}" -% \end{syntax} -% Functions that execute the first or second argument respectively, -% after removing the surrounding braces. Used to implement conditionals. -% \end{function} % -% \begin{function}{% -% \use_choice_i:nnn | -% \use_choice_ii:nnn | -% \use_choice_iii:nnn | +% +% \begin{function}{\io_put_log:x | +% \io_put_term:x | +% \io_put_deferred:Nx | % } % \begin{syntax} -% "\use_choice_i:nnn" "{" "}{" "}{" "}" +% "\io_put_log:x" "{""}" +% "\io_put_deferred:Nx" "{""}" % \end{syntax} -% Functions that pick up one of three arguments and execute them after -% removing the surrounding braces. Should be described somewhere else. +% Writes to either to log or the terminal. % \end{function} % -% \begin{function}{\use:n} -% \begin{syntax} -% "\use:n" "{" "}" -% \end{syntax} -% Function that executes the next argument after removing the -% surrounding braces. Used to implement conditionals. -% \end{function} +% \subsection{Defining functions} +% % -% \section{Defining functions} -% % There are two types of function definitions in \LaTeX3: versions % that check if the function name is still unused, and versions that % simply make the definition. The later are used for internal scratch % functions that get new meanings all over the place. -% -% (Parts of this module are a mess, as far as naming conventions are -% concerned.) +% +% For each type there is an additional choice to be made: Does the +% function to be defined contain delimited arguments? The answer in +% 99\% of the cases is no, so in most cases the programmer just want +% to input the number of arguments, which is basically how +% \cs{newcommand} in \LaTeXe{} works. Therefore we provide functions +% that expect a number as the primary type and later on in this module +% you can find the ones with the more primitive syntax. +% +% A definition of a new function can be done locally and globally. Currently +% nearly all function definitions are done locally on top level, in +% other words they are global but don't show it. Therefore I think it may +% be better to remove the local variants in the future and declare all +% checked function definitions global. % % \begin{texnote} % While \TeX{} makes all definition functions directly available to the @@ -249,132 +526,462 @@ % \TeX{} a combination of prefixes and definition functions are provided % as individual functions. % \end{texnote} -% -% \subsection{Defining new functions} -% -% A definition of a new function can be done locally and globally. Currently -% nearly all function definitions are done locally on top level, in -% other words they are global but don't show it. Therefore I think it may -% be better to remove the local variants in the future and declare all -% checked function definitions global. -% -% \begin{function}{\def_new:Npn | -% \def_new:Npx | -% \def_new:cpn | -% \def_new:cpx +% +% +% \subsubsection{Defining new functions} +% +% Firstly comes to variants most used namely those taking a number to +% denote the number of arguments. +% +% \begin{function}{\def_new:NNn | +% \def_new:NNx | +% \def_new:cNn | +% \def_new:cNx % } % \begin{syntax} -% "\def_new:Npn" "{" "}" +% "\def_new:NNn" "{" "}" % \end{syntax} % Defines a new function, making sure that is unused so far. -% may consist of arbitrary parameter specification in \TeX{} -% syntax. It is under the responsibility of the programmer to name the -% new function according to the rules laid out in the previous section. -% is either passed literally or may be subject to expansion -% (under the "x" variants). +% is the number of arguments which is in the interval $[0,9]$ +% otherwise an error is raised. It is under the responsibility of the +% programmer to name the new function according to the rules laid out +% in the previous section. is either passed literally or may +% be subject to expansion (under the "x" variants). % \end{function} % -% \begin{function}{\gdef_new:Npn +% \begin{function}{\gdef_new:NNn | +% \gdef_new:cNn | +% \gdef_new:NNx | +% \gdef_new:cNx % } % \begin{syntax} -% "\gdef_new:Npn" "{" "}" +% "\gdef_new:NNn" "{" "}" % \end{syntax} -% Like "\def_new:Npn" but defines the new function globally. See -% comments above. +% Like "\def_new:NNn" but defines the new function globally. % \end{function} -% -% \begin{function}{\def_long_new:Npn | +% +% \begin{function}{\def_long_new:NNn | +% \def_long_new:NNx | +% \def_long_new:cNn | +% \def_long_new:cNx % } % \begin{syntax} -% "\def_long_new:Npn" "{" "}" +% "\def_long_new:NNn" "{" "}" % \end{syntax} % Defines a function that may contain "\par" tokens in the argument(s) % when called. This is not allowed for normal functions. % \end{function} -% -% \begin{function}{\let_new:NN | -% \glet_new:NN} +% +% \begin{function}{\gdef_long_new:NNn | +% \gdef_long_new:NNx | +% \gdef_long_new:cNn | +% \gdef_long_new:cNx +% } % \begin{syntax} -% "\let_new:NN" +% "\gdef_long_new:NNn" "{" "}" % \end{syntax} -% Gives the function the current meaning of . Again, we may -% do this alway globally. +% Global versions of the above functions. % \end{function} -% -% \subsection{Defining internal functions (no checks)} -% -% Besides the function definitions that check whether or not their -% argument is an unused function we need function definitions that -% overwrite currently used definitions. The following functions are -% provided for this purpose. -% -% \begin{function}{\def:Npn | -% \def:Npx | -% \def:cpn | -% \def:cpx | +% +% \begin{function}{\def_protected_new:NNn | +% \def_protected_new:NNx | +% \def_protected_new:cNn | +% \def_protected_new:cNx % } % \begin{syntax} -% "\def:Npn" "{" "}" +% "\def_protected_new:NNn" "{" "}" % \end{syntax} -% Like "\def_new:Npn" etc.\ but does not check the name. -% \begin{texnote} -% "\def:Npn" is the \LaTeX3 name for \TeX{}'s \tn{def} and "\def:Npx" -% corresponds to the primitive \tn{edef}. The "\def:cpn" function was -% known in \LaTeX2 as \tn{@namedef}. "\def:cpx" has no equivalent. -% \end{texnote} +% Defines a function that does not expand when inside an |x| type +% expansion. % \end{function} -% -% \begin{function}{\gdef:Npn | -% \gdef:Npx | -% \gdef:cpn | -% \gdef:cpx | +% +% \begin{function}{\gdef_protected_new:NNn | +% \gdef_protected_new:NNx | +% \gdef_protected_new:cNn | +% \gdef_protected_new:cNx % } % \begin{syntax} -% "\gdef:Npn" "{" "}" +% "\gdef_protected_new:NNn" "{" "}" % \end{syntax} -% Like "\def:Npn" but defines the globally. -% \begin{texnote} -% "\gdef:Npn" and "\gdef:Npx" are known to \TeX{}hackers as \tn{gdef} -% and \tn{xdef}. -% \end{texnote} +% Global versions of the above functions. % \end{function} -% -% \begin{function}{\def:No | -% \gdef:No +% +% \begin{function}{\def_protected_long_new:NNn | +% \def_protected_long_new:NNx | +% \def_protected_long_new:cNn | +% \def_protected_long_new:cNx % } % \begin{syntax} -% "\def:No" "{" "}" +% "\def_protected_long_new:NNn" "{" "}" % \end{syntax} -% Local and global variant that expands code once before defining . -% The function may not take as the others do. Perhaps this -% should be changed. +% Defines a function that is both robust and may contain "\par" tokens +% in the argument(s) when called. % \end{function} -% -% \begin{function}{\def_long:Npn | -% \def_long:Npx | -% \def_long:cpn | +% +% \begin{function}{\gdef_protected_long_new:NNn | +% \gdef_protected_long_new:NNx | +% \gdef_protected_long_new:cNn | +% \gdef_protected_long_new:cNx % } % \begin{syntax} -% "\def_long:Npn" "{" "}" +% "\gdef_protected_long_new:NNn" "{" "}" % \end{syntax} -% Like "\def:Npn" but allows "\par" tokens in the arguments of the -% function being defined. +% Global versions of the above functions. % \end{function} -% -% \begin{function}{\gdef_long:Npn | +% +% +% +% +% +% Secondly comes the ones where the programmer can use delimited +% arguments. Rarely needed outside the kernel. +% +% +% \begin{function}{\def_new:Npn | +% \def_new:Npx | +% \def_new:cpn | +% \def_new:cpx +% } +% \begin{syntax} +% "\def_new:Npn" "{" "}" +% \end{syntax} +% Defines a new function, making sure that is unused so far. +% may consist of arbitrary parameter specification in \TeX{} +% syntax. It is under the responsibility of the programmer to name the +% new function according to the rules laid out in the previous section. +% is either passed literally or may be subject to expansion +% (under the "x" variants). +% \end{function} +% +% \begin{function}{\gdef_new:Npn | +% \gdef_new:cpn | +% \gdef_new:Npx | +% \gdef_new:cpx +% } +% \begin{syntax} +% "\gdef_new:Npn" "{" "}" +% \end{syntax} +% Like "\def_new:Npn" but defines the new function globally. See +% comments above. +% \end{function} +% +% \begin{function}{\def_long_new:Npn | +% \def_long_new:Npx | +% \def_long_new:cpn | +% \def_long_new:cpx +% } +% \begin{syntax} +% "\def_long_new:Npn" "{" "}" +% \end{syntax} +% Defines a function that may contain "\par" tokens in the argument(s) +% when called. This is not allowed for normal functions. +% \end{function} +% +% \begin{function}{\gdef_long_new:Npn | +% \gdef_long_new:Npx | +% \gdef_long_new:cpn | +% \gdef_long_new:cpx +% } +% \begin{syntax} +% "\gdef_long_new:Npn" "{" "}" +% \end{syntax} +% Global versions of the above functions. +% \end{function} +% +% \begin{function}{\def_protected_new:Npn | +% \def_protected_new:Npx | +% \def_protected_new:cpn | +% \def_protected_new:cpx +% } +% \begin{syntax} +% "\def_protected_new:Npn" "{" "}" +% \end{syntax} +% Defines a function that does not expand when inside an |x| type +% expansion. +% \end{function} +% +% \begin{function}{\gdef_protected_new:Npn | +% \gdef_protected_new:Npx | +% \gdef_protected_new:cpn | +% \gdef_protected_new:cpx +% } +% \begin{syntax} +% "\gdef_protected_new:Npn" "{" "}" +% \end{syntax} +% Global versions of the above functions. +% \end{function} +% +% \begin{function}{\def_protected_long_new:Npn | +% \def_protected_long_new:Npx | +% \def_protected_long_new:cpn | +% \def_protected_long_new:cpx +% } +% \begin{syntax} +% "\def_protected_long_new:Npn" "{" "}" +% \end{syntax} +% Defines a function that is both robust and may contain "\par" tokens +% in the argument(s) when called. +% \end{function} +% +% \begin{function}{\gdef_protected_long_new:Npn | +% \gdef_protected_long_new:Npx | +% \gdef_protected_long_new:cpn | +% \gdef_protected_long_new:cpx +% } +% \begin{syntax} +% "\gdef_protected_long_new:Npn" "{" "}" +% \end{syntax} +% Global versions of the above functions. +% \end{function} +% +% \begin{function}{\let_new:NN | +% \let_new:cN | +% \let_new:Nc | +% \let_new:cc | +% \glet_new:NN| +% \glet_new:cN| +% \glet_new:Nc| +% \glet_new:cc } +% \begin{syntax} +% "\let_new:NN" +% \end{syntax} +% Gives the function the current meaning of . Again, we may +% do this always globally. +% \end{function} +% +% +% +% \subsubsection{Undefining functions} +% +% \begin{function}{ \cs_gundefine:N +% } +% \begin{syntax} +% "\cs_gundefine:N" +% \end{syntax} +% Undefines the control sequence. +% \end{function} +% +% \subsubsection{Defining internal functions (no checks)} +% +% Besides the function definitions that check whether or not their +% argument is an unused function we need function definitions that +% overwrite currently used definitions. The following functions are +% provided for this purpose. +% +% First comes the versions expecting a number to denote the number of +% arguments. +% +% \begin{function}{\def:NNn | +% \def:NNx | +% \def:cNn | +% \def:cNx | +% } +% \begin{syntax} +% "\def:NNn" "{" "}" +% \end{syntax} +% Like "\def_new:NNn" etc.\ but does not check the name. +% \end{function} +% +% \begin{function}{\gdef:NNn | +% \gdef:NNx | +% \gdef:cNn | +% \gdef:cNx | +% } +% \begin{syntax} +% "\gdef:NNn" "{" "}" +% \end{syntax} +% Like "\def:NNn" but defines the globally. +% \end{function} +% +% +% \begin{function}{\def_long:NNn | +% \def_long:NNx | +% \def_long:cNn | +% \def_long:cNx | +% } +% \begin{syntax} +% "\def_long:NNn" "{" "}" +% \end{syntax} +% Like "\def:NNn" but allows "\par" tokens in the arguments of the +% function being defined. +% \end{function} +% +% \begin{function}{\gdef_long:NNn | +% \gdef_long:NNx | +% \gdef_long:cNn | +% \gdef_long:cNx | +% } +% \begin{syntax} +% "\gdef_long:NNn" "{" "}" +% \end{syntax} +% Global variant of "\def_long:NNn". +% \end{function} +% +% \begin{function}{\def_protected:NNn | +% \def_protected:cNn | +% \def_protected:NNx | +% \def_protected:cNx | +% } +% \begin{syntax} +% "\def_protected:NNn" "{" "}" +% \end{syntax} +% Naturally robust macro that won't expand in an |x| type argument. +% This also comes as a |long| version. If you for some reason want to +% expand it inside an |x| type expansion, prefix it with +% |\exp_after:NN \use_noop:|. +% \end{function} +% +% \begin{function}{\gdef_protected:NNn | +% \gdef_protected:cNn | +% \gdef_protected:NNx | +% \gdef_protected:cNx | +% } +% \begin{syntax} +% "\gdef_protected:NNn" "{" "}" +% \end{syntax} +% Global versions of the above functions. +% \end{function} +% +% \begin{function}{\def_protected_long:NNn | +% \def_protected_long:cNn | +% \def_protected_long:NNx | +% \def_protected_long:cNx | +% } +% \begin{syntax} +% "\def_protected_long:NNn" "{" "}" +% \end{syntax} +% Naturally robust macro that won't expand in an |x| type argument. +% These varieties also allow |\par| tokens in the arguments of the +% function being defined. +% \end{function} +% +% \begin{function}{\gdef_protected_long:NNn | +% \gdef_protected_long:cNn | +% \gdef_protected_long:NNx | +% \gdef_protected_long:cNx | +% } +% \begin{syntax} +% "\gdef_protected_long:NNn" "{" "}" +% \end{syntax} +% Global versions of the above functions. +% \end{function} +% +% Secondly the ones that use the primitive parameter build-up: +% +% \begin{function}{\def:Npn | +% \def:Npx | +% \def:cpn | +% \def:cpx | +% } +% \begin{syntax} +% "\def:Npn" "{" "}" +% \end{syntax} +% Like "\def_new:Npn" etc.\ but does not check the name. +% \begin{texnote} +% "\def:Npn" is the \LaTeX3 name for \TeX{}'s \tn{def} and "\def:Npx" +% corresponds to the primitive \tn{edef}. The "\def:cpn" function was +% known in \LaTeX2 as \tn{@namedef}. "\def:cpx" has no equivalent. +% \end{texnote} +% \end{function} +% +% \begin{function}{\gdef:Npn | +% \gdef:Npx | +% \gdef:cpn | +% \gdef:cpx | +% } +% \begin{syntax} +% "\gdef:Npn" "{" "}" +% \end{syntax} +% Like "\def:Npn" but defines the globally. +% \begin{texnote} +% "\gdef:Npn" and "\gdef:Npx" are known to \TeX{}hackers as \tn{gdef} +% and \tn{xdef}. +% \end{texnote} +% \end{function} +% +% +% \begin{function}{\def_long:Npn | +% \def_long:Npx | +% \def_long:cpn | +% \def_long:cpx | +% } +% \begin{syntax} +% "\def_long:Npn" "{" "}" +% \end{syntax} +% Like "\def:Npn" but allows "\par" tokens in the arguments of the +% function being defined. +% \end{function} +% +% \begin{function}{\gdef_long:Npn | % \gdef_long:Npx | +% \gdef_long:cpn | +% \gdef_long:cpx | % } % \begin{syntax} % "\gdef_long:Npn" "{" "}" % \end{syntax} % Global variant of "\def_long:Npn". % \end{function} -% +% +% \begin{function}{\def_protected:Npn | +% \def_protected:cpn | +% \def_protected:Npx | +% \def_protected:cpx | +% } +% \begin{syntax} +% "\def_protected:Npn" "{" "}" +% \end{syntax} +% Naturally robust macro that won't expand in an |x| type argument. +% This also comes as a |long| version. If you for some reason want to +% expand it inside an |x| type expansion, prefix it with +% |\exp_after:NN \use_noop:|. +% \end{function} +% +% \begin{function}{\gdef_protected:Npn | +% \gdef_protected:cpn | +% \gdef_protected:Npx | +% \gdef_protected:cpx | +% } +% \begin{syntax} +% "\gdef_protected:Npn" "{" "}" +% \end{syntax} +% Global versions of the above functions. +% \end{function} +% +% \begin{function}{\def_protected_long:Npn | +% \def_protected_long:cpn | +% \def_protected_long:Npx | +% \def_protected_long:cpx | +% } +% \begin{syntax} +% "\def_protected_long:Npn" "{" "}" +% \end{syntax} +% Naturally robust macro that won't expand in an |x| type argument. +% These varieties also allow |\par| tokens in the arguments of the +% function being defined. +% \end{function} +% +% \begin{function}{\gdef_protected_long:Npn | +% \gdef_protected_long:cpn | +% \gdef_protected_long:Npx | +% \gdef_protected_long:cpx | +% } +% \begin{syntax} +% "\gdef_protected_long:Npn" "{" "}" +% \end{syntax} +% Global versions of the above functions. +% \end{function} +% +% +% % \begin{function}{\let:NN | -% \glet:NN | % \let:cN | % \let:Nc | -% \let:cc +% \let:cc | +% \glet:NN | +% \glet:cN | +% \glet:Nc | +% \glet:cc % } % \begin{syntax} % "\let:cN" @@ -382,7 +989,7 @@ % Gives the function the current meaning of . Again, we may % always do this globally. % \end{function} -% +% % \begin{function}{\let:NwN} % \begin{syntax} % "\let:NwN" @@ -399,61 +1006,388 @@ % \end{function} % % +% \subsection{Defining test functions} +% +% +% \begin{function}{ +% \def_test_function:npn | +% \def_long_test_function:npn | +% \def_test_function_new:npn | +% \def_long_test_function_new:npn | +% } +% \begin{syntax} +% "\def_test_function_new:npn" "{"name"}" "{""}" +% \end{syntax} +% Define all the common test cases for a simple test to reduce the +% risk of typos. As an example here's how we defined the functions +% "\cs_free:cTF", "\cs_free:cT" and "\cs_free:cF". You just have to +% fill in the test. +% \begin{verbatim} +% \def_test_function:npn{cs_free:c} #1 { +% \exp_after:NN \if_meaning:NN \cs:w#1\cs_end: \scan_stop:} +% \end{verbatim} +% Be careful not to use this function inside some primitive +% conditional as \TeX\ will most likely get confused because of the +% unmatched conditionals. +% \end{function} +% +% +% \subsection{The innards of a function} +% +% \begin{function}{\cs_to_str:N} +% \begin{syntax} +% "\cs_to_str:N" +% \end{syntax} +% This function return the name of as a sequence of letters with +% the escape character removed. +% \end{function} +% +% \begin{function}{\token_to_string:N} +% \begin{syntax} +% "\token_to_string:N" +% \end{syntax} +% This function return the name of as a sequence of letters +% including the escape character. +% \end{function} +% +% \begin{function}{\token_to_meaning:N} +% \begin{syntax} +% "\token_to_meaning:N" +% \end{syntax} +% This function returns the type and definition of as a sequence +% of letters. +% \end{function} +% +% Other functions regarding arbitrary tokens can be found in the +% \textsf{l3token} module. +% +% \subsection{Grouping and scanning} +% +% \begin{function}{\scan_stop:} +% \begin{syntax} +% "\scan_stop:" +% \end{syntax} +% This function stops \TeX's scanning ahead when ending a number. +% \begin{texnote} +% This is the \TeX{} primitive \tn{relax} renamed. +% \end{texnote} +% \end{function} +% +% +% \begin{function}{\group_begin:| +% \group_end:} +% \begin{syntax} +% "\group_begin:" <...> "\group_end:" +% \end{syntax} +% Encloses <...> inside a group. +% \begin{texnote} +% These are the \TeX{} primitives \tn{begingroup} and \tn{endgroup} +% renamed. +% \end{texnote} +% \end{function} +% +% +% \subsection{Engine specific definitions} +% +% \begin{function}{\engine_aleph:TF} +% \begin{syntax} +% "\engine_aleph:TF" "{""}" "{""}" +% \end{syntax} +% This function detects if we're running an Aleph based format. This +% is particularly useful when allocating registers. +% \end{function} +% +% +% % \StopEventually{} -% -% \section{Renaming some \TeX{} primitives (again)} % +% +% \subsection{The Implementation} +% We start by ensuring that the required packages are loaded. We need +% \textsf{l3names} to get things going but we actually need it very +% early on, so it is loaded at the very top of this file. Also, most +% of the code below won't run until \textsf{l3expan} has been +% loaded. +% +% \subsubsection{Renaming some \TeX{} primitives (again)} +% +% \begin{macro}{\let:NwN} % Having given all the tex primitives a consistent name, we need to % give sensible names to the ones we actually want to use. -% These will be defined as needed in the apropriate modules, but +% These will be defined as needed in the appropriate modules, but % do a few now, just to get started.\footnote{This renaming gets expensive % in terms of csname usage, an alternative scheme would be to just use % the ``tex\ldots D'' name in the cases where no good alternative exists.} % \begin{macrocode} -%<*package> -\tex_let:D \let:NwN \tex_let:D -\let:NwN \def:Npn \tex_def:D +%<*initex|package> +\tex_let:D \let:NwN \tex_let:D +% \end{macrocode} +% \end{macro} +% \begin{macro}{\if_true:} +% \begin{macro}{\if_false:} +% \begin{macro}{\else:} +% \begin{macro}{\fi:} +% \begin{macro}{\reverse_if:N} +% \begin{macro}{\if:w} +% \begin{macro}{\if_charcode:w} +% \begin{macro}{\if_catcode:w} +% Then some conditionals. +% \begin{macrocode} +\let:NwN \if_true: \tex_iftrue:D +\let:NwN \if_false: \tex_iffalse:D +\let:NwN \else: \tex_else:D +\let:NwN \fi: \tex_fi:D +\let:NwN \reverse_if:N \etex_unless:D +\let:NwN \if:w \tex_if:D +\let:NwN \if_charcode:w \tex_if:D +\let:NwN \if_catcode:w \tex_ifcat:D +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\if_meaning:NN} +% \begin{macro}{\if_token_eq:NN} +% \begin{macro}{\if_cs_meaning_eq:NN} +% Some different names for |\ifx|.\footnote{MH: Clean up at some point} +% \begin{macrocode} +\let:NwN \if_meaning:NN \tex_ifx:D +\let:NwN \if_token_eq:NN \tex_ifx:D +\let:NwN \if_cs_meaning_eq:NN\tex_ifx:D +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\if_mode_math:} +% \begin{macro}{\if_mode_horizontal:} +% \begin{macro}{\if_mode_vertical:} +% \begin{macro}{\if_mode_inner:} +% \TeX{} lets us detect some if its modes. +% \begin{macrocode} +\let:NwN \if_mode_math: \tex_ifmmode:D +\let:NwN \if_mode_horizontal:\tex_ifhmode:D +\let:NwN \if_mode_vertical: \tex_ifvmode:D +\let:NwN \if_mode_inner: \tex_ifinner:D +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\if_cs_exist:N} +% \begin{macro}{\if_cs_exist:w} +% \begin{macrocode} +\let:NwN \if_cs_exist:N \etex_ifdefined:D +\let:NwN \if_cs_exist:w \etex_ifcsname:D +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\exp_after:NN} +% \begin{macro}{\exp_not:N} +% \begin{macro}{\exp_not:n} +% The three |\exp_| functions are used in the \textsf{l3expan} module +% where they are described. +% \begin{macrocode} +\let:NwN \exp_after:NN \tex_expandafter:D +\let:NwN \exp_not:N \tex_noexpand:D +\let:NwN \exp_not:n \etex_unexpanded:D +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\io_put_deferred:Nx} +% \begin{macro}{\token_to_meaning:N} +% \begin{macro}{\token_to_string:N} +% \begin{macro}{\cs:w} +% \begin{macro}{\cs_end:} +% \begin{macro}{\cs_meaning:N} +% \begin{macro}{\cs_meaning:c} +% \begin{macro}{\cs_show:N} +% \begin{macro}{\cs_show:c} +% \begin{macrocode} +\let:NwN \io_put_deferred:Nx \tex_write:D +\let:NwN \token_to_meaning:N \tex_meaning:D +\let:NwN \token_to_string:N \tex_string:D +\let:NwN \cs:w \tex_csname:D +\let:NwN \cs_end: \tex_endcsname:D +\let:NwN \cs_meaning:N \tex_meaning:D +\tex_def:D \cs_meaning:c #1{\exp_after:NN\cs_meaning:N\cs:w #1\cs_end:} +\let:NwN \cs_show:N \tex_show:D +\tex_def:D \cs_show:c #1{\exp_after:NN\cs_show:N\cs:w #1\cs_end:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\scan_stop:} +% \begin{macro}{\group_begin:} +% \begin{macro}{\group_end:} +% The next three are basic functions for which there also exist +% versions that are safe inside alignments. These safe versions are +% defined in the \textsf{l3prg} module. +% \begin{macrocode} +\let:NwN \scan_stop: \tex_relax:D +\let:NwN \group_begin: \tex_begingroup:D +\let:NwN \group_end: \tex_endgroup:D +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\group_execute_after:N} +% \begin{macrocode} +\let:NwN \group_execute_after:N \tex_aftergroup:D +% \end{macrocode} +% \end{macro} +% \begin{macro}{\the_internal:D} +% \begin{macro}{\pref_global:D} +% \begin{macro}{\pref_long:D} +% \begin{macro}{\pref_protected:D} +% These following names are temporary and should be removed as soon +% as possible (April 1998). +% \begin{macrocode} +\let:NwN \the_internal:D \tex_the:D +\let:NwN \pref_global:D \tex_global:D +% \end{macrocode} +% "\pref_long:D" has been documented for years but didn't exist\dots{} +% Added it and the robustness prefix. +% \begin{macrocode} +\let:NwN \pref_long:D \tex_long:D +\let:NwN \pref_protected:D \etex_protected:D +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% \subsubsection {Defining functions} +% +% +% We start by providing functions for the typical definition +% functions. First the local ones. +% +% \begin{macro}{\def:Npn} +% \begin{macro}{\def:Npx} +% \begin{macro}{\def_long:Npn} +% \begin{macro}{\def_long:Npx} +% \begin{macro}{\def_protected:Npn} +% \begin{macro}{\def_protected:Npx} +% \begin{macro}{\def_protected_long:Npn} +% \begin{macro}{\def_protected_long:Npx} +% All assignment functions in \LaTeX3 should be naturally robust; +% after all, the \TeX\ primitives for assignments are and it can be +% a cause of problems if others aren't. +% \begin{macrocode} +\let:NwN \def:Npn \tex_def:D +\let:NwN \def:Npx \tex_edef:D +\pref_protected:D \def:Npn \def_long:Npn {\pref_long:D \def:Npn} +\pref_protected:D \def:Npn \def_long:Npx {\pref_long:D \def:Npx} +\pref_protected:D \def:Npn \def_protected:Npn {\pref_protected:D \def:Npn} +\pref_protected:D \def:Npn \def_protected:Npx {\pref_protected:D \def:Npx} +\def_protected:Npn \def_protected_long:Npn { + \pref_protected:D \pref_long:D \def:Npn +} +\def_protected:Npn \def_protected_long:Npx { + \pref_protected:D \pref_long:D \def:Npx +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\gdef:Npn} +% \begin{macro}{\gdef:Npx} +% \begin{macro}{\gdef_long:Npn} +% \begin{macro}{\gdef_long:Npx} +% \begin{macro}{\gdef_protected:Npn} +% \begin{macro}{\gdef_protected:Npx} +% \begin{macro}{\gdef_protected_long:Npn} +% \begin{macro}{\gdef_protected_long:Npx} +% Global versions of the above functions. +% \begin{macrocode} \let:NwN \gdef:Npn \tex_gdef:D -\let:NwN \def:Npx \tex_edef:D \let:NwN \gdef:Npx \tex_xdef:D -\let:NwN \if:w \tex_if:D -\let:NwN \if_num:w \tex_ifnum:D -\let:NwN \if_meaning:NN \tex_ifx:D -\let:NwN \if_false: \tex_iffalse:D -\let:NwN \else: \tex_else:D -\let:NwN \fi: \tex_fi:D -\let:NwN \io_put_deferred:Nx \tex_write:D -\let:NwN \token_to_meaning:N \tex_meaning:D -\let:NwN \token_to_string:N \tex_string:D -\let:NwN \cs:w \tex_csname:D -\let:NwN \cs_end: \tex_endcsname:D -\let:NwN \exp_after:NN \tex_expandafter:D -\let:NwN \scan_stop: \tex_relax:D -\let:NwN \exp_not:N \tex_noexpand:D -\let:NwN \group_begin: \tex_begingroup:D -\let:NwN \group_end: \tex_endgroup:D -% \end{macrocode} -% -% These following names are temporary and should be removed as soon -% as possible (April 1998). -% \begin{macrocode} -\let:NwN \the_internal:D \tex_the:D -\let:NwN \pref_global:D \tex_global:D +\def_protected:Npn \gdef_long:Npn {\pref_long:D \gdef:Npn} +\def_protected:Npn \gdef_long:Npx {\pref_long:D \gdef:Npx} +\def_protected:Npn \gdef_protected:Npn {\pref_protected:D \gdef:Npn} +\def_protected:Npn \gdef_protected:Npx {\pref_protected:D \gdef:Npx} +\def_protected:Npn \gdef_protected_long:Npn { + \pref_protected:D \pref_long:D \gdef:Npn +} +\def_protected:Npn \gdef_protected_long:Npx { + \pref_protected:D \pref_long:D \gdef:Npx +} % \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsubsection{Predicate implementation} % -% -% \section {Defining and checking (new) functions} +% I think Michael originated the idea of expandable boolean tests. At +% first these were supposed to expand into either \texttt{TT} or +% \texttt{TF} to be tested using |\if:w| but this was later changed to +% \texttt{00} and \texttt{01}, so they can be used in logical +% operations (see the \textsf{l3prg} module). We need this from the +% get-go. % -% We need some constants now, that should actually all be defined -% together. We try to avoid using count registers for constants as -% much as possible. +% \begin{macro}{\c_true} +% \begin{macro}{\c_false} +% Here are the canonical boolean values. +% \begin{macrocode} +\def:Npn \c_true {00} +\def:Npn \c_false {01} +% \end{macrocode} +% \end{macro} +% \end{macro} % +% \subsubsection {Defining and checking (new) functions} +% +% \begin{macro}{\c_minus_one} +% \begin{macro}{\c_sixteen} +% We need the constants |\c_minus_one| and |\c_sixteen| now for +% writing information to the log and the terminal but the +% rest are defined in the \textsf{l3num} module -- at least for the +% ones that can be defined with |\tex_chardef:D| or +% |\tex_mathchardef:D|. Otherwise the \textsf{l3int} module is +% required but it can't be used until the allocation has been set +% up properly! The actual allocation mechanism is in +% \textsf{l3alloc} and as \TeX{} wants to reserve count registers +% 0--9, the first available one is~10 so we use that for +% |\c_minus_one|. % \begin{macrocode} -\let:NwN\c_minus_one\m@ne -\tex_chardef:D \c_one = 1\scan_stop: +%<*!initex> +\let:NwN \c_minus_one\m@ne +% +%<*!package> +\tex_countdef:D \c_minus_one = 10 \scan_stop: +\c_minus_one = -1 \scan_stop: +% \tex_chardef:D \c_sixteen = 16\scan_stop: -\tex_mathchardef:D \c_two_hundred_fifty_six = 256\scan_stop: % \end{macrocode} +% \end{macro} +% \end{macro} % % We provide two kinds of functions that can be used to define % control sequences. On the one hand we have functions that check @@ -462,11 +1396,11 @@ % if the argument is already defined. % % Before we can define them, we need some auxiliary macros that -% allow us to generate error messages. The definitions here are +% allow us to generate error messages. The definitions here are % only temporary, they will be redefined later on. % -% \begin{macro}{\io_put_log:x} -% \begin{macro}{\io_put_term:x} +% \begin{macro}{\io_put_log:x} +% \begin{macro}{\io_put_term:x} % We define a routine to write only to the log file. And a % similar one for writing to both the log file and the terminal. % @@ -476,18 +1410,18 @@ \def:Npn \io_put_term:x{ \tex_immediate:D\io_put_deferred:Nx \c_sixteen } % \end{macrocode} -% \end{macro} -% \end{macro} +% \end{macro} +% \end{macro} % -% \begin{macro}{\err_latex_bug:n} +% \begin{macro}{\err_latex_bug:x} % This will show internal errors. % \begin{macrocode} -\def:Npn\err_latex_bug:n#1{ +\def:Npn\err_latex_bug:x#1{ \io_put_term:x{This~is~a~LaTeX~bug!~Check~coding!}\tex_errmessage:D{#1}} % \end{macrocode} % \end{macro} % -% \begin{macro}{\cs_record_meaning:N} +% \begin{macro}{\cs_record_meaning:N} % This macro will be used later on for tracing purposes. But we % need some more modules to define it, so we just give some dummy % definition here. @@ -496,241 +1430,894 @@ \def:Npn \cs_record_meaning:N#1{} % % \end{macrocode} -% \end{macro} -% -% \subsection{Checking new definitions} +% \end{macro} % +% We need these two to make |\chk_new_cs:N| bulletproof. +% \begin{macrocode} +\def_long:Npn \use_none:n #1{} +\def_long:Npn \use_arg_i:n #1{#1} +% \end{macrocode} % \begin{macro}{\chk_new_cs:N} -% This command is called by |\def_new:Npn| and |\let_new:NN| etc.\ -% to make sure that the argument sequence is not already in use. If -% it is, an error is signalled. -% It checks if \m{csname} is undefined or -% |\scan_stop:|. Otherwise an error message is issued. +% This command is called by |\def_new:Npn| and |\let_new:NN| etc.\ +% to make sure that the argument sequence is not already in use. If +% it is, an error is signalled. It checks if \m{csname} is +% undefined or |\scan_stop:|. Otherwise an error message is +% issued. We have to make sure we don't put the argument into the +% conditional processing since it may be an |\if...| type function! % \begin {macrocode} \def:Npn \chk_new_cs:N #1{ - \if_meaning:NN #1\c_undefined - \else: - \if_meaning:NN #1\scan_stop: - \else: - \err_latex_bug:n {Command~name~`\token_to_string:N #1'~ - already~defined!~ - Current~meaning:~\token_to_meaning:N #1 - } - \fi: - \fi: + \if:w \cs_if_free_p:N #1 + \exp_after:NN \use_none:n + \else: + \exp_after:NN \use_arg_i:n + \fi: + { + \err_latex_bug:x {Command~name~`\token_to_string:N #1'~ + already~defined!~ + Current~meaning:~\token_to_meaning:N #1 + } + } %<*trace> - \cs_record_meaning:N#1 -% \io_put_term:x{Defining~\token_to_string:N #1~on~ - \io_put_log:x{Defining~\token_to_string:N #1~on~ - line~\tex_the:D \tex_inputlineno:D} + \cs_record_meaning:N#1 +% \io_put_term:x{Defining~\token_to_string:N #1~on~%} + \io_put_log:x{Defining~\token_to_string:N #1~on~ + line~\tex_the:D \tex_inputlineno:D} % - } +} % \end{macrocode} -% \end {macro} +% \end{macro} % -% \begin{macro}{\cs_exist_p:N} -% Expands into |\c_true| if the control sequence given as its -% argument {\em is} in use. +% On 2005/11/20 Morten said: I think names for testing if a certain +% condition is true or false should always contain |if| to avoid +% confusion. This is what we do for lots of other types of test +% functions. For now I have defined both names for the functions +% checking names of control sequences. % +% \begin{macro}{\cs_if_exist_p:N} +% Expands into |\c_true| if the control sequence given as its +% argument \emph{is} in use. % \begin{macrocode} -\def:Npn \cs_exist_p:N #1{ - \if:w \cs_free_p:N #1 +\def:Npn \cs_if_exist_p:N #1{ + \if:w \cs_if_free_p:N #1 \c_false \else: \c_true \fi:} % \end{macrocode} % \end{macro} % -% \begin{macro}{\chk_exist_cs:N } -% This function issues a warning message when the control sequence -% in its argument does not exist. +% \begin{macro}{\chk_if_exist_cs:N } +% \begin{macro}{\chk_if_exist_cs:c } +% This function issues a warning message when the control sequence +% in its argument does not exist. +% \begin{macrocode} +\def:Npn \chk_if_exist_cs:N #1 { + \if:w \cs_if_exist_p:N #1 + \else: + \err_latex_bug:x{Command~ `\token_to_string:N #1'~ + not~ yet~ defined!} + \fi:} +\def:Npn \chk_if_exist_cs:c #1 { + \exp_after:NN \chk_if_exist_cs:N \cs:w #1\cs_end: } +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\cs_if_free_p:N} +% Expands into |\c_true| if the control sequence given as its +% argument is not yet in use. Note that we make sure to expand +% into |\c_false| if the control sequence is textually +% |\c_undefined| or |\scan_stop:|, so that we don't end up +% (re)defining them. +% \begin{macrocode} +\def:Npn \cs_if_free_p:N #1{ + \if_cs_exist:N #1 + \if_meaning:NN#1\scan_stop: + \if:w\cs_if_eq_name_p:NN #1\scan_stop: + \c_false \else: \c_true \fi: + \else: + \c_false + \fi: + \else: + \if:w \cs_if_eq_name_p:NN #1\c_undefined + \c_false \else: \c_true \fi: + \fi: +} +\let:NwN \cs_free_p:N \cs_if_free_p:N +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\str_if_eq_p:nn} +% \begin{macro}{\str_if_eq_p_aux:w} +% Takes 2 lists of characters as arguments and expands into +% |\c_true| if they are equal, and |\c_false| otherwise. Note that +% in the current implementation spaces in these strings are +% ignored.\footnote{This is a function which could use +% \cs{tlist_compare:xx}.} +% \begin{macrocode} +\def:Npn \str_if_eq_p:nn #1#2{ + \str_if_eq_p_aux:w #1\scan_stop:\\#2\scan_stop:\\ +} +\def:Npn \str_if_eq_p_aux:w #1#2\\#3#4\\{ + \if_meaning:NN#1#3 + \if_meaning:NN#1\scan_stop:\c_true \else: + \if_meaning:NN#3\scan_stop:\c_false \else: + \str_if_eq_p_aux:w #2\\#4\\\fi:\fi: + \else:\c_false \fi:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\cs_if_eq_name_p:NN} +% An application of the above function, already streamlined for +% speed, so I put it in here. It takes two control sequences as +% arguments and expands into true iff they have the same name. +% We make it long in case one of them is |\par|! +% \begin{macrocode} +\def_long:Npn \cs_if_eq_name_p:NN #1#2{ + \exp_after:NN\exp_after:NN + \exp_after:NN\str_if_eq_p_aux:w + \exp_after:NN\token_to_string:N + \exp_after:NN#1 + \exp_after:NN\scan_stop: + \exp_after:NN\\ + \token_to_string:N#2\scan_stop:\\} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\str_if_eq_var_p:nf} +% \begin{macro}{\str_if_eq_var_start:nnN} +% \begin{macro}{\str_if_eq_var_stop:w} +% A variant of |\str_if_eq_p:nn| which has the advantage of obeying +% spaces in at least the second argument. See \textsf{l3quark} for +% an application. From the hand of David Kastrup with slight +% modifications to make it fit with the remainder of the expl3 +% language. +% +% The macro builds a string of |\if:w \fi:| pairs from the first +% argument. The idea is to turn the comparison of |ab| and |cde| +% into +% \begin{verbatim} +% \tex_number:D +% \if:w \scan_stop: \if:w b\if:w a cde\scan_stop: '\fi: \fi: \fi: +% 13 +% \end{verbatim} +% The |'| is important here. If all tests are true, the |'| is read +% as part of the number in which case the returned number is |13| in +% octal notation so |\tex_number:D| returns |11|. If one test +% returns false the |'| is never seen and then we get just |13|. We +% wrap the whole process in an external |\if:w| in order to make it +% return either |\c_true| or |\c_false| since some parts of +% \textsf{l3prg} expect a predicate to return one of these two +% tokens. +% \begin{macrocode} +\def:Npn \str_if_eq_var_p:nf#1{ + \if:w \tex_number:D\str_if_eq_var_start:nnN{}{}#1\scan_stop: +} +\def:Npn\str_if_eq_var_start:nnN#1#2#3{ + \if:w#3\scan_stop:\exp_after:NN\str_if_eq_var_stop:w\fi: + \str_if_eq_var_start:nnN{\if:w#3#1}{#2\fi:} +} +\def:Npn\str_if_eq_var_stop:w\str_if_eq_var_start:nnN#1#2#3{ + #1#3\scan_stop:'#213~\c_true\else:\c_false\fi: +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% +% \subsubsection{More new definitions} +% +% +% +% \begin{macro}{\def_new:Npn} +% \begin{macro}{\def_new:Npx} +% \begin{macro}{\def_long_new:Npn} +% \begin{macro}{\def_long_new:Npx} +% \begin{macro}{\def_protected_new:Npn} +% \begin{macro}{\def_protected_new:Npx} +% \begin{macro}{\def_protected_long_new:Npn} +% \begin{macro}{\def_protected_long_new:Npx} +% These are like |\def:Npn| and |\let:NN|, but they first check that +% the argument command is not already in use. You may use +% |\pref_global:D|, |\pref_long:D|, |\pref_protected:D|, and +% |\tex_outer:D| as prefixes. +% \begin {macrocode} +\def_protected:Npn \def_new:Npn #1{\chk_new_cs:N #1 + \def:Npn #1} +\def_protected:Npn \def_new:Npx #1{\chk_new_cs:N #1 + \def:Npx #1} +\def_protected:Npn \def_long_new:Npn #1{\chk_new_cs:N #1 + \def_long:Npn #1} +\def_protected:Npn \def_long_new:Npx #1{\chk_new_cs:N #1 + \def_long:Npx #1} +\def_protected:Npn \def_protected_new:Npn #1{\chk_new_cs:N #1 + \def_protected:Npn #1} +\def_protected:Npn \def_protected_new:Npx #1{\chk_new_cs:N #1 + \def_protected:Npx #1} +\def_protected:Npn \def_protected_long_new:Npn #1{\chk_new_cs:N #1 + \def_protected_long:Npn #1} +\def_protected:Npn \def_protected_long_new:Npx #1{\chk_new_cs:N #1 + \def_protected_long:Npx #1} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\gdef_new:Npn} +% \begin{macro}{\gdef_new:Npx} +% \begin{macro}{\gdef_long_new:Npn} +% \begin{macro}{\gdef_long_new:Npx} +% \begin{macro}{\gdef_protected_new:Npn} +% \begin{macro}{\gdef_protected_new:Npx} +% \begin{macro}{\gdef_protected_long_new:Npn} +% \begin{macro}{\gdef_protected_long_new:Npx} +% Global versions of the above functions. +% \begin {macrocode} +\def_protected_new:Npn \gdef_new:Npn #1{\chk_new_cs:N #1 + \gdef:Npn #1} +\def_protected_new:Npn \gdef_new:Npx #1{\chk_new_cs:N #1 + \gdef:Npx #1} +\def_protected_new:Npn \gdef_long_new:Npn #1{\chk_new_cs:N #1 + \gdef_long:Npn #1} +\def_protected_new:Npn \gdef_long_new:Npx #1{\chk_new_cs:N #1 + \gdef_long:Npx #1} +\def_protected_new:Npn \gdef_protected_new:Npn #1{\chk_new_cs:N #1 + \gdef_protected:Npn #1} +\def_protected_new:Npn \gdef_protected_new:Npx #1{\chk_new_cs:N #1 + \gdef_protected:Npx #1} +\def_protected_new:Npn \gdef_protected_long_new:Npn #1{\chk_new_cs:N #1 + \gdef_protected_long:Npn #1} +\def_protected_new:Npn \gdef_protected_long_new:Npx #1{\chk_new_cs:N #1 + \gdef_protected_long:Npx #1} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\def:cpn} +% \begin{macro}{\def:cpx} +% \begin{macro}{\gdef:cpn} +% \begin{macro}{\gdef:cpx} +% \begin{macro}{\def_new:cpn} +% \begin{macro}{\def_new:cpx} +% \begin{macro}{\gdef_new:cpn} +% \begin{macro}{\gdef_new:cpx} +% Like |\def:Npn| and |\def_new:Npn|, except that the first argument +% consists of the sequence of characters that should be used to form +% the name of the desired control sequence (the |c| stands for +% csname argument, see the expansion module.). Global versions are +% also provided. +% +% |\def:cpn|\m{string}\m{rep-text} will turn \m{string} into a +% csname and then assign \m {rep-text} to it by using |\def:Npn|. +% This means that there might be a parameter string between the two +% arguments. +% \begin{macrocode} +\def_new:Npn \def:cpn #1{\exp_after:NN \def:Npn \cs:w #1\cs_end:} +\def_new:Npn \def:cpx #1{\exp_after:NN \def:Npx \cs:w #1\cs_end:} +\def_new:Npn \gdef:cpn #1{\exp_after:NN \gdef:Npn \cs:w #1\cs_end:} +\def_new:Npn \gdef:cpx #1{\exp_after:NN \gdef:Npx \cs:w #1\cs_end:} +\def_new:Npn \def_new:cpn #1{\exp_after:NN \def_new:Npn \cs:w #1\cs_end:} +\def_new:Npn \def_new:cpx #1{\exp_after:NN \def_new:Npx \cs:w #1\cs_end:} +\def_new:Npn \gdef_new:cpn #1{\exp_after:NN \gdef_new:Npn \cs:w #1\cs_end:} +\def_new:Npn \gdef_new:cpx #1{\exp_after:NN \gdef_new:Npx \cs:w #1\cs_end:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% \begin{macro}{\def_long:cpn} +% \begin{macro}{\def_long:cpx} +% \begin{macro}{\gdef_long:cpn} +% \begin{macro}{\gdef_long:cpx} +% \begin{macro}{\def_long_new:cpn} +% \begin{macro}{\def_long_new:cpx} +% \begin{macro}{\gdef_long_new:cpn} +% \begin{macro}{\gdef_long_new:cpx} +% Variants of the |\def_long:Npn| versions which make a csname out +% of the first arguments. We may also do this globally. +% \begin{macrocode} +\def_new:Npn \def_long:cpn #1{\exp_after:NN \def_long:Npn \cs:w #1\cs_end:} +\def_new:Npn \def_long:cpx #1{ + \exp_after:NN\def_long:Npx\cs:w #1\cs_end:} +\def_new:Npn \gdef_long:cpn #1{ + \exp_after:NN \gdef_long:Npn \cs:w #1\cs_end:} +\def_new:Npn \gdef_long:cpx #1{ + \exp_after:NN\gdef_long:Npx\cs:w #1\cs_end:} +\def_new:Npn \def_long_new:cpn #1{ + \exp_after:NN \def_long_new:Npn \cs:w #1\cs_end:} +\def_new:Npn \def_long_new:cpx #1{ + \exp_after:NN \def_long_new:Npx \cs:w #1\cs_end:} +\def_new:Npn \gdef_long_new:cpn #1{ + \exp_after:NN \gdef_long_new:Npn \cs:w #1\cs_end:} +\def_new:Npn \gdef_long_new:cpx #1{ + \exp_after:NN \gdef_long_new:Npx \cs:w #1\cs_end:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\def_protected:cpn} +% \begin{macro}{\def_protected:cpx} +% \begin{macro}{\gdef_protected:cpn} +% \begin{macro}{\gdef_protected:cpx} +% \begin{macro}{\def_protected_new:cpn} +% \begin{macro}{\def_protected_new:cpx} +% \begin{macro}{\gdef_protected_new:cpn} +% \begin{macro}{\gdef_protected_new:cpx} +% Variants of the |\def_protected:Npn| versions which make a csname +% out of the first arguments. We may also do this globally. +% \begin{macrocode} +\def_new:Npn \def_protected:cpn #1{ + \exp_after:NN \def_protected:Npn \cs:w #1\cs_end:} +\def_new:Npn \def_protected:cpx #1{ + \exp_after:NN\def_protected:Npx\cs:w #1\cs_end:} +\def_new:Npn \gdef_protected:cpn #1{ + \exp_after:NN \gdef_protected:Npn \cs:w #1\cs_end:} +\def_new:Npn \gdef_protected:cpx #1{ + \exp_after:NN\gdef_protected:Npx\cs:w #1\cs_end:} +\def_new:Npn \def_protected_new:cpn #1{ + \exp_after:NN \def_protected_new:Npn \cs:w #1\cs_end:} +\def_new:Npn \def_protected_new:cpx #1{ + \exp_after:NN \def_protected_new:Npx \cs:w #1\cs_end:} +\def_new:Npn \gdef_protected_new:cpn #1{ + \exp_after:NN \gdef_protected_new:Npn \cs:w #1\cs_end:} +\def_new:Npn \gdef_protected_new:cpx #1{ + \exp_after:NN \gdef_protected_new:Npx \cs:w #1\cs_end:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\def_protected_long:cpn} +% \begin{macro}{\def_protected_long:cpx} +% \begin{macro}{\gdef_protected_long:cpn} +% \begin{macro}{\gdef_protected_long:cpx} +% \begin{macro}{\def_protected_long_new:cpn} +% \begin{macro}{\def_protected_long_new:cpx} +% \begin{macro}{\gdef_protected_long_new:cpn} +% \begin{macro}{\gdef_protected_long_new:cpx} +% Variants of the |\def_protected_long:Npn| versions which make a csname +% out of the first arguments. We may also do this globally. +% \begin{macrocode} +\def_new:Npn \def_protected_long:cpn #1{ + \exp_after:NN \def_protected_long:Npn \cs:w #1\cs_end:} +\def_new:Npn \def_protected_long:cpx #1{ + \exp_after:NN\def_protected_long:Npx\cs:w #1\cs_end:} +\def_new:Npn \gdef_protected_long:cpn #1{ + \exp_after:NN \gdef_protected_long:Npn \cs:w #1\cs_end:} +\def_new:Npn \gdef_protected_long:cpx #1{ + \exp_after:NN\gdef_protected_long:Npx\cs:w #1\cs_end:} +\def_new:Npn \def_protected_long_new:cpn #1{ + \exp_after:NN \def_protected_long_new:Npn \cs:w #1\cs_end:} +\def_new:Npn \def_protected_long_new:cpx #1{ + \exp_after:NN \def_protected_long_new:Npx \cs:w #1\cs_end:} +\def_new:Npn \gdef_protected_long_new:cpn #1{ + \exp_after:NN \gdef_protected_long_new:Npn \cs:w #1\cs_end:} +\def_new:Npn \gdef_protected_long_new:cpx #1{ + \exp_after:NN \gdef_protected_long_new:Npx \cs:w #1\cs_end:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\def_aux_0:NNn} +% \begin{macro}{\def_aux_1:NNn} +% \begin{macro}{\def_aux_2:NNn} +% \begin{macro}{\def_aux_3:NNn} +% \begin{macro}{\def_aux_4:NNn} +% \begin{macro}{\def_aux_5:NNn} +% \begin{macro}{\def_aux_6:NNn} +% \begin{macro}{\def_aux_7:NNn} +% \begin{macro}{\def_aux_8:NNn} +% \begin{macro}{\def_aux_9:NNn} +% \begin{macro}{\def_aux:NNnn} +% \begin{macro}{\def_aux:Ncnn} +% \begin{macro}{\def_arg_number_error_msg:Nn} +% Defining a function with $n$ arguments. First some helper functions. +% \begin{macrocode} +\def_new:cpn {def_aux_0:NNn} #1#2 {#1 #2 } +\def_new:cpn {def_aux_1:NNn} #1#2 {#1 #2 ##1 } +\def_new:cpn {def_aux_2:NNn} #1#2 {#1 #2 ##1##2 } +\def_new:cpn {def_aux_3:NNn} #1#2 {#1 #2 ##1##2##3 } +\def_new:cpn {def_aux_4:NNn} #1#2 {#1 #2 ##1##2##3##4 } +\def_new:cpn {def_aux_5:NNn} #1#2 {#1 #2 ##1##2##3##4##5 } +\def_new:cpn {def_aux_6:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6 } +\def_new:cpn {def_aux_7:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6##7 } +\def_new:cpn {def_aux_8:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6##7##8 } +\def_new:cpn {def_aux_9:NNn} #1#2 {#1 #2 ##1##2##3##4##5##6##7##8##9 } +% \end{macrocode} +% Then the function itself which checks for the existance of such a +% helper function. If it doesn't exist, return an error. Otherwise +% call it to define \verb|#2| with the correct number of arguments. +% \begin{macrocode} +\def_protected_long_new:Npn \def_aux:NNnn #1#2#3#4 { + \cs_if_really_exist:cTF {def_aux_\tex_the:D\etex_numexpr:D #3 :NNn} + { + \cs_use:c {def_aux_\tex_the:D\etex_numexpr:D #3 :NNn} #1 #2 {#4} + } + { \def_arg_number_error_msg:Nn #2{#3} } +} +\def_new:Npn \def_aux:Ncnn #1#2{ + \exp_after:NN \def_aux:NNnn \exp_after:NN #1 \cs:w #2\cs_end:} +% \end{macrocode} +% The error message. +% \begin{macrocode} +\def_new:Npn \def_arg_number_error_msg:Nn #1#2 { + \err_latex_bug:x{ + You're~ trying~ to~ define~ the~ command~ `\token_to_string:N #1'~ + with~ \use_arg_i:n{\tex_the:D\etex_numexpr:D #2\scan_stop:} ~ + arguments~ but~ I~ only~ allow~ 0-9~ arguments.~ I~ can~ probably~ + not~ help~ you~ here + } +} +% \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} +% +% \begin{macro}{\def_aux_use_0_parameter:} +% \begin{macro}{\def_aux_use_1_parameter:} +% \begin{macro}{\def_aux_use_2_parameter:} +% \begin{macro}{\def_aux_use_3_parameter:} +% \begin{macro}{\def_aux_use_4_parameter:} +% \begin{macro}{\def_aux_use_5_parameter:} +% \begin{macro}{\def_aux_use_6_parameter:} +% \begin{macro}{\def_aux_use_7_parameter:} +% \begin{macro}{\def_aux_use_8_parameter:} +% \begin{macro}{\def_aux_use_9_parameter:} +% Something similar to |\def_aux_9:NNn| but for using the +% parameters. +% \begin{macrocode} +\def:cpn{def_aux_use_0_parameter:}{} +\def:cpn{def_aux_use_1_parameter:}{{##1}} +\def:cpn{def_aux_use_2_parameter:}{{##1}{##2}} +\def:cpn{def_aux_use_3_parameter:}{{##1}{##2}{##3}} +\def:cpn{def_aux_use_4_parameter:}{{##1}{##2}{##3}{##4}} +\def:cpn{def_aux_use_5_parameter:}{{##1}{##2}{##3}{##4}{##5}} +\def:cpn{def_aux_use_6_parameter:}{{##1}{##2}{##3}{##4}{##5}{##6}} +\def:cpn{def_aux_use_7_parameter:}{{##1}{##2}{##3}{##4}{##5}{##6}{##7}} +\def:cpn{def_aux_use_8_parameter:}{ + {##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}} +\def:cpn{def_aux_use_9_parameter:}{ + {##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}{##9}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\def:NNn} +% \begin{macro}{\def:NNx} +% \begin{macro}{\def:cNn} +% \begin{macro}{\def:cNx} +% \begin{macro}{\gdef:NNn} +% \begin{macro}{\gdef:NNx} +% \begin{macro}{\gdef:cNn} +% \begin{macro}{\gdef:cNx} +% \begin{macro}{\def_new:NNn} +% \begin{macro}{\def_new:NNx} +% \begin{macro}{\def_new:cNn} +% \begin{macro}{\def_new:cNx} +% \begin{macro}{\gdef_new:NNn} +% \begin{macro}{\gdef_new:NNx} +% \begin{macro}{\gdef_new:cNn} +% \begin{macro}{\gdef_new:cNx} +% Defining macros without delimited arguments is now relatively +% easy. First local and global versions of the usual |\def:Npn| +% operation. +% \begin{macrocode} +\def_new:Npn \def:NNn { \def_aux:NNnn \def:Npn } +\def_new:Npn \def:NNx { \def_aux:NNnn \def:Npx } +\def_new:Npn \def:cNn { \def_aux:Ncnn \def:Npn } +\def_new:Npn \def:cNx { \def_aux:Ncnn \def:Npx } +\def_new:Npn \gdef:NNn { \def_aux:NNnn \gdef:Npn } +\def_new:Npn \gdef:NNx { \def_aux:NNnn \gdef:Npx } +\def_new:Npn \gdef:cNn { \def_aux:Ncnn \gdef:Npn } +\def_new:Npn \gdef:cNx { \def_aux:Ncnn \gdef:Npx } +\def_new:Npn \def_new:NNn { \def_aux:NNnn \def_new:Npn } +\def_new:Npn \def_new:NNx { \def_aux:NNnn \def_new:Npx } +\def_new:Npn \def_new:cNn { \def_aux:Ncnn \def_new:Npn } +\def_new:Npn \def_new:cNx { \def_aux:Ncnn \def_new:Npx } +\def_new:Npn \gdef_new:NNn { \def_aux:NNnn \gdef_new:Npn } +\def_new:Npn \gdef_new:NNx { \def_aux:NNnn \gdef_new:Npx } +\def_new:Npn \gdef_new:cNn { \def_aux:Ncnn \gdef_new:Npn } +\def_new:Npn \gdef_new:cNx { \def_aux:Ncnn \gdef_new:Npx } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\def_long:NNn} +% \begin{macro}{\def_long:NNx} +% \begin{macro}{\def_long:cNn} +% \begin{macro}{\def_long:cNx} +% \begin{macro}{\gdef_long:NNn} +% \begin{macro}{\gdef_long:NNx} +% \begin{macro}{\gdef_long:cNn} +% \begin{macro}{\gdef_long:cNx} +% \begin{macro}{\def_long_new:NNn} +% \begin{macro}{\def_long_new:NNx} +% \begin{macro}{\def_long_new:cNn} +% \begin{macro}{\def_long_new:cNx} +% \begin{macro}{\gdef_long_new:NNn} +% \begin{macro}{\gdef_long_new:NNx} +% \begin{macro}{\gdef_long_new:cNn} +% \begin{macro}{\gdef_long_new:cNx} +% Long versions of the above. +% \begin{macrocode} +\def_new:Npn \def_long:NNn { \def_aux:NNnn \def_long:Npn } +\def_new:Npn \def_long:NNx { \def_aux:NNnn \def_long:Npx } +\def_new:Npn \def_long:cNn { \def_aux:Ncnn \def_long:Npn } +\def_new:Npn \def_long:cNx { \def_aux:Ncnn \def_long:Npx } +\def_new:Npn \gdef_long:NNn { \def_aux:NNnn \gdef_long:Npn } +\def_new:Npn \gdef_long:NNx { \def_aux:NNnn \gdef_long:Npx } +\def_new:Npn \gdef_long:cNn { \def_aux:Ncnn \gdef_long:Npn } +\def_new:Npn \gdef_long:cNx { \def_aux:Ncnn \gdef_long:Npx } +\def_new:Npn \def_long_new:NNn { \def_aux:NNnn \def_long_new:Npn } +\def_new:Npn \def_long_new:NNx { \def_aux:NNnn \def_long_new:Npx } +\def_new:Npn \def_long_new:cNn { \def_aux:Ncnn \def_long_new:Npn } +\def_new:Npn \def_long_new:cNx { \def_aux:Ncnn \def_long_new:Npx } +\def_new:Npn \gdef_long_new:NNn { \def_aux:NNnn \gdef_long_new:Npn } +\def_new:Npn \gdef_long_new:NNx { \def_aux:NNnn \gdef_long_new:Npx } +\def_new:Npn \gdef_long_new:cNn { \def_aux:Ncnn \gdef_long_new:Npn } +\def_new:Npn \gdef_long_new:cNx { \def_aux:Ncnn \gdef_long_new:Npx } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\def_protected:NNn} +% \begin{macro}{\def_protected:NNx} +% \begin{macro}{\def_protected:cNn} +% \begin{macro}{\def_protected:cNx} +% \begin{macro}{\gdef_protected:NNn} +% \begin{macro}{\gdef_protected:NNx} +% \begin{macro}{\gdef_protected:cNn} +% \begin{macro}{\gdef_protected:cNx} +% \begin{macro}{\def_protected_new:NNn} +% \begin{macro}{\def_protected_new:NNx} +% \begin{macro}{\def_protected_new:cNn} +% \begin{macro}{\def_protected_new:cNx} +% \begin{macro}{\gdef_protected_new:NNn} +% \begin{macro}{\gdef_protected_new:NNx} +% \begin{macro}{\gdef_protected_new:cNn} +% \begin{macro}{\gdef_protected_new:cNx} +% Protected versions of the above. % \begin{macrocode} -\def:Npn \chk_exist_cs:N #1 { - \if:w \cs_exist_p:N #1 - \else: - \err_latex_bug:n{Command~ `\token_to_string:N #1'~ - not~ yet~ defined!} - \fi:} +\def_new:Npn \def_protected:NNn { \def_aux:NNnn \def_protected:Npn } +\def_new:Npn \def_protected:NNx { \def_aux:NNnn \def_protected:Npx } +\def_new:Npn \def_protected:cNn { \def_aux:Ncnn \def_protected:Npn } +\def_new:Npn \def_protected:cNx { \def_aux:Ncnn \def_protected:Npx } +\def_new:Npn \gdef_protected:NNn { \def_aux:NNnn \gdef_protected:Npn } +\def_new:Npn \gdef_protected:NNx { \def_aux:NNnn \gdef_protected:Npx } +\def_new:Npn \gdef_protected:cNn { \def_aux:Ncnn \gdef_protected:Npn } +\def_new:Npn \gdef_protected:cNx { \def_aux:Ncnn \gdef_protected:Npx } +\def_new:Npn \def_protected_new:NNn { \def_aux:NNnn \def_protected_new:Npn } +\def_new:Npn \def_protected_new:NNx { \def_aux:NNnn \def_protected_new:Npx } +\def_new:Npn \def_protected_new:cNn { \def_aux:Ncnn \def_protected_new:Npn } +\def_new:Npn \def_protected_new:cNx { \def_aux:Ncnn \def_protected_new:Npx } +\def_new:Npn \gdef_protected_new:NNn { \def_aux:NNnn \gdef_protected_new:Npn } +\def_new:Npn \gdef_protected_new:NNx { \def_aux:NNnn \gdef_protected_new:Npx } +\def_new:Npn \gdef_protected_new:cNn { \def_aux:Ncnn \gdef_protected_new:Npn } +\def_new:Npn \gdef_protected_new:cNx { \def_aux:Ncnn \gdef_protected_new:Npx } % \end{macrocode} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % -% \begin{macro}{\cs_free_p:N} -% Expands into |\c_true| if the control sequence given as its -% argument is not yet in use. Note that we make sure to expand -% into |\c_false | if the control sequence is textually -% |\c_undefined| or |\scan_stop:|, so that we don't end up -% (re)defining them. +% \begin{macro}{\def_protected_long:NNn} +% \begin{macro}{\def_protected_long:NNx} +% \begin{macro}{\def_protected_long:cNn} +% \begin{macro}{\def_protected_long:cNx} +% \begin{macro}{\gdef_protected_long:NNn} +% \begin{macro}{\gdef_protected_long:NNx} +% \begin{macro}{\gdef_protected_long:cNn} +% \begin{macro}{\gdef_protected_long:cNx} +% \begin{macro}{\def_protected_long_new:NNn} +% \begin{macro}{\def_protected_long_new:NNx} +% \begin{macro}{\def_protected_long_new:cNn} +% \begin{macro}{\def_protected_long_new:cNx} +% \begin{macro}{\gdef_protected_long_new:NNn} +% \begin{macro}{\gdef_protected_long_new:NNx} +% \begin{macro}{\gdef_protected_long_new:cNn} +% \begin{macro}{\gdef_protected_long_new:cNx} +% And finally both long and protected. % \begin{macrocode} -\def:Npn \cs_free_p:N #1{ - \if_meaning:NN#1\c_undefined - \if:w\cs_eq_p:NN #1\c_undefined \c_false - \else: \c_true \fi: - \else: - \if_meaning:NN#1\scan_stop: - \if:w\cs_eq_p:NN #1\scan_stop: \c_false - \else: \c_true \fi: - \else: - \c_false \fi:\fi:} +\def_new:Npn \def_protected_long:NNn { \def_aux:NNnn \def_protected_long:Npn } +\def_new:Npn \def_protected_long:NNx { \def_aux:NNnn \def_protected_long:Npx } +\def_new:Npn \def_protected_long:cNn { \def_aux:Ncnn \def_protected_long:Npn } +\def_new:Npn \def_protected_long:cNx { \def_aux:Ncnn \def_protected_long:Npx } +\def_new:Npn \gdef_protected_long:NNn { \def_aux:NNnn \gdef_protected_long:Npn } +\def_new:Npn \gdef_protected_long:NNx { \def_aux:NNnn \gdef_protected_long:Npx } +\def_new:Npn \gdef_protected_long:cNn { \def_aux:Ncnn \gdef_protected_long:Npn } +\def_new:Npn \gdef_protected_long:cNx { \def_aux:Ncnn \gdef_protected_long:Npx } +\def_new:Npn \def_protected_long_new:NNn { + \def_aux:NNnn \def_protected_long_new:Npn } +\def_new:Npn \def_protected_long_new:NNx { + \def_aux:NNnn \def_protected_long_new:Npx } +\def_new:Npn \def_protected_long_new:cNn { + \def_aux:Ncnn \def_protected_long_new:Npn } +\def_new:Npn \def_protected_long_new:cNx { + \def_aux:Ncnn \def_protected_long_new:Npx } +\def_new:Npn \gdef_protected_long_new:NNn { + \def_aux:NNnn \gdef_protected_long_new:Npn } +\def_new:Npn \gdef_protected_long_new:NNx { + \def_aux:NNnn \gdef_protected_long_new:Npx } +\def_new:Npn \gdef_protected_long_new:cNn { + \def_aux:Ncnn \gdef_protected_long_new:Npn } +\def_new:Npn \gdef_protected_long_new:cNx { + \def_aux:Ncnn \gdef_protected_long_new:Npx } % \end{macrocode} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % -% \subsection{More new definitions} % -% \begin{macro}{\let:NN} -% \begin{macro}{\let:cN} -% \begin{macro}{\let:Nc} -% \begin{macro}{\let:cc} +% \begin{macro}{\let:NN} +% \begin{macro}{\let:cN} +% \begin{macro}{\let:Nc} +% \begin{macro}{\let:cc} +% \begin{macro}{\let_new:NN} +% \begin{macro}{\let_new:cN} +% \begin{macro}{\let_new:Nc} +% \begin{macro}{\let_new:cc} % These macros allow us to copy the definition of a control sequence -% to another control sequence. Maybe we should implement a few more -% of these. -% +% to another control sequence. % \begin{macrocode} -\tex_long:D\def:Npn \let:NN #1{ +\def_protected_long_new:Npn \let:NN #1{ % \end{macrocode} % The |=| sign allows us to define funny char tokens like .|=| % itself or \verb*= = with this function. For the definition of % |\c_space_chartok{~}| to work we need the |~| after the |=| -% % \begin{macrocode} \let:NwN #1=~} -\def:Npn\let:cN #1 {\exp_after:NN\let:NwN\cs:w#1\cs_end:=~} -\def:Npn\let:Nc{\exp_args:NNc\let:NN} -\def:Npn\let:cc{\exp_args:Ncc\let:NN} -% \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% -% \begin {macro}{\def_new:Npn} -% \begin {macro}{\def_new:Npx} -% \begin {macro}{\let_new:NN} -% These are like |\def:Npn| and |\let:NN|, but they first check that -% the argument command is not already in use. You may use -% |\tex_global:D|, |\tex_long:D|, and |\tex_outer:D| as -% prefixes. -% \begin {macrocode} -\def:Npn \def_new:Npn #1{\chk_new_cs:N #1 - \def:Npn #1} -\def:Npn \def_new:Npx #1{\chk_new_cs:N #1 - \def:Npx #1} +\def_new:Npn\let:cN #1 {\exp_after:NN\let:NN\cs:w#1\cs_end:} +\def_new:Npn\let:Nc{\exp_args:NNc\let:NN} +\def_new:Npn\let:cc{\exp_args:Ncc\let:NN} \def_new:Npn \let_new:NN #1{\chk_new_cs:N #1 \let:NN #1} +\def_new:Npn \let_new:cN {\exp_args:Nc \let_new:NN} +\def_new:Npn \let_new:Nc {\exp_args:NNc \let_new:NN} +\def_new:Npn \let_new:cc {\exp_args:Ncc \let_new:NN} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\glet:NN} +% \begin{macro}{\glet:cN} +% \begin{macro}{\glet:Nc} +% \begin{macro}{\glet:cc} +% \begin{macro}{\glet_new:NN} +% \begin{macro}{\glet_new:cN} +% \begin{macro}{\glet_new:Nc} +% \begin{macro}{\glet_new:cc} +% These are global versions of some of the previously defined functions. +% \begin{macrocode} +\def_protected_new:Npn \glet:NN {\pref_global:D \let:NN} +\def_protected_new:Npn \glet:Nc {\exp_args:NNc \glet:NN} +\def_protected_new:Npn \glet:cN {\exp_args:Nc \glet:NN} +\def_new:Npn \glet:cc {\exp_args:Ncc \glet:NN} +\def_new:Npn \glet_new:NN #1{\chk_new_cs:N #1 + \tex_global:D\let:NN #1} +\def_new:Npn \glet_new:cN {\exp_args:Nc \glet_new:NN} +\def_new:Npn \glet_new:Nc {\exp_args:NNc \glet_new:NN} +\def_new:Npn \glet_new:cc {\exp_args:Ncc \glet_new:NN} % \end{macrocode} -% \end {macro} -% \end {macro} -% \end {macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % -% \begin {macro}{\def:cpn} -% \begin {macro}{\def:cpx} -% \begin {macro}{\def_new:cpn} -% \begin {macro}{\def_new:cpx} -% Like |\def:Npn| and |\def_new:Npn|, except that the first -% argument consists of the sequence of characters that should be -% used to form the name of the desired control sequence ( the |c| -% stands for csname argument, see the expansion module.). % -% |\def:cpn|\m{string}\m{rep-text} will turn \m{string} into a -% csname and then assign \m {rep-text} to it by using |\def:Npn|. -% This means that there might be a parameter string between the two -% arguments. -% \begin {macrocode} -\def_new:Npn \def:cpn #1{\exp_after:NN - \def:Npn - \cs:w #1\cs_end:} -\def_new:Npn \def:cpx #1{\exp_after:NN - \def:Npx - \cs:w #1\cs_end:} -\def_new:Npn \def_new:cpn #1{\exp_after:NN - \def_new:Npn - \cs:w #1\cs_end:} -\def_new:Npn \def_new:cpx #1{\exp_after:NN - \def_new:Npx - \cs:w #1\cs_end:} -% \end{macrocode} -% \end {macro} -% \end {macro} -% \end {macro} -% \end {macro} -% -% -% \begin{macro}{\def:No} -% |\def:No| expands its second argument one time before making +% \begin{macro}{\def:No} +% \begin{macro}{\gdef:No} +% |\def:No| expands its second argument one time before making % the definition. % \begin{macrocode} \def_new:Npn \def:No{\exp_args:NNo\def:Npn} -% \end{macrocode} -% \end{macro} -% -% \begin {macro}{\def_long:Npn} -% \begin {macro}{\def_long_new:Npn} -% \begin {macro}{\def_long:cpn} -% \begin {macro}{\def_long:Npx} -% |\def_long:Npn| stands for |\tex_long:D| |\def:Npn|. -% |\def_long:Npx| expands its second argument. -% \begin {macrocode} -\def_new:Npn \def_long:Npn {\tex_long:D\def:Npn} -\def_new:Npn \def_long_new:Npn #1{\chk_new_cs:N #1 - \def_long:Npn #1} -\def_new:Npn \def_long:cpn #1{\exp_after:NN - \def_long:Npn - \cs:w #1\cs_end:} -\def_new:Npn \def_long:Npx {\tex_long:D\def:Npx} -% \end{macrocode} -% \end {macro} -% \end {macro} -% \end {macro} -% \end {macro} -% -% \begin {macro}{\glet:NN} -% \begin {macro}{\glet_new:NN} -% \begin {macro}{\gdef_new:Npn} -% \begin {macro}{\gdef:cpn} -% \begin {macro}{\gdef:cpx} -% \begin {macro}{\gdef:No} -% These are global versions of some of the previosly defined functions. -% \begin {macrocode} -\def_new:Npn \glet:NN {\tex_global:D \let:NN} -\def_new:Npn \glet_new:NN #1{\chk_new_cs:N #1 - \tex_global:D\let:NN #1} -\def_new:Npn \gdef_new:Npn #1{\chk_new_cs:N #1 - \gdef:Npn #1} -\def_new:Npn \gdef:cpn {\tex_global:D \def:cpn} -\def_new:Npn \gdef:cpx {\tex_global:D \def:cpx} \def_new:Npn \gdef:No {\exp_args:NNo\gdef:Npn} % \end{macrocode} -% \end {macro} -% \end {macro} -% \end {macro} -% \end {macro} -% \end {macro} -% \end {macro} - -% \begin {macro}{\gdef_long:Npn} -% \begin {macro}{\gdef_long:Npx} -% |\gdef_long:Npn| stands for |\tex_long:D| |\tex_global:D| |\def:Npn|. -% |\gdef_long:Npx| expands its second argument. -% \begin {macrocode} -\def_new:Npn \gdef_long:Npn {\tex_long:D\gdef:Npn} -\def_new:Npn \gdef_long:Npx {\tex_long:D\gdef:Npx} -% \end{macrocode} -% \end {macro} -% \end {macro} +% \end{macro} +% \end{macro} % -% \begin {macro}{\gfuturelet:NNN} -% This is a global version of |\let_peek_after:NNN| -% \begin {macrocode} -\def_new:Npn \gfuturelet:NNN{\tex_global:D \let_peek_after:NNN} +% \begin{macro}{\def_test_function_aux:Nnnn} +% \begin{macro}{\def_test_function_aux:Nnnx} +% \begin{macro}{\def_test_function:npn} +% \begin{macro}{\def_test_function:npx} +% \begin{macro}{\def_long_test_function:npn} +% \begin{macro}{\def_long_test_function:npx} +% \begin{macro}{\def_test_function_new:npn} +% \begin{macro}{\def_test_function_new:npx} +% \begin{macro}{\def_long_test_function_new:npn} +% \begin{macro}{\def_long_test_function_new:npx} +% We will often be defining several almost identical TF, T and F +% type functions so it makes sense for us to define a small function +% that will do this for us so that we are less likely to introduce +% typos (it does tend to happen). By doing it in two steps as below +% we can still retain a simple interface where you write the \TeX\ +% parameters as usual. Just don't do it when you're already within a +% conditional! +% +% I think the ways of exiting conditionals below are as fast as they +% get. Using |\reverse_if:N| instead of |\else:| didn't give any +% difference I could measure. +% \begin{macrocode} +\def_long_new:Npn \def_test_function_aux:Nnnn #1#2#3#4{ + #1 {#2TF} #3 {#4 + \exp_after:NN\use_arg_i:nn\else:\exp_after:NN\use_arg_ii:nn\fi:} + #1 {#2T} #3 {#4 + \else:\exp_after:NN\use_none:nn\fi:\use_arg_i:n} + #1 {#2F} #3 {#4 + \exp_after:NN\use_none:nn\fi:\use_arg_i:n}} +\def_long_new:Npn \def_test_function_aux:Nnnx #1#2#3#4{ + #1 {#2TF} #3 {#4 + \exp_not:n{\exp_after:NN\use_arg_i:nn\else:\exp_after:NN\use_arg_ii:nn\fi:}} + #1 {#2T} #3 {#4 + \exp_not:n{\else:\exp_after:NN\use_none:nn\fi:\use_arg_i:n}} + #1 {#2F} #3 {#4 + \exp_not:n{\exp_after:NN\use_none:nn\fi:\use_arg_i:n}}} +\def_long_new:Npn \def_test_function:npn #1#2#{ + \def_test_function_aux:Nnnn \def:cpn {#1}{#2} +} +\def_long_new:Npn \def_test_function:npx #1#2#{ + \def_test_function_aux:Nnnx \def:cpx {#1}{#2} +} +\def_long_new:Npn \def_long_test_function:npn #1#2#{ + \def_test_function_aux:Nnnn \def_long:cpn {#1}{#2} +} +\def_long_new:Npn \def_long_test_function:npx #1#2#{ + \def_test_function_aux:Nnnx \def_long:cpx {#1}{#2} +} +\def_long_new:Npn \def_test_function_new:npn #1#2#{ + \def_test_function_aux:Nnnn \def_new:cpn {#1}{#2} +} +\def_long_new:Npn \def_long_test_function_new:npn #1#2#{ + \def_test_function_aux:Nnnn \def_long_new:cpn {#1}{#2} +} +\def_long_new:Npn \def_test_function_new:npx #1#2#{ + \def_test_function_aux:Nnnx \def_new:cpx {#1}{#2} +} +\def_long_new:Npn \def_long_test_function_new:npx #1#2#{ + \def_test_function_aux:Nnnx \def_long_new:cpx {#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} +% % -% \subsection{Further checking} -% -% \begin{macro}{\cs_free:NTF} -% \begin{macro}{\cs_free:NT} -% \begin{macro}{\cs_free:NF} -% The old |\@ifundefined| of \LaTeX{} 2.09 is reimplemented in the +% \subsubsection{Further checking} +% +% \begin{macro}{\cs_if_free:NTF} +% \begin{macro}{\cs_if_free:NT} +% \begin{macro}{\cs_if_free:NF} +% The old |\@ifundefined| of \LaTeX{} 2.09 is re-implemented in the % function |\cs_free:cTF|, again in a way that |\else:| and |\fi:| % are removed. In this implementation this is absolutely % necessary because functions inside the conditional parts expect @@ -739,141 +2326,260 @@ % \m{csnames} directly and therefore allows both |\scan_stop:| and % |\c_undefined|. % \begin{macrocode} -\def_long_new:Npn \cs_free:NTF #1{\if:w\cs_free_p:N #1 - \exp_after:NN \use_choice_i:nn \else: - \exp_after:NN \use_choice_ii:nn \fi:} -\def_long_new:Npn \cs_free:NT #1{\if:w\cs_free_p:N #1 - \exp_after:NN \use:n \else: - \exp_after:NN \use_none:n \fi:} -\def_long_new:Npn \cs_free:NF #1{\if:w\cs_free_p:N #1 - \exp_after:NN \use_none:n \else: - \exp_after:NN \use:n \fi:} +\def_long_test_function_new:npn {cs_if_free:N}#1{\if:w\cs_if_free_p:N #1} +\let:NN \cs_free:NTF \cs_if_free:NTF +\let:NN \cs_free:NT \cs_if_free:NT +\let:NN \cs_free:NF \cs_if_free:NF % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % -% \begin{macro}{\cs_free:cTF} -% \begin{macro}{\cs_free:cT} -% \begin{macro}{\cs_free:cF} +% \begin{macro}{\cs_if_free:cTF} +% \begin{macro}{\cs_if_free:cT} +% \begin{macro}{\cs_if_free:cF} % We have to implement the |c| variants `by hand' because a different % test is necessary and I don't want the overhead for the test with % |\if:w|. What a mistake Don made by making this a % feature of |\cs:w|. If I'm not totally mistaken this % feature alone has cost him more than 600\$ for bug-checks. % \begin{macrocode} -\def_long_new:Npn \cs_free:cTF #1{ - \exp_after:NN - \if_meaning:NN - \cs:w#1\cs_end: - \scan_stop: - \exp_after:NN \use_choice_i:nn - \else: - \exp_after:NN \use_choice_ii:nn - \fi:} -\def_long_new:Npn \cs_free:cF #1{\exp_after:NN - \if_meaning:NN \cs:w#1\cs_end: \scan_stop: - \exp_after:NN \use_none:nn \fi: \use:n} -\def_long_new:Npn \cs_free:cT #1{\exp_after:NN - \if_meaning:NN \cs:w#1\cs_end: \scan_stop: - \else: - \exp_after:NN \use_none:nn \fi: \use:n} +\def_long_test_function_new:npn {cs_if_free:c}#1{ + \exp_after:NN \if_meaning:NN \cs:w#1\cs_end: \scan_stop:} +\let:NN \cs_free:cTF \cs_if_free:cTF +\let:NN \cs_free:cT \cs_if_free:cT +\let:NN \cs_free:cF \cs_if_free:cF +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\cs_if_really_free:cTF} +% \begin{macro}{\cs_if_really_free:cT} +% \begin{macro}{\cs_if_really_free:cF} +% These versions are for special control sequences that can only be +% formed through |\cs:w ... \cs_end:|. They do not turn the control +% sequence formed into |\scan_stop:|. +% \begin{macrocode} +\def_long_test_function_new:npn {cs_if_really_free:c}#1{ + \reverse_if:N\if_cs_exist:w #1\cs_end:} +\let:NN \cs_really_free:cTF \cs_if_really_free:cTF +\let:NN \cs_really_free:cT \cs_if_really_free:cT +\let:NN \cs_really_free:cF \cs_if_really_free:cF +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\cs_if_exist:NTF} +% \begin{macro}{\cs_if_exist:NT} +% \begin{macro}{\cs_if_exist:NF} +% \begin{macro}{\cs_if_exist:cTF} +% \begin{macro}{\cs_if_exist:cT} +% \begin{macro}{\cs_if_exist:cF} +% \begin{macro}{\cs_if_really_exist:cTF} +% \begin{macro}{\cs_if_really_exist:cT} +% \begin{macro}{\cs_if_really_exist:cF} +% Now the same functions but with reverse logic: test if the control +% sequence exists. +% \begin{macrocode} +\def_long_test_function_new:npn {cs_if_exist:N}#1{\if:w\cs_if_exist_p:N #1} +\def_long_test_function_new:npn {cs_if_exist:c}#1{ + \exp_after:NN\reverse_if:N + \exp_after:NN \if_meaning:NN \cs:w#1\cs_end: \scan_stop:} +\def_long_test_function_new:npn {cs_if_really_exist:c}#1{ + \if_cs_exist:w #1\cs_end:} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % -% \subsection{Freeing memory} +% \subsubsection{Freeing memory} % -% \begin{macro}{\gundefine:N } +% \begin{macro}{\cs_gundefine:N } % The following function is used to free the main memory from the % definition of some function that isn't in use any longer. % \begin{macrocode} -\def_new:Npn \gundefine:N #1{\glet:NN #1\c_undefined} +\def_new:Npn \cs_gundefine:N #1{\glet:NN #1\c_undefined} % \end{macrocode} % \end{macro} % -% \subsection{Gobbling tokens from input} % -% \begin{macro}{\use_none:n} -% \begin{macro}{\use_none:nn} -% \begin{macro}{\use_none:nnn} -% \begin{macro}{\use_none:nnnn} -% To gobble tokens from the input we use a standard naming -% convention: the number of tokens gobbled is given by the number -% of |n|'s following the |:| in the name. +% \subsubsection{Engine specific definitions} +% +% \begin{macro}{\engine_aleph:TF} +% In some cases it will be useful to know which engine we're running. % \begin{macrocode} -\def_long_new:Npn \use_none:n #1{} -\def_long_new:Npn \use_none:nn #1#2{} -\def_long_new:Npn \use_none:nnn #1{\use_none:nn} -\def_long_new:Npn \use_none:nnnn - {\exp_after:NN\use_none:nn \use_none:nn} +\def_test_function_new:npn {engine_aleph:}{\if_cs_exist:N \aleph_textdir:D} % \end{macrocode} % \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} % % -% \subsection{Selecting tokens} % -% \begin{macro}{\use:n} +% \subsubsection{Selecting tokens} +% +% \begin{macro}{\use_arg_i:n} % This macro grabs its argument and returns it back to the input % (with outer braces removed). % \begin{macrocode} -\def_long_new:Npn \use:n #1{#1} +%\def_long_new:Npn \use_arg_i:n #1{#1}% moved earlier % \end{macrocode} % \end{macro} % % \begin{macro}{\use:c} +% \begin{macro}{\cs_use:c} % \begin{macro}{\use:cc} % This macro grabs its argument and returns a csname from it. % \begin{macrocode} \def_new:Npn \use:c #1{\cs:w #1\cs_end:} - +\def_new:Npn \cs_use:c #1 { \cs:w#1\cs_end: } % \end{macrocode} -% THE NAME IS COMPLETELY WRONG!!!!! +% THE NAME IS COMPLETELY WRONG!!!!! +% Morten says: Perhaps this is really |\exp_args:cc| instead? % \begin{macrocode} \def_new:Npn \use:cc #1#2 {\cs:w #1\exp_after:NN\cs_end:\cs:w #2\cs_end:} % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % -% \begin{macro}{\use_choice_i:nn} -% \begin{macro}{\use_choice_ii:nn} +% \begin{macro}{\use_arg_i:nn} +% \begin{macro}{\use_arg_ii:nn} % These macros are needed to provide functions with true and false % cases, as introduced by Michael some time ago. By using -% |\exp_after:NN| |\use_choice_i:nn | |\else:| constructions it +% |\exp_after:NN| |\use_arg_i:nn | |\else:| constructions it % is possible to write code where the true or false case is able to % access the following tokens from the input stream, which is not % possible if the |\c_true| syntax is used. % \begin{macrocode} -\def_long_new:Npn \use_choice_i:nn #1#2{#1} -\def_long_new:Npn \use_choice_ii:nn #1#2{#2} +\def_long_new:Npn \use_arg_i:nn #1#2{#1} +\def_long_new:Npn \use_arg_ii:nn #1#2{#2} % \end{macrocode} % \end{macro} % \end{macro} % % % -% \begin{macro}{\use_choice_i:nnn} -% \begin{macro}{\use_choice_ii:nnn} -% \begin{macro}{\use_choice_iii:nnn} +% \begin{macro}{\use_arg_i:nnn} +% \begin{macro}{\use_arg_ii:nnn} +% \begin{macro}{\use_arg_iii:nnn} +% \begin{macro}{\use_arg_i:nnnn} +% \begin{macro}{\use_arg_ii:nnnn} +% \begin{macro}{\use_arg_iii:nnnn} +% \begin{macro}{\use_arg_iv:nnnn} % We also need something for picking up arguments from a longer -% list. +% list. +% \begin{macrocode} +\def_long_new:NNn \use_arg_i:nnn 3{#1} +\def_long_new:NNn \use_arg_ii:nnn 3{#2} +\def_long_new:NNn \use_arg_iii:nnn 3{#3} +\def_long_new:NNn \use_arg_i:nnnn 4{#1} +\def_long_new:NNn \use_arg_ii:nnnn 4{#2} +\def_long_new:NNn \use_arg_iii:nnnn 4{#3} +\def_long_new:NNn \use_arg_iv:nnnn 4{#4} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\use_arg_i_ii:nn} +% And a function for grabbing two arguments and returning them +% again. +% \begin{macrocode} +\def_long_new:NNn\use_arg_i_ii:nn 2{#1#2} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\use_none_delimit_by_q_nil:w} +% \begin{macro}{\use_none_delimit_by_q_stop:w} +% Functions that gobble everything until they see either |\q_nil| or +% |\q_stop| resp. +% \begin{macrocode} +\def_long_new:Npn \use_none_delimit_by_q_nil:w #1\q_nil{} +\def_long_new:Npn \use_none_delimit_by_q_stop:w #1\q_stop{} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\use_arg_i_delimit_by_q_nil:nw} +% \begin{macro}{\use_arg_i_delimit_by_q_stop:nw} +% Same as above but execute first argument after gobbling. Very +% useful when you need to skip the rest of a mapping sequence but +% want an easy way to control what should be expanded next. +% \begin{macrocode} +\def_long_new:Npn \use_arg_i_delimit_by_q_nil:nw #1#2\q_nil{#1} +\def_long_new:Npn \use_arg_i_delimit_by_q_stop:nw #1#2\q_stop{#1} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\use_arg_i_after_fi:nw} +% \begin{macro}{\use_arg_i_after_else:nw} +% \begin{macro}{\use_arg_i_after_or:nw} +% Returns the first argument after ending the conditional. +% \begin{macrocode} +\def_long_new:Npn \use_arg_i_after_fi:nw #1\fi:{\fi: #1} +\def_long_new:Npn \use_arg_i_after_else:nw #1\else:#2\fi:{\fi: #1} +\def_long_new:Npn \use_arg_i_after_or:nw #1\or: #2\fi: {\or:\fi:#1} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \subsubsection{Gobbling tokens from input} +% +% \begin{macro}{\use_none:n} +% \begin{macro}{\use_none:nn} +% \begin{macro}{\use_none:nnn} +% \begin{macro}{\use_none:nnnn} +% \begin{macro}{\use_none:nnnnn} +% \begin{macro}{\use_none:nnnnnn} +% \begin{macro}{\use_none:nnnnnnn} +% \begin{macro}{\use_none:nnnnnnnn} +% \begin{macro}{\use_none:nnnnnnnnn} +% To gobble tokens from the input we use a standard naming +% convention: the number of tokens gobbled is given by the number of +% |n|'s following the |:| in the name. Although defining +% |\use_none:nnn| and above as separate calls of |\use_none:n| and +% |\use_none:nn| is slightly faster, this is very non-intuitive to +% the programmer who will assume that expanding such a function once +% will take care of gobbling all the tokens in one go. % \begin{macrocode} -\def_long_new:Npn\use_choice_i:nnn#1#2#3{#1} -\def_long_new:Npn\use_choice_ii:nnn#1#2#3{#2} -\def_long_new:Npn\use_choice_iii:nnn#1#2#3{#3} +%\def_long_new:NNn \use_none:n 1{}% moved earlier +\def_long_new:NNn \use_none:nn 2{} +\def_long_new:NNn \use_none:nnn 3{} +\def_long_new:NNn \use_none:nnnn 4{} +\def_long_new:NNn \use_none:nnnnn 5{} +\def_long_new:NNn \use_none:nnnnnn 6{} +\def_long_new:NNn \use_none:nnnnnnn 7{} +\def_long_new:NNn \use_none:nnnnnnnn 8{} +\def_long_new:NNn \use_none:nnnnnnnnn 9{} % \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} % % -% \subsection{Scratch functions} +% \subsubsection{Scratch functions} % % \begin{macro}{\gtmp:w} % This function is for global scratch definitions that are used @@ -902,92 +2608,68 @@ % \end{macrocode} % \end{macro} % -% \section{Strings and input stream token lists} +% \subsubsection{Strings and input stream token lists} % % \begin{macro}{\cs_to_str:N} -% This converts a control sequence into the character string of its +% This converts a control sequence into the character string of its % name, removing the leading escape character. % \begin{macrocode} \def_new:Npn \cs_to_str:N {\exp_after:NN\use_none:n \token_to_string:N} % \end{macrocode} % \end{macro} % -% \begin{macro}{\tlist_eq:nnTF} -% \begin{macro}{\tlist_eq:onTF} -% |\tlist_eq:nnTF| tests whether the first two arguments are equal and -% executes either its third or fourth argument. -% |\tlist_eq:onTF| expands its first argument once. -% \begin{macrocode} -\def_new:Npn \tlist_eq:nnTF #1#2{ - \tlp_gset:Nn \g_testa_tlp {#1} - \tlp_gset:Nn \g_testb_tlp {#2} - \if_meaning:NN\g_testa_tlp \g_testb_tlp - \exp_after:NN\use_choice_i:nn \else: - \exp_after:NN\use_choice_ii:nn \fi:} -\def_new:Npn \tlist_eq:onTF {\exp_args:No \tlist_eq:nnTF} -% \end{macrocode} -% \end{macro} -% \end{macro} % % -% \begin{macro}{\tlist_empty:nTF} -% \begin{macro}{\tlist_empty:nF} -% These test whether a token list is empty and act accordingly. -% \begin{macrocode} -\def_new:Npn \tlist_empty:nTF #1{\tlp_gset:Nn \g_testa_tlp {#1} - \if_meaning:NN\g_testa_tlp \c_empty_tlp - \exp_after:NN \use_choice_i:nn \else: - \exp_after:NN \use_choice_ii:nn \fi:} -\def_new:Npn \tlist_empty:nF #1{\tlp_gset:Nn \g_testa_tlp {#1} - \if_meaning:NN\g_testa_tlp \c_empty_tlp - \exp_after:NN \use_none:nn \fi: \use:n} -% \end{macrocode} -% \end{macro} -% \end{macro} % % -% \begin{macro}{\str_eq_p:nn} -% Takes 2 lists of characters as arguments and expands into -% |\c_true| if they are equal, and |\c_false| otherwise. I'm -% pretty sure that the non expandable version above is faster, but -% it's not expandable so we also include this one. +% \begin{macro}{\cs_if_eq:NNTF} +% \begin{macro}{\cs_if_eq:NNT} +% \begin{macro}{\cs_if_eq:NNF} +% \begin{macro}{\cs_if_eq:cNTF} +% \begin{macro}{\cs_if_eq:cNT} +% \begin{macro}{\cs_if_eq:cNF} +% \begin{macro}{\cs_if_eq:NcTF} +% \begin{macro}{\cs_if_eq:NcT} +% \begin{macro}{\cs_if_eq:NcF} +% \begin{macro}{\cs_if_eq:ccTF} +% \begin{macro}{\cs_if_eq:ccT} +% \begin{macro}{\cs_if_eq:ccF} +% Check if two control sequences are identical. % \begin{macrocode} -\def_new:Npn \str_eq_p:nn #1#2{\str_eq_p_aux:w #1\scan_stop:\\#2\scan_stop:\\} -\def_new:Npn \str_eq_p_aux:w #1#2\\#3#4\\{ - \if_meaning:NN#1#3 - \if_meaning:NN#1\scan_stop:\c_true \else: - \if_meaning:NN#3\scan_stop:\c_false \else: - \str_eq_p_aux:w #2\\#4\\\fi:\fi: - \else:\c_false \fi:} +\def_test_function_new:npn {cs_if_eq:NN} #1#2{\if_meaning:NN #1#2} +\def_new:Npn \cs_if_eq:cNTF {\exp_args:Nc \cs_if_eq:NNTF} +\def_new:Npn \cs_if_eq:cNT {\exp_args:Nc \cs_if_eq:NNT} +\def_new:Npn \cs_if_eq:cNF {\exp_args:Nc \cs_if_eq:NNF} +\def_new:Npn \cs_if_eq:NcTF {\exp_args:NNc \cs_if_eq:NNTF} +\def_new:Npn \cs_if_eq:NcT {\exp_args:NNc \cs_if_eq:NNT} +\def_new:Npn \cs_if_eq:NcF {\exp_args:NNc \cs_if_eq:NNF} +\def_new:Npn \cs_if_eq:ccTF {\exp_args:Ncc \cs_if_eq:NNTF} +\def_new:Npn \cs_if_eq:ccT {\exp_args:Ncc \cs_if_eq:NNT} +\def_new:Npn \cs_if_eq:ccF {\exp_args:Ncc \cs_if_eq:NNF} % \end{macrocode} % \end{macro} -% -% \begin{macro}{\cs_eq_p:NN} -% An application of the above function, already streamlined for -% speed, so I put it in here. It takes two control sequences as -% arguments and expands into true iff they have the same name. -% \begin{macrocode} -\def:Npn \cs_eq_p:NN #1#2{ - \exp_after:NN\exp_after:NN - \exp_after:NN\str_eq_p_aux:w - \exp_after:NN\token_to_string:N - \exp_after:NN#1 - \exp_after:NN\scan_stop: - \exp_after:NN\\ - \token_to_string:N#2\scan_stop:\\} -% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % \end{macro} % -% Finally some code that is needed as we -% do not distribute the file module at the moment (so we simply define -% the needed function via an existing \LaTeX{} command) and some other -% stuff which was set up elsewhere, in undistributed modules. +% Finally some code that is needed as we do not distribute the file +% module at the moment (so we simply define the needed function via an +% existing \LaTeX{} command) and some other stuff which was set up +% elsewhere, in undistributed modules. % \begin{macrocode} \def_new:Npn\file_not_found:nTF #1#2#3{\IfFileExists{#1}{#3}{#2}} % \end{macrocode} % -% -% \section{Predicates and conditionals} +% +% \subsubsection{Predicates and conditionals} % \label{sec:predicates} % % \LaTeX3 has three concepts for conditional flow processing: @@ -995,8 +2677,8 @@ % % \item % Functions that carry out a test an then execute, depending on its -% result, either the code supplied in the or the . These arguments are denoted with "T" and "F" repectively. An +% result, either the code supplied in the \m{true arg} or the \m{false +% arg}. These arguments are denoted with "T" and "F" repectively. An % example would be % \begin{quote} % "\cs_free:cTF{abc}{...}{...}" @@ -1027,52 +2709,108 @@ % thoughts. % \end{enumerate} % -% Important to note is that conditionals with and/or are always defined in a way that the code of the chosen +% Important to note is that conditionals with \m{true code} and/or +% \m{false code} are always defined in a way that the code of the chosen % alternative can operate on following tokens in the input stream while % the predicate implementations always have an "\else:" or "\fi:" % interfering. This can be important in scanner implementations. % -% \subsection{Variables} % -% \begin{variable}{% -% \c_true | \c_false | -% } -% Constants that represend `true' or `false', respectively. Used to -% implement predicates. -% \end{variable} +% \begin{macrocode} +% +%<*showmemory> +\showMemUsage +% +% \end{macrocode} % -% \begin{variable}{\l_testa_tlp | -% \l_testb_tlp | -% \g_testa_tlp | -% \g_testb_tlp | -% } -% All conditionals and predicates never use tmp variables. Instead they -% use the following reserved variables. -% \end{variable} +% \endinput % -% \subsection{Predicate implementation} +% $Log$ +% Revision 1.38 2006/08/06 17:05:25 morten +% Make \chk_new_cs:N bulletproof % -% I think Michael originated the idea of expandable boolean tests. -% They must expand into either \texttt{TT} or \texttt{TF} and are -% tested using |\if:w|. +% Revision 1.37 2006/07/30 14:37:47 morten +% Added \str_if_eq_var_p:nf % +% Revision 1.36 2006/07/23 13:43:21 morten +% Removed extra occurrence of \str_if_eq_p:nn % -% \begin{macro}{\c_true} -% \begin{macro}{\c_false} -% Here are the canonical boolean values. -% \begin{macrocode} -\def_new:Npn \c_true {TT} -\def_new:Npn \c_false {TF} -% \end{macrocode} -% \end{macro} -% \end{macro} +% Revision 1.35 2006/07/17 22:25:31 morten +% Fix logic of \chk_new_cs:N and rename \cs_if_eq_p:NN to +% \cs_if_eq_name_p:NN because it is not their meaning but their names +% which are compared. +% +% Revision 1.34 2006/07/08 22:46:17 morten +% Rearranged some code and added complete set of \use_none: +% functions. +% +% Revision 1.33 2006/07/06 14:53:56 morten +% Added \def:NNn functions, reorganized code and much much more. +% +% Revision 1.32 2006/06/03 17:14:43 morten +% Added more \use_arg_... functions. +% +% Revision 1.31 2006/03/20 18:26:33 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.30 2006/01/22 19:35:46 morten +% Changed \use_none:nnn to gobble all tokens in one go and added +% \use_arg_i_ii:nn for l3keyval. +% +% Revision 1.29 2006/01/16 09:47:49 morten +% Fixed deleted brace +% +% Revision 1.28 2006/01/15 19:08:28 morten +% Fixed typos in some \if names +% +% Revision 1.27 2006/01/04 01:29:36 morten +% Changed "robust" to "protected". +% +% Revision 1.26 2005/12/27 09:53:55 morten +% Fixed some names, added a few more \use_... functions, changed RCS +% information retrieval +% +% Revision 1.25 2005/12/23 11:16:15 morten +% *** empty log message *** +% +% Revision 1.24 2005/12/02 15:21:55 morten +% Fixed minor typo +% +% Revision 1.23 2005/11/20 07:10:03 morten +% Added a few missing functions. New function type +% \def_test_function:npn to help define TF-type functions. +% +% Revision 1.22 2005/11/08 04:16:17 morten +% Fixed typo. +% +% Revision 1.21 2005/10/27 22:35:13 morten +% Cleaned up a bit and moved some code to l3num. +% +% Revision 1.20 2005/07/12 16:10:24 morten +% Allow \cs_if_eq_p:NN to accept \par. (Yes, real life experience) +% +% Revision 1.19 2005/04/06 21:34:55 morten +% Added more functions. Moved \engine_aleph:TF from l3prg +% +% Revision 1.18 2005/03/25 23:52:24 braams +% The definition of \next needs to be seen at initex time, +% not at typesetting time +% +% Revision 1.17 2005/03/22 23:28:46 morten +% Moved some code to l3prg, removed obsolete code, cleaned up documentation. +% +% Revision 1.16 2005/03/16 22:31:44 braams +% Changed definition of \c_zero and \c_minus_one +% +% Revision 1.15 2005/03/15 23:16:27 braams +% Some tweaking with the docstrip guards to get the documentation to +% come out right. +% +% Revision 1.14 2005/03/15 22:50:00 braams +% Made loadable by initex as the second file +% +% Revision 1.13 2005/03/11 21:32:21 braams +% Fixed the use of RCS information; +% moved \RequirePackage after \StopEventually % -% \begin{macrocode} -% -%<*showmemory> -\showMemUsage -% -% \end{macrocode} -% - diff --git a/Master/texmf-dist/source/latex/expl3/l3box.dtx b/Master/texmf-dist/source/latex/expl3/l3box.dtx new file mode 100644 index 00000000000..96e0d4696a8 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3box.dtx @@ -0,0 +1,933 @@ +% \iffalse +%% File: l3box.dtx Copyright (C) 2005-2006 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. +%% +%% ----------------------------------------------------------------------- +% +%\RequirePackage{l3names} +%<*dtx> +%\fi +\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{% + \def\fileversion{#2}% + \def\filedate{#3/#4/#5}% + \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]% +} +%\iffalse +% +%\fi +\GetIdInfo$Id: l3box.dtx 573 2006-08-21 20:59:37Z morten $ + {L3 Experimental Box module} +% +% \iffalse +%<*driver> +\documentclass{l3doc} + +\begin{document} +\DocInput{l3box.dtx} +\end{document} +% +% \fi +% +% +% \title{The \textsf{l3box} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Boxes} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% \section{Boxes} +% +% +% There are three kinds of box operations: horizontal mode denoted +% with prefix |\hbox_|, vertical mode with prefix |\vbox_|, and the +% generic operations working in both modes with prefix |\box_|. +% +% +% \subsection{Generic functions} +% +% \begin{function}{% +% \box_new:N | +% \box_new:c | +% \box_new_l:N +% } +% \begin{syntax} +% "\box_new:N" +% \end{syntax} +% Defines to be a new variable of type "box". +% \begin{texnote} +% "\box_new:N" is the equivalent of plain \TeX{}'s \tn{newbox}. +% However, the internal register allocation is done differently. +% \end{texnote} +% \end{function} +% +% \begin{function}{% +% \if_hbox:N | +% \if_vbox:N | +% \if_box_empty:N | +% } +% \begin{syntax} +% "\if_hbox:N" "\else:" "\fi:" +% "\if_box_empty:N" "\else:" "\fi:" +% \end{syntax} +% "\if_hbox:N" and "\if_vbox:N" check if is an horizontal or +% vertical box resp. "\if_box_empty:N" tests if is empty (void) +% and executes "code" according to the test outcome. +% \begin{texnote} +% These are the \TeX{} primitives \tn{ifhbox}, \tn{ifvbox} and +% \tn{ifvoid}. +% \end{texnote} +% \end{function} +% +% \begin{function}{% +% \box_if_empty:NTF | +% \box_if_empty:cTF | +% \box_if_empty:NT | +% \box_if_empty:cT | +% \box_if_empty:NF | +% \box_if_empty:cF | +% } +% \begin{syntax} +% "\box_if_empty:NTF" "{"\m{true code}"}" "{"\m{false code}"}" +% \end{syntax} +% Tests if is empty (void) and executes "code" according to the +% test outcome. +% \begin{texnote} +% "\box_if_empty:NTF" is the \LaTeX3 function name for \tn{ifvoid}. +% \end{texnote} +% \end{function} +% +% +% \begin{function}{% +% \box_set_eq:NN | +% \box_set_eq:cN | +% \box_set_eq:Nc | +% \box_set_eq:cc | +% } +% \begin{syntax} +% "\box_set_eq:NN" +% \end{syntax} +% Sets equal to . Note that this eradicates the contents +% of afterwards. +% \end{function} +% +% +% \begin{function}{% +% \box_gset_eq:NN | +% \box_gset_eq:cN | +% \box_gset_eq:Nc | +% \box_gset_eq:cc | +% } +% \begin{syntax} +% "\box_gset_eq:NN" +% \end{syntax} +% Globally sets equal to . +% \end{function} +% +% +% \begin{function}{% +% \box_set_to_previous:N | +% \box_set_to_previous:c | +% \box_gset_to_previous:N | +% \box_gset_to_previous:c | +% } +% \begin{syntax} +% "\box_set_to_previous:N" +% \end{syntax} +% Sets equal to the previous box |\R_previous_box| and removes +% |\R_previous_box| from the current list (unless in outer vertical +% or math mode). +% \end{function} +% +% \begin{function}{% +% \box_move_right:nn | +% \box_move_left:nn | +% \box_move_up:nn | +% \box_move_down:nn | +% } +% \begin{syntax} +% "\box_move_left:nn" "{""}" "{""}" +% \end{syntax} +% Moves in the direction specified. is either an operation on a box such as "\box_use:N" or a +% ``raw'' box specification like "\vbox:n{xyz}". +% \end{function} +% +% \begin{function}{% +% \box_clear:N | +% \box_clear:c | +% \box_gclear:N | +% \box_gclear:c | +% } +% \begin{syntax} +% "\box_clear:N" +% \end{syntax} +% Clears by setting it to the constant "\c_void_box". +% "\box_gclear:N" does it globally. +% \end{function} +% +% +% \begin{function}{% +% \box_use:N | +% \box_use:c | +% \box_use_clear:N | +% \box_use_clear:c | +% } +% \begin{syntax} +% "\box_use:N" \\ +% "\box_use_clear:N" +% \end{syntax} +% "\box_use:N" puts a copy of on the current list while +% "\box_use_clear:N" puts the box on the current list and then +% eradicates the contents of it. +% \begin{texnote} +% "\box_use:N" and "\box_use_clear:N" are the \TeX{} primitives +% \tn{copy} and \tn{box} with new (descriptive) names. +% \end{texnote} +% \end{function} +% +% +% \begin{function}{% +% \box_ht:N | +% \box_ht:c | +% \box_dp:N | +% \box_dp:c | +% \box_wd:N | +% \box_wd:c | +% } +% \begin{syntax} +% "\box_ht:N" +% \end{syntax} +% Returns the height, depth, and width of for use in dimension +% settings. +% \begin{texnote} +% These are the \TeX{} primitives \tn{ht}, \tn{dp} and \tn{wd}. +% \end{texnote} +% \end{function} +% +% \begin{function}{% +% \box_show:N | +% \box_show:c | +% } +% \begin{syntax} +% "\box_show:N" +% \end{syntax} +% Writes the contents of to the log file. +% \begin{texnote} +% This is the \TeX{} primitive \tn{showbox}. +% \end{texnote} +% \end{function} +% +% +% \begin{variable}{% +% \c_empty_box | +% \l_tmpa_box | +% \l_tmpb_box | +% } +% \begin{syntax} +% \end{syntax} +% "\c_empty_box" is the constantly empty box. The others are scratch +% boxes. +% \end{variable} +% +% +% \begin{variable}{% +% \R_previous_box | +% } +% \begin{syntax} +% \end{syntax} +% "\R_previous_box" is a read-only box register. You can set other +% boxes to this box, which will then be removed from the current +% list. +% \end{variable} +% +% +% \subsection{Horizontal mode} +% +% \begin{function}{% +% \hbox:n | +% } +% \begin{syntax} +% "\hbox:n" "{""}" +% \end{syntax} +% Places a "hbox" of natural size. +% \end{function} +% +% \begin{function}{% +% \hbox_set:Nn | +% \hbox_set:cn | +% \hbox_gset:Nn | +% \hbox_gset:cn | +% } +% \begin{syntax} +% "\hbox_set:Nn" "{"\m{contents}"}" +% \end{syntax} +% Sets to be a vertical mode box containing \m{contents}. It has +% it's natural size. "\hbox_gset:Nn" does it globally. +% \end{function} +% +% +% \begin{function}{% +% \hbox_set_to_wd:Nnn | +% \hbox_set_to_wd:cnn | +% \hbox_gset_to_wd:Nnn | +% \hbox_gset_to_wd:cnn | +% } +% \begin{syntax} +% "\hbox_set_to_wd:Nnn" "{"\m{dimen}"}" "{"\m{contents}"}" +% \end{syntax} +% Sets to contain \m{contents} and have width . +% "\hbox_gset_to_wd:Nn" does it globally. +% \end{function} +% +% +% \begin{function}{% +% \hbox_to_wd:nn | +% } +% \begin{syntax} +% "\hbox_to_wd:nn" "{""}" +% \end{syntax} +% Places a of width containing . +% \end{function} +% +% +% \begin{function}{% +% \hbox_set_inline_begin:N | +% \hbox_set_inline_end: | +% \hbox_gset_inline_begin:N | +% \hbox_gset_inline_end: | +% } +% \begin{syntax} +% "\hbox_set_inline_begin:N" +% "\hbox_set_inline_end:" +% \end{syntax} +% Sets to contain . This type is useful for use in +% environment definitions. +% \end{function} +% +% +% \begin{function}{% +% \hbox_unpack:N | +% \hbox_unpack_clear:N | +% } +% \begin{syntax} +% "\hbox_unpack:N" +% \end{syntax} +% "\hbox_unpack:N" unpacks the contents of the register and +% "\hbox_unpack_clear:N" also clears the after unpacking it. +% \begin{texnote} +% These are the \TeX{} primitives \tn{unhcopy} and \tn{unhbox}. +% \end{texnote} +% \end{function} +% +% +% +% +% +% \subsection{Vertical mode} +% +% \begin{function}{% +% \vbox_set:Nn | +% \vbox_set:cn | +% \vbox_gset:Nn | +% \vbox_gset:cn | +% } +% \begin{syntax} +% "\vbox_set:Nn" "{"\m{contents}"}" +% \end{syntax} +% Sets to be a vertical mode box containing \m{contents}. It has +% it's natural size. "\vbox_gset:Nn" does it globally. +% \end{function} +% +% +% \begin{function}{% +% \vbox_set_to_ht:Nnn | +% \vbox_set_to_ht:cnn | +% \vbox_gset_to_ht:Nnn | +% \vbox_gset_to_ht:cnn | +% \vbox_gset_to_ht:ccn | +% } +% \begin{syntax} +% "\vbox_set_to_ht:Nnn" "{"\m{dimen}"}" "{"\m{contents}"}" +% \end{syntax} +% Sets to contain \m{contents} and have total height . +% "\vbox_gset_to_ht:Nn" does it globally. +% \end{function} +% +% +% \begin{function}{% +% \vbox_set_inline_begin:N | +% \vbox_set_inline_end: | +% \vbox_gset_inline_begin:N | +% \vbox_gset_inline_end: | +% } +% \begin{syntax} +% "\vbox_set_inline_begin:N" +% "\vbox_set_inline_end:" +% \end{syntax} +% Sets to contain \m{contents}. This type is useful for use in +% environment definitions. +% \end{function} +% +% \begin{function}{% +% \vbox_set_split_to_ht:NNn | +% } +% \begin{syntax} +% "\vbox_set_split_to_ht:NNn" "{""}" +% \end{syntax} +% Sets to contain the top part of . +% \begin{texnote} +% This is the \TeX{} primitive \tn{vsplit}. +% \end{texnote} +% \end{function} +% +% \begin{function}{% +% \vbox:n | +% } +% \begin{syntax} +% "\vbox:n" "{""}" +% \end{syntax} +% Places a "vbox" of natural size with baseline equal to the baseline +% of the last line in the box. +% \end{function} +% +% \begin{function}{% +% \vbox_to_ht:nn | +% \vbox_to_zero:n | +% } +% \begin{syntax} +% "\vbox_to_ht:nn" "{""}" \\ +% "\vbox_to_zero:n" +% \end{syntax} +% Places a of size containing . +% \end{function} +% +% +% \begin{function}{% +% \vbox_unpack:N | +% \vbox_unpack_clear:N | +% } +% \begin{syntax} +% "\vbox_unpack:N" +% \end{syntax} +% "\vbox_unpack:N" unpacks the contents of the register and +% "\vbox_unpack_clear:N" also clears the after unpacking it. +% \begin{texnote} +% These are the \TeX{} primitives \tn{unvcopy} and \tn{unvbox}. +% \end{texnote} +% \end{function} +% +% +% \StopEventually{} +% +% +% +% \subsection{The Implementation} +% +% +% We start by ensuring that the required packages are loaded. +% \begin{macrocode} +%\RequirePackage{l3prg}\par +%\RequirePackage{l3chk}\par +%<*initex|package> +% \end{macrocode} +% +% The code in this module is very straight forward so I'm not going to +% comment it very extensively. +% +% +% \subsubsection{Generic boxes} +% +% \begin{macro}{\box_new:N} +% \begin{macro}{\box_new_l:N} +% \begin{macro}{\box_new:c} +% Defining a new \m{box} register. +% \begin{macrocode} +%<*initex> +\alloc_setup_type:nnn {box} \c_zero \c_max_register_num +% \end{macrocode} +% Now, remember that |\box255| has a special role in \TeX, it +% shouldn't be allocated\dots +% \begin{macrocode} +\seq_put_right:Nn \g_box_allocation_seq {255} +\def_new:Npn \box_new:N #1 {\alloc_reg:NnNN g {box} \tex_mathchardef:D #1} +\def_new:Npn \box_new_l:N #1 {\alloc_reg:NnNN l {box} \tex_mathchardef:D #1} +% +% \end{macrocode} +% When we run on top of \LaTeX, we just use its allocation +% mechanism. +% \begin{macrocode} +%\let_new:NN \box_new:N \newbox +\def_new:Npn \box_new:c {\exp_args:Nc \box_new:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\if_hbox:N} +% \begin{macro}{\if_vbox:N} +% \begin{macro}{\if_box_empty:N} +% The primitives for testing if a \m{box} is empty/void or which +% type of box it is. +% \begin{macrocode} +\let_new:NN \if_hbox:N \tex_ifhbox:D +\let_new:NN \if_vbox:N \tex_ifvbox:D +\let_new:NN \if_box_empty:N \tex_ifvoid:D +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\box_if_empty:NTF} +% \begin{macro}{\box_if_empty:cTF} +% \begin{macro}{\box_if_empty:NT} +% \begin{macro}{\box_if_empty:cT} +% \begin{macro}{\box_if_empty:NF} +% \begin{macro}{\box_if_empty:cF} +% Testing if a \m{box} is empty/void. +% \begin{macrocode} +\def_test_function_new:npn {box_if_empty:N}#1{\if_box_empty:N #1} +\def_new:Npn \box_if_empty:cTF {\exp_args:Nc \box_if_empty:NTF} +\def_new:Npn \box_if_empty:cT {\exp_args:Nc \box_if_empty:NT} +\def_new:Npn \box_if_empty:cF {\exp_args:Nc \box_if_empty:NF} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\box_set_eq:NN} +% \begin{macro}{\box_set_eq:cN} +% \begin{macro}{\box_set_eq:Nc} +% \begin{macro}{\box_set_eq:cc} +% Assigning the contents of a box to be another box. +% This clears the second box globally (that's how \TeX{} does it). +% \begin{macrocode} +\def_new:Npn \box_set_eq:NN #1#2 {\tex_setbox:D #1 \tex_box:D #2} +\def_new:Npn \box_set_eq:cN {\exp_args:Nc \box_set_eq:NN} +\def_new:Npn \box_set_eq:Nc {\exp_args:NNc \box_set_eq:NN} +\def_new:Npn \box_set_eq:cc {\exp_args:Ncc \box_set_eq:NN} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\box_gset_eq:NN} +% \begin{macro}{\box_gset_eq:cN} +% \begin{macro}{\box_gset_eq:Nc} +% \begin{macro}{\box_gset_eq:cc} +% Global version of the above. +% \begin{macrocode} +\def_new:Npn \box_gset_eq:NN {\pref_global:D\box_set_eq:NN} +\def_new:Npn \box_gset_eq:cN {\exp_args:Nc \box_gset_eq:NN} +\def_new:Npn \box_gset_eq:Nc {\exp_args:NNc \box_gset_eq:NN} +\def_new:Npn \box_gset_eq:cc {\exp_args:Ncc \box_gset_eq:NN} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\R_previous_box} +% A different name for this read-only primitive. +% \begin{macrocode} +\let_new:NN \R_previous_box \tex_lastbox:D +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\box_set_to_previous:N} +% \begin{macro}{\box_set_to_previous:c} +% \begin{macro}{\box_gset_to_previous:N} +% \begin{macro}{\box_gset_to_previous:c} +% Set a box to the previous box. +% \begin{macrocode} +\def_new:Npn \box_set_to_previous:N #1{\tex_setbox:D#1\R_previous_box} +\def_new:Npn \box_set_to_previous:c {\exp_args:Nc \box_set_to_previous:N} +\def_new:Npn \box_gset_to_previous:N {\pref_global:D \box_set_to_previous:N} +\def_new:Npn \box_gset_to_previous:c {\exp_args:Nc \box_gset_to_previous:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\box_move_left:nn} +% \begin{macro}{\box_move_right:nn} +% \begin{macro}{\box_move_up:nn} +% \begin{macro}{\box_move_down:nn} +% Move box material in different directions. +% \begin{macrocode} +\def_long_new:Npn \box_move_left:nn #1#2{\tex_moveleft:D\dim_eval:n{#1}{#2}} +\def_long_new:Npn \box_move_right:nn #1#2{\tex_moveright:D\dim_eval:n{#1}{#2}} +\def_long_new:Npn \box_move_up:nn #1#2{\tex_raise:D\dim_eval:n{#1}{#2}} +\def_long_new:Npn \box_move_down:nn #1#2{\tex_lower:D\dim_eval:n{#1}{#2}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\box_clear:N} +% \begin{macro}{\box_clear:c} +% \begin{macro}{\box_gclear:N} +% \begin{macro}{\box_gclear:c} +% Clear a \m{box} register. +% \begin{macrocode} +\def_new:Npn \box_clear:N #1{\box_set_eq:NN #1 \c_empty_box } +\def_new:Npn \box_clear:c {\exp_args:Nc \box_clear:N } +\def_new:Npn \box_gclear:N {\pref_global:D\box_clear:N} +\def_new:Npn \box_gclear:c {\exp_args:Nc \box_gclear:c } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\box_ht:N} +% \begin{macro}{\box_ht:c} +% \begin{macro}{\box_dp:N} +% \begin{macro}{\box_dp:c} +% \begin{macro}{\box_wd:n} +% \begin{macro}{\box_wd:c} +% Accessing the height, depth, and width of a \m{box} register. +% \begin{macrocode} +\let_new:NN \box_ht:N \tex_ht:D +\def_new:Npn \box_ht:c {\exp_args:Nc \box_ht:N} +\let_new:NN \box_dp:N \tex_dp:D +\def_new:Npn \box_dp:c {\exp_args:Nc \box_dp:N} +\let_new:NN \box_wd:N \tex_wd:D +\def_new:Npn \box_wd:c {\exp_args:Nc \box_wd:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\box_use_clear:N} +% \begin{macro}{\box_use_clear:c} +% \begin{macro}{\box_use:N} +% \begin{macro}{\box_use:c} +% Using a \m{box}. This is just \TeX{} primitives with meaningful +% names. +% \begin{macrocode} +\let_new:NN \box_use_clear:N \tex_box:D +\def_new:Npn \box_use_clear:c {\exp_args:Nc \box_use_clear:N} +\let_new:NN \box_use:N \tex_copy:D +\def_new:Npn \box_use:c {\exp_args:Nc \box_use:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\box_show:N} +% \begin{macro}{\box_show:c} +% Show the contents of a box and write it into the log file. +% \begin{macrocode} +\let:NN \box_show:N \tex_showbox:D +\def_new:Npn \box_show:c {\exp_args:Nc \box_show:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\c_empty_box} +% \begin{macro}{\l_tmpa_box} +% \begin{macro}{\l_tmpb_box} +% We allocate some \m{box} registers here (and borrow a few from \LaTeX). +% \begin{macrocode} +%\let:NN \c_empty_box \voidb@x +%\let_new:NN \l_tmpa_box \@tempboxa +%\box_new:N \c_empty_box +%\box_new:N \l_tmpa_box +\box_new:N \l_tmpb_box +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \subsubsection{Vertical boxes} +% +% +% \begin{macro}{\vbox:n} +% Put a vertical box directly into the input stream. +% \begin{macrocode} +\def_new:Npn \vbox:n {\tex_vbox:D \scan_stop:} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\vbox_set:Nn} +% \begin{macro}{\vbox_set:cn} +% \begin{macro}{\vbox_gset:Nn} +% \begin{macro}{\vbox_gset:cn} +% Storing material in a vertical box with a natural height. +% \begin{macrocode} +\def_long_new:Npn \vbox_set:Nn #1#2 {\tex_setbox:D #1 \tex_vbox:D {#2}} +\def_new:Npn \vbox_set:cn {\exp_args:Nc \vbox_set:Nn} +\def_new:Npn \vbox_gset:Nn {\pref_global:D \vbox_set:Nn} +\def_new:Npn \vbox_gset:cn {\exp_args:Nc \vbox_gset:Nn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\vbox_set_to_ht:Nnn} +% \begin{macro}{\vbox_set_to_ht:cnn} +% \begin{macro}{\vbox_gset_to_ht:Nnn} +% \begin{macro}{\vbox_gset_to_ht:cnn} +% \begin{macro}{\vbox_gset_to_ht:ccn} +% Storing material in a vertical box with a specified height. +% \begin{macrocode} +\def_long_new:Npn \vbox_set_to_ht:Nnn #1#2#3 { + \tex_setbox:D #1 \tex_vbox:D to #2 {#3}} +\def_new:Npn \vbox_set_to_ht:cnn{\exp_args:Nc \vbox_set_to_ht:Nnn } +\def_new:Npn \vbox_gset_to_ht:Nnn {\pref_global:D \vbox_set_to_ht:Nnn } +\def_new:Npn \vbox_gset_to_ht:cnn{\exp_args:Nc \vbox_gset_to_ht:Nnn } +\def_new:Npn \vbox_gset_to_ht:ccn {\exp_args:Ncc \vbox_gset_to_ht:Nnn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\vbox_set_inline_begin:N} +% \begin{macro}{\vbox_set_inline_end:} +% \begin{macro}{\vbox_gset_inline_begin:N} +% \begin{macro}{\vbox_set_inline_end:} +% Storing material in a vertical box. This type is useful in +% environment definitions. +% \begin{macrocode} +\def_new:Npn \vbox_set_inline_begin:N #1 { + \tex_setbox:D #1 \tex_vbox:D \c_group_begin_token } +\let_new:NN \vbox_set_inline_end: \c_group_end_token +\def_new:Npn \vbox_gset_inline_begin:N { + \pref_global:D \vbox_set_inline_begin:N } +\let_new:NN \vbox_gset_inline_end: \c_group_end_token +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\vbox_to_ht:nn} +% \begin{macro}{\vbox_to_zero:n} +% Put a vertical box directly into the input stream. +% \begin{macrocode} +\def_long_new:Npn \vbox_to_ht:nn #1#2{\tex_vbox:D to \dim_eval:n{#1}{#2}} +\def_long_new:Npn \vbox_to_zero:n #1 {\tex_vbox:D to \c_zero_dim {#1}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\vbox_set_split_to_ht:NNn} +% Splitting a vertical box in two. +% \begin{macrocode} +\def_new:Npn \vbox_set_split_to_ht:NNn #1#2#3{ + \tex_setbox:D #1 \tex_vsplit:D #2 to #3 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\vbox_unpack:N} +% \begin{macro}{\vbox_unpack:c} +% \begin{macro}{\vbox_unpack_clear:N} +% \begin{macro}{\vbox_unpack_clear:c} +% Unpacking a box and if requested also clear it. +% \begin{macrocode} +\let_new:NN \vbox_unpack:N \tex_unvcopy:D +\def_new:Npn \vbox_unpack:c {\exp_args:Nc \vbox_unpack:N} +\let_new:NN \vbox_unpack_clear:N \tex_unvbox:D +\def_new:Npn \vbox_unpack_clear:c {\exp_args:Nc \vbox_unpack_clear:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% +% +% +% \subsubsection{Horizontal boxes} +% +% +% \begin{macro}{\hbox:n} +% Put a horizontal box directly into the input stream. +% \begin{macrocode} +\def_new:Npn \hbox:n {\tex_hbox:D \scan_stop:} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\hbox_set:Nn} +% \begin{macro}{\hbox_set:cn} +% \begin{macro}{\hbox_gset:Nn} +% \begin{macro}{\hbox_gset:cn} +% Assigning the contents of a box to be another box. +% This clears the second box globally (that's how \TeX{} does it). +% \begin{macrocode} +\def_long_new:Npn \hbox_set:Nn #1#2 {\tex_setbox:D #1 \tex_hbox:D {#2}} +\def_new:Npn \hbox_set:cn {\exp_args:Nc \hbox_set:Nn} +\def_new:Npn \hbox_gset:Nn {\pref_global:D \hbox_set:Nn} +\def_new:Npn \hbox_gset:cn {\exp_args:Nc \hbox_gset:Nn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\hbox_set_to_wd:Nnn} +% \begin{macro}{\hbox_set_to_wd:cnn} +% \begin{macro}{\hbox_gset_to_wd:Nnn} +% \begin{macro}{\hbox_gset_to_wd:cnn} +% Storing material in a horizontal box with a specified width. +% \begin{macrocode} +\def_long_new:Npn \hbox_set_to_wd:Nnn #1#2#3 { + \tex_setbox:D #1 \tex_hbox:D to \dim_eval:n{#2} {#3}} +\def_new:Npn \hbox_set_to_wd:cnn{\exp_args:Nc \hbox_set_to_wd:Nnn } +\def_new:Npn \hbox_gset_to_wd:Nnn {\pref_global:D \hbox_set_to_wd:Nnn } +\def_new:Npn \hbox_gset_to_wd:cnn{\exp_args:Nc \hbox_gset_to_wd:Nnn } +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\hbox_set_inline_begin:N} +% \begin{macro}{\hbox_set_inline_end:} +% \begin{macro}{\hbox_gset_inline_begin:N} +% \begin{macro}{\hbox_set_inline_end:} +% Storing material in a horizontal box. This type is useful in +% environment definitions. +% \begin{macrocode} +\def_new:Npn \hbox_set_inline_begin:N #1 { + \tex_setbox:D #1 \tex_hbox:D \c_group_begin_token } +\let_new:NN \hbox_set_inline_end: \c_group_end_token +\def_new:Npn \hbox_gset_inline_begin:N { + \pref_global:D \hbox_set_inline_begin:N } +\let_new:NN \hbox_gset_inline_end: \c_group_end_token +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\hbox_to_wd:nn} +% \begin{macro}{\hbox_to_zero:n} +% Put a horizontal box directly into the input stream. +% \begin{macrocode} +\def_long_new:Npn \hbox_to_wd:nn #1#2 {\tex_hbox:D to #1 {#2}} +\def_long_new:Npn \hbox_to_zero:n #1 {\tex_hbox:D to \c_zero_skip {#1}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\hbox_unpack:N} +% \begin{macro}{\hbox_unpack:c} +% \begin{macro}{\hbox_unpack_clear:N} +% \begin{macro}{\hbox_unpack_clear:c} +% Unpacking a box and if requested also clear it. +% \begin{macrocode} +\let_new:NN \hbox_unpack:N \tex_unhcopy:D +\def_new:Npn \hbox_unpack:c {\exp_args:Nc \hbox_unpack:N} +\let_new:NN \hbox_unpack_clear:N \tex_unhbox:D +\def_new:Npn \hbox_unpack_clear:c {\exp_args:Nc \hbox_unpack_clear:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +%^^A xo-or.sty:1528: \setbox\z@\vsplit\c_twohundred_fifty_five to\l_tmpa_dim +%^^A xo-or.dtx:222: \global\setbox\removed@guard@box\lastbox} +% +%^^A it probably should be \vbox_set:nn not \vbox_set:Nn as we can +%^^A have a number as the first arg ... do do we argue that this is not +%^^A supported on this level? +%^^A MH comment: +%^^A I don't think we should ever see people using numbers directly. +%^^A If they do it's \vbox_set:Nn \c_zero {...} anyway, not two-digit +%^^A numbers. +% +% \begin{macrocode} +% +%<*showmemory> +\showMemUsage +% +% \end{macrocode} +% +% \endinput +% +% $Log$ +% Revision 1.10 2006/03/20 18:26:34 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.9 2006/01/19 22:30:30 morten +% Added functions for accessing \tex_lastbox:D and moving box material +% in the four directions. +% +% Revision 1.8 2005/12/27 16:04:12 morten +% Changed RCS information retrieval +% +% Revision 1.7 2005/10/27 23:11:12 morten +% Moved \if_hbox:N, \if_vbox:N and _if_box_empty:N here +% +% Revision 1.6 2005/04/25 16:15:17 morten +% Fixed \bgroup/\egroup and made it run under initex +% +% Revision 1.5 2005/04/06 22:35:33 braams +% Now we have register allocation fitted +% +% Revision 1.4 2005/03/26 21:08:12 morten +% Fix \c_zero -> \c_zero_skip +% +% Revision 1.3 2005/03/16 22:36:46 braams +% Added the tweaks necessary to be able to load with initex +% +% Revision 1.2 2005/03/11 21:31:07 braams +% Fixed the use of RCS information; added \StopEventually +% diff --git a/Master/texmf-dist/source/latex/expl3/l3calc.dtx b/Master/texmf-dist/source/latex/expl3/l3calc.dtx new file mode 100644 index 00000000000..f00c2941940 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3calc.dtx @@ -0,0 +1,930 @@ +% \iffalse +%% File: l3calc.dtx Copyright (C) 2006 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. +%% +%% ----------------------------------------------------------------------- +%\RequirePackage{l3names} +%<*dtx> +%\fi +\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{% + \def\fileversion{#2}% + \def\filedate{#3/#4/#5}% + \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]% +} +%\iffalse +% +%\fi +\GetIdInfo$Id: l3calc.dtx 573 2006-08-21 20:59:37Z morten $ + {L3 Experimental calc module} +% \iffalse +%<*driver> +\documentclass{l3doc} + +\begin{document} +\DocInput{l3calc.dtx} +\end{document} +% +% \fi +% +% \title{The \textsf{l3calc} package\thanks{This file has version +% number \fileversion, last +% revised \filedate.}\\ +% Infix notation arithmetic in \LaTeX3} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% \section{Infix notation arithmetic} +% +% This is pretty much a straight adaption of the \textsf{calc} package +% and as such has same syntax for the \meta{calc expression}. However, +% there are some noticeable differences. +% \begin{itemize} +% \item The calc expression is expanded fully, which means there are +% no problems with unfinished conditionals. However, the contents of +% |\widthof| etc.\ is not expanded at all. +% \item Muskip registers are supported although they can only be used +% in |\ratio| if already evaluating a muskip expression. For the +% other three register types, you can use points. +% \item All results are rounded, not truncated. More precisely, the +% primitive \TeX\ operations |\divide| and |\multiply| are not used. +% \end{itemize} +% +% \begin{function}{ +% \calc_int_set:Nn | +% \calc_int_gset:Nn | +% \calc_int_add:Nn | +% \calc_int_gadd:Nn | +% \calc_int_sub:Nn | +% \calc_int_gsub:Nn | +% } +% \begin{syntax} +% "\calc_int_set:Nn" "{""}" +% \end{syntax} +% Evaluates and either adds or subtracts it from +% or sets to it. These operations can also be global. +% \end{function} +% +% +% \begin{function}{ +% \calc_dim_set:Nn | +% \calc_dim_gset:Nn | +% \calc_dim_add:Nn | +% \calc_dim_gadd:Nn | +% \calc_dim_sub:Nn | +% \calc_dim_gsub:Nn | +% } +% \begin{syntax} +% "\calc_dim_set:Nn" "{""}" +% \end{syntax} +% Evaluates and either adds or subtracts it from +% or sets to it. These operations can also be global. +% \end{function} +% +% +% \begin{function}{ +% \calc_skip_set:Nn | +% \calc_skip_gset:Nn | +% \calc_skip_add:Nn | +% \calc_skip_gadd:Nn | +% \calc_skip_sub:Nn | +% \calc_skip_gsub:Nn | +% } +% \begin{syntax} +% "\calc_skip_set:Nn" "{""}" +% \end{syntax} +% Evaluates and either adds or subtracts it from +% or sets to it. These operations can also be global. +% \end{function} +% +% +% \begin{function}{ +% \calc_muskip_set:Nn | +% \calc_muskip_gset:Nn | +% \calc_muskip_add:Nn | +% \calc_muskip_gadd:Nn | +% \calc_muskip_sub:Nn | +% \calc_muskip_gsub:Nn | +% } +% \begin{syntax} +% "\calc_muskip_set:Nn" "{""}" +% \end{syntax} +% Evaluates and either adds or subtracts it from +% or sets to it. These operations can also be +% global. +% \end{function} +% +% +% \begin{function}{ +% \calc_calculate_box_size:nnn | +% } +% \begin{syntax} +% "\calc_calculate_box_size:nnn" "{""}" \\ +% "{" ... "}" "{""}" +% \end{syntax} +% Sets in a temporary box "\l_tmpa_box". Then +% is put in front of a loop that inserts "+"\meta{item$\sb{i}$} in +% front of "\l_tmpa_box" and this is evaluated. For instance, if we +% wanted to determine the total height of the text "xyz" and store +% it in "\l_tmpa_dim", we would call it as. +% \begin{verbatim} +% \calc_calculate_box_size:nnn +% {\dim_set:Nn\l_tmpa_dim}{\box_ht:N\box_dp:N}{xyz} +% \end{verbatim} +% Similarly, if we wanted the difference between height and depth, +% we could call it as +% \begin{verbatim} +% \calc_calculate_box_size:nnn +% {\dim_set:Nn\l_tmpa_dim}{\box_ht:N{-\box_dp:N}}{xyz} +% \end{verbatim} +% \end{function} +% +% \StopEventually{} +% +% \subsection{The Implementation} +% +% Since this is basically a re-worked version of the \textsf{calc} +% package, I haven't bothered with too many comments except for in the +% places where this package differs. This may (and should) change at +% some point. +% +% We start by ensuring that the required packages are loaded. +% \begin{macrocode} +%<*package> +\RequirePackage{l3int} +\RequirePackage{l3skip} +\RequirePackage{l3box} +% +%<*initex|package> +% \end{macrocode} +% +% +% \begin{macro}{\l_calc_expression_tlp} +% \begin{macro}{\g_calc_A_register} +% \begin{macro}{\l_calc_B_register} +% \begin{macro}{\l_calc_current_type_int} +% Here we define some registers and pointers we will need. +% \begin{macrocode} +\tlp_new:Nn\l_calc_expression_tlp{} +\def_new:Npn \g_calc_A_register{} +\def_new:Npn \l_calc_B_register{} +\int_new:N \l_calc_current_type_int +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\g_calc_A_int} +% \begin{macro}{\l_calc_B_int} +% \begin{macro}{\l_calc_C_int} +% \begin{macro}{\g_calc_A_dim} +% \begin{macro}{\l_calc_B_dim} +% \begin{macro}{\l_calc_C_dim} +% \begin{macro}{\g_calc_A_skip} +% \begin{macro}{\l_calc_B_skip} +% \begin{macro}{\l_calc_C_skip} +% \begin{macro}{\g_calc_A_muskip} +% \begin{macro}{\l_calc_B_muskip} +% \begin{macro}{\l_calc_C_muskip} +% For each type of register we will need three registers to do our +% manipulations. +% \begin{macrocode} +\int_new:N \g_calc_A_int +\int_new:N \l_calc_B_int +\int_new:N \l_calc_C_int +\dim_new:N \g_calc_A_dim +\dim_new:N \l_calc_B_dim +\dim_new:N \l_calc_C_dim +\skip_new:N \g_calc_A_skip +\skip_new:N \l_calc_B_skip +\skip_new:N \l_calc_C_skip +\muskip_new:N \g_calc_A_muskip +\muskip_new:N \l_calc_B_muskip +\muskip_new:N \l_calc_C_muskip +% \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}{\calc_assign_generic:NNNNNn} +% The generic function. |#1| is a number denoting which type we are +% doing. (0=int, 1=dim, 2=skip, 3=muskip), |#2| = temp register A, +% |#3| = temp register B, |#4| is a function acting on |#5| which is +% the register to be set. |#6| is the calc expression. This version +% relies on |\real| and |\ratio| having our definitions. +% \begin{macrocode} +\def_long_new:Npn \calc_assign_generic:NNNNNn#1#2#3#4#5#6{ + \let:NN\g_calc_A_register#2\let:NN\l_calc_B_register#3 + \int_set:Nn \l_calc_current_type_int {#1} + \tlp_set:Nx\l_calc_expression_tlp{#6} + \exp_after:NN\calc_open:w\exp_after:NN(\l_calc_expression_tlp! + \pref_global:D\g_calc_A_register\l_calc_B_register + \group_end: + #4#5\l_calc_B_register +} +% \end{macrocode} +% One could lift these restrictions by defining |\calc_generic:NNNNNn| +% like this: +% \begin{verbatim} +% \def_long_new:Npn \calc_assign_generic:NNNNNn#1#2#3#4#5#6{ +% \let:NN\g_calc_A_register#2\let:NN\l_calc_B_register#3 +% \int_set:Nn \l_calc_current_type_int {#1} +% \group_begin: +% \let:NN \real\calc_real:n +% \let:NN \ratio\calc_ratio:nn +% \tlp_set:Nx\l_calc_expression_tlp{#6} +% \exp_after:NN +% \group_end: +% \exp_after:NN\calc_open:w\exp_after:NN(\l_calc_expression_tlp! +% \pref_global:D\g_calc_A_register\l_calc_B_register +% \group_end: +% #4#5\l_calc_B_register +% } +% \end{verbatim} +% \end{macro} +% +% +% +% \begin{macro}{\calc_int_set:Nn} +% \begin{macro}{\calc_int_gset:Nn} +% \begin{macro}{\calc_int_add:Nn} +% \begin{macro}{\calc_int_gadd:Nn} +% \begin{macro}{\calc_int_sub:Nn} +% \begin{macro}{\calc_int_gsub:Nn} +% Here are the individual versions for the different register +% types. First integer registers. +% \begin{macrocode} +\def_new:Npn\calc_int_set:Nn{ + \calc_assign_generic:NNNNNn\c_zero\g_calc_A_int\l_calc_B_int\int_set:Nn +} +\def_new:Npn\calc_int_gset:Nn{ + \calc_assign_generic:NNNNNn\c_zero\g_calc_A_int\l_calc_B_int\int_gset:Nn +} +\def_new:Npn\calc_int_add:Nn{ + \calc_assign_generic:NNNNNn\c_zero\g_calc_A_int\l_calc_B_int\int_add:Nn +} +\def_new:Npn\calc_int_gadd:Nn{ + \calc_assign_generic:NNNNNn\c_zero\g_calc_A_int\l_calc_B_int\int_gadd:Nn +} +\def_new:Npn\calc_int_sub:Nn{ + \calc_assign_generic:NNNNNn\c_zero\g_calc_A_int\l_calc_B_int\int_sub:Nn +} +\def_new:Npn\calc_int_gsub:Nn{ + \calc_assign_generic:NNNNNn\c_zero\g_calc_A_int\l_calc_B_int\int_gsub:Nn +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\calc_dim_set:Nn} +% \begin{macro}{\calc_dim_gset:Nn} +% \begin{macro}{\calc_dim_add:Nn} +% \begin{macro}{\calc_dim_gadd:Nn} +% \begin{macro}{\calc_dim_sub:Nn} +% \begin{macro}{\calc_dim_gsub:Nn} +% Dimens. +% \begin{macrocode} +\def_new:Npn\calc_dim_set:Nn{ + \calc_assign_generic:NNNNNn\c_one\g_calc_A_dim\l_calc_B_dim\dim_set:Nn +} +\def_new:Npn\calc_dim_gset:Nn{ + \calc_assign_generic:NNNNNn\c_one\g_calc_A_dim\l_calc_B_dim\dim_gset:Nn +} +\def_new:Npn\calc_dim_add:Nn{ + \calc_assign_generic:NNNNNn\c_one\g_calc_A_dim\l_calc_B_dim\dim_add:Nn +} +\def_new:Npn\calc_dim_gadd:Nn{ + \calc_assign_generic:NNNNNn\c_one\g_calc_A_dim\l_calc_B_dim\dim_gadd:Nn +} +\def_new:Npn\calc_dim_sub:Nn{ + \calc_assign_generic:NNNNNn\c_one\g_calc_A_int\l_calc_B_int\dim_sub:Nn +} +\def_new:Npn\calc_dim_gsub:Nn{ + \calc_assign_generic:NNNNNn\c_one\g_calc_A_int\l_calc_B_int\dim_gsub:Nn +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\calc_skip_set:Nn} +% \begin{macro}{\calc_skip_gset:Nn} +% \begin{macro}{\calc_skip_add:Nn} +% \begin{macro}{\calc_skip_gadd:Nn} +% \begin{macro}{\calc_skip_sub:Nn} +% \begin{macro}{\calc_skip_gsub:Nn} +% Skips. +% \begin{macrocode} +\def_new:Npn\calc_skip_set:Nn{ + \calc_assign_generic:NNNNNn\c_two\g_calc_A_dim\l_calc_B_dim\skip_set:Nn +} +\def_new:Npn\calc_skip_gset:Nn{ + \calc_assign_generic:NNNNNn\c_two\g_calc_A_dim\l_calc_B_dim\skip_gset:Nn +} +\def_new:Npn\calc_skip_add:Nn{ + \calc_assign_generic:NNNNNn\c_two\g_calc_A_dim\l_calc_B_dim\skip_add:Nn +} +\def_new:Npn\calc_skip_gadd:Nn{ + \calc_assign_generic:NNNNNn\c_two\g_calc_A_dim\l_calc_B_dim\skip_gadd:Nn +} +\def_new:Npn\calc_skip_sub:Nn{ + \calc_assign_generic:NNNNNn\c_two\g_calc_A_dim\l_calc_B_dim\skip_sub:Nn +} +\def_new:Npn\calc_skip_gsub:Nn{ + \calc_assign_generic:NNNNNn\c_two\g_calc_A_dim\l_calc_B_dim\skip_gsub:Nn +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\calc_muskip_set:Nn} +% \begin{macro}{\calc_muskip_gset:Nn} +% \begin{macro}{\calc_muskip_add:Nn} +% \begin{macro}{\calc_muskip_gadd:Nn} +% \begin{macro}{\calc_muskip_sub:Nn} +% \begin{macro}{\calc_muskip_gsub:Nn} +% Muskips. +% \begin{macrocode} +\def_new:Npn\calc_muskip_set:Nn{ + \calc_assign_generic:NNNNNn\c_three\g_calc_A_dim\l_calc_B_dim\muskip_set:Nn +} +\def_new:Npn\calc_muskip_gset:Nn{ + \calc_assign_generic:NNNNNn\c_three\g_calc_A_dim\l_calc_B_dim\muskip_gset:Nn +} +\def_new:Npn\calc_muskip_add:Nn{ + \calc_assign_generic:NNNNNn\c_three\g_calc_A_dim\l_calc_B_dim\muskip_add:Nn +} +\def_new:Npn\calc_muskip_gadd:Nn{ + \calc_assign_generic:NNNNNn\c_three\g_calc_A_dim\l_calc_B_dim\muskip_gadd:Nn +} +\def_new:Npn\calc_muskip_sub:Nn{ + \calc_assign_generic:NNNNNn\c_three\g_calc_A_dim\l_calc_B_dim\muskip_add:Nn +} +\def_new:Npn\calc_muskip_gsub:Nn{ + \calc_assign_generic:NNNNNn\c_three\g_calc_A_dim\l_calc_B_dim\muskip_gadd:Nn +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\calc_pre_scan:N} +% In case we found one of the special operations, this should just +% be executed. +% \begin{macrocode} +\def_new:Npn \calc_pre_scan:N #1{ + \if_meaning:NN(#1 + \exp_after:NN\calc_open:w + \else: + \if_meaning:NN \calc_textsize:Nn #1 + \else: + \if_meaning:NN \calc_maxmin_operation:Nnn #1 + \else: +% \end{macrocode} +% |\calc_numeric:| uses a primitive assignment so doesn't care about +% these dangling |\fi:|s. +% \begin{macrocode} + \calc_numeric: + \fi: + \fi: + \fi: + #1} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\calc_open:w} +% \begin{macrocode} +\def_new:Npn \calc_open:w({ + \group_begin:\group_execute_after:N\calc_init_B: + \group_begin:\group_execute_after:N\calc_init_B: + \calc_pre_scan:N +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\calc_init_B:} +% \begin{macro}{\calc_numeric:} +% \begin{macro}{\calc_close:} +% \begin{macrocode} +\def_new:Npn\calc_init_B:{\l_calc_B_register\g_calc_A_register} +\def_new:Npn\calc_numeric:{ + \tex_afterassignment:D\calc_post_scan:N + \pref_global:D\g_calc_A_register +} +\def_new:Npn\calc_close:{ + \group_end:\pref_global:D\g_calc_A_register\l_calc_B_register + \group_end:\pref_global:D\g_calc_A_register\l_calc_B_register + \calc_post_scan:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\calc_post_scan:N} +% Look at what token we have and decide where to go. +% \begin{macrocode} +\def_new:Npn\calc_post_scan:N#1{ + \if_meaning:NN#1!\let:NN\calc_next:w\group_end: \else: + \if_meaning:NN#1+\let:NN\calc_next:w\calc_add: \else: + \if_meaning:NN#1-\let:NN\calc_next:w\calc_subtract: \else: + \if_meaning:NN#1*\let:NN\calc_next:w\calc_multiply:N \else: + \if_meaning:NN#1/\let:NN\calc_next:w\calc_divide:N \else: + \if_meaning:NN#1)\let:NN\calc_next:w\calc_close: \else: +% \end{macrocode} +% If we get here, there is an error but let's also disable +% |\calc_next:w| since it is otherwise undefined. No need to give +% extra errors just for that. +% \begin{macrocode} + \let:NN \calc_next:w \scan_stop: + \calc_error:N#1 + \fi: + \fi: + \fi: + \fi: + \fi: + \fi: + \calc_next:w} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\calc_multiply:N} +% \begin{macro}{\calc_divide:N} +% The switches for multiplication and division. +% \begin{macrocode} +\def_new:Npn \calc_multiply:N #1{ + \if_meaning:NN \calc_maxmin_operation:Nnn #1 + \let:NN \calc_next:w \calc_maxmin_multiply: + \else: + \if_meaning:NN \calc_ratio_multiply:nn #1 + \let:NN \calc_next:w \calc_ratio_multiply:nn + \else: + \if_meaning:NN \calc_real_evaluate:nn #1 + \let:NN \calc_next:w \calc_real_multiply:n + \else: + \def:Npn \calc_next:w{\calc_multiply: #1} + \fi: + \fi: + \fi: + \calc_next:w +} +\def_new:Npn \calc_divide:N #1{ + \if_meaning:NN \calc_maxmin_operation:Nnn #1 + \let:NN \calc_next:w \calc_maxmin_divide: + \else: + \if_meaning:NN \calc_ratio_multiply:nn #1 + \let:NN \calc_next:w \calc_ratio_divide:nn + \else: + \if_meaning:NN \calc_real_evaluate:nn #1 + \let:NN \calc_next:w \calc_real_divide:n + \else: + \def:Npn \calc_next:w{\calc_divide: #1} + \fi: + \fi: + \fi: + \calc_next:w +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\calc_generic_add:N} +% \begin{macro}{\calc_add:} +% \begin{macro}{\calc_subtract:} +% \begin{macro}{\calc_add_A_to_B:} +% \begin{macro}{\calc_subtract_A_from_B:} +% Here is how we add and subtract. +% \begin{macrocode} +\def_new:Npn\calc_generic_add_or_subtract:N#1{ + \group_end: + \pref_global:D\g_calc_A_register\l_calc_B_register\group_end: + \group_begin:\group_execute_after:N#1\group_begin: + \group_execute_after:N\calc_init_B: + \calc_pre_scan:N} +\def_new:Npn\calc_add:{\calc_generic_add_or_subtract:N\calc_add_A_to_B:} +\def_new:Npn\calc_subtract:{ + \calc_generic_add_or_subtract:N\calc_subtract_A_from_B:} +% \end{macrocode} +% Don't use |\tex_advance:D| since it allows overflows. +% \begin{macrocode} +\def_new:Npn\calc_add_A_to_B:{ + \l_calc_B_register + \if_case:w\l_calc_current_type_int + \etex_numexpr:D\or: + \etex_dimexpr:D\or: + \etex_glueexpr:D\or: + \etex_muexpr:D\fi: + \l_calc_B_register + \g_calc_A_register\scan_stop: +} +\def_new:Npn\calc_subtract_A_from_B:{ + \l_calc_B_register + \if_case:w\l_calc_current_type_int + \etex_numexpr:D\or: + \etex_dimexpr:D\or: + \etex_glueexpr:D\or: + \etex_muexpr:D\fi: + \l_calc_B_register - \g_calc_A_register\scan_stop: +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\calc_generic_multiply_or_divide:N} +% \begin{macro}{\calc_multiply_B_by_A:} +% \begin{macro}{\calc_divide_B_by_A:} +% \begin{macro}{\calc_multiply:} +% \begin{macro}{\calc_divide:} +% And here is how we multiply and divide. Note that we do not use the +% primitive \TeX{} operations but the expandable operations provided +% by \eTeX. This means that all results are rounded not truncated! +% \begin{macrocode} +\def_new:Npn\calc_generic_multiply_or_divide:N#1{ + \group_end: + \group_begin: + \let:NN\g_calc_A_register\g_calc_A_int + \let:NN\l_calc_B_register\l_calc_B_int + \group_execute_after:N#1\calc_pre_scan:N +} +\def_new:Npn\calc_multiply_B_by_A:{ + \l_calc_B_register + \if_case:w\l_calc_current_type_int + \etex_numexpr:D\or: + \etex_dimexpr:D\or: + \etex_glueexpr:D\or: + \etex_muexpr:D\fi: + \l_calc_B_register*\g_calc_A_int\scan_stop: +} +\def_new:Npn\calc_divide_B_by_A:{ + \l_calc_B_register + \if_case:w\l_calc_current_type_int + \etex_numexpr:D\or: + \etex_dimexpr:D\or: + \etex_glueexpr:D\or: + \etex_muexpr:D\fi: + \l_calc_B_register/\g_calc_A_int\scan_stop: +} +\def_new:Npn\calc_multiply:{ + \calc_generic_multiply_or_divide:N\calc_multiply_B_by_A:} +\def_new:Npn\calc_divide:{ + \calc_generic_multiply_or_divide:N\calc_divide_B_by_A:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\calc_calculate_box_size:nnn} +% \begin{macro}{\calc_calculate_box_size_aux:n} +% Put something in a box and measure it. |#1| is a list of +% |\box_ht:N| etc., |#2| should be |\dim_set:Nn|\meta{dim register} +% or |\dim_gset:Nn|\meta{dim register} and |#3| is the contents. +% \begin{macrocode} +\def_long_new:Npn \calc_calculate_box_size:nnn #1#2#3{ + \hbox_set:Nn \l_tmpa_box {{#3}} + #2{\c_zero_dim \tlist_map_function:nN{#1}\calc_calculate_box_size_aux:n} +} +% \end{macrocode} +% Helper for calculating the final dimension. +% \begin{macrocode} +\def:Npn \calc_calculate_box_size_aux:n#1{ + #1\l_tmpa_box} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\calc_textsize:Nn} +% Now we can define |\calc_textsize:Nn|. +% \begin{macrocode} +\def_protected_long:Npn \calc_textsize:Nn#1#2{ + \group_begin: + \let:NN\widthof\box_wd:N + \let:NN\heightof\box_ht:N + \let:NN\depthof\box_dp:N + \def:Npn\totalheightof{\box_ht:N\box_dp:N} + \exp_args:No\calc_calculate_box_size:nnn{#1} + {\dim_gset:Nn\g_calc_A_register} +% \end{macrocode} +% Restore the four user commands here since there might be a recursive +% call. +% \begin{macrocode} + { + \let:NN \depthof\calc_depthof:n + \let:NN \widthof\calc_widthof:n + \let:NN \heightof\calc_heightof:n + \let:NN \totalheightof\calc_totalheightof:n + #2 + } + \group_end: + \calc_post_scan:N +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\calc_ratio_multiply:nn} +% \begin{macro}{\calc_ratio_divide:nn} +% Evaluate a ratio. If we were already evaluation a \meta{muskip} +% register, the ratio is probably also done with this type and we'll +% have to convert them to regular points. +% \begin{macrocode} +\def_protected_long:Npn\calc_ratio_multiply:nn#1#2{ + \group_end:\group_begin: + \if_num:w\l_calc_current_type_int < \c_three + \calc_dim_set:Nn\l_calc_B_int{#1} + \calc_dim_set:Nn\l_calc_C_int{#2} + \else: + \calc_dim_muskip:Nn{\l_calc_B_int\etex_mutoglue:D}{#1} + \calc_dim_muskip:Nn{\l_calc_C_int\etex_mutoglue:D}{#2} + \fi: +% \end{macrocode} +% Then store the ratio as a fraction, which we just pass on. +% \begin{macrocode} + \gdef:Npx\calc_calculated_ratio:{ + \int_use:N\l_calc_B_int/\int_use:N\l_calc_C_int + } + \group_end: +% \end{macrocode} +% Here we set the new value of |\l_calc_B_register| and remember to +% evaluate it as the correct type. Note that the intermediate +% calculation is a scaled operation (meaning the intermediate value is +% 64-bit) so we don't get into trouble when first multiplying by a +% large number and then dividing. +% \begin{macrocode} + \l_calc_B_register + \if_case:w\l_calc_current_type_int + \etex_numexpr:D\or: + \etex_dimexpr:D\or: + \etex_glueexpr:D\or: + \etex_muexpr:D\fi: + \l_calc_B_register*\calc_calculated_ratio:\scan_stop: + \group_begin: + \calc_post_scan:N} +% \end{macrocode} +% Division is just flipping the arguments around. +% \begin{macrocode} +\def_long_new:Npn \calc_ratio_divide:nn#1#2{\calc_ratio_multiply:nn{#2}{#1}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\calc_real_evaluate:nn} +% \begin{macro}{\calc_real_multiply:n} +% \begin{macro}{\calc_real_divide:n} +% Although we could define the |\real| function as a subcase of +% |\ratio|, this is horribly inefficient since we just want to convert +% the decimal to a fraction. +% \begin{macrocode} +\def_protected_new:Npn\calc_real_evaluate:nn #1#2{ + \group_end: + \l_calc_B_register + \if_case:w\l_calc_current_type_int + \etex_numexpr:D\or: + \etex_dimexpr:D\or: + \etex_glueexpr:D\or: + \etex_muexpr:D\fi: + \l_calc_B_register * + \tex_number:D \dim_eval:n{#1pt}/ + \tex_number:D\dim_eval:n{#2pt} + \scan_stop: + \group_begin: + \calc_post_scan:N} +\def_new:Npn \calc_real_multiply:n #1{\calc_real_evaluate:nn{#1}{1}} +\def_new:Npn \calc_real_divide:n {\calc_real_evaluate:nn{1}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\calc_maxmin_operation:Nnn} +% \begin{macro}{\calc_maxmin_generic:Nnn} +% \begin{macro}{\calc_maxmin_div_or_mul:NNnn} +% \begin{macro}{\calc_maxmin_multiply:} +% \begin{macro}{\calc_maxmin_multiply:} +% The max and min functions. +% \begin{macrocode} +\def_protected_long:Npn\calc_maxmin_operation:Nnn#1#2#3{ + \group_begin: + \calc_maxmin_generic:Nnn#1{#2}{#3} + \group_end: + \calc_post_scan:N +} +% \end{macrocode} +% |#1| is either |>| or |<| and was expanded into this initially. +% \begin{macrocode} +\def_protected_long_new:Npn \calc_maxmin_generic:Nnn#1#2#3{ + \group_begin: + \if_case:w\l_calc_current_type_int + \calc_int_set:Nn\l_calc_C_int{#2}% + \calc_int_set:Nn\l_calc_B_int{#3}% + \pref_global:D\g_calc_A_register + \if_num:w\l_calc_C_int#1\l_calc_B_int + \l_calc_C_int\else:\l_calc_B_int\fi: + \or: + \calc_dim_set:Nn\l_calc_C_dim{#2}% + \calc_dim_set:Nn\l_calc_B_dim{#3}% + \pref_global:D\g_calc_A_register + \if_dim:w\l_calc_C_dim#1\l_calc_B_dim + \l_calc_C_dim\else:\l_calc_B_dim\fi: + \or: + \calc_skip_set:Nn\l_calc_C_skip{#2}% + \calc_skip_set:Nn\l_calc_B_skip{#3}% + \pref_global:D\g_calc_A_register + \if_dim:w\l_calc_C_skip#1\l_calc_B_skip + \l_calc_C_skip\else:\l_calc_B_skip\fi: + \else: + \calc_muskip_set:Nn\l_calc_C_muskip{#2}% + \calc_muskip_set:Nn\l_calc_B_muskip{#3}% + \pref_global:D\g_calc_A_register + \if_dim:w\l_calc_C_muskip#1\l_calc_B_muskip + \l_calc_C_muskip\else:\l_calc_B_muskip\fi: + \fi: + \group_end: +} +\def_long_new:Npn\calc_maxmin_div_or_mul:NNnn#1#2#3#4{ + \group_end: + \group_begin: + \int_zero:N\l_calc_current_type_int + \group_execute_after:N#1 + \calc_maxmin_generic:Nnn#2{#3}{#4} + \group_end: + \group_begin: + \calc_post_scan:N +} +\def_new:Npn\calc_maxmin_multiply:{ + \calc_maxmin_div_or_mul:NNnn\calc_multiply_B_by_A:} +\def_new:Npn\calc_maxmin_divide: { + \calc_maxmin_div_or_mul:NNnn\calc_divide_B_by_A:} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\calc_error:N} +% The error message. +% \begin{macrocode} +\def_new:Npn\calc_error:N#1{ + \PackageError{calc} + {`\token_to_string:N#1'~ invalid~ at~ this~ point} + {I~ expected~ to~ see~ one~ of:~ +~ -~ *~ /~ )} +} +% \end{macrocode} +% \end{macro} +% +% \subsection{Higher level commands} +% +% The various operations allowed. +% +% \begin{macro}{\calc_maxof:nn} +% \begin{macro}{\calc_minof:nn} +% \begin{macro}{\maxof} +% \begin{macro}{\minof} +% Max and min operations +% \begin{macrocode} +\def_long_new:Npn \calc_maxof:nn#1#2{ + \calc_maxmin_operation:Nnn > \exp_not:n{{#1}{#2}} +} +\def_long_new:Npn \calc_minof:nn#1#2{ + \calc_maxmin_operation:Nnn < \exp_not:n{{#1}{#2}} +} +\let_new:NN \maxof \calc_maxof:nn +\let_new:NN \minof \calc_minof:nn +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\calc_widthof:n} +% \begin{macro}{\calc_heightof:n} +% \begin{macro}{\calc_depthof:n} +% \begin{macro}{\calc_totalheightof:n} +% \begin{macro}{\widthof} +% \begin{macro}{\heightof} +% \begin{macro}{\depthof} +% \begin{macro}{\totalheightof} +% Text dimension commands. +% \begin{macrocode} +\def_long_new:Npn \calc_widthof:n#1{ + \calc_textsize:Nn \exp_not:N\widthof\exp_not:n{{#1}} +} +\def_long_new:Npn \calc_heightof:n#1{ + \calc_textsize:Nn \exp_not:N\heightof\exp_not:n{{#1}} +} +\def_long_new:Npn \calc_depthof:n#1{ + \calc_textsize:Nn \exp_not:N\depthof\exp_not:n{{#1}} +} +\def_long_new:Npn \calc_totalheightof:n#1{ + \calc_textsize:Nn \exp_not:N\totalheightof\exp_not:n{{#1}} +} +\let:NN \depthof\calc_depthof:n +\let:NN \widthof\calc_widthof:n +\let:NN \heightof\calc_heightof:n +\let:NN \totalheightof\calc_totalheightof:n +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\calc_ratio:nn} +% \begin{macro}{\calc_real:n} +% \begin{macro}{\ratio} +% \begin{macro}{\real} +% Ratio and real. +% \begin{macrocode} +\def_long_new:Npn \calc_ratio:nn#1#2{ + \calc_ratio_multiply:nn\exp_not:n{{#1}{#2}}} +\let_new:NN \calc_real:n \calc_real_evaluate:nn +% \end{macrocode} +% We can implement real and ratio without actually using these +% names. We'll see. +% \begin{macrocode} +\let_new:NN \ratio\calc_ratio:nn +\let_new:NN \real\calc_real:n +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macrocode} +% +%<*showmemory> +\showMemUsage +% +% \end{macrocode} +% +% \endinput +% +% $Log$ +% Revision 1.2 2006/01/27 23:11:47 morten +% Fixed bug in \calc_pre_scan:N and avoid using \advance in order to +% catch overflows. +% +% Revision 1.1 2006/01/27 07:51:13 morten +% Initial version of a calc module +% diff --git a/Master/texmf-dist/source/latex/expl3/l3chk.dtx b/Master/texmf-dist/source/latex/expl3/l3chk.dtx index 56b9cf5c34c..f492a516903 100644 --- a/Master/texmf-dist/source/latex/expl3/l3chk.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3chk.dtx @@ -1,16 +1,50 @@ % \iffalse -%% File: l3chk.dtx Copyright (C) 1990-1998 LaTeX3 project -% +%% File: l3chk.dtx Copyright (C) 1990-2006 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. +%% +%% ----------------------------------------------------------------------- +%% +%\RequirePackage{l3names} %<*dtx> - \ProvidesFile{l3chk.dtx} +%\fi +\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{% + \def\fileversion{#2}% + \def\filedate{#3/#4/#5}% + \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]% +} +%\iffalse % -%\NeedsTeXFormat{LaTeX2e} -%\ProvidesPackage{l3chk} -% \ProvidesFile{l3chk.drv} -% \fi -% \ProvidesFile{l3chk.dtx} - [1998/04/20 v1.0e L3 Experimental check module] -% +%\fi +\GetIdInfo$Id: l3chk.dtx 573 2006-08-21 20:59:37Z morten $ + {L3 Experimental check module} % \iffalse %<*driver> \documentclass{l3doc} @@ -21,7 +55,6 @@ % % \fi % -% \GetFileInfo{l3chk.dtx} % \title{The \textsf{l3chk} package\thanks{This file % has version number \fileversion, last % revised \filedate.}\\ @@ -35,11 +68,12 @@ % To ensure that functions and variables are properly used certain % checking functions are implemented that may or may not be compiled % into the final format. -% +% % \subsection{Functions} -% +% % \begin{function}{% % \chk_var_or_const:N | +% \chk_var_or_const:c | % } % \begin{syntax} % "\chk_var_or_const:N" @@ -47,10 +81,12 @@ % Checks that is a proper variable or constant which means that its % name starts out with "\L", "\l", "\G", "\g", "\R", "\C", "\c", or "\q". % \end{function} -% +% % \begin{function}{% % \chk_local:N | +% \chk_local:c | % \chk_global:N | +% \chk_global:c | % } % \begin{syntax} % "\chk_local:N" @@ -58,7 +94,7 @@ % Checks that is a proper local or global variable. This means that % its name starts out with "\L", "\l", or "\G", "\g" respectively. % \end{function} -% +% % \begin{function}{% % \chk_local_or_pref_global:N | % \pref_global_chk: | @@ -82,16 +118,16 @@ % "\pref_global:D" turns its operation into a global one. See % implementation for details. % \end{function} -% +% % \subsection{Constants} -% +% % \begin{variable}{\c_undefined} % This constant is always undefined and therefore can be used to check % for free function names. % \end{variable} -% +% % \subsection{Internal functions} -% +% % \begin{function}{% % \chk_global_aux:w | % \chk_local_aux:w | @@ -102,13 +138,13 @@ % % \StopEventually{} % -% \section{The code} +% \subsection{The Implementation} % % We start by ensuring that the required packages are loaded. % \begin{macrocode} %\RequirePackage{l3basics} -%\RequirePackage{l3int} -%<*package> +%\RequirePackage{l3int,l3prg} +%<*initex|package> % \end{macrocode} % % The |\chk| module contains those functions that are used primarily @@ -116,33 +152,34 @@ % too badly. All these functions are of type `{\tt e}' since they % issue error messages if certain conditions are violated. % -% \subsection{Checking variable assignments} +% \subsubsection{Checking variable assignments} % % \begin{macro}{\chk_local:N} % \begin{macro}{\chk_local_aux:w} % This function checks that its argument is a proper local -% variable, i.e.\ its name starts with |\l| or |\L|. +% variable, i.e.\ its name starts with |\l| or |\L|. % It is not allowed that the name starts with |\g| or |\G|, % which means that we do not allow to update global -% variables locally. But see |\pref_global_chk:| below for +% variables locally. But see |\pref_global_chk:| below for % the encoding of functions that might accept global variables % in certain situations. Not checked is the case that the -% argument isn't a variable at all, i.e.\ it doesn't have +% argument isn't a variable at all, i.e.\ it doesn't have % a |_| as second letter. Maybe we should add this for safety % during the implementation since it will find certain errors % involving wrong expansion in earlier stage. % \begin{macrocode} -\def_new:Npn \chk_local:N #1{\exp_after:NN - \chk_local_aux:w \token_to_string:N#1\q_stop} +\def_new:Npn \chk_local:N #1{ + \exp_after:NN \chk_local_aux:w \token_to_string:N#1\q_stop} + \def_new:Npn \chk_local_aux:w #1#2#3\q_stop{ \if_num:w\tex_uccode:D`#2=`G\scan_stop: - \err_latex_bug:n{Local~mismatch:~local~function~called~with~ + \err_latex_bug:x{Local~mismatch:~local~function~called~with~ global~variable:^^J\text_put_four_sp: #1#2#3~ on~line~\tex_the:D\tex_inputlineno:D} \else: \if_num:w\tex_uccode:D`#2=`L\scan_stop: \else: - \err_latex_bug:n{Variable~mismatch:~function~not~called~with~ + \err_latex_bug:x{Variable~mismatch:~function~not~called~with~ proper~variable:^^J\text_put_four_sp: #1#2#3~ on~line~\tex_the:D\tex_inputlineno:D}\fi: \fi:} @@ -164,13 +201,13 @@ \chk_global_aux:w \token_to_string:N#1\q_stop} \def_new:Npn \chk_global_aux:w #1#2#3\q_stop{ \if_num:w\tex_uccode:D`#2=`L\scan_stop: - \err_latex_bug:n{Global~mismatch:~global~function~called~with~ + \err_latex_bug:x{Global~mismatch:~global~function~called~with~ local~variable:~#1#2#3~ on~line~\tex_the:D\tex_inputlineno:D} \else: \if_num:w\tex_uccode:D`#2=`G\scan_stop: \else: - \err_latex_bug:n{Variable~mismatch:~function~not~called~with~ + \err_latex_bug:x{Variable~mismatch:~function~not~called~with~ proper~variable:~#1#2#3~ on~line~\tex_the:D\tex_inputlineno:D}\fi:\fi:} % \end{macrocode} @@ -230,7 +267,7 @@ % \end{macrocode} % We also allow the beast to be a quark, i.e.\ to start with |\q|. % \begin{macrocode} - \if_char_code:w#2q\scan_stop: + \if_charcode:w#2q\scan_stop: \else: % \end{macrocode} % We might also want to allow that it is a user definable @@ -238,7 +275,7 @@ % could check this by testing that there is no |_|, but this is not % implemented so far. % \begin{macrocode} - \err_latex_bug:n{Variable~mismatch:~function~not~called~with~ + \err_latex_bug:x{Variable~mismatch:~function~not~called~with~ proper~variable:^^J\text_put_four_sp: #1#2#3~ on~line~\tex_the:D\tex_inputlineno:D}\fi:\fi:\fi: \fi:} @@ -247,7 +284,7 @@ % \end{macro} % % -% \subsection{Doing some tracing} +% \subsubsection{Doing some tracing} % % \begin{macro}{\tracingall} % \begin{macro}{\absolutelytracingall} @@ -288,7 +325,7 @@ \pref_global:D\g_trace_box_breadth_int\c_ten_thousand \pref_global:D\g_trace_box_depth_int\c_ten_thousand \pref_global:D\g_trace_online_status\c_one - \mode_errorstop:D} + \tex_errorstopmode:D} % % Use LaTeX2e definition for now. %\def_new:Npn\tracingall{ @@ -323,27 +360,29 @@ % \end{macrocode} % \end{macro} % -% \subsection{Tracing modules} +% \subsubsection{Tracing modules} % % \begin{macro}{\traceon} % \begin{macro}{\traceoff} % Turning the tracing of modules on or off. (primitive version). % \begin{macrocode} %<*trace> -\def_new:Npn\traceon#1{\for_clist:Nnn\l_tmpa_tlp{#1} - { - \cs_free:cF{g_trace_\l_tmpa_tlp _status} - {\int_gincr:c{g_trace_\l_tmpa_tlp _status}} - }} -\def_new:Npn\traceoff#1{\for_clist:Nnn\l_tmpa_tlp{#1} - { - \cs_free:cF{g_trace_\l_tmpa_tlp _status} - {\int_gdecr:c{g_trace_\l_tmpa_tlp _status}} - }} +\def_new:Npn\traceon#1{ + \clist_map_inline:nn {#1}{ + \cs_free:cF{g_trace_ ##1 _status} + {\int_gincr:c{g_trace_ ##1 _status}} + } +} +\def_new:Npn\traceoff#1{ + \clist_map_inline:nn {#1}{ + \cs_free:cF{g_trace_ ##1 _status} + {\int_gdecr:c{g_trace_ ##1 _status}} + } +} % %<-trace>\let_new:NN\traceon\use_none:n %<-trace>\let_new:NN\traceoff\use_none:n -% +% % \end{macrocode} % \end{macro} % \end{macro} @@ -356,3 +395,22 @@ % % \end{macrocode} % +% \endinput +% +% $Log$ +% Revision 1.14 2006/03/20 18:26:34 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.13 2005/12/27 09:58:01 morten +% Minor changes plus changed RCS information retrieval +% +% Revision 1.12 2005/04/12 12:07:53 morten +% Removed unnecessary functions +% +% Revision 1.11 2005/03/15 23:31:54 braams +% Some fiddling with docstrip guards for initex use +% +% Revision 1.10 2005/03/11 21:33:31 braams +% Fixed the use of RCS information +% diff --git a/Master/texmf-dist/source/latex/expl3/l3clist.dtx b/Master/texmf-dist/source/latex/expl3/l3clist.dtx new file mode 100644 index 00000000000..f8fdba275bb --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3clist.dtx @@ -0,0 +1,1082 @@ +% \iffalse +%% File: l3clist.dtx Copyright (C) 2005-2006 Frank Mittelbach, 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. +%% +%% ----------------------------------------------------------------------- +% +%\RequirePackage{l3names} +%<*dtx> +%\fi +\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{% + \def\fileversion{#2}% + \def\filedate{#3/#4/#5}% + \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]% +} +%\iffalse +% +%\fi +\GetIdInfo$Id: l3clist.dtx 573 2006-08-21 20:59:37Z morten $ + {L3 Experimental comma separated lists} +% +% \iffalse +%<*driver> +\documentclass{l3doc} +\begin{document} +\DocInput{l3clist.dtx} +\end{document} +% +% \fi +% +% +% +% \title{The \textsf{l3clist} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Comma separated lists} +% \author{Frank Mittelbach} +% \date{\filedate} +% \maketitle +% +% +% +% \section{Comma lists} +% +% \LaTeX3 implements a data type called `clist (comma-lists)'. These +% are special +% token lists that can be accessed via special function on the `left'. +% Appending tokens is possible at both ends. Appended token lists can be +% accessed only as a union. The token lists that form the individual +% items of a comma-list might contain any tokens except for commas that +% are used to structure comma-lists (braces are need if commas are +% part of the value). It is also possible to map functions on such +% comma-lists so that they are executed for every item of the comma-list. +% +% All functions that return items from a comma-list in some \m{tlp} assume +% that the \m{tlp} is local. See remarks below if you need a global +% returned value. +% +% The defined functions are not orthogonal in the sense that every +% possible variation possible is actually available. If you need a new +% variant use the expansion functions described in the package +% \texttt{l3expan} to build it. +% +% Adding items to the left of a comma-list can currently be done with +% either something like "\clist_put_left:Nn" or with a ``stack'' function +% like "\clist_push:Nn" which has the same effect. Maybe one should +% therefore remove the ``left'' functions totally. +% +% \subsection{Functions} +% +% \begin{function}{% +% \clist_new:N | +% \clist_new:c | +% } +% \begin{syntax} +% "\clist_new:N" +% \end{syntax} +% Defines to be a variable of type clist. +% \end{function} +% +% \begin{function}{% +% \clist_clear:N | +% \clist_clear:c | +% \clist_gclear:N | +% \clist_gclear:c | +% } +% \begin{syntax} +% "\clist_clear:N" +% \end{syntax} +% These functions locally or globally clear . +% \end{function} +% +% \begin{function}{% +% \clist_put_left:Nn | +% \clist_put_left:No | +% \clist_put_left:Nx | +% \clist_put_left:cn | +% \clist_put_right:Nn | +% \clist_put_right:No | +% \clist_put_right:Nx | +% } +% \begin{syntax} +% "\clist_put_left:Nn" +% \end{syntax} +% Locally appends as a single item to the left +% or right of . might get expanded before +% appending. +% \end{function} +% +% \begin{function}{% +% \clist_gput_left:Nn | +% \clist_gput_right:Nn | +% \clist_gput_right:No | +% \clist_gput_right:cn | +% \clist_gput_right:co | +% \clist_gput_right:cc | +% } +% \begin{syntax} +% "\clist_gput_left:Nn" +% \end{syntax} +% Globally appends as a single item to the left +% or right of . +% \end{function} +% +% \begin{function}{% +% \clist_get:NN | +% \clist_get:cN | +% } +% \begin{syntax} +% "\clist_get:NN" +% \end{syntax} +% Functions that locally assign the left-most item of to the +% token list pointer . Item is not removed from ! If you +% need a global return value you need to code something like this: +% \begin{quote} +% "\clist_get:NN" "\l_tmpa_tlp" \\ +% "\tlp_gset_eq:NN" "\l_tmpa_tlp" +% \end{quote} +% But if this kind of construction is used often enough a separate +% function should be provided. +% \end{function} +% +% \begin{function}{% +% \clist_set_eq:NN +% } +% \begin{syntax} +% "\clist_set_eq:NN" +% \end{syntax} +% Function that locally makes identical to . +% \end{function} +% +% +% \begin{function}{% +% \clist_gset_eq:NN | +% \clist_gset_eq:cN | +% \clist_gset_eq:Nc | +% \clist_gset_eq:cc +% } +% \begin{syntax} +% "\clist_gset_eq:NN" +% \end{syntax} +% Function that globally makes identical to . +% \end{function} +% +% +% \begin{function}{% +% \clist_concat:NNN | +% \clist_gconcat:NNN | +% \clist_gconcat:NNc | +% \clist_gconcat:ccc | +% } +% \begin{syntax} +% "\clist_gconcat:NNN" +% \end{syntax} +% Function that concatenates and and globally assigns the +% result to . +% \end{function} +% +% +% \begin{function}{% +% \clist_remove_duplicates:N | +% \clist_gremove_duplicates:N | +% } +% \begin{syntax} +% "\clist_gremove_duplicates:N" +% \end{syntax} +% Function that removes any duplicate entries in . +% \end{function} +% +% \begin{function}{% +% \clist_use:N | +% \clist_use:c +% } +% \begin{syntax} +% "\clist_use:N" +% \end{syntax} +% Function that inserts the into the processing stream. Mainly +% useful if one knows what the contains, e.g., for displaying +% the content of template parameters. +% \end{function} +% +% +% \subsection{Mapping functions} +% +% +% We provide three types of mapping functions, each with their own +% strengths. The "\clist_map_function:NN" is expandable whereas +% "\clist_map_inline:Nn" type uses "##1" as a placeholder for the +% current item in \m{clist}. Finally we have the +% "\clist_map_variable:NNn" type which uses a user-defined variable as +% placeholder. Both the |_inline| and |_variable| versions are nestable. +% +% +% \begin{function}{\clist_map_function:NN| +% \clist_map_function:cN| +% \clist_map_function:nN +% } +% \begin{syntax} +% "\clist_map_function:NN" +% \end{syntax} +% This function applies (which must be a function with one +% argument) to every item of . is not executed +% within a sub-group so that side effects can be achieved locally. The +% operation is expandable which means that it can be used within write +% operations etc. +% \end{function} +% +% \begin{function}{\clist_map_inline:Nn | +% \clist_map_inline:cn | +% \clist_map_inline:nn | +% } +% \begin{syntax} +% "\clist_map_inline:Nn" "{" "}" +% \end{syntax} +% Applies (which should be the direct coding for a +% function with one argument (i.e.\ use "##1" as the placeholder for +% this argument)) to every item of . is not +% executed within a sub-group so that side effects can be achieved locally. +% The operation is not expandable which means that it can't be used +% within write operations etc. These functions can be nested. +% \end{function} +% +% +% \begin{function}{\clist_map_variable:NNn | +% \clist_map_variable:cNn | +% \clist_map_variable:nNn | +% } +% \begin{syntax} +% "\clist_map_variable:NNn" "{" "}" +% \end{syntax} +% Assigns to each element in and then executes +% which should contain . As the +% operation performs an assignment, it is not expandable. +% \begin{texnote} +% These functions resemble the \LaTeXe{} function \tn{@for} but does +% not borrow the somewhat strange syntax. +% \end{texnote} +% \end{function} +% +% \begin{function}{% +% \clist_map_break:w | +% } +% \begin{syntax} +% "\clist_map_break:w" +% \end{syntax} +% For breaking out of a loop. To be used inside "TF" type functions as +% in the example below. +% \begin{verbatim} +% \def_new:Npn \test_function:n #1 { +% \int_compare:nNnTF {#1}> 3 {\clist_map_break:w}{``#1''} +% } +% \clist_map_function:nN {1,2,3,4,5,6,7,8}\test_function:n +% \end{verbatim} +% This would return "``1''``2''``3''". +% \end{function} +% +% +% \subsection{Predicates and conditionals} +% +% \begin{function}{\clist_if_empty_p:N} +% \begin{syntax} +% "\clist_if_empty_p:N" +% \end{syntax} +% This predicate returns `true' if is `empty' i.e., doesn't +% contain any tokens. +% \end{function} +% +% \begin{function}{% +% \clist_if_empty:NTF | +% \clist_if_empty:cTF | +% \clist_if_empty:NF | +% \clist_if_empty:cF | +% } +% \begin{syntax} +% "\clist_if_empty:NTF" "{" "}{" "}" +% \end{syntax} +% Set of conditionals that test whether or not a particular +% is empty and if so executes either or . +% \end{function} +% +% \begin{function}{% +% \clist_if_eq:NNTF | +% } +% \begin{syntax} +% "\clist_if_eq:NNTF" "{" +% "}{" "}" +% \end{syntax} +% Check if and are equal and execute +% either or accordingly. +% \end{function} +% +% \begin{function}{% +% \clist_if_in:NnTF | +% \clist_if_in:NoTF | +% \clist_if_in:cnTF | +% \clist_if_in:coTF | +% } +% \begin{syntax} +% "\clist_if_in:NnTF" "{" "}{" "}{" +% "}" +% \end{syntax} +% Function that tests if is in . Depending on the result +% either or is executed. +% \end{function} +% +% \subsection{Internal functions} +% +% \begin{function}{\clist_if_empty_err:N} +% \begin{syntax} +% "\clist_if_empty_err:N" +% \end{syntax} +% Signals an \LaTeX3 error if is empty. +% \end{function} +% +% \begin{function}{\clist_pop_aux:nnNN} +% \begin{syntax} +% "\clist_pop_aux:nnNN" +% \end{syntax} +% Function that assigns the left-most item of to using +% and assigns the tail to using . This +% function could be used to implement a global return function. +% \end{function} +% +% \begin{function}{% +% \clist_get_aux:w | +% \clist_pop_aux:w | +% \clist_pop_auxi:w | +% \clist_put_aux:NNnnNn | +% } +% \begin{syntax}\end{syntax} +% Functions used to implement put and get operations. They are not for +% meant for direct use. +% \end{function} +% +% +% +% \begin{function}{% +% \clist_map_function_aux:Nw | +% \clist_map_inline_aux:Nw | +% \clist_map_variable_aux:Nnw | +% } +% \begin{syntax}\end{syntax} +% Internal helper functions for the mapping functions. +% \end{function} +% +% +% \begin{function}{% +% \clist_concat_aux:NNNN | +% \clist_remove_duplicates_aux:NN | +% \clist_remove_duplicates_aux:n | +% \l_clist_remove_duplicates_clist | +% } +% \begin{syntax}\end{syntax} +% Functions that help concatenate s and remove duplicate +% elements from a . +% \end{function} +% +% +% +% \subsection{Comma list Stacks} +% +% Special comma-lists in \LaTeX3 are `stacks' with their usual operations +% of `push', `pop', and `top'. They are internally implemented as +% comma-lists and share some of the functions (like "\clist_new:N" etc.) +% +% +% \begin{function}{% +% \clist_push:Nn | +% \clist_push:No | +% \clist_push:cn | +% \clist_gpush:Nn | +% \clist_gpush:No | +% \clist_gpush:cn | +% } +% \begin{syntax} +% "\clist_push:Nn" "{" "}" +% \end{syntax} +% Locally or globally pushes as a single item onto the +% . might get expanded before the operation. +% \end{function} +% +% \begin{function}{% +% \clist_pop:NN | +% \clist_pop:cN | +% \clist_gpop:NN | +% \clist_gpop:cN | +% } +% \begin{syntax} +% "\clist_pop:NN" +% \end{syntax} +% Functions that assign the top item of to the token +% list pointer and removes it from ! +% \end{function} +% +% \begin{function}{% +% \clist_top:NN | +% \clist_top:cN | +% } +% \begin{syntax} +% "\clist_top:NN" +% \end{syntax} +% Functions that locally assign the top item of to the token +% list pointer . Item is not removed from ! +% \end{function} +% +% \StopEventually{} +% +% Use "clist" functions. +% +% +% \subsection {The Implementation} +% +% We start by ensuring that the required packages are loaded. +% \begin{macrocode} +%<*package> +\NeedsTeXFormat{LaTeX2e} +%\RequirePackage{l3prg,l3quark} +%\RequirePackage{l3chk} +% +%<*initex|package> +% \end{macrocode} +% +% +% \begin{macro}{\clist_new:N} +% \begin{macro}{\clist_new:c} +% Comma-Lists are implemented using token lists. +% \begin{macrocode} +\def_new:Npn \clist_new:N #1{\tlp_new:Nn #1{}} +\def_new:Npn \clist_new:c {\exp_args:Nc \clist_new:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\clist_clear:N} +% \begin{macro}{\clist_clear:c} +% \begin{macro}{\clist_gclear:N} +% \begin{macro}{\clist_gclear:c} +% Clearing a comma-list is the same as clearing a token list. +% \begin{macrocode} +\let_new:NN \clist_clear:N \tlp_clear:N +\let_new:NN \clist_clear:c \tlp_clear:c +\let_new:NN \clist_gclear:N \tlp_gclear:N +\let_new:NN \clist_gclear:c \tlp_gclear:c +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\clist_set_eq:NN} +% We can set one \meta{clist} equal to another. +% \begin{macrocode} +\let_new:NN \clist_set_eq:NN \let:NN +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\clist_set_eq:NN} +% \begin{macro}{\clist_set_eq:cN} +% \begin{macro}{\clist_set_eq:Nc} +% \begin{macro}{\clist_set_eq:cc} +% An of course globally which seems to be needed far more often. +% \begin{macrocode} +\let_new:NN \clist_gset_eq:NN \glet:NN +\def_new:Npn \clist_gset_eq:cN {\exp_args:Nc \clist_gset_eq:NN} +\def_new:Npn \clist_gset_eq:Nc {\exp_args:NNc \clist_gset_eq:NN} +\def_new:Npn \clist_gset_eq:cc {\exp_args:Ncc \clist_gset_eq:NN} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\clist_if_empty_p:N} +% A predicate which evaluates to |\c_true| iff the comma-list is empty. +% \begin{macrocode} +\let_new:NN \clist_if_empty_p:N \tlp_if_empty_p:N +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clist_if_empty:NTF} +% \begin{macro}{\clist_if_empty:NT} +% \begin{macro}{\clist_if_empty:NF} +% \begin{macro}{\clist_if_empty:cTF} +% \begin{macro}{\clist_if_empty:cT} +% \begin{macro}{\clist_if_empty:cF} +% |\clist_if_empty:NTF|\m{clist}\m{true~case}\m{false~case} will check +% whether the \m{clist} is empty and then select one of the other +% arguments. |\clist_if_empty:cTF| turns its first argument into a +% control comma-list to get the name of the comma-list. +% \begin{macrocode} +\def_test_function_new:npn {clist_if_empty:N}#1{\if_meaning:NN#1\c_empty_tlp} +\def_new:Npn \clist_if_empty:cTF {\exp_args:Nc\clist_if_empty:NTF} +\def_new:Npn \clist_if_empty:cT {\exp_args:Nc\clist_if_empty:NT} +\def_new:Npn \clist_if_empty:cF {\exp_args:Nc\clist_if_empty:NF} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\clist_if_empty_err:N} +% Signals an error if the comma-list is empty. +% \begin{macrocode} +\def_new:Npn \clist_if_empty_err:N #1{ + \if_meaning:NN#1\c_empty_tlp + \tlp_clear:N \l_testa_tlp % catch prefixes + \err_latex_bug:x{Empty~comma-list~`\token_to_string:N#1'} + \fi:} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clist_if_eq:NNTF} +% As comma lists are token list pointers internally this is just an +% alias. +% \begin{macrocode} +\let_new:NN \clist_if_eq:NNTF \tlp_if_eq:NNTF +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clist_get:NN} +% \begin{macro}{\clist_get:cN} +% |\clist_get:NN |\zz{comma-list}\zz{cmd} defines \zz{cmd} to be the +% left-most element of \zz{comma-list}. +% \begin{macrocode} +\def_new:Npn \clist_get:NN #1{ + \clist_if_empty_err:N #1 + \exp_after:NN\clist_get_aux:w #1,\q_stop} +% \end{macrocode} +% \begin{macrocode} +\def_new:Npn \clist_get_aux:w #1,#2\q_stop #3{\tlp_set:Nn #3{#1}} +% \end{macrocode} +% \begin{macrocode} +\def_new:Npn \clist_get:cN {\exp_args:Nc \clist_get:NN} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\clist_pop_aux:nnNN} +% \begin{macro}{\clist_pop_aux:w} +% \begin{macro}{\clist_pop_auxi:w} +% |\clist_pop_aux:nnNN| \zz{def$\sb1$} \zz{def$\sb2$} \zz{comma-list} +% \zz{cmd} assigns the left-most element of \zz{comma-list} to +% \zz{cmd} using \zz{def$\sb2$}, and assigns the tail of +% \zz{comma-list} to \zz{comma-list} using \zz{def$\sb1$}. +% \begin{macrocode} +\def_new:Npn \clist_pop_aux:nnNN #1#2#3{ + \clist_if_empty_err:N #3 + \exp_after:NN\clist_pop_aux:w #3,\q_nil\q_stop #1#2#3} +% \end{macrocode} +% \begin{macrocode} +\def_new:Npn \clist_pop_aux:w #1,#2\q_stop #3#4#5#6{ + #4#6{#1} + #3#5{#2} +% \end{macrocode} +% If there was only one element in the original clist, it now contains +% only |\q_nil|. +% \begin{macrocode} + \quark_if_nil:NTF #5 + { #3#5{} } + { \clist_pop_auxi:w #2 #3#5 } +} +% \end{macrocode} +% \begin{macrocode} +\def_new:Npn\clist_pop_auxi:w #1,\q_nil #2#3 {#2#3{#1}} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\clist_put_aux:NNnnNn} +% The generic put function. +% \begin{macrocode} +\def_new:Npn \clist_put_aux:NNnnNn #1#2#3#4#5#6{ +% \end{macrocode} +% When adding we have to distinguish between an empty \meta{clist} +% and one that contains at least one item (otherwise we accumulate +% commas). +% \begin{macrocode} + \clist_if_empty:NTF#5 {#1 #5{#6}} +% \end{macrocode} +% MH says: Perhaps we should make sure that empty arguments don't get +% on the stack as that is probably a mistake. That's what I've +% implemented here. Since |\tlist_if_empty:nF| is expandable prefixes +% are still allowed. +% \begin{macrocode} + { \tlist_if_empty:nF {#6}{ #2 #5{#3#6#4} } } +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\clist_put_left:Nn} +% \begin{macro}{\clist_put_left:No} +% \begin{macro}{\clist_put_left:Nx} +% \begin{macro}{\clist_put_left:cn} +% The operations for adding to the left. +% \begin{macrocode} +\def_new:Npn \clist_put_left:Nn { + \clist_put_aux:NNnnNn \tlp_set:Nn \tlp_put_left:Nn {} , +} +\def_new:Npn \clist_put_left:cn {\exp_args:Nc \clist_put_left:Nn} +\def_new:Npn \clist_put_left:No {\exp_args:NNo\clist_put_left:Nn} +\def_new:Npn \clist_put_left:Nx {\exp_args:Nnx\clist_put_left:Nn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \begin{macro}{\clist_gput_left:Nn} +% Global versions. +% \begin{macrocode} +\def_new:Npn \clist_gput_left:Nn { + \clist_put_aux:NNnnNn \tlp_gset:Nn \tlp_gput_left:Nn {} , +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clist_put_right:Nn} +% \begin{macro}{\clist_put_right:cn} +% \begin{macro}{\clist_put_right:No} +% \begin{macro}{\clist_put_right:Nx} +% Adding something to the right side is almost the same. +% \begin{macrocode} +\def_new:Npn \clist_put_right:Nn { + \clist_put_aux:NNnnNn \tlp_set:Nn \tlp_put_right:Nn , {} +} +\def_new:Npn \clist_put_right:cn {\exp_args:Nc \clist_put_right:Nn} +\def_new:Npn \clist_put_right:No {\exp_args:Nno\clist_put_right:Nn} +\def_new:Npn \clist_put_right:Nx {\exp_args:Nnx\clist_put_right:Nn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\clist_gput_right:Nn} +% \begin{macro}{\clist_gput_right:No} +% \begin{macro}{\clist_gput_right:cn} +% \begin{macro}{\clist_gput_right:co} +% \begin{macro}{\clist_gput_right:cc} +% \begin{macro}{\clist_gput_right:NC} +% An here the global variants. +% \begin{macrocode} +\def_new:Npn \clist_gput_right:Nn { + \clist_put_aux:NNnnNn \tlp_set:Nn \tlp_put_right:Nn , {} +} +\def_new:Npn \clist_gput_right:No {\exp_args:NNo \clist_gput_right:Nn} +\def_new:Npn \clist_gput_right:cn {\exp_args:Nc \clist_gput_right:Nn} +\def_new:Npn \clist_gput_right:co {\exp_args:Nco \clist_gput_right:Nn} +\def_new:Npn \clist_gput_right:cc {\exp_args:Ncc \clist_gput_right:Nn} +% \end{macrocode} +% \begin{macrocode} +\def_new:Npn \clist_gput_right:NC {\exp_args:NNC \clist_gput_right:Nn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\clist_map_function:nN} +% \begin{macro}{\clist_map_function:cN} +% \begin{macro}{\clist_map_function:NN} +% |\clist_map_function:NN| \zz{comma-list} \zz{cmd} applies \zz{cmd} to each +% element of \zz{comma-list}, from left to right. +% \begin{macrocode} +\def_new:Npn \clist_map_function:NN #1#2{ + \clist_if_empty:NF #1 + { + \exp_after:NN \clist_map_function_aux:Nw + \exp_after:NN #2 #1 , \q_nil , \q_stop + } +} +\def_new:Npn \clist_map_function:cN{\exp_args:Nc\clist_map_function:NN} +\def_new:Npn \clist_map_function:nN #1#2{ + \tlist_if_empty:nF {#1} + { \clist_map_function_aux:Nw #2 #1 , \q_nil , \q_stop } +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\clist_map_function_aux:Nw} +% The general loop. Tests if we hit the first stop marker and exits if +% we did. If we didn't, place the function "#1" in front of the +% element "#2", which is surrounded by braces. +% \begin{macrocode} +\def_new:Npn \clist_map_function_aux:Nw #1#2,{ + \quark_if_nil:nT{#2} \clist_map_break:w + #1{#2} + \clist_map_function_aux:Nw #1 +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clist_map_break:w} +% The break statement is easy: Just gobble everything op to the last +% of the two stop markers "\q_stop" waiting at the end and close the +% "\if_..." we're in. Technically this should get an "w" specifier, +% but it doesn't take any arguments when you call it -- at least not +% any you would expect. +% \begin{macrocode} +\let_new:NN \clist_map_break:w \use_none_delimit_by_q_stop:w +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clist_map_inline:Nn} +% \begin{macro}{\clist_map_inline:cn} +% \begin{macro}{\clist_map_inline:nn} +% The inline type is faster but not expandable. In order to make it +% nestable, we use a counter to keep track of the nesting level so +% that all of the functions called have distict names. A simpler +% approach would of course be to use grouping and thus the save +% stack but then you lose the ability to do things locally. +% \begin{macrocode} +\int_new:N \l_clist_inline_level_int +\def_new:Npn \clist_map_inline:Nn #1#2{ + \clist_if_empty:NF #1 + { + \int_incr:N \l_clist_inline_level_int + \def:cpn {clist_map_inline_ \int_use:N \l_clist_inline_level_int :n} + ##1{#2} +% \end{macrocode} +% Recall that the |E| in |\exp_args:NcE| means `single token expanded +% once and no braces added'. It is a lot more efficient to carry over +% the special function rather than constructing the same csname over +% and over again, so we just do it once. We reuse +% |\clist_map_function_aux:Nw| for the actual loop. +% \begin{macrocode} + \exp_args:NcE \clist_map_function_aux:Nw + {clist_map_inline_ \int_use:N \l_clist_inline_level_int :n} + #1 , \q_nil , \q_stop + \int_decr:N \l_clist_inline_level_int + } +} +\def_new:Npn \clist_map_inline:cn{\exp_args:Nc\clist_map_inline:Nn} +\def_new:Npn \clist_map_inline:nn #1#2{ + \tlist_if_empty:nF {#1} + { + \int_incr:N \l_clist_inline_level_int + \def:cpn {clist_map_inline_ \int_use:N \l_clist_inline_level_int :n} + ##1{#2} + \exp_args:Nc \clist_map_function_aux:Nw + {clist_map_inline_ \int_use:N \l_clist_inline_level_int :n} + #1 , \q_nil , \q_stop + \int_decr:N \l_clist_inline_level_int + } +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\clist_map_variable:nNn} +% \begin{macro}{\clist_map_variable:NNn} +% \begin{macro}{\clist_map_variable:cNn} +% |\clist_map:NNn| \zz{comma-list} \zz{temp} \zz{action} assigns +% \zz{temp} to each element and executes \zz{action}. +% \begin{macrocode} +\def_new:Npn \clist_map_variable:nNn #1#2#3{ + \tlist_if_empty:nF{#1} + { + \clist_map_variable_aux:Nnw #2 {#3} #1 , \q_nil , \q_stop + } +} +\def_new:Npn \clist_map_variable:NNn {\exp_args:No \clist_map_variable:nNn} +\def_new:Npn \clist_map_variable:cNn {\exp_args:Nc \clist_map_variable:NNn} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\clist_map_variable_aux:Nnw} +% 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_new:Npn \clist_map_variable_aux:Nnw #1#2#3,{ + \def:Npn #1{#3} + \quark_if_nil:NT #1 \clist_map_break:w + #2 \clist_map_variable_aux:Nnw #1{#2} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clist_concat_aux:NNNN} +% \begin{macro}{\clist_concat:NNN} +% \begin{macro}{\clist_gconcat:NNN} +% \begin{macro}{\clist_gconcat:NNc} +% \begin{macro}{\clist_gconcat:ccc} +% |\clist_gconcat:NNN| \m{clist~1} \m{clist~2} \m{clist~3} will globally +% assign \m{clist~1} the concatenation of \m{clist~2} and +% \m{clist~3}. +% \begin{macrocode} +\def_new:Npn \clist_concat_aux:NNNN #1#2#3#4{ + \toks_set:No \l_tmpa_toks {#3} + \toks_set:No \l_tmpb_toks {#4} + #1 #2 { + \toks_use:N \l_tmpa_toks +% \end{macrocode} +% Again the situation is a bit more complicated because of the use +% of commas between items, so if either list is empty we have to avoid +% adding a comma. +% \begin{macrocode} + \toks_if_empty:NF \l_tmpa_toks {\toks_if_empty:NF \l_tmpb_toks ,} + \toks_use:N \l_tmpb_toks + } +} +\def_new:Npn \clist_concat:NNN {\clist_concat_aux:NNNN \tlp_set:Nx} +\def_new:Npn \clist_gconcat:NNN {\clist_concat_aux:NNNN \tlp_gset:Nx} +% \end{macrocode} +% And the usual versions. +% \begin{macrocode} +\def_new:Npn \clist_gconcat:NNc{\exp_args:Nnnc\clist_gconcat:NNN} +\def_new:Npn \clist_gconcat:ccc{\exp_args:Nccc\clist_gconcat:NNN} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\clist_remove_duplicates_aux:NN} +% \begin{macro}{\clist_remove_duplicates_aux:n} +% \begin{macro}{\clist_remove_duplicates:N} +% \begin{macro}{\clist_gremove_duplicates:N} +% Removing duplicate entries in a \meta{clist} is fairly straight +% forward. We use a temporary variable and then go through the list +% from left to right. For each element check if the element is +% already present in the list. +% \begin{macrocode} +\def:Npn \clist_remove_duplicates_aux:NN #1#2 { + \clist_clear:N \l_clist_remove_duplicates_clist + \clist_map_function:NN #2 \clist_remove_duplicates_aux:n + #1 #2 \l_clist_remove_duplicates_clist +} +\def:Npn \clist_remove_duplicates_aux:n #1 { + \clist_if_in:NnTF \l_clist_remove_duplicates_clist {#1} {} + {\clist_put_right:Nn \l_clist_remove_duplicates_clist {#1}} +} +% \end{macrocode} +% The high level functions are just for telling if it should be a +% local or global setting. +% \begin{macrocode} +\def_new:Npn \clist_remove_duplicates:N { + \clist_remove_duplicates_aux:NN \clist_set_eq:NN +} +\def_new:Npn \clist_gremove_duplicates:N { + \clist_remove_duplicates_aux:NN \clist_gset_eq:NN +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\l_clist_remove_duplicates_clist} +% \begin{macrocode} +\clist_new:N \l_clist_remove_duplicates_clist +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\clist_use:N} +% \begin{macro}{\clist_use:c} +% Using a \meta{clist} is just executing it but\dots +% \begin{macrocode} +\def_new:Npn \clist_use:N #1 { + \if_meaning:NN #1 \scan_stop: +% \end{macrocode} +% \dots\ if \m{clist} 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 {Comma~list~ `\token_to_string:N #1'~ + has~ an~ erroneous~ structure!} + \else: + \exp_after:NN #1 + \fi: +} +\def_new:Npn \clist_use:c {\exp_args:Nc \clist_use:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\clist_if_in:NnTF} +% \begin{macro}{\clist_if_in:NoTF} +% \begin{macro}{\clist_if_in:cnTF} +% \begin{macro}{\clist_if_in:coTF} +% |\clist_if_in:NnTF| \m{clist}\m{item} \m{true~case} \m{false~case} +% will check whether \m{item} is in \m{clist} and then either execute +% the \m{true~case} or the \m{false~case}. \m{true~case} and +% \m{false~case} may contain incomplete |\if_charcode:w| +% statements. +% \begin{macrocode} +\def_new:Npn \clist_if_in:NnTF #1#2{ + \def:Npn \tmp:w ##1 ,#2, ##2##3\q_stop{ + \if_meaning:NN\q_no_value##2 + \exp_after:NN\use_arg_ii:nn + \else: + \exp_after:NN\use_arg_i:nn + \fi: + } + \exp_after:NN \tmp:w + \exp_after:NN , #1, #2, \q_no_value \q_stop +} +\def_new:Npn \clist_if_in:NoTF {\exp_args:NNo \clist_if_in:NnTF} +\def_new:Npn \clist_if_in:coTF {\exp_args:Nco \clist_if_in:NnTF} +\def_new:Npn \clist_if_in:cnTF {\exp_args:Nc \clist_if_in:NnTF} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% \subsubsection{Stack operations} +% +% We build stacks from comma-lists, but here we put the +% specific functions together. +% +% +% \begin{macro}{\clist_push:Nn} +% \begin{macro}{\clist_push:No} +% \begin{macro}{\clist_push:cn} +% \begin{macro}{\clist_pop:NN} +% \begin{macro}{\clist_pop:cN} +% Since comma-lists can be used as stacks, we ought to have both +% `push' and `pop'. In most cases they are nothing more then new +% names for old functions. +% \begin{macrocode} +\let_new:NN \clist_push:Nn \clist_put_left:Nn +\let_new:NN \clist_push:No \clist_put_left:No +\let_new:NN \clist_push:cn \clist_put_left:cn +\def_new:Npn \clist_pop:NN {\clist_pop_aux:nnNN \tlp_set:Nn \tlp_set:Nn} +\def_new:Npn \clist_pop:cN {\exp_args:Nc \clist_pop:NN} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% \begin{macro}{\clist_gpush:Nn} +% \begin{macro}{\clist_gpush:No} +% \begin{macro}{\clist_gpush:cn} +% \begin{macro}{\clist_gpop:NN} +% \begin{macro}{\clist_gpop:cN} +% I don't agree with Denys that one needs only local stacks, +% actually I believe that one will probably need the functions +% here more often. In case of |\clist_gpop:NN| the value is +% nevertheless returned locally. +% \begin{macrocode} +\let_new:NN \clist_gpush:Nn \clist_gput_left:Nn +\def_new:Npn \clist_gpush:No {\exp_args:NNo \clist_gpush:Nn} +\def_new:Npn \clist_gpush:cn {\exp_args:Nc \clist_gpush:Nn} +\def_new:Npn \clist_gpop:NN {\clist_pop_aux:nnNN \tlp_gset:Nn \tlp_set:Nn} +\def_new:Npn \clist_gpop:cN {\exp_args:Nc \clist_gpop:NN} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\clist_top:NN} +% \begin{macro}{\clist_top:cN} +% Looking at the top element of the stack without removing it is +% done with this operation. +% \begin{macrocode} +\let_new:NN \clist_top:NN \clist_get:NN +\let_new:NN \clist_top:cN \clist_get:cN +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% Show token usage: +% \begin{macrocode} +% +%<*showmemory> +%\showMemUsage +% +% \end{macrocode} +% +% +% +% \endinput +% +% $Log$ +% Revision 1.16 2006/07/30 15:45:46 morten +% Made \clist_map_inline:Nn and variants nestable plus a little cleanup. +% +% Revision 1.15 2006/03/20 18:26:34 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.14 2006/01/04 01:32:09 morten +% Minor changes to code to reflect changes in l3tlp. +% +% Revision 1.13 2005/12/27 09:52:51 morten +% Minor changes plus changed RCS information retrieval +% +% Revision 1.12 2005/10/27 23:14:49 morten +% Improved loops. +% +% Revision 1.11 2005/04/12 16:45:22 morten +% Enabled put operations. Added function that removes duplicate entries (mostly for +% use after concatenating to clists) +% +% Revision 1.10 2005/04/12 13:22:13 morten +% Mostly cosmetic changes. \clist_gconcat:NNN reprogrammed using "proper" methods, \clist_put_right:Nn likewise. +% +% Revision 1.9 2005/03/22 23:26:54 morten +% Fix error message +% +% Revision 1.8 2005/03/16 22:36:43 braams +% Added the tweaks necessary to be able to load with initex +% +% Revision 1.7 2005/03/11 21:36:36 braams +% Fixed the use of RCS information; +% Fixed a few documentation typos; added \StopEventually +% Replaced \ifx by \if_meaning:NN, \c_if_empty_toks became \c_empty_toks +% but needs further work according to Morten +% diff --git a/Master/texmf-dist/source/latex/expl3/l3expan.dtx b/Master/texmf-dist/source/latex/expl3/l3expan.dtx index 7f634d74f77..8eaac134482 100644 --- a/Master/texmf-dist/source/latex/expl3/l3expan.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3expan.dtx @@ -1,15 +1,50 @@ % \iffalse -%% File: l3expan.dtx Copyright (C) 1990-1998 LaTeX3 project -% +%% File: l3expan.dtx Copyright (C) 1990-2006 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. +%% +%% ----------------------------------------------------------------------- +% +%\RequirePackage{l3names} %<*dtx> - \ProvidesFile{l3expan.dtx} +%\fi +\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{% + \def\fileversion{#2}% + \def\filedate{#3/#4/#5}% + \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]% +} +%\iffalse % -%\NeedsTeXFormat{LaTeX2e} -%\ProvidesPackage{l3expan} -% \ProvidesFile{l3expan.drv} -% \fi -% \ProvidesFile{l3expan.dtx} - [1998/04/20 v1.0e L3 Experimental Argument Expansion module] +%\fi +\GetIdInfo$Id: l3expan.dtx 573 2006-08-21 20:59:37Z morten $ + {L3 Experimental Argument Expansion module} % % \iffalse %<*driver> @@ -22,7 +57,6 @@ % \fi % % -% \GetFileInfo{l3expan.dtx} % \title{The \textsf{l3expan} package\thanks{This file % has version number \fileversion, last % revised \filedate.}\\ @@ -33,7 +67,7 @@ % % % \section{\LaTeX3 functions} -% +% % All \LaTeX3 functions contain a colon in their % name. Characters following the colon are used to denote the number and % the ``type'' of arguments that the function takes. An uppercase "N" is @@ -46,12 +80,12 @@ % is a function that takes two arguments, the first is a single token % (the sequence) and the second may consist of several tokens surrounded % by braces. -% +% % This concept of argument specification makes it easy to read the code % and should be followed when defining new functions. -% +% % \subsection{Expanding arguments of functions} -% +% % Within code it is often necessary to expand or partially expand % arguments before passing it on to some function. For example, if the % token list pointer "\l_tmpa_tlp" contains the current file @@ -73,7 +107,7 @@ % "\exp_after:NN" \\ % " {\l_tmpa_tlp}" % \end{quote} -% +% % The above example is probably the simplest case but is already shows % how the code changes to something difficult to understand. Therefore % \LaTeX3 provides the programmer with a general scheme that keeps the @@ -88,7 +122,7 @@ % \end{quote} % to achieve the desired effect. Here the "o" stands for expand this % (the second) argument once before passing it to the function. -% +% % The following letters can be used to denote special treatment of % arguments before passing it to the basic function: % \begin{description} @@ -96,18 +130,24 @@ % effectively only the first token in the list gets expanded. Since % the expansion might result in more than one token, the result is % surrounded for further processing with braces. -% +% % \item[x] Fully expanded token or token-list. Like "o" but the % argument is expanded using "\def:Npx" before it is passed on. This means -% that expansion takes place until only unexpandable tokens are left. -% +% that expansion takes place until only unexpandable tokens are left. +% +% \item[f] Almost the same as the |x| type except here the token list +% is expanded fully until the first unexpandable token is found and +% the rest is left unchanged. Note that if this function finds a +% space at the beginning of the argument it will gobble it and not +% expand the next argument. +% % \item[N,O,X] Like "n", "o", "x" but the argument must be a single % token without any braces around it. -% +% % \item[c] A character string or a token-list that ultimately expands % to characters. This string (after expansion) is used to construct a % command name that is eventually passed on. -% +% % \item[C] A character string or a token-list that ultimately expands % to characters. From this string (after expansion) a command name is % constructed and then this command name is expanded once (like "o"). @@ -118,24 +158,48 @@ % " {l_tmpa_tlp}" % \end{quote} % Has the same effect as the example above. -% -% -% +% +% % \end{description} % +% Here are three new expansion types that may be useful but I'm not +% sure yet. Only time will tell\dots{} Proper documentation of these +% functions is postponed until later. +% \begin{description} +% \item[d] This is pretty much like the |o| type except the token list +% get's expanded twice before being passed on. (|d| is for double) +% +% \item[E] Sometimes you need to unpack a token list or something else +% but you don't want it to add the braces that the |o| type +% does. This is where you usually wind up with a lot of +% |\exp_after:NN|s and we would like to avoid that. This type works +% quite well with the other syntax but it won't work in certain +% circumstances: Since the generic expansion functions read their +% arguments when the expanded code is shuffled around, this type +% will have a problem if the last token you want to expand once is +% |\token_to_str:N| \emph{and} you're in an argument expansion +% process involving arguments in braces such as the |n| and |o| type +% arguments. If you stick to functions invloving only |N| and |E| +% everything will work just fine. (|E| is for expanded, single +% token.) +% +% \item[e] Same as above but the argument must be given in braces. +% \end{description} +% % Due to memory constraints not all possible variations are implemented % for every base function. Instead only those that are used within the -% \LaTeX3 kernel or otherwise seem of general interest are implemented. +% \LaTeX3 kernel or otherwise seem to be of general interest are +% implemented. % Consult the module description to find out which functions are % actually defined. The next section explains how to define missing % variants. -% +% % \subsection{Defining new variants} -% +% % The definition of variant forms for base functions may be necessary % when writing new functions or when applying a kernel function in a % situation that we haven't thought of before. -% +% % Internally preprocessing of arguments is done with functions from the % "\exp_" module. They all look alike, an example would be % "\exp_args:NNo". This function has three arguments, the first and the @@ -162,7 +226,37 @@ % new definition is identical to an already given one. Therefore adding % such definition to later releases of the kernel will not make such % style files obsolete. -% +% +% The |f| type is so special that it deserves an example. +% Let's pretend we want to set "\aaa" equal to the control sequence +% stemming from turning "b \l_tmpa_tlp b" into a control +% sequence. Furthermore we want to store the execution of it in a +% \m{toks} register. In this example we assume "\l_tmpa_tlp" contains +% the text string "lur". The straight forward approach is +% \begin{quote} +% "\toks_set:No \l_tmpa_toks {\let:Nc \aaa {b \l_tmpa_tlp b}}" +% \end{quote} +% Unfortunately this only puts +% "\exp_args:NNc \let:NN \aaa {b \l_tmpa_tlp b}" into "\l_tmpa_toks" +% and not "\let:NwN \aaa = \blurb" as we probably wanted. Using +% "\toks_set:Nx" is not an option as that will die horribly. Instead +% we can do a +% \begin{quote} +% "\toks_set:Nf \l_tmpa_toks {\let:Nc \aaa {b \l_tmpa_tlp b}}" +% \end{quote} +% which puts the desired result in "\l_tmpa_toks". It requires +% "\toks_set:Nf" to be defined as +% \begin{quote} +% "\def:Npn \toks_set:Nf {\exp_args:NNf \toks_set:Nn}" +% \end{quote} +% If you use this type of expansion in conditional processing then +% you should stick to using "TF" type functions only as it does not +% try to finish any "\if... \fi:" itself! +% +% +% +% +% % The available internal functions for argument expansion come in to % flavours, some of them are faster then others. Therefore it is usually % best to follow the following guidelines when defining new functions @@ -176,17 +270,17 @@ % \item % Arguments that need full expansion (i.e., are denoted with "x") % should be avoided if possible as they can not be processed very fast. -% \item -% In general "n", "x", and "o" (if not in the last position) will -% need special processing which is not fast and not expandable, i.e., -% functions of this type may not work correctly in arguments that are -% itself subject to "x" expansion. Therefore it is best to use the -% ``expandable'' functions (i.e., those that contain only "c", "N", "O" -% or "o" in the last position) whenever possible. +% \item +% In general "n", "x", and "o" (if not in the last position) will +% need special processing which is not fast and not expandable, +% i.e., functions of this type may not work correctly in arguments +% that are itself subject to "x" expansion. Therefore it is best to +% use the ``expandable'' functions (i.e., those that contain only +% "c", "N", "O", "o" or "f" in the last position) whenever possible. % \end{itemize} -% +% % \subsection{Manipulating the first argument} -% +% % \begin{function}{% % \exp_args:No % } @@ -197,7 +291,7 @@ % result is surrounded by braces and passed to . may have % more than one argument---all others are passed unchanged. % \end{function} -% +% % \begin{function}{% % \exp_args:Nc % } @@ -210,7 +304,7 @@ % sequence and passed to as the first argument. may have % more than one argument---all others are passed unchanged. % \end{function} -% +% % \begin{function}{% % \exp_args:NC % } @@ -224,7 +318,7 @@ % passed to as the first argument. may have more than % one argument---all others are passed unchanged. % \end{function} -% +% % \begin{function}{% % \exp_args:Nx % } @@ -237,62 +331,84 @@ % others are passed unchanged. % As mentioned before, this type of function is relatively slow. % \end{function} -% +% +% \begin{function}{% +% \exp_args:Nf +% } +% \begin{syntax} +% " \exp_args:Nf" "..." +% \end{syntax} +% The first argument of (i.e., ) undergoes full +% expansion until the first unexpandable token is encountered, the +% result is surrounded by braces and passed to . may +% have more than one argument---all others are passed unchanged. +% Beware of its special behavior as explained above. +% \end{function} +% +% % \subsection{Manipulating two arguments} -% +% % \begin{function}{% -% \exp_args:Nno | % \exp_args:NNx | % \exp_args:Nnx | -% \exp_args:Noo | +% \exp_args:Ncx | % \exp_args:Nox | % \exp_args:Nxo | % \exp_args:Nxx | % } % \begin{syntax} -% "\exp_args:Nno" "..." +% "\exp_args:Nnx" "..." % \end{syntax} % The above functions all manipulate the first two arguments of . % They are all slow and non-expandable. % \end{function} -% +% % \begin{function}{% % \exp_args:NNo | +% \exp_args:NNf | +% \exp_args:Nno | % \exp_args:NNc | +% \exp_args:Noo | % \exp_args:NOo | % \exp_args:NOc | % \exp_args:Nco | % \exp_args:Ncc | +% \exp_args:NNC | % } % \begin{syntax} % "\exp_args:NNo" "..." % \end{syntax} % These are the fast and expandable functions for the first two arguments. % \end{function} -% +% % \subsection{Manipulating three arguments} -% +% % So far not all possible functions are provided and even the selection % below may be reduced in the future as far as the non-expandable % functions are concerned. -% +% % \begin{function}{% -% \exp_args:Nnno | % \exp_args:Nnnx | % \exp_args:Noox | % \exp_args:Nnox | % \exp_args:Ncnx | % } % \begin{syntax} -% "\exp_args:Nnno" "..." +% "\exp_args:Nnnx" "..." % \end{syntax} % All the above functions are non-expandable. % \end{function} -% +% % \begin{function}{% +% \exp_args:NnnN | +% \exp_args:Nnno | % \exp_args:NNOo | % \exp_args:NOOo | % \exp_args:Nccc | +% \exp_args:NcNc | +% \exp_args:Nnnc | +% \exp_args:NcNo | +% \exp_args:Ncco | % } % \begin{syntax} % "\exp_args:NNOo" "..." @@ -300,9 +416,9 @@ % These are the fast and expandable functions for the first three % arguments. % \end{function} -% +% % \subsection{Internal functions and variables} -% +% % \begin{function}{\exp_after:NN} % \begin{syntax} % "\exp_after:NN" @@ -315,41 +431,53 @@ % the naming conventions of \LaTeX3. % \end{texnote} % \end{function} -% +% % \begin{function}{\exp_not:N | -% \exp_not:c } +% \exp_not:c | +% \exp_not:n } % \begin{syntax} % "\exp_not:N" +% "\exp_not:n" "{" "}" % \end{syntax} % This function will prohibit the expansion of in situation % where would otherwise be replaced by it definition, e.g., % inside an argument that is handled by the "x" convention. % \begin{texnote} -% "\exp_not:N" is the primitive \tn{noexpand} renamed. +% "\exp_not:N" is the primitive \tn{noexpand} renamed and "\exp_not:n" +% is the \eTeX{} primitive \tn{unexpanded}. % \end{texnote} % \end{function} -% -% +% +% % \begin{function}{\exp_not:o} % \begin{syntax} -% "\exp_not:o" +% "\exp_not:o" "{""}" % \end{syntax} +% Same as "\exp_not:n" except is expanded once and the +% result of this expansion is then prohibited from being expanded +% further. +% \end{function} % +% \begin{function}{\exp_not:E} +% \begin{syntax} +% "\exp_not:E" +% \end{syntax} % The name of this command is a lie. Perhaps it should be called -% ``"exp_perhaps_once"''. What it actually does is, it expands and -% then issues an "\exp_not:N" to prohibit further expansion of the -% first token in the replacement text of . This means that if the -% replacement text of consists of more than one token all -% further tokens are still subject to full expansion. The command is, for -% example, useful when generating a new cs name inside a "x" situation -% that shouldn't be expanded further, e.g., "\exp_not:o" "\cs:w" "foo" -% "\cs_end:". +% ``"exp_perhaps_once"''. What it actually does is, it expands +% and then issues an "\exp_not:N" to prohibit further expansion of the +% first token in the replacement text of . This means that if +% the replacement text of consists of more than one token all +% further tokens are still subject to full expansion. % \begin{texnote} % This command has no equivalent. % \end{texnote} % \end{function} % -% \begin{variable}{\l_exp_tlp | \l_exp_toks} +% +% +% +% \begin{variable}{\l_exp_tlp | } +% \begin{syntax}\end{syntax} % The "\exp_" module has its private variables to temporarily store % results of the argument expansion. This is done to avoid interference % with other functions using temporary variables. @@ -357,23 +485,25 @@ % % \StopEventually{} % -% \section {Argument Expansion} +% \subsection {The Implementation} % % We start by ensuring that the required packages are loaded. % \begin{macrocode} -%\RequirePackage{l3basics} %\RequirePackage{l3tlp} -%<*package> +%<*initex|package> % \end{macrocode} -% -% \subsection{General expansion} +% +% \subsubsection{General expansion} % % In this section a general mechanism for defining functions to handle -% argument handling is defined. -% These general expansion functions are expandable unless |x| is used. -% (Any version of |x| is going to have to use -% one of the \LaTeX3\ names for |\def:Npx| at some point, and so is never -% going to be expandable.) +% argument handling is defined. These general expansion functions are +% expandable unless |x| is used. (Any version of |x| is going to have +% to use one of the \LaTeX3\ names for |\def:Npx| at some point, and +% so is never going to be expandable.\footnote{However, some +% primitives have certain characteristics that means that their +% arguments undergo an \texttt{x} type expansion but the primitive +% is in fact still expandable. We shall make it very clear when such +% a function is expandable.}) % % In a later section some common cases are coded by a more direct % method, typically using calls to |\exp_after:NN|. @@ -390,8 +520,9 @@ % \begin{macro}{\exp_arg_next:nnn} % This is basically the same function as |\Dexp_arg_next:nnn|. % \begin{macrocode} -\def_new:Npn\exp_arg_next:nnn#1#2#3{% - #2\:::{#3#1}} +\def_new:Npn\exp_arg_next:nnn#1#2#3{ + #2\:::{#3#1} +} % \end{macrocode} % \end{macro} % @@ -399,8 +530,9 @@ % This function is used to skip an argument that doesn't need to % be expanded. % \begin{macrocode} -\def_new:Npn\::n#1\:::#2#3{% - #1\:::{#2{#3}}} +\def_new:Npn\::n#1\:::#2#3{ + #1\:::{#2{#3}} +} % \end{macrocode} % \end{macro} % @@ -409,8 +541,9 @@ % single token and doesn't need to be expanded. %^^A was \let_new:NN\::N\::n (changed to match \;N above. % \begin{macrocode} -\def_new:Npn\::N#1\:::#2#3{% - #1\:::{#2#3}} +\def_new:Npn\::N#1\:::#2#3{ + #1\:::{#2#3} +} % \end{macrocode} % \end{macro} % @@ -418,25 +551,52 @@ % This function is used to skip an argument that is turned into % as control sequence without expansion. % \begin{macrocode} -\def_new:Npn\::c#1\:::#2#3{% - \exp_after:NN\exp_arg_next:nnn\cs:w #3\cs_end:{#1}{#2}} +\def_new:Npn\::c#1\:::#2#3{ + \exp_after:NN\exp_arg_next:nnn\cs:w #3\cs_end:{#1}{#2} +} % \end{macrocode} % \end{macro} % % \begin{macro}{\::o} % This function is used to expand an argument once. % \begin{macrocode} -\def_new:Npn\::o#1\:::#2#3{% - \exp_after:NN\exp_arg_next:nnn\exp_after:NN{\exp_after:NN{#3}}{#1}{#2}} +\def_new:Npn\::o#1\:::#2#3{ + \exp_after:NN\exp_arg_next:nnn\exp_after:NN{\exp_after:NN{#3}}{#1}{#2} +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\::f} +% This function is used to expand a token list until the first +% unexpandable token is found. +% The underlying "\int_to_roman:w -`0" expands everything in its +% way to find something terminating the number and thereby expands the +% function in front of it. This scanning procedure is terminated once +% the expansion hits something non-expandable or a space; in case the +% scanner hits a number, this number also terminates the scanning and +% is left untouched. In the example shown earlier the scanning was +% stopped once \TeX{} had fully expanded +% "\let:Nc \aaa {b \l_tmpa_tlp b}" into "\let:NwN \aaa = \blurb" which +% then turned out to contain the non-expandable token "\let:NwN". +% Since the expansion of "\int_to_roman:w -`0" is \m{null}, we +% wind up with a fully expanded list, only \TeX{} has not tried to +% execute any of the non-expandable tokens. This is what +% differentiates this function from the "x" argument type. +% \begin{macrocode} +\def_new:Npn\::f#1\:::#2#3{ + \exp_after:NN\exp_arg_next:nnn + \exp_after:NN{\exp_after:NN{\int_to_roman:w -`0 #3}} + {#1}{#2} +} % \end{macrocode} % \end{macro} % % \begin{macro}{\::x} % This function is used to expand an argument fully. -% % \begin{macrocode} -\def_new:Npn\::x#1\:::#2#3{% - \tlp_set:Nx\l_exp_tlp{{{#3}}}% +\def_new:Npn\::x#1\:::#2#3{ + \tlp_set:Nx\l_exp_tlp{{{#3}}} \exp_after:NN\exp_arg_next:nnn\l_exp_tlp{#1}{#2}} % \end{macrocode} % \end{macro} @@ -452,7 +612,7 @@ % This function creates a control sequence out of |#3| and expands % that once before passing it on to |\exp_arg_next:nnn|. % \begin{macrocode} -\def_new:Npn\::C#1\:::#2#3{% +\def_new:Npn\::C#1\:::#2#3{ \exp_after:NN\exp_C_aux:nnn\cs:w #3\cs_end:{#1}{#2}} % \end{macrocode} % \end{macro} @@ -474,10 +634,64 @@ % \end{macrocode} % \end{macro} % +% Here are some that might not stay but let's see. +% \begin{macro}{\::E} +% This function is used to expand an argument once and return it +% \emph{without} braces. Use this only when you feel pretty +% comfortable about your input! Actually this is pretty much just +% generic wrapper for |\exp_after:NN|. +% \begin{macrocode} +\def:Npn\::E#1\:::#2#3{ + \exp_after:NN\exp_arg_next:nnn \exp_after:NN{#3}{#1}{#2} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\::e} +% Same as |\::E| really but conceptually they are different. +% \begin{macrocode} +\def:Npn\::e#1\:::#2#3{ + \exp_after:NN\exp_arg_next:nnn \exp_after:NN{#3}{#1}{#2} +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\::d} +% This function is used to expand an argument twice. Mostly useful +% for |toks| type things. +% \begin{macrocode} +\def:Npn\::d#1\:::#2#3{ + \exp_after:NN\exp_after:NN\exp_after:NN\exp_arg_next:nnn + \exp_after:NN\exp_after:NN\exp_after:NN{ + \exp_after:NN\exp_after:NN\exp_after:NN{#3}}{#1}{#2} +} +% \end{macrocode} +% \end{macro} +% +% We do most of them by hand here. This also means that we get a name +% for |\exp_after:NN| that fits with the rest of the code. +% \begin{macrocode} +\let:NN \exp_args:NE \exp_after:NN +\def:Npn \exp_args:NNE #1{\exp_args:NE#1\exp_args:NE} +\def:Npn \exp_args:NNNE #1#2{\exp_args:NE#1\exp_args:NE#2\exp_args:NE} +\def:Npn \exp_args:NEE #1{\exp_args:NE\exp_args:NE\exp_args:NE#1\exp_args:NE} +\def:Npn \exp_args:NcE #1#2{\exp_after:NN #1\cs:w #2\exp_after:NN\cs_end:} +\def:Npn \exp_args:Nd {\::d\:::} +\def:Npn \exp_args:NNd {\::N\::d\:::} +% \end{macrocode} +% % \begin{macro}{\exp_args:NC} +% \begin{macro}{\exp_args:Ncx} +% \begin{macro}{\exp_args:Ncco} % \begin{macro}{\exp_args:Nccx} % \begin{macro}{\exp_args:Ncnx} +% \begin{macro}{\exp_args:NcNc} +% \begin{macro}{\exp_args:Nf} +% \begin{macro}{\exp_args:NNf} +% \begin{macro}{\exp_args:Nfo} +% \begin{macro}{\exp_args:Nnf} % \begin{macro}{\exp_args:NNno} +% \begin{macro}{\exp_args:NnnN} % \begin{macro}{\exp_args:Nnno} % \begin{macro}{\exp_args:Nnnx} % \begin{macro}{\exp_args:Nno} @@ -490,6 +704,8 @@ % \begin{macro}{\exp_args:Nx} % \begin{macro}{\exp_args:Nxx} % \begin{macro}{\exp_args:Nxx} +% \begin{macro}{\exp_args:NNC} +% \begin{macro}{\exp_args:Nnnc} % Here are the actual function definitions, using the helper functions % above. % \begin{macrocode} @@ -497,12 +713,23 @@ %\def:Npn \exp_args:Nc {\::c\:::} %\def:Npn \exp_args:Ncc {\::c\::c\:::} %\def:Npn \exp_args:Nccc {\::c\::c\::c\:::} +\def:Npn \exp_args:Ncx {\::c\::x\:::} +\def:Npn \exp_args:Ncco {\::c\::c\::o\:::} \def:Npn \exp_args:Nccx {\::c\::c\::x\:::} \def:Npn \exp_args:Ncnx {\::c\::n\::x\:::} +\def:Npn \exp_args:NcNc {\::c\::N\::c\:::} +\def:Npn \exp_args:NcNo {\::c\::N\::o\:::} +\def:Npn \exp_args:Ncco {\::c\::c\::o\:::} %\def:Npn \exp_args:Nco {\::c\::o\:::} %\def:Npn \exp_args:NNc {\::N\::c\:::} +\def:Npn \exp_args:Nf {\::f\:::} +\def:Npn \exp_args:NNf {\::N\::f\:::} +\def:Npn \exp_args:Nfo{\::f\::o\:::} +\def:Npn \exp_args:Nnf {\::n\::f\:::} %\def:Npn \exp_args:NNNo {\::N\::N\::o\:::} \def:Npn \exp_args:NNno {\::N\::n\::o\:::} +%% Strange one this next one... +\def:Npn \exp_args:NnnN {\::n\::n\::N\:::} \def:Npn \exp_args:Nnno {\::n\::n\::o\:::} \def:Npn \exp_args:Nnnx {\::n\::n\::x\:::} %\def:Npn \exp_args:NNo {\::N\::o\::\:::} @@ -521,6 +748,8 @@ \def:Npn \exp_args:Nx {\::x\:::} \def:Npn \exp_args:Nxo {\::x\::o\:::} \def:Npn \exp_args:Nxx {\::x\::x\:::} +\def:Npn \exp_args:NNC {\::N\::C\:::} +\def:Npn \exp_args:Nnnc {\::n\::n\::c\:::} % \end{macrocode} % \end{macro} % \end{macro} @@ -538,25 +767,39 @@ % \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} % % -% \subsection{Preventing expansion} +% \subsubsection{Preventing expansion} % -% \begin{macro}{\exp_not:N} -% This is the \TeX\ primitive that was defined earlier. -% \end{macro} % % \begin{macro}{\exp_not:o} +% \begin{macrocode} +\def_new:Npn\exp_not:o#1{\exp_not:n\exp_after:NN{#1}} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\exp_not:E} % \begin{macro}{\exp_not:c} % Two helper functions, which we can probably live without it. % \begin{macrocode} -\def_new:Npn\exp_not:o{\exp_after:NN\exp_not:N} +\def_new:Npn\exp_not:E{\exp_after:NN\exp_not:N} \def_new:Npn\exp_not:c#1{\exp_after:NN\exp_not:N\cs:w#1\cs_end:} % \end{macrocode} % \end{macro} % \end{macro} % -% \subsection{Single token expansion} +% +% \subsubsection{Single token expansion} % % Expansion for arguments that are single tokens is done with the % functions below. I first thought of using a different module name @@ -575,6 +818,7 @@ % \begin{macro}{\exp_args:No} % \begin{macro}{\exp_args:NOo} % \begin{macro}{\exp_args:NNo} +% \begin{macro}{\exp_args:NNO} % \begin{macro}{\exp_args:NOOo} % \begin{macro}{\exp_args:NNOo} % \begin{macro}{\exp_args:NNNo} @@ -589,6 +833,8 @@ \exp_after:NN#1\exp_after:NN#2\exp_after:NN#3\exp_after:NN{#4}} \def_new:Npn \exp_args:NNo #1#2#3{\exp_after:NN#1\exp_after:NN#2 \exp_after:NN{#3}} +\def_new:Npn \exp_args:NNO #1#2#3 {\exp_after:NN#1 + \exp_after:NN#2 #3} \def_new:Npn \exp_args:NNOo #1#2#3#4{\exp_after:NN\exp_args:NNo \exp_after:NN#1\exp_after:NN#2\exp_after:NN#3\exp_after:NN{#4}} \def_new:Npn \exp_args:NNNo #1#2#3#4{\exp_after:NN#1\exp_after:NN#2 @@ -600,6 +846,7 @@ % \end{macro} % \end{macro} % \end{macro} +% \end{macro} % % % \begin{macro}{\exp_args:Nc} @@ -640,35 +887,35 @@ % % % \begin{macro}{\exp_def_form:nnn} -% This command is a recent addition which was actually added +% This command is a recent addition which was actually added % when we wrote the article for TUGboat (while most of the other % code goes way back to 1993). % \begin{macrocode} \def:Npn\exp_def_form:nnn#1#2#3{ \exp_after:NN \def:Npn - \cs:w - #1:#3 + \cs:w + #1:#3 \exp_after:NN \cs_end: \exp_after:NN { - \cs:w - exp_args:N#3 + \cs:w + exp_args:N#3 \exp_after:NN \cs_end: - \cs:w + \cs:w #1:#2 \cs_end: } % \end{macrocode} -% We also have to test if |exp_arg:N#3| is already defined +% We also have to test if |exp_args:N#3| is already defined % and if not define it via the % |\::| commands using the chars in |#3| % \begin{macrocode} - \cs_free:cT + \cs_if_free:cT {exp_args:N#3} - {\def:cpx {exp_args:N#3} + {\def:cpx {exp_args:N#3} {\exp_args_form_x:w #3 :} } } @@ -677,29 +924,80 @@ % % % \begin{macro}{\exp_args_form_x:w} -% This command graps char by char outputting |\::#1| (not expanded +% This command grabs char by char outputting |\::#1| (not expanded % further) until we see a |:|. That colon is in fact also turned into % |\:::| so that the required structure for |\exp_args...| commands % is correctly terminated. % \begin{macrocode} \def_new:Npn\exp_args_form_x:w #1 { - \exp_after:NN \exp_not:N \cs:w ::#1 \cs_end: + \exp_not:c{::#1} \if_meaning:NN #1 : \else: \exp_after:NN\exp_args_form_x:w \fi:} % \end{macrocode} % \end{macro} - +% % Show token usage: % \begin{macrocode} -% +% %<*showmemory> \showMemUsage % % \end{macrocode} % +% \endinput +% +% $Log$ +% Revision 1.29 2006/07/30 15:43:38 morten +% Minor touch-up plus added functions needed by clist module +% +% Revision 1.28 2006/06/03 18:56:31 morten +% A few more functions +% +% Revision 1.27 2006/03/20 18:26:35 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.26 2006/02/17 23:01:47 braams +% Imported \exp_args:NNO from l3messages +% +% Revision 1.25 2005/12/27 10:00:45 morten +% Changed RCS information retrieval +% +% Revision 1.24 2005/12/22 13:56:03 morten +% Fixed error in \exp_args:NNd +% +% Revision 1.23 2005/12/21 20:44:30 morten +% Corrected typo. +% +% Revision 1.22 2005/12/06 15:34:46 morten +% Made \exp_not:o do what you'd expect +% +% Revision 1.21 2005/11/23 07:37:29 morten +% A few new expansion types, we shall see if they will be useful. +% +% Revision 1.20 2005/04/12 16:44:06 morten +% Fix to make it run as a package +% +% Revision 1.19 2005/04/12 13:24:07 morten +% Minor updates +% +% Revision 1.18 2005/04/09 21:06:46 morten +% Added yet another function. +% +% Revision 1.17 2005/04/06 21:38:10 morten +% Added more functions. +% +% Revision 1.16 2005/03/26 21:09:44 morten +% Added f argument type for "force expansion" +% +% Revision 1.15 2005/03/22 23:24:40 morten +% Fixed documentation error. +% +% Revision 1.14 2005/03/16 22:36:37 braams +% Added the tweaks necessary to be able to load with initex +% +% Revision 1.13 2005/03/11 21:37:37 braams +% Fixed the use of RCS information % - - - diff --git a/Master/texmf-dist/source/latex/expl3/l3final.dtx b/Master/texmf-dist/source/latex/expl3/l3final.dtx new file mode 100644 index 00000000000..2eb42fb4a41 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3final.dtx @@ -0,0 +1,129 @@ +% \iffalse +%% File: l3final.dtx Copyright (C) 1990-2006 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. +%% +%% ----------------------------------------------------------------------- +% +%\RequirePackage{l3names} +%<*dtx> +%\fi +\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{% + \def\fileversion{#2}% + \def\filedate{#3/#4/#5}% + \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]% +} +%\iffalse +% +%\fi +%<*!ini> +\GetIdInfo$Id: l3final.dtx 573 2006-08-21 20:59:37Z morten $ + {L3 Experimental final module} +% +% +% \iffalse +%<*driver> +\documentclass{l3doc} + +\begin{document} +\DocInput{l3final.dtx} +\end{document} +% +% \fi +% +% \section{Final Wrap-up} +% +% This module will contain all the last minute coding necessary to +% round off the format. +% +% \subsection{Cleaning up} +% +% Some of the macros needed in creating the format are no longer +% needed and will either be removed are modified to generate error +% messages. +%<*initex> +% +% \subsection{Closing the error file} +% +% Earlier on in the format a file was opened to collect all the +% error messages. This file needs to be closed before the format is +% dumped. +% \begin{macrocode} +\err_file_close:N\c_kernel_err_tlp +% \end{macrocode} +% +% \subsection{Dumping the format} +% +% The last action to take is to dump the format. +% \begin{macrocode} +\tex_dump:D +% \end{macrocode} +% +% \subsection{Creating the format} +% +% There is one more thing needed for creating the format; a file +% called \file{lbase.ini}. For now this is included here. +%<*ini> +% \begin{macrocode} +%% Derived from a file by Thomas Esser + +\ifx\pdfoutput\undefined \else + \ifx\pdfoutput\relax \else + % We're building the latex format with the pdfetex engine (started 2004). + % See this file for details. + \input pdftex-dvi.tex + \fi +\fi + +%% the usual format initialization. +%%\scrollmode +\input lbase.ltx +\endinput +% \end{macrocode} +% +% \endinput +% +% $Log$ +% Revision 1.5 2006/03/19 15:03:22 braams +% Added code to close the kernel error file +% +% Revision 1.4 2006/01/13 23:20:07 braams +% Added lbase.ini to be generated from this file +% +% Revision 1.3 2005/12/27 16:01:48 morten +% Changed RCS information retrieval +% +% Revision 1.2 2005/04/12 22:48:24 braams +% Corrected a slight mistake +% +% Revision 1.1 2005/04/12 22:41:38 braams +% This file will contain al the last minute things needed in the format. +% For starters it just dumps the format. +% diff --git a/Master/texmf-dist/source/latex/expl3/l3format.ins b/Master/texmf-dist/source/latex/expl3/l3format.ins new file mode 100644 index 00000000000..cc3d0d984b8 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3format.ins @@ -0,0 +1,72 @@ + +\input docstrip.tex +\askforoverwritefalse + +\preamble + + +EXPERIMENTAL CODE + +Do not distribute this file without also distributing the +source files specified above. + +Do not distribute a modified version of this file. + + +\endpreamble +% stop docstrip adding \endinput +\postamble +\endpostamble + +\keepsilent + +% generate the format file +\generate{% + \file{lbase.ltx}{% + \from{l3names.dtx}{initex} % The naming conventions + \from{l3basics.dtx}{initex} % Initialisations + \from{l3chk.dtx}{initex} % Checking functions + \from{l3tlp.dtx}{initex} % token list pointers + \from{l3expan.dtx}{initex} % Controlling expansion of arguments + \from{l3quark.dtx}{initex} % quarks + \from{l3num.dtx}{initex} % Storing integers in macros + \from{l3seq.dtx}{initex} % Sequences and Stacks + \from{l3alloc.dtx}{initex} % Register allocations + \from{l3io.dtx}{initex} % dealing with I/O + \from{l3int.dtx}{initex} % dealing with integer registers + \from{l3clist.dtx}{initex} % Comma separated lists + \from{l3prop.dtx}{initex} % property lists + \from{l3token.dtx}{initex} % token investigation +% + \from{l3vers.dtx}{initex} % Version information +% + \from{l3skip.dtx}{initex} % dealing with skip registers + \from{l3toks.dtx}{initex} % dealing with token registers + \from{l3messages.dtx}{initex} % seting up for user communication + \from{l3box.dtx}{initex} % dealing with box registers + \from{l3precom.dtx}{initex,precompile} % + \from{l3prg.dtx}{initex} % Program control structures + \from{l3xref.dtx}{initex} % Cross references +% + \from{l3final.dtx}{initex} % Final wrap-up + } +} +% generate the format initialisation file +\generate{% + \file{lbase.ini}{% + \from{l3final.dtx}{ini} + } +} + +\Msg{} +\Msg{*************************************} +\Msg{*} +\Msg{* Now run (PDF)EINITEX on *lbase.ini} +\Msg{*} +\Msg{* On an up to date system, run } +\Msg{* pdfetex -ini "*lbase.ini" } +\Msg{*} +\Msg{*************************************} +\Msg{} + +\endbatchfile diff --git a/Master/texmf-dist/source/latex/expl3/l3int.dtx b/Master/texmf-dist/source/latex/expl3/l3int.dtx index d219a9d27bb..f4e582ec12f 100644 --- a/Master/texmf-dist/source/latex/expl3/l3int.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3int.dtx @@ -1,15 +1,50 @@ % \iffalse -%% File: l3int.dtx Copyright (C) 1990-1998 LaTeX3 project -% +%% File: l3int.dtx Copyright (C) 1990-2006 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. +%% +%% ----------------------------------------------------------------------- +% +%\RequirePackage{l3names} %<*dtx> - \ProvidesFile{l3int.dtx} +%\fi +\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{% + \def\fileversion{#2}% + \def\filedate{#3/#4/#5}% + \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]% +} +%\iffalse % -%\NeedsTeXFormat{LaTeX2e} -%\ProvidesPackage{l3int} -% \ProvidesFile{l3int.drv} -% \fi -% \ProvidesFile{l3int.dtx} - [1998/04/20 v1.0c L3 Experimental Integer module] +%\fi +\GetIdInfo$Id: l3int.dtx 573 2006-08-21 20:59:37Z morten $ + {L3 Experimental Integer module} % % \iffalse %<*driver> @@ -22,7 +57,6 @@ % \fi % % -% \GetFileInfo{l3int.dtx} % \title{The \textsf{l3int} package\thanks{This file % has version number \fileversion, last % revised \filedate.}\\ @@ -31,40 +65,32 @@ % \date{\filedate} % \maketitle % -% \section{Counters} +% \section{Integers} % % \LaTeX3 maintains two type of integer registers for internal use. -% One (associated with the name "int") uses the builtin counter -% registers of \TeX{} and is therefore relatively fast and one -% (associated with the name "fint" for fake counter) that implements the -% operations within the \TeX{} macro language and is therefore much -% slower in processing. This type of counter is also far more restricted -% in its range. -% -% The fake counter should be used for variables that are not accessed -% very often since this saves the important fast internal registers -% (\TeX{} has only 255 of those). For example, all allocation routines -% in \LaTeX3 make use of fake counters to remember the values of recent -% allocated register numbers etc. -% -% Since all functions for both types are very similar (they usually -% differ only in the initial "f") we describe them together. But -% remember that you need to use "fint" variables when using "fint" -% functions. +% One (associated with the name "num") for low level uses in the +% allocation mechanism using macros only and "int": the one described +% here. +% +% The "int" type uses the built-in counter registers of \TeX{} and is +% therefore relatively fast compared to the "num" type and should be +% preferred in all cases as there is little chance we should ever run +% out of registers when being based on at least \eTeX. % % \subsection{Functions} % % \begin{function}{% % \int_new:N | % \int_new:c | -% \fint_new:N | +% \int_new_l:N | % } % \begin{syntax} % "\int_new:N" -% "\fint_new:N" % \end{syntax} -% Defines to be a new variable of type "int". There is no way to -% define constant counters with these functions. +% Globally defines to be a new variable of type "int" although +% you can still choose if it should be a an "\l_" or "\g_" type. +% There is no way to define constant counters with these functions. +% The function "\int_new_l:N" defines locally only. % \begin{texnote} % "\int_new:N" is the equivalent to plain \TeX{}'s \tn{newcount}. % However, the internal register allocation is done differently. @@ -75,12 +101,9 @@ % \int_incr:N | % \int_gincr:N | % \int_gincr:c | -% \fint_incr:N | -% \fint_gincr:N | % } % \begin{syntax} % "\int_incr:N" -% "\fint_incr:N" % \end{syntax} % Increments by one. For global variables the global versions % should be used. @@ -90,12 +113,9 @@ % \int_decr:N | % \int_gdecr:N | % \int_gdecr:c | -% \fint_decr:N | -% \fint_gdecr:N | % } % \begin{syntax} % "\int_decr:N" -% "\fint_decr:N" % \end{syntax} % Decrements by one. For global variables the global versions % should be used. @@ -106,119 +126,101 @@ % \int_set:cn | % \int_gset:Nn | % \int_gset:cn | -% \fint_set:Nn | -% \fint_gset:Nn | % } % \begin{syntax} -% "\int_set:Nn" "{" "}" -% "\fint_set:Nn" "{" "}" +% "\int_set:Nn" "{" "}" % \end{syntax} -% These functions will set the register to the value. +% These functions will set the register to the +% value. This value can contain simple calc-like expressions as +% provided by \eTeX. % \end{function} % +% % \begin{function}{% -% \fint_set_eq:NN | -% \fint_gset_eq:NN | +% \int_zero:N | +% \int_zero:c | +% \int_gzero:N | +% \int_gzero:c | % } % \begin{syntax} -% "\fint_set_eq:NN" +% "\int_zero:N" % \end{syntax} -% Fast form for -% \begin{syntax} -% "\fint_set:No" "{\fint_use:N" "}" -% \end{syntax} -% when is known to be a variable of fake counter. Note that a -% corresponding function for real counters is not implemented since the -% "\int_set:Nn" function does this operation sufficiently when then second -% argument is a instead of "{""}" value. +% These functions sets the register to zero either locally +% or globally. % \end{function} % +% % \begin{function}{% % \int_add:Nn | % \int_add:cn | % \int_gadd:Nn | -% \fint_add:Nn | -% \fint_gadd:Nn | % } % \begin{syntax} -% "\int_add:Nn" "{" "}" -% "\fint_add:Nn" "{" "}" +% "\int_add:Nn" "{" "}" % \end{syntax} -% These functions will add to the register the value . If -% the second argument is a register too, the surrounding braces -% can be left out. -% -% It not allowed to use a instead of the . If a fake -% counter should be used as the second argument one needs to turn the -% first into an by applying "\fint_use:N". +% These functions will add to the register the value . If the second argument is a register too, the +% surrounding braces can be left out. % \end{function} % % \begin{function}{% % \int_sub:Nn | % \int_gsub:Nn | -% \fint_sub:Nn | -% \fint_gsub:Nn | % } % \begin{syntax} -% "\int_gsub:Nn" "{" "}" -% "\fint_gsub:Nn" "{" "}" +% "\int_gsub:Nn" "{" "}" % \end{syntax} % These functions will subtract from the register the value -% . If the second argument is a register too, the +% . If the second argument is a register too, the % surrounding braces can be left out. -% -% It is not allowed to use a instead of the . If a fake -% counter should be used as the second argument one needs to turn the -% first into an by applying "\fint_use:N". % \end{function} % % \begin{function}{% % \int_use:N | % \int_use:c | -% \fint_use:N | % } % \begin{syntax} % "\int_use:N" -% "\fint_use:N" % \end{syntax} % This function returns the integer value kept in in a way -% suitable for further processing. Be sure to use "\fint_use:N" if you -% are accessing the value of a fake counter because otherwise your -% result will be to some surprise to you (there is no check). +% suitable for further processing. % \begin{texnote} % The function "\int_use:N" could be implemented directly as the \TeX{} % primitive "\tex_the:D" which is also responsible to produce the values for % other internal quantities. We have chosen to use individual functions -% for counters, dimenions etc.\ to allow checks and to make the code -% more selfexplaining. +% for counters, dimensions etc.\ to allow checks and to make the code +% more self-explaining. % \end{texnote} % \end{function} % % \subsection{Formatting a counter value} % -% \begin{function}{\int_to_arabic:n | -% \int_to_alph:n | -% \int_to_Alph:n | -% \int_to_roman:n | -% \int_to_Roman:n | -% \int_to_symbol:n | +% \begin{function}{ +% \int_to_arabic:n | +% \int_to_alph:n | +% \int_to_Alph:n | +% \int_to_roman:n | +% \int_to_Roman:n | +% \int_to_symbol:n | % } % \begin{syntax} % "\int_to_alph:n" "{" "}" % "\int_to_alph:n" -% "\int_to_alph:n" "{" "\fint_use:N" "}" % \end{syntax} % If some or the the current value of a should be % displayed or typeset in a special ways (e.g., as uppercase roman -% numerals) these function can be used. We need braces if the argument -% is a simple , they can be omitted in case of a . -% -% To format s with these functions it is necessary to turn the -% value of the first into an by applying "\fint_use:N" -% within the argument braces. +% numerals) these function can be used. We need braces if the +% argument is a simple , they can be omitted in case of a +% . By default the letters produced by "\int_to_roman:n" and +% "\int_to_Roman:n" have catcode~11. % % All functions are fully expandable and will therefore produce the -% correct output when used inside of deferred writes, etc. +% correct output when used inside of deferred writes, etc. In case the +% number in an |alph| or |Alph| function is greater than the default +% base number (26) it follows a simple conversion rule so that 27 is +% turned into |aa|, 50 into |ax| and so on and so forth. These two +% functions can be modified quite easily to take a different base +% number and conversion rule so that other languages can be supported. % \begin{texnote} % These are more or less the internal \LaTeX2 functions \tn{@arabic}, % \tn{@alph}, \tn{Alph}, \tn{@roman}, \tn{@Roman}, and \tn{@fnsymbol} @@ -226,36 +228,65 @@ % \end{texnote} % \end{function} % -% \subsection{Variable and constants} +% \subsubsection{Internal functions} % -% \begin{variable}{% -% \c_int_max | -% \c_fint_max | +% \begin{function}{\int_to_roman:w} +% \begin{syntax} +% "\int_to_roman:w" \textit{or} +% \end{syntax} +% Converts to it lowercase roman representation. Note that +% it produces a string of letters with catcode 12. +% \begin{texnote} +% This is the \TeX{} primitive \tn{romannumeral} renamed. +% \end{texnote} +% \end{function} +% \begin{function}{ +% \int_roman_lcuc_mapping:Nnn | +% \int_to_roman_lcuc:NN | % } -% Constant that denote the maximum value which can be stored in a -% or register. -% \end{variable} +% \begin{syntax} +% "\int_roman_lcuc_mapping:Nnn" "{""}" "{""}" +% "\int_to_roman_lcuc:NN" +% \end{syntax} +% "\int_roman_lcuc_mapping:Nnn" specifies how the roman +% numeral (i, v, x, l, c, d, or m) should be +% interpreted when converting the number. is the lower case and +% is the uppercase mapping. "\int_to_roman_lcuc:NN" is a +% recursive function converting the roman numerals. +% \end{function} +% +% +% \begin{function}{ +% \int_convert_number_with_rule:nnN | +% \int_alph_default_conversion_rule:n | +% \int_Alph_default_conversion_rule:n | +% \int_symbol_math_conversion_rule:n | +% \int_symbol_text_conversion_rule:n | +% } +% \begin{syntax} +% "\int_convert_number_with_rule:nnN" "{""}" "{""}" +% "\int_alph_default_conversion_rule:n" "{""}" +% \end{syntax} +% "\int_convert_number_with_rule:nnN" converts into letters, +% symbols, whatever as defined by . denotes the base +% number for the conversion. +% \end{function} +% +% +% +% +% +% +% \subsection{Variable and constants} % % \begin{variable}{% -% \c_minus_one | -% \c_zero | -% \c_one | -% \c_two | -% \c_three | -% \c_sixteen | -% \c_twohundred_fifty_five | -% \c_twohundredfiftysix | -% \c_thousand | -% \c_ten_thousand | -% \c_twenty_thousand | +% \c_max_int | % } -% Set of constants denoting useful values. -% \begin{texnote} -% Most of these constants have been available under \LaTeX2 under names -% like \tn{tw@}, \tn{thr@@} etc. -% \end{texnote} +% Constant that denote the maximum value which can be stored in an +% register. % \end{variable} % +% % \begin{variable}{% % \l_tmpa_int | % \l_tmpb_int | @@ -268,16 +299,143 @@ % \end{variable} % % -% \section{Integer registers} +% \subsection{Testing and evaluating integer expressions} +% +% \begin{function}{% +% \int_eval:n | +% \int_div_truncate:nn | +% \int_div_round:nn | +% \int_mod:nn | +% } +% \begin{syntax} +% "\int_eval:n" "{""}" \\ +% "\int_div_truncate:n" "{""}" "{""}" \\ +% "\int_mod:nn" "{""}" "{""}" +% \end{syntax} +% Evaluates the value of a integer expression so that +% "\int_eval:n {3*5/4}" puts "4" back into the input stream. Note that +% the results of divisions are rounded by the primitive operations. If +% you want the result of a division to be truncated use +% "\int_div_truncate:nn". "\int_div_round:nn" is added for +% completeness. "\int_mod:nn" returns the remainder of a division. All +% of these functions are expandable. +% \begin{texnote} +% "\int_eval:n" is the \eTeX primitive \tn{numexpr} turned into a function +% taking an argument. +% \end{texnote} +% \end{function} +% +% \begin{function}{% +% \int_compare:nNnTF | +% \int_compare:nNnT | +% \int_compare:nNnF | +% } +% \begin{syntax} +% "\int_compare:nNnTF" "{""}" "{""}" +% "{""}" "{""}" +% \end{syntax} +% These functions test two integer expressions against each other. They +% are both evaluated by "\int_eval:n". Note that if both expressions +% are normal integer variables as in +% \begin{quote} +% "\int_compare:nNnTF \l_temp_int < \c_zero {negative}{non-negative}" +% \end{quote} +% you can safely omit the braces. +% \begin{texnote} +% This is the \TeX{} primitive \tn{ifnum} turned into a function. +% \end{texnote} +% \end{function} +% +% \begin{function}{% +% \int_compare_p:nNn | +% } +% \begin{syntax} +% "\int_compare_p:nNn" "{""}" "{""}" +% \end{syntax} +% A predicate version of the above mentioned functions. +% \end{function} +% +% \begin{function}{% +% \int_if_odd:nTF | +% \int_if_odd_p:n | +% } +% \begin{syntax} +% "\int_if_odd:nTF" "{""}" "{""}" "{""}" +% \end{syntax} +% These functions test if an integer expression is even or odd. We +% also define a predicate version of it. +% \begin{texnote} +% This is the \TeX{} primitive \tn{ifodd} turned into a function. +% \end{texnote} +% \end{function} +% +% \begin{function}{% +% \int_whiledo:nNnT | +% \int_whiledo:nNnF | +% \int_dowhile:nNnT | +% \int_dowhile:nNnF | +% } +% \begin{syntax} +% "\int_whiledo:nNnT" "{""}" +% \end{syntax} +% "\int_whiledo:nNnT" tests the integer expressions and if true performs +% the body "T" until the test fails. "\int_dowhile:nNnT" is similar +% but executes the body first and then performs the check, thus +% ensuring that the body is executed at least once. The "F" versions +% are similar but continue the loop as long as the test is false. They +% could be omitted as it is just a matter of switching the arguments +% in the test. +% \end{function} +% + +% \subsection{Conversion} +% +% \begin{function}{% +% \int_convert_from_base_ten:nn | +% } +% \begin{syntax} +% "\int_convert_from_base_ten:nn" "{""}""{""}" +% \end{syntax} +% Converts the base~10 number into its equivalent +% representation written in base~. Expandable. +% \end{function} +% +% +% \begin{function}{% +% \int_convert_to_base_ten:nn | +% } +% \begin{syntax} +% "\int_convert_to_base_ten:nn" "{""}""{""}" +% \end{syntax} +% Converts the base~ number into its equivalent +% representation written in base~10. can consist of digits +% and ascii letters. Expandable. +% \end{function} +% +% +% \StopEventually{} +% \subsection{The Implementation} +% % -% % We start by ensuring that the required packages are loaded. % \begin{macrocode} -%\RequirePackage{l3basics}\par -%\RequirePackage{l3chk}\par -%<*package> +%\RequirePackage{l3num} +%\RequirePackage{l3chk} +%<*initex|package> % \end{macrocode} % +% \begin{macro}{\int_to_roman:w} +% \begin{macro}{\int_to_number:w} +% \begin{macro}{\int_advance:w} +% A new name for the primitives. +% \begin{macrocode} +\let_new:NN \int_to_roman:w \tex_romannumeral:D +\let_new:NN \int_to_number:w \tex_number:D +\let_new:NN \int_advance:w \tex_advance:D +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} % Functions that support \LaTeX's user accessible counters should be % added here, too. But first the internal counters. % @@ -288,12 +446,12 @@ % Incrementing and decrementing of integer registers is done with % the following functions. % \begin{macrocode} -\def_new:Npn \int_incr:N #1{\tex_advance:D#1\c_one +\def_new:Npn \int_incr:N #1{\int_advance:w#1\c_one %<*check> \chk_local_or_pref_global:N #1 % } -\def_new:Npn \int_decr:N #1{\tex_advance:D#1\c_minus_one +\def_new:Npn \int_decr:N #1{\int_advance:w#1\c_minus_one %<*check> \chk_local_or_pref_global:N #1 % @@ -335,16 +493,22 @@ % % % \begin{macro}{\int_new:N} +% \begin{macro}{\int_new_l:N} % \begin{macro}{\int_new:c} % Allocation of a new internal counter is already done above. Here we define % the next likely variant. % \begin{macrocode} -\def_new:Npn \int_new:N {} % but since we don't distribute -\let:NN \int_new:N \newcount % allocation better nick the LaTeX one ... +%<*initex> +\alloc_setup_type:nnn {int} \c_eleven \c_max_register_num +\def_new:Npn \int_new:N #1 {\alloc_reg:NnNN g {int} \tex_countdef:D#1} +\def_new:Npn \int_new_l:N #1 {\alloc_reg:NnNN l {int} \tex_countdef:D#1} +% +%\let:NN \int_new:N \newcount% allocation better nick the LaTeX one... \def_new:Npn \int_new:c {\exp_args:Nc \int_new:N} % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} % % % \begin{macro}{\int_set:Nn} @@ -354,7 +518,7 @@ % Setting counters is again something that I would like to make % uniform at the moment to get a better overview. % \begin{macrocode} -\def_new:Npn \int_set:Nn #1#2{#1#2\scan_stop: +\def_new:Npn \int_set:Nn #1#2{#1 \int_eval:w #2\scan_stop: %<*check> \chk_local_or_pref_global:N #1 % @@ -373,6 +537,21 @@ % \end{macro} % \end{macro} % +% \begin{macro}{\int_zero:N} +% \begin{macro}{\int_zero:c} +% \begin{macro}{\int_gzero:N} +% \begin{macro}{\int_gzero:c} +% Functions that reset an \m{int} register to zero. +% \begin{macrocode} +\def_new:Npn \int_zero:N #1 {#1=\c_zero} +\def_new:Npn \int_zero:c #1 {\exp_args:Nc \int_zero:N} +\def_new:Npn \int_gzero:N #1 {\pref_global:D #1=\c_zero} +\def_new:Npn \int_gzero:c {\exp_args:Nc \int_gzero:N} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % \begin{macro}{\int_add:Nn} % \begin{macro}{\int_add:cn} @@ -383,14 +562,19 @@ % We should think of using these functions % \begin{macrocode} \def_new:Npn \int_add:Nn #1#2{ - \tex_advance:D#1#2\scan_stop: +% \end{macrocode} +% We need to say |by| in case the first argument is a register +% accessed by its number, e.g., |\count23|. Not that it should +% ever happen but\dots +% \begin{macrocode} + \int_advance:w #1 by \int_eval:w #2\scan_stop: %<*check> \chk_local_or_pref_global:N #1 % } \def_new:Npn\int_add:cn{\exp_args:Nc\int_add:Nn} \def_new:Npn \int_sub:Nn #1#2{ - \tex_advance:D#1-#2\scan_stop: + \int_advance:w #1-\int_eval:w #2\scan_stop: %<*check> \chk_local_or_pref_global:N #1 % @@ -415,341 +599,649 @@ % \end{macro} % % -% \begin{macro}{\int_use:N} -% \begin{macro}{\int_use:c} +% \begin{macro}{\int_use:N} +% \begin{macro}{\int_use:c} % Here is how counters are accessed: % \begin{macrocode} \let_new:NN \int_use:N \tex_the:D \def_new:Npn \int_use:c #1{\int_use:N \cs:w#1\cs_end:} % \end{macrocode} -% \end{macro} -% \end{macro} - +% \end{macro} +% \end{macro} % -% \begin{macro}{\int_gincr:c} -% \begin{macro}{\int_gdecr:c} +% +% \begin{macro}{\int_gincr:c} +% \begin{macro}{\int_gdecr:c} % We also need \ldots % \begin{macrocode} \def_new:Npn \int_gincr:c {\exp_args:Nc \int_gincr:N} \def_new:Npn \int_gdecr:c {\exp_args:Nc \int_gdecr:N} % \end{macrocode} -% \end{macro} -% \end{macro} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\int_to_arabic:n} +% Nothing exciting here. +% \begin{macrocode} +\def_new:Npn \int_to_arabic:n #1{\int_to_number:w \int_eval:n{#1}} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\int_roman_lcuc_mapping:Nnn} +% Using \TeX's built-in feature for producing roman numerals has some +% surprising features. One is the the characters resulting from +% |\int_to_roman:w| have category code~12 so they may fail in +% certain comparison tests. Therefore we use a mapping from the +% character \TeX{} produces to the character we actually want which +% will give us letters with category code~11.% +% \begin{macrocode} +\def_new:Npn \int_roman_lcuc_mapping:Nnn #1#2#3{ + \def:cpn {int_to_lc_roman_#1:}{#2} + \def:cpn {int_to_uc_roman_#1:}{#3} +} +% \end{macrocode} +% \end{macro} +% Here are the default mappings. I haven't found any examples of say +% Turkish doing the mapping |i \i I| but at least there is a +% possibility for it if needed. Note: I have now asked a Turkish +% person and he tells me they do the |i I| mapping. +% \begin{macrocode} +\int_roman_lcuc_mapping:Nnn i i I +\int_roman_lcuc_mapping:Nnn v v V +\int_roman_lcuc_mapping:Nnn x x X +\int_roman_lcuc_mapping:Nnn l l L +\int_roman_lcuc_mapping:Nnn c c C +\int_roman_lcuc_mapping:Nnn d d D +\int_roman_lcuc_mapping:Nnn m m M +% \end{macrocode} +% For the delimiter we cheat and let it gobble its arguments instead. +% \begin{macrocode} +\int_roman_lcuc_mapping:Nnn Q \use_none:nn \use_none:nn +% \end{macrocode} +% +% \begin{macro}{\int_to_roman:n} +% \begin{macro}{\int_to_Roman:n} +% \begin{macro}{\int_to_roman_lcuc:NN} +% The commands for producing the lower and upper case roman numerals +% run a loop on one character at a time and also carries some +% information for upper or lower case with it. We put it through +% |\int_eval:n| first which is safer and more flexible. +% \begin{macrocode} +\def_new:Npn \int_to_roman:n #1 { + \exp_after:NN \int_to_roman_lcuc:NN \exp_after:NN l + \int_to_roman:w \int_eval:n {#1} Q +} +\def_new:Npn \int_to_Roman:n #1 { + \exp_after:NN \int_to_roman_lcuc:NN \exp_after:NN u + \int_to_roman:w \int_eval:n {#1} Q +} +\def_new:Npn \int_to_roman_lcuc:NN #1#2{ + \cs_use:c {int_to_#1c_roman_#2:} + \int_to_roman_lcuc:NN #1 +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% +% +% \begin{macro}{\int_convert_number_with_rule:nnN} +% This is our major workhorse for conversions. |#1| is the number we +% want converted, |#2| is the base number, and |#3| is the function +% converting the number. This function expects to receive a +% non-negative integer and as such is ideal for something using +% |\if_case:w| internally. +% +% The basic example is this: We want to convert the number 50 (|#1|) +% into an alphabetic equivalent |ax|. For the English language our +% list contains 26 elements so this is our argument |#2| while the +% function |#3| just turns |1| into |a|, |2| into |b|, etc. Hence our +% goal is to turn 50 into the sequence |#3{1}#1{24}| so what we do is +% to first divide 50 by 26 and truncating the result returning 1. +% Then before we execute this we call the function again but this time +% on the result of the remainder of the division. This goes on until +% the remainder is less than or equal to the base number where we just +% call the function |#3| directly on the number. +% +% We do a little pre-expansion of the arguments below as they +% otherwise have a tendency to grow quite large. +% \begin{macrocode} +\def:Npn \int_convert_number_with_rule:nnN #1#2#3{ + \int_compare:nNnTF {#1}>{#2} + { + \exp_args:No \int_convert_number_with_rule:nnN + { \int_use:N\int_div_truncate:nn {#1-1}{#2} }{#2} + #3 +% \end{macrocode} +% Note that we have to nudge our modulus function so it won't +% return~$0$ as that wouldn't work with |\if_case:w| when that +% expects a positive number to produce a letter. +% \begin{macrocode} + \exp_args:No #3 { \int_use:N\int_eval:n{1+\int_mod:nn {#1-1}{#2}} } + } + { \exp_args:No #3{ \int_use:N\int_eval:n{#1} } } +} +% \end{macrocode} +% As can be seen it is even simpler to convert to number systems +% that contain 0, since then we don't have to add or subtract 1 +% here and there. +% \end{macro} +% +% \begin{macro}{\int_alph_default_conversion_rule:n} +% \begin{macro}{\int_Alph_default_conversion_rule:n} +% Now we just set up a default conversion rule. Ideally every language +% should have one such rule, as say in Danish there are 29 letters in +% the alphabet. +% \begin{macrocode} +\def_new:Npn \int_alph_default_conversion_rule:n #1{ + \if_case:w #1 + \or: a\or: b\or: c\or: d\or: e\or: f + \or: g\or: h\or: i\or: j\or: k\or: l + \or: m\or: n\or: o\or: p\or: q\or: r + \or: s\or: t\or: u\or: v\or: w\or: x + \or: y\or: z + \fi: +} +\def_new:Npn \int_Alph_default_conversion_rule:n #1{ + \if_case:w #1 + \or: A\or: B\or: C\or: D\or: E\or: F + \or: G\or: H\or: I\or: J\or: K\or: L + \or: M\or: N\or: O\or: P\or: Q\or: R + \or: S\or: T\or: U\or: V\or: W\or: X + \or: Y\or: Z + \fi: +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macro}{\int_to_alph:n} +% \begin{macro}{\int_to_Alph:n} +% The actual functions are just instances of the generic function. The +% second argument of |\int_convert_number_with_rule:nnN| should of +% course match the number of |\or:|s in the conversion rule. +% \begin{macrocode} +\def_new:Npn \int_to_alph:n #1{ + \int_convert_number_with_rule:nnN {#1}{26} + \int_alph_default_conversion_rule:n +} +\def_new:Npn \int_to_Alph:n #1{ + \int_convert_number_with_rule:nnN {#1}{26} + \int_Alph_default_conversion_rule:n +} +% \end{macrocode} +% \end{macro} +% \end{macro} % +% \begin{macro}{\int_to_symbol:n} +% Turning a number into a symbol is also easy enough. +% \begin{macrocode} +\def_new:Npn \int_to_symbol:n #1{ + \mode_math:TF + { + \int_convert_number_with_rule:nnN {#1}{9} + \int_symbol_math_conversion_rule:n + } + { + \int_convert_number_with_rule:nnN {#1}{9} + \int_symbol_text_conversion_rule:n + } +} +% \end{macrocode} +% \end{macro} +% \begin{macro}{\int_symbol_math_conversion_rule:n} +% \begin{macro}{\int_symbol_text_conversion_rule:n} +% Nothing spectacular here. +% \begin{macrocode} +\def_new:Npn \int_symbol_math_conversion_rule:n #1 { + \if_case:w #1 + \or: * + \or: \dagger + \or: \ddagger + \or: \mathsection + \or: \mathparagraph + \or: \| + \or: ** + \or: \dagger\dagger + \or: \ddagger\ddagger + \fi: +} +\def_new:Npn \int_symbol_text_conversion_rule:n #1 { + \if_case:w #1 + \or: \textasteriskcentered + \or: \textdagger + \or: \textdaggerdbl + \or: \textsection + \or: \textparagraph + \or: \textbardbl + \or: \textasteriskcentered\textasteriskcentered + \or: \textdagger\textdagger + \or: \textdaggerdbl\textdaggerdbl + \fi: +} +% \end{macrocode} +% \end{macro} +% \end{macro} % % \begin{macro}{\l_tmpa_int} % \begin{macro}{\l_tmpb_int} % \begin{macro}{\l_tmpc_int} % \begin{macro}{\g_tmpa_int} % \begin{macro}{\g_tmpb_int} -% We provide two local and two global scratch counters, maybe we -% need more or less. Instead of using the allocation routines we -% partly allocate them by hand. -% \begin{macrocode} -\chk_new_cs:N \l_tmpa_int -% \end{macrocode} -% If it turns out that we don't need local counters then this -% register should be used for global counter. We might also think of -% using the |\l_last_alloc_fint| as a scratch register. +% \begin{macro}{\l_loop_int} +% We provide four local and two global scratch counters, maybe we +% need more or less. % \begin{macrocode} -\tex_countdef:D\l_tmpa_int 255 +\int_new:N \l_tmpa_int \int_new:N \l_tmpb_int \int_new:N \l_tmpc_int \int_new:N \g_tmpa_int \int_new:N \g_tmpb_int +\int_new:N \l_loop_int % a variable for use in loops (whilenum etc) % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} +% \end{macro} +% % -% \begin{macro}{\c_minus_one} -% \begin{macro}{\c_zero} -% \begin{macro}{\c_one} -% \begin{macro}{\c_two} -% \begin{macro}{\c_three} -% \begin{macro}{\c_four} -% \begin{macro}{\c_sixteen} -% \begin{macro}{\c_thirty_two} -% \begin{macro}{\c_twohundred_fifty_five} -% \begin{macro}{\c_twohundred_fifty_six} -% \begin{macro}{\c_thousand} -% \begin{macro}{\c_ten_thousand} -% \begin{macro}{\c_ten_thousand_one} -% \begin{macro}{\c_ten_thousand_two} -% \begin{macro}{\c_ten_thousand_three} -% \begin{macro}{\c_ten_thousand_four} -% \begin{macro}{\c_twenty_thousand} -% \begin{macro}{\c_int_max} -% And the usual constants, others are still missing. Please, make -% every constant a real constant at least for the moment. We can -% easily convert things in the end when we have found what -% constants are used in critical places and what not. +% \begin{macro}{\int_eval:n} +% \begin{macro}{\int_eval:w} +% Evaluating a calc expression using normal operators. Many of these +% are exactly the same as the ones in the \textsf{num} module so we +% just use them. % \begin{macrocode} -\tex_chardef:D \c_zero = 0 \scan_stop: -\tex_chardef:D \c_one = 1 \scan_stop: -\tex_chardef:D \c_two = 2 \scan_stop: -\tex_chardef:D \c_three = 3 \scan_stop: -\tex_chardef:D \c_four = 4 \scan_stop: -\tex_chardef:D \c_sixteen = 16 \scan_stop: -\tex_chardef:D \c_thirty_two = 32 \scan_stop: -\tex_chardef:D \c_twohundred_fifty_five = 255 \scan_stop: -\tex_mathchardef:D \c_twohundred_fifty_six = 256 \scan_stop: -\tex_mathchardef:D \c_thousand = 1000 \scan_stop: -\tex_mathchardef:D \c_ten_thousand = 10000 \scan_stop: -\tex_mathchardef:D \c_ten_thousand_one = 10001 \scan_stop: -\tex_mathchardef:D \c_ten_thousand_two = 10002 \scan_stop: -\tex_mathchardef:D \c_ten_thousand_three = 10003 \scan_stop: -\tex_mathchardef:D \c_ten_thousand_four = 10004 \scan_stop: -\tex_mathchardef:D \c_twenty_thousand = 20000 \scan_stop: -% already defined ... -%\int_new:N \c_minus_one -% \c_minus_one = -1 +\let_new:NN \int_eval:n \num_eval:n +\let_new:NN \int_eval:w \num_eval:w % \end{macrocode} -% The |\c_int_max| will be defined internally as the largest -% dimen. +% \end{macro} +% \end{macro} +% +% \begin{macro}{\c_max_int} +% The largest number allowed is $2^{31}-1$ % \begin{macrocode} -%\int_new:N \c_int_max -% \c_int_max = 2147483647 +\const_new:Nn \c_max_int {2147483647} % \end{macrocode} % \end{macro} +% +% \begin{macro}{\int_pre_eval_one_arg:Nn} +% \begin{macro}{\int_pre_eval_two_args:Nnn} +% These might be handy when handing down values to other +% functions. All they do is evaluate the number in advance. +% \begin{macrocode} +\def:Npn \int_pre_eval_one_arg:Nnn #1#2{\exp_args:No#1{\int_eval:w#2}} +\def:Npn \int_pre_eval_two_args:Nnn #1#2#3{ + \exp_args:Noo#1{\int_use:N\int_eval:w#2}{\int_use:N\int_eval:w#3} +} +% \end{macrocode} % \end{macro} % \end{macro} +% +% \begin{macro}{\int_div_truncate:nn} +% \begin{macro}{\int_div_round:nn} +% \begin{macro}{\int_mod:nn} +% \begin{macro}{\int_div_truncate_raw:nn} +% \begin{macro}{\int_div_round_raw:nn} +% \begin{macro}{\int_mod_raw:nn} +% As "\num_eval:w" rounds the result of a division we also +% provide a version that truncates the result. +% \begin{macrocode} +\def_new:Npn \int_div_truncate:nn { + \int_pre_eval_two_args:Nnn\int_div_truncate_raw:nn +} +\def_new:Npn \int_div_truncate_raw:nn #1#2 { + \int_eval:n{ (2*#1 - #2) / (2* #2) } +} +% \end{macrocode} +% For the sake of completeness: +% \begin{macrocode} +\def_new:Npn \int_div_round:nn { + \int_pre_eval_two_args:Nnn\int_div_round_raw:nn +} +\def_new:Npn \int_div_round_raw:nn #1#2 {\int_eval:n{#1/#2}} +% \end{macrocode} +% Finally there's the modulus operation. +% \begin{macrocode} +\def_new:Npn \int_mod:nn {\int_pre_eval_two_args:Nnn\int_mod_raw:nn} +\def_new:Npn \int_mod_raw:nn #1#2 { + \int_eval:n{ #1 - \int_div_truncate_raw:nn {#1}{#2} * #2 } +} +% \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} % \end{macro} +% +% +% \begin{macro}{\int_compare:nNnTF} +% \begin{macro}{\int_compare:nNnT} +% \begin{macro}{\int_compare:nNnF} +% Simple comparison tests. +% \begin{macrocode} +\let_new:NN \int_compare:nNnTF \num_compare:nNnTF +\let_new:NN \int_compare:nNnT \num_compare:nNnT +\let_new:NN \int_compare:nNnF \num_compare:nNnF +% \end{macrocode} % \end{macro} % \end{macro} % \end{macro} +% +% \begin{macro}{\int_compare_p:nNn} +% A predicate function. +% \begin{macrocode} +\let_new:NN \int_compare_p:nNn \num_compare_p:nNn +% \end{macrocode} % \end{macro} +% +% \begin{macro}{\int_if_odd_p:n} +% \begin{macro}{\int_if_odd:nTF} +% \begin{macro}{\int_if_odd:nT} +% \begin{macro}{\int_if_odd:nF} +% A predicate function. +% \begin{macrocode} +\def_new:Npn \int_if_odd_p:n #1 { + \if_num_odd:w \int_eval:n{#1} + \c_true + \else: + \c_false + \fi: +} +\def_test_function_new:npn {int_if_odd:n}#1{\if_num_odd:w \int_eval:n{#1}} +% \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} -% \end{macro} -% % -% Show token usage: +% \begin{macro}{\int_whiledo:nNnT} +% \begin{macro}{\int_whiledo:nNnF} +% \begin{macro}{\int_dowhile:nNnT} +% \begin{macro}{\int_dowhile:nNnF} +% These are quite easy given the above functions. The "while" versions +% test first and then execute the body. The "dowhile" does it the +% other way round. % \begin{macrocode} -% -%<*showmemory> -\showMemUsage -% +\def_new:Npn \int_whiledo:nNnT #1#2#3#4{ + \int_compare:nNnT {#1}#2{#3}{#4 \int_whiledo:nNnT {#1}#2{#3}{#4}} +} +\def_new:Npn \int_whiledo:nNnF #1#2#3#4{ + \int_compare:nNnF {#1}#2{#3}{#4 \int_whiledo:nNnF {#1}#2{#3}{#4}} +} +\def_new:Npn \int_dowhile:nNnT #1#2#3#4{ + #4 \int_compare:nNnT {#1}#2{#3}{\int_dowhile:nNnT {#1}#2{#3}{#4}} +} +\def_new:Npn \int_dowhile:nNnF #1#2#3#4{ + #4 \int_compare:nNnF {#1}#2{#3}{\int_dowhile:nNnF {#1}#2{#3}{#4}} +} % \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % -% \section{Fake registers} -% -% Fake registers are registers which implement \m{counter}s, -% \m{dimen}s, etc.\ which aren't used often and therefore don't need -% to run efficiently. One possible way of using them is to prepare certain -% registers this way, but |\let:NN| the mutator functions to real -% \m{counter}s as long as we have a sufficient number available. Now -% if we are making real large formats (by adding Pic\TeX, for example) -% we can turn them easily into fake registers and everything will work -% as before (only a bit slower). -% -% -% I haven't implemented anything besides counters so far, but \m{dimen} -% and \m{skip} present no principal problem and should probably be -% added. +% \subsubsection{Scanning and conversion} % -% \subsection{Fake counters} % -% \begin{macro}{\fint_new:N} -% A fake counter is internally a \m{muskip} register. A count value -% \m{x} is saved as \m{x}|mu| (more exactly as \m{x}|.0mu|) in this -% register. This means that fake counter values are far more -% restricted then usual counters, the largest value is 16383, -% i.e.\ the |pt| part of \TeX{}'s largest \m{dimen}. This could be -% changed by using more complicated conversion routines, but it -% might be all right in usual applications. +% Conversion between different numbering schemes requires meticulous +% work. A number can be preceeded by any number of |+| and/or |-|. We +% define a generic function which will return the sign and/or the +% remainder. % -% Of course, we should make sure that we don't reach the borders, -% otherwise the user will be faced by the surprising message that -% some dimension got to large. (Not done yet). +% \begin{macro}{\int_get_sign_and_digits:n} +% \begin{macro}{\int_get_sign:n} +% \begin{macro}{\int_get_digits:n} +% \begin{macro}{\int_get_sign_and_digits_aux:nNNN} +% \begin{macro}{\int_get_sign_and_digits_aux:oNNN} +% A number may be preceeded by any number of |+|s and |-|s. Start out +% by assuming we have a positive number. % \begin{macrocode} -%<*package> -\let_new:NN \fint_new:N \newmuskip % nicked from LaTeX +\def_new:Npn \int_get_sign_and_digits:n #1{ + \int_get_sign_and_digits_aux:nNNN {#1} \c_true \c_true \c_true +} +\def_new:Npn \int_get_sign:n #1{ + \int_get_sign_and_digits_aux:nNNN {#1} \c_true \c_true \c_false +} +\def_new:Npn \int_get_digits:n #1{ + \int_get_sign_and_digits_aux:nNNN {#1} \c_true \c_false \c_true +} % \end{macrocode} -% \end{macro} -% -% -% \begin{macro}{\fint_use:N} -% \begin{macro}{\fint_use_aux:w} -% To use the value of a fake counter we have to get rid of |.0mu| in -% an expandable way, since we want to allow constructions like -% \begin{verbatim} -% \if_num:w\fint_use:N \l_test_fint > 55\scan_stop: ... -%\end{verbatim} -% The simplest way I came up with (not much thinking behind) was -% using parameter matching. +% Now check the first character in the string. Only a |-| can change +% if a number is positive or negative, hence we reverse the boolean +% governing this. Then gobble the |-| and start over. % \begin{macrocode} -\def_new:Npn \fint_use:N {\exp_after:NN\fint_use_aux:w\the_internal:D} +\def_new:Npn \int_get_sign_and_digits_aux:nNNN #1#2#3#4{ + \tlist_if_head_eq_charcode:fNTF {#1} - + { + \bool_if:NTF #2 + { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} \c_false #3#4 } + { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} \c_true #3#4 } + } % \end{macrocode} -% In the |\fint_use_aux:w| function we remove the |.0mu| and pass the -% the result back into the input stream. The only thing we -% have to think of, is that both |mu| have category code 12 when -% they are returned by |\the_internal:D|. +% The other cases are much simpler since we either just have to gobble +% the |+| or exit immediately and insert the correct sign. % \begin{macrocode} -\tex_lccode:D`\!=`\m \tex_lccode:D`\?=`\u -\tex_lowercase:D{\def_new:Npn \fint_use_aux:w #1.0!?{#1}} -\tex_lccode:D`\!=0\scan_stop: \tex_lccode:D`\?=0\scan_stop: + { + \tlist_if_head_eq_charcode:fNTF {#1} + + { \int_get_sign_and_digits_aux:oNNN {\use_none:n #1} #2#3#4} + { % \end{macrocode} -% \end{macro} -% \end{macro} -% -% -% \begin{macro}{\fint_set:Nn} -% \begin{macro}{\fint_gset:Nn} -% The way both routines are set up, the second argument might be -% either a \m{normal integer}, or an internal register. +% The boolean |#3| is for printing the sign while |#4| is for printing +% the digits. % \begin{macrocode} -\def_new:Npn \fint_set:Nn #1#2{#1#2~mu\scan_stop: -%<*check> - \chk_local_or_pref_global:N #1 -% + \bool_double_if:NNnnnn #3#4 + { \bool_if:NF #2 - #1 } + { \bool_if:NF #2 - } + { #1 } { } + } + } +} +\def_new:Npn \int_get_sign_and_digits_aux:oNNN{ + \exp_args:No\int_get_sign_and_digits_aux:nNNN } -\def_new:Npn \fint_gset:Nn{ -%<*check> - \pref_global_chk: -% -%<-check> \pref_global:D - \fint_set:Nn} % \end{macrocode} % \end{macro} % \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} % % -% \begin{macro}{\fint_set_eq:NN} -% \begin{macro}{\fint_gset_eq:NN} -% We can easily set two fake counters equal to each other, but if -% fake counters and real counters are used, we have to use the -% slower |set| functions. +% \begin{macro}{\int_convert_from_base_ten:nn} +% \begin{macro}{\int_convert_from_base_ten_aux:nnn} +% \begin{macro}{\int_convert_from_base_ten_aux:non} +% \begin{macro}{\int_convert_from_base_ten_aux:fon} +% |#1| is the base 10 number to be converted to base |#2|. We split +% off the sign first, print if if there and then convert only the +% number. Since this is supposedly a base~10 number we can let \TeX\ +% do the reading of |+| and |-|. % \begin{macrocode} -\def_new:Npn \fint_set_eq:NN #1#2{#1#2 -%<*check> - \chk_local_or_pref_global:N #1\chk_var_or_const:N #2 -% +\def:Npn \int_convert_from_base_ten:nn#1#2{ + \num_compare:nNnTF {#1}<\c_zero + { + - \int_convert_from_base_ten_aux:non {} + { \int_use:N \int_eval:n {-#1} } + } + { + \int_convert_from_base_ten_aux:non {} + { \int_use:N \int_eval:n {#1} } + } + {#2} } -\def_new:Npn \fint_gset_eq:NN { -%<*check> - \pref_global_chk: -% -%<-check> \pref_global:D - \fint_set_eq:NN} % \end{macrocode} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\fint_add:Nn} -% \begin{macro}{\fint_gadd:Nn} -% \begin{macro}{\fint_sub:Nn} -% \begin{macro}{\fint_gsub:Nn} -% Adding and substracting; we make use of the fact that internally -% \TeX{} always use the same primitives to advance a register. +% The algorithm runs like this: +% \begin{enumerate} +% \item If the number \meta{num} is greater than \meta{base}, +% calculate modulus of \meta{num} and \meta{base} and carry that +% over for next round. The remainder is calculated as a truncated +% division of \meta{num} and \meta{base}. Start over with these new +% values. +% \item If \meta{num} is less than or equal to \meta{base} convert it +% to the correct symbol, print the previously calculated digits and +% exit. +% \end{enumerate} +% |#1| is the carried over result, |#2| the remainder and |#3| the +% base number. % \begin{macrocode} -\def_new:Npn \fint_add:Nn #1#2{\int_add:Nn#1{#2mu}} -\def_new:Npn \fint_gadd:Nn { -%<*check> - \pref_global_chk: -% -%<-check> \pref_global:D - \fint_add:Nn} -\def_new:Npn \fint_sub:Nn #1#2{\int_sub:Nn#1{#2mu}} -\def_new:Npn \fint_gsub:Nn { -%<*check> - \pref_global_chk: -% -%<-check> \pref_global:D - \fint_sub:Nn} +\def_new:Npn \int_convert_from_base_ten_aux:nnn#1#2#3{ + \num_compare:nNnTF {#2}<{#3} + { \int_convert_number_to_letter:n{#2} #1 } + { + \int_convert_from_base_ten_aux:fon + { + \int_convert_number_to_letter:n {\int_use:N\int_mod_raw:nn {#2}{#3}} + #1 + } + {\int_use:N \int_div_truncate_raw:nn{#2}{#3}} + {#3} + } +} +\def:Npn \int_convert_from_base_ten_aux:non{ + \exp_args:Nno\int_convert_from_base_ten_aux:nnn +} +\def:Npn \int_convert_from_base_ten_aux:fon{ + \exp_args:Nfo\int_convert_from_base_ten_aux:nnn +} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % \end{macro} +% \begin{macro}{\int_convert_number_to_letter:n} +% Turning a number for a different base into a letter or digit. +% \begin{macrocode} +\def:Npn \int_convert_number_to_letter:n #1{ \if_case:w \int_eval:w + #1-10\scan_stop: \exp_after:NN A \or: \exp_after:NN B \or: + \exp_after:NN C \or: \exp_after:NN D \or: \exp_after:NN E \or: + \exp_after:NN F \or: \exp_after:NN G \or: \exp_after:NN H \or: + \exp_after:NN I \or: \exp_after:NN J \or: \exp_after:NN K \or: + \exp_after:NN L \or: \exp_after:NN M \or: \exp_after:NN N \or: + \exp_after:NN O \or: \exp_after:NN P \or: \exp_after:NN Q \or: + \exp_after:NN R \or: \exp_after:NN S \or: \exp_after:NN T \or: + \exp_after:NN U \or: \exp_after:NN V \or: \exp_after:NN W \or: + \exp_after:NN X \or: \exp_after:NN Y \or: \exp_after:NN Z \else: + \use_arg_i_after_fi:nw{ #1 }\fi: } +% \end{macrocode} +% \end{macro} % -% \begin{macro}{\fint_incr:N} -% \begin{macro}{\fint_gincr:N} -% \begin{macro}{\fint_decr:N} -% \begin{macro}{\fint_gdecr:N} -% Incrementing and decrementing the fake counters: +% \begin{macro}{\int_convert_to_base_ten:nn} +% |#1| is the number, |#2| is its base. First we get the sign, then +% use only the digits/letters from it and pass that onto a new +% function. % \begin{macrocode} -\def_new:Npn \fint_incr:N #1{\advance:D#1\c_one mu\scan_stop: -%<*check> - \chk_local_or_pref_global:N #1 -% +\def:Npn \int_convert_to_base_ten:nn #1#2 { + \int_use:N\int_eval:n{ + \int_get_sign:n{#1} + \exp_args:Nf\int_convert_to_base_ten_aux:nn {\int_get_digits:n{#1}}{#2} + } } -\def_new:Npn \fint_decr:N #1{\advance:D#1\c_minus_one mu\scan_stop: -%<*check> - \chk_local_or_pref_global:N #1 -% +% \end{macrocode} +% This is an intermediate function to get things started. +% \begin{macrocode} +\def_new:Npn \int_convert_to_base_ten_aux:nn #1#2{ + \int_convert_to_base_ten_auxi:nnN {0}{#2} #1 \q_nil } -\def_new:Npn \fint_gincr:N { -%<*check> - \pref_global_chk: -% -%<-check> \pref_global:D - \fint_incr:N} -\def_new:Npn \fint_gdecr:N { -%<*check> - \pref_global_chk: -% -%<-check> \pref_global:D - \fint_decr:N} % \end{macrocode} -% This can be achieved with less tokens but extra expansions: +% Here we check each letter/digit and calculate the next number. |#1| +% is the previously calculated result (to be multiplied by the base), +% |#2| is the base and |#3| is the next letter/digit to be added. % \begin{macrocode} -\def:Npn \fint_incr:N #1{\fint_add:Nn#1\c_one} -\def:Npn \fint_decr:N #1{\fint_add:Nn#1\c_minus_one} +\def_new:Npn \int_convert_to_base_ten_auxi:nnN#1#2#3{ + \quark_if_nil:NTF #3 + {#1} + {\exp_args:No\int_convert_to_base_ten_auxi:nnN + {\int_use:N \int_eval:n{ #1*#2+\int_convert_letter_to_number:N #3} } + {#2} + } +} % \end{macrocode} -% \end{macro} -% \end{macro} -% \end{macro} -% \end{macro} -% -% \begin{macro}{\c_fint_max} -% A constant, denoting the largest possible value for fake counters. +% This is for turning a letter or digit into a number. This function +% also takes care of handling lowercase and uppercase letters. Hence +% |a| is turned into |11| and so is |A|. % \begin{macrocode} -\tex_mathchardef:D\c_fint_max=16383 \scan_stop: +\def:Npn \int_convert_letter_to_number:N #1{ + \int_compare:nNnTF{`#1}<{58}{#1} + { + \int_eval:n{ `#1 - + \if:w\int_compare_p:nNn{`#1}<{91} + 55 + \else: + 87 + \fi: + } + } +} % \end{macrocode} % \end{macro} % % -% \subsection{Fake skip registers} % -% One has to convert simply from the \m{x}|pt| |plus| \m{y}|pt| |minus| -% \m{z}|pt| representation produced by |\the_internal:D|, to the -% corresponding |mu| representation. Complications arise from the -% possibility that |plus| and/or |minus| is not present,\footnote{This -% can be catched by adding a suitable constant and removing the -% corresponding constant in the other representation.} and by the -% possibility that the stretch or shrink component is a |fil| unit. % -% \subsection{Fake dimen registers} % -% I suppose this could be viewed as a subcase of the skip registers. -% See later section for a fake fake version for the moment. % % -% \subsection{Allocation routines} -% -% Counters are rare goods in \TeX{} and we are near the limit, if -% for example \LaTeX{} and Pic\TeX{} are merged. Therefore we should -% be careful not to throw away counter registers unnecessarily. One -% place for instance, where we can save some of them are the -% allocation routines. Instead of using counters we maintain the -% number of the last allocated register in a fake counter. -% -% +% Show token usage: % \begin{macrocode} -% +% %<*showmemory> \showMemUsage % % \end{macrocode} - +% +% +% \endinput +% +% $Log$ +% Revision 1.26 2006/06/03 17:17:08 morten +% Functions for converting between number bases +% +% Revision 1.25 2006/03/20 18:26:35 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.24 2006/01/17 22:47:43 morten +% Changed \int_while:nNnT to \int_whiledo:nNnT to avoid confusion with +% the dowhile versions. +% +% Revision 1.23 2005/12/27 10:02:37 morten +% Minor changes plus changed RCS information retrieval +% +% Revision 1.22 2005/12/21 20:43:32 morten +% Fixed silly bugs! +% +% Revision 1.21 2005/12/06 17:31:23 morten +% fixed \int_convert_number_with_rule:nnN +% +% Revision 1.20 2005/12/06 14:49:36 morten +% Fixed primitive names plus a few minor touch-ups +% +% Revision 1.19 2005/04/25 15:02:47 morten +% Added ifodd functions +% +% Revision 1.18 2005/04/09 21:07:39 morten +% Added (extensible) implementations of \int_to_roman:n etc. +% +% Revision 1.17 2005/04/06 22:35:43 braams +% Now we have register allocation fitted +% +% Revision 1.16 2005/03/25 23:48:47 braams +% Added a missing \end{macro} +% +% Revision 1.15 2005/03/22 23:22:09 morten +% Moved definitions of constants to l3num +% +% Revision 1.14 2005/03/16 22:36:30 braams +% Added the tweaks necessary to be able to load with initex +% +% Revision 1.13 2005/03/11 21:38:31 braams +% Fixed the use of RCS information; added \StopEventually +% diff --git a/Master/texmf-dist/source/latex/expl3/l3io.dtx b/Master/texmf-dist/source/latex/expl3/l3io.dtx index ae155f4d2b3..04efa42b8d7 100644 --- a/Master/texmf-dist/source/latex/expl3/l3io.dtx +++ b/Master/texmf-dist/source/latex/expl3/l3io.dtx @@ -1,15 +1,50 @@ % \iffalse -%% File: l3io.dtx Copyright (C) 1990-1998 LaTeX3 project -% +%% File: l3io.dtx Copyright (C) 1990-2006 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. +%% +%% ----------------------------------------------------------------------- +% +%\RequirePackage{l3names} %<*dtx> - \ProvidesFile{l3io.dtx} +%\fi +\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{% + \def\fileversion{#2}% + \def\filedate{#3/#4/#5}% + \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]% +} +%\iffalse % -%\NeedsTeXFormat{LaTeX2e} -%\ProvidesPackage{l3io} -% \ProvidesFile{l3io.drv} -% \fi -% \ProvidesFile{l3io.dtx} - [1998/04/20 v1.0c L3 Experimental i/o module] +%\fi +\GetIdInfo$Id: l3io.dtx 573 2006-08-21 20:59:37Z morten $ + {L3 Experimental i/o module} % % \iffalse %<*driver> @@ -233,13 +268,6 @@ % prompting. % \end{variable} % -% \begin{variable}{\g_iow_newline_code} -% Global variable holding the character number of the character that -% denotes a new line when something is written to an output stream. -% \begin{texnote} -% A.k.a \tn{newlinechar}. -% \end{texnote} -% \end{variable} % % \subsection{Internal functions} % @@ -264,14 +292,15 @@ % \end{texnote} % \end{function} % +% \StopEventually{} % -% \section{Lowlevel i/o-commands} +% \subsection{The Implementation} % % We start by ensuring that the required packages are loaded. % \begin{macrocode} %\RequirePackage{l3chk}\par %\RequirePackage{l3toks}\par -%<*package> +%<*initex|package> % \end{macrocode} % % This section is primarily concerned with input and output streams. @@ -279,7 +308,7 @@ % (for write) as module names. e.g.\ |\c_ior_test_stream| is an input stream % variable called `test'. % -% \subsection{Output streams} +% \subsubsection{Output streams} % % \begin{macro}{\iow_new:N} % \begin{macro}{\iow_new:c} @@ -287,8 +316,11 @@ % As we currently do not distribute a new allocation module we nick % the |\newwrite| function. % \begin{macrocode} -\def_new:Npn \iow_new:N {} -\let:NN \iow_new:N \newwrite +%<*initex> +\alloc_setup_type:nnn {iow} \c_zero \c_sixteen +\def_new:Npn \iow_new:N #1 {\alloc_reg:NnNN g {iow} \tex_chardef:D #1} +% +%\let:NN \iow_new:N \newwrite \def_new:Npn \iow_new:c {\exp_args:Nc \iow_new:N} % \end{macrocode} % \end{macro} @@ -301,7 +333,7 @@ % are provided. The streams are opened immediately. % % From some bad experiences on the mainframe, I learned that it is -% better to force the close before opening a dataset for writing. +% better to force the close before opening a dataset for writing. % We have to check whether this is also necessary in case of % |\tex_openin:D|. % \begin{macrocode} @@ -337,7 +369,7 @@ % \end{macro} % \end{macro} % -% \subsubsection{Immediate writing} +% \paragraph{Immediate writing} % % \begin{macro}{\iow_expanded:Nn} % An abbreviation for an often used operation, which immediately @@ -353,8 +385,8 @@ % If the first argument is no output stream at all, we get an % internal error. % \begin{macrocode} -\def_new:Npn \iow_unexpanded:Nn #1#2{\toks_gset:Nn \g_tmpa_toks {#2} - \iow_expanded:Nn #1{\toks_use:N \g_tmpa_toks}} +\def_new:Npn \iow_unexpanded:Nn #1#2{ + \iow_expanded:Nn #1{\exp_not:n{#2}}} % \end{macrocode} % \end{macro} % @@ -391,7 +423,7 @@ \def_new:Npn \iow_unexpanded_if_avail:Nn #1{ % \end{macrocode} % In this routine we have to check whether or not the output stream -% that was requested is defined at all. +% that was requested is defined at all. % So we check if the name is still free. % \begin{macrocode} \cs_free:NTF #1\use_none:n {\iow_unexpanded:Nn #1}} @@ -422,10 +454,10 @@ % % \begin{macrocode} \def_new:Npn \iow_long_expanded_aux:w #1#2#3{ - \group_begin:\g_iow_newline_code`\ #1#2{#3}\group_end:} -\def_new:Npn \iow_long_expanded:Nn {\iow_long_expanded_aux:w + \group_begin:\tex_newlinechar:D`\ #1#2{#3}\group_end:} +\def_new:Npn \iow_long_expanded:Nn {\iow_long_expanded_aux:w \iow_expanded:Nn} -\def_new:Npn \iow_long_unexpanded:Nn {\iow_long_expanded_aux:w +\def_new:Npn \iow_long_unexpanded:Nn {\iow_long_expanded_aux:w \iow_unexpanded:Nn} % \end{macrocode} % \end{macro} @@ -433,7 +465,10 @@ % \end{macro} % % -% \subsubsection{Deferred writing} +% \paragraph{Deferred writing} +% +% With \eTeX\ available deferred writing is easy. The comments below +% are old. % % Deferred writing to output streams is a bit more complicated because % there seems to be no nice hack for writing unexpanded. The only @@ -459,24 +494,35 @@ % Now the harder part: % \begin{macrocode} \def_new:Npn \iow_deferred_unexpanded:Nn #1#2{ - \tlp_set:Nn \l_tmpa_tlp {#2} - \tlp_set:Nx \l_tmpb_tlp - {\iow_deferred_expanded:Nn #1{\tlp_to_str:N \l_tmpa_tlp}} - \l_tmpb_tlp} + \iow_deferred_expanded:Nn{\exp_not:n{#2}} +} +%% Old implementation: +%\def_new:Npn \iow_deferred_unexpanded:Nn #1#2{ +% \tlp_set:Nn \l_tmpa_tlp {#2} +% \tlp_set:Nx \l_tmpb_tlp +% {\iow_deferred_expanded:Nn #1{\tlp_to_str:N \l_tmpa_tlp}} +% \l_tmpb_tlp} % \end{macrocode} % \end{macro} % % Long forms of these functions are not possible since the deferred -% writing will restore the value of |\g_iow_newline_code| before it will have +% writing will restore the value of |\tex_newlinechar:D| before it will have % a chance to act. But on the other hand it is nevertheless possible -% to make all deferred writes long by setting the |\g_iow_newline_code| +% to make all deferred writes long by setting the |\tex_newlinechar:D| % inside the output routine just before the |\tex_shipout:D|. The only % disadvantage of this method is the fact that messages to the % terminal during this time will also then break at spaces. But we % should consider this. % -% \subsubsection{Special characters for writing} +% \paragraph{Special characters for writing} % +% \begin{macro}{\iow_newline:} +% Global variable holding the character that forces a new line when +% something is written to an output stream. +% \begin{macrocode} +\def_new:Npn \iow_newline: {^^J} +% \end{macrocode} +% \end{macro} % % \begin{macro}{\c_iow_comment_char} % \begin{macro}{\c_iow_lbrace_char} @@ -485,44 +531,46 @@ % achieve this by defining global constants to expand into a version of % these characters with |\tex_catcode:D|${}=12$. % \begin{macrocode} -\tex_catcode:D `\%= 12 \scan_stop: -\tlp_new:Nn \c_iow_comment_char {%} -\tex_catcode:D `\%= 14 \scan_stop: +\tlp_new:Nx \c_iow_comment_char {\cs_to_str:N\%} % \end{macrocode} % To avoid another allocation function which is probably only % necessary here we use the |\def:Npx| command directly. % \begin{macrocode} -\tlp_new:Nn \c_iow_lbrace_char{} -\tlp_new:Nn \c_iow_rbrace_char{} -\def:Npx\c_iow_lbrace_char {\token_to_string:N{} -\def:Npx\c_iow_rbrace_char {\token_to_string:N}} +\tlp_new:Nx \c_iow_lbrace_char{\cs_to_str:N\{} +\tlp_new:Nx \c_iow_rbrace_char{\cs_to_str:N\}} % \end{macrocode} % \end{macro} % \end{macro} % \end{macro} % % -% \subsection{Input streams} +% \subsubsection{Input streams} % % \begin{macro}{\ior_new:N} % Allocation of new input streams is done by this function. % As we currently do not distribute a new allocation module we nick % the |\newwread| function. % \begin{macrocode} -\def_new:Npn \ior_new:N {} -\let:NN \ior_new:N \newread +%<*initex> +\alloc_setup_type:nnn {ior} \c_zero \c_sixteen +\def_new:Npn \ior_new:N #1 {\alloc_reg:NnNN g {ior} \tex_chardef:D #1} +% +%\let:NN \ior_new:N \newread % \end{macrocode} % \end{macro} % % \begin{macro}{\ior_open:Nn} +% \begin{macro}{\ior_close:Nn} % Processing of input-streams (via |\tex_openin:D| and |closein|) is % always `immediate' as far as \TeX{} is concerned. An extra % |\tex_immediate:D| is silently ignored. % \begin{macrocode} +\let:NN \ior_close:N \tex_closein:D \def_new:Npn \ior_open:Nn #1#2{\ior_close:N #1\scan_stop: \tex_openin:D#1#2\scan_stop:} % \end{macrocode} % \end{macro} +% \end{macro} % % \begin{macro}{\ior_eof:NTF} % |\ior_eof:NTF | \m{stream} \m{true case} \m{false case}. To @@ -530,19 +578,22 @@ % conditional is provided: % \begin{macrocode} \def_new:Npn \ior_eof:NTF #1{\if_eof:w#1 - \exp_after:NN\use_choice_i:nn \else: - \exp_after:NN\use_choice_ii:nn \fi:} + \exp_after:NN\use_arg_i:nn \else: + \exp_after:NN\use_arg_ii:nn \fi:} % \end{macrocode} % \end{macro} % % \begin{macro}{\ior_eof:NF} +% \begin{macro}{\if_eof:w} % |\ior_eof:NF | \m{stream} \m{false case}. Do something if % if there is still something to read from this file: % \begin{macrocode} +\let:NN \if_eof:w \tex_ifeof:D \def_new:Npn \ior_eof:NF #1{\if_eof:w#1 - \exp_after:NN \use_none:nn \fi: \use:n} + \exp_after:NN \use_none:nn \fi: \use_arg_i:n} % \end{macrocode} % \end{macro} +% \end{macro} % % % \begin{macro}{\ior_to:NN} @@ -567,11 +618,35 @@ % % Show token usage: % \begin{macrocode} -% +% %<*showmemory> \showMemUsage % % \end{macrocode} % +% \endinput +% +% $Log$ +% Revision 1.16 2006/03/20 18:26:36 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.15 2005/12/27 09:51:27 morten +% Changed the use of RCS information +% +% Revision 1.14 2005/11/07 17:59:48 morten +% Fixed definition of \iow_newline: (moved it to the right place) +% +% Revision 1.13 2005/04/29 22:29:23 braams +% Replaced the undefined \g_iow_newline_code with \tex_newlinechar:D +% and added the definition for \iow_newline: +% +% Revision 1.12 2005/04/06 22:35:37 braams +% Now we have register allocation fitted +% +% Revision 1.11 2005/03/16 22:36:24 braams +% Added the tweaks necessary to be able to load with initex +% +% Revision 1.10 2005/03/11 21:39:10 braams +% Fixed the use of RCS information; added \StopEventually % - diff --git a/Master/texmf-dist/source/latex/expl3/l3keyval.dtx b/Master/texmf-dist/source/latex/expl3/l3keyval.dtx new file mode 100644 index 00000000000..8848946602a --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3keyval.dtx @@ -0,0 +1,666 @@ +% \iffalse +%% File: l3keyval.dtx Copyright (C) 2006 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. +%% +%% ----------------------------------------------------------------------- +%\RequirePackage{l3names} +%<*dtx> +%\fi +\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{% + \def\fileversion{#2}% + \def\filedate{#3/#4/#5}% + \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]% +} +%\iffalse +% +%\fi +\GetIdInfo$Id: l3keyval.dtx 573 2006-08-21 20:59:37Z morten $ + {L3 Experimental keyval processing} +% \iffalse +%<*driver> +\documentclass{l3doc} + +\begin{document} +\DocInput{l3keyval.dtx} +\end{document} +% +% \fi +% +% \title{The \textsf{l3keyval} package\thanks{This file +% has version number \fileversion, last +% revised \filedate.}\\ +% Key-value parsing} +% \author{\Team} +% \date{\filedate} +% \maketitle +% +% \section{Introduction} +% +% Currently, this module only provides functions for extracting keys +% and values from a list. How this information is used is up to the +% programmer. +% +% A \meta{keyval list} is a list consisting of +% \begin{verbatim} +% key 1 = value 1 , +% key 2 , +% key 3 = value 3 , +% \end{verbatim} +% +% The function names for retrieving the keys and values are long but +% explain what they do. All these functions start with the name +% |\KV_parse_|. If a value is surrounded by braces, one level (and +% only one) is removed from the value. This is useful if you need to +% input a value which contains |=| or |,|. There are two primary +% actions we can take on a \meta{keyval list}. +% \begin{itemize} +% \item A \meta{keyval list} can be sanitized so that top level active +% commas or equal signs are converted into catcode 12. When +% declaring templates in the preamble one can probably safely assume +% that there are no active commas or equals; these things should +% only be active in the document. The name for this is either +% |no_sanitize| or |sanitize|. +% \item Spaces on either side of a key or value can be trimmed. When +% using the \LaTeX3 programming interface, spaces are automatically +% ignored so there it would be a waste of time to search for extra +% spaces since there would be none. At the document level however, +% spaces must be removed. The name for this is either +% |no_space_removal| or |space_removal|. Note that when +% |space_removal| is called you get an additional option where you +% can decide if one level of braces should be stripped from the key +% and/or value; see the description of the boolean +% |\l_KV_remove_one_level_of_braces_bool| for details. +% \end{itemize} +% +% During the parsing process, keys or values are not expanded and no +% |#|s are doubled. When the parsing process is over, the keys and +% values are executed in the form +% \begin{quote} +% "\KV_key_value_elt:nn{key 1}{value 1}" \\ +% "\KV_key_no_value_elt:n{key 2}" \\ +% "\KV_key_value_elt:nn{key 3}{value 3}" +% \end{quote} +% It is up to the programmer to provide a suitable definition of these +% two functions before starting the parsing process. +% +% +% \subsection{Functions} +% +% +% +% +% \begin{function}{ +% \KV_parse_no_space_removal_no_sanitize:n | +% } +% \begin{syntax} +% "\KV_parse_no_space_removal_no_sanitize:n" "{""}" +% \end{syntax} +% Parses the keys and values literally. For use when spaces are +% ignored and |=| and |,| have normal catcodes. +% \end{function} +% +% \begin{function}{ +% \KV_parse_space_removal_no_sanitize:n | +% } +% \begin{syntax} +% "\KV_parse_space_removal_no_sanitize:n" "{""}" +% \end{syntax} +% As above but also removes spaces around keys and values. For use +% when spaces are not ignored. +% \end{function} +% +% \begin{function}{ +% \KV_parse_space_removal_sanitize:n | +% } +% \begin{syntax} +% "\KV_parse_space_removal_sanitize:n" "{""}" +% \end{syntax} +% As above but additionally also replaces top-level active |=| and +% |,| with harmless versions. +% \end{function} +% +% \begin{variable}{ +% \l_KV_remove_one_level_of_braces_bool | +% } +% \begin{syntax} +% \end{syntax} +% This boolean controls whether or not one level of braces is +% stripped from the key and value. The default value for this +% boolean is \meta{true} so that exactly one level of braces is +% stripped. For certain applications it is desirable to keep the +% braces in which case the programmer just has to set the boolean +% false temporarily. Setting this boolean has no effect when you +% call the |no_space_removal| functions since not stripping braces +% is a rare request and would clutter the otherwise elegant code of +% the |no_space_removal| functions for very little gain. If you need +% to preserve braces choose the slower |space_removal| functions. +% \end{variable} +% +% \begin{function}{ +% \KV_key_no_value_elt:n | +% \KV_key_value_elt:nn | +% } +% \begin{syntax} +% "\KV_key_no_value_elt:n" "{""}" \\ +% "\KV_key_value_elt:n" "{""}" "{""}" +% \end{syntax} +% Functions returned by the |\KV_parse_| functions. The default +% definition of these two functions is an error message! +% \end{function} +% +% +% \StopEventually{} +% +% \section{Implementation} +% +% +% We start by ensuring that the required packages are loaded. +% \begin{macrocode} +%<*package> +\RequirePackage{l3quark} +\RequirePackage{l3toks} +\RequirePackage{l3int} +\RequirePackage{l3token} +% +%<*initex|package> +% \end{macrocode} +% +% +% +% +% \begin{macro}{\l_KV_tmpa_tlp} +% \begin{macro}{\l_KV_tmpb_tlp} +% \begin{macro}{\c_KV_single_equal_sign_tlp} +% Various useful things. +% \begin{macrocode} +\tlp_new:Nn\l_KV_tmpa_tlp{} +\tlp_new:Nn\l_KV_tmpb_tlp{} +\tlp_new:Nn \c_KV_single_equal_sign_tlp{=} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\l_KV_parse_toks} +% \begin{macro}{\l_KV_currkey_toks} +% \begin{macro}{\l_KV_currval_toks} +% Some more useful things. +% \begin{macrocode} +\toks_new:N \l_KV_parse_toks +\toks_new:N \l_KV_currkey_toks +\toks_new:N \l_KV_currval_toks +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\l_KV_remove_one_level_of_braces_bool} +% A boolean to control +% \begin{macrocode} +\bool_new:N \l_KV_remove_one_level_of_braces_bool +\bool_set_true:N \l_KV_remove_one_level_of_braces_bool +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\KV_sanitize_outerlevel_active_equals:N} +% \begin{macro}{\KV_sanitize_outerlevel_active_commas:N} +% Some functions for sanitizing top level equals and commas. Replace +% |=|$\sb{13}$ and |,|$\sb{13}$ with |=|$\sb{12}$ and |,|$\sb{12}$ +% resp. +% \begin{macrocode} +\group_begin: +\char_set_catcode:nn{`\=}{13} +\char_set_catcode:nn{`\,}{13} +\char_set_lccode:nn{`\8}{`\=} +\char_set_lccode:nn{`\9}{`\,} +\tlist_to_lowercase:n{\group_end: +\def_new:Npn \KV_sanitize_outerlevel_active_equals:N #1{ + \tlp_replace_all_in:Nnn #1 = 8 +} +\def_new:Npn \KV_sanitize_outerlevel_active_commas:N #1{ + \tlp_replace_all_in:Nnn #1 , 9 +} +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% +% +% \begin{macro}{\KV_remove_surrounding_spaces:nw} +% \begin{macro}{\KV_remove_surrounding_spaces_auxi:w} +% \begin{macro}{\KV_remove_surrounding_spaces_auxii:w} +% \begin{macro}{\KV_set_key_element:w} +% \begin{macro}{\KV_set_value_element:w} +% The macro |\KV_remove_surrounding_spaces:Nw| removes a possible +% leading space plus a possible ending space from its second +% argument and stores it in the token register |#1|. +% +% Based on Around the Bend No.~15 but with some enhancements. For +% instance, this definition is purely expandable. +% +% We use a funny token |Q|$\sb3$ as a delimiter. +% \begin{macrocode} +\group_begin: +\char_set_catcode:nn{`\Q}{3} +% \end{macrocode} +% \begin{macrocode} +\gdef_long_new:Npn\KV_remove_surrounding_spaces:nw#1#2\q_nil{ +% \end{macrocode} +% The idea in this processing is to use a Q with strange catcode to +% remove a trailing space. But first, how to get this expansion going? +% +% If you have read the fine print in the \textsf{l3expan} module, +% you'll know that the |f| type expansion will expand until the first +% non-expandable token is seen and if this token is a space, it will +% be gobbled. Sounds useful for removing a leading space but we also +% need to make sure that it does nothing but removing that space! +% Therefore we prepend the argument to be trimmed with an +% |\exp_not:N|. Now why is that? |\exp_not:N| in itself is an +% expandable command so will allow the |f| expansion to continue. If +% the first token in the argument to be trimmed is a space, it will be +% gobbled and the expansion stop. If the first token isn't a space, +% the |\exp_not:N| turns it temporarily into |\scan_stop:| which is +% unexpandable. The processing stops but the token following directly +% after |\exp_not:N| is now back to normal. +% +% The function here allows you to insert arbitrary functions in the +% first argument but they should all be with an |f| type +% expansion. For the application in this module, we use +% |\toks_set:Nf|. +% +% Once the expansion has been kick-started, we apply +% |\KV_remove_surrounding_spaces_auxi:w| to the replacement text of +% |#2|, adding a leading |\exp_not:N|. Note that no braces are +% stripped off of the original argument. +% \begin{macrocode} + #1{\KV_remove_surrounding_spaces_auxi:w \exp_not:N#2Q~Q} +} +% \end{macrocode} +% |\KV_remove_surrounding_spaces_auxi:w| removes a trailing space if +% present, then calls |\KV_remove_surrounding_spaces_auxii:w| to clean +% up any leftover bizarre Qs. In order for +% |\KV_remove_surrounding_spaces_auxii:w| to work properly we need to +% put back a Q first. +% \begin{macrocode} +\gdef_long_new:Npn\KV_remove_surrounding_spaces_auxi:w#1~Q{ + \KV_remove_surrounding_spaces_auxii:w #1 Q +} +% \end{macrocode} +% Now all that is left to do is remove a leading space which should be +% taken care of by the function used to initiate the expansion. Simply +% return the argument before the funny Q. +% \begin{macrocode} +\gdef_long_new:Npn\KV_remove_surrounding_spaces_auxii:w#1Q#2{#1} +% \end{macrocode} +% Here are some specialized versions of the above. They do exactly +% what we want in one go. First trim spaces from the value and then +% put the result surrounded in braces onto |\l_KV_parse_toks|. +% \begin{macrocode} +\gdef_long_new:Npn\KV_add_value_element:w\q_stop#1\q_nil{ + \toks_set:Nf\l_KV_currval_toks { + \KV_remove_surrounding_spaces_auxi:w \exp_not:N#1Q~Q + } + \toks_put_right:No\l_KV_parse_toks{ + \exp_after:NN {\toks_use:N \l_KV_currval_toks} + } +} +% \end{macrocode} +% When storing the key we firstly remove spaces plus the prepended +% |\q_no_value|. +% \begin{macrocode} +\gdef_long_new:Npn\KV_set_key_element:w#1\q_nil{ + \toks_set:Nf\l_KV_currkey_toks + { + \exp_after:NN\KV_remove_surrounding_spaces_auxi:w + \exp_after:NN\exp_not:N\use_none:n #1Q~Q + } +% \end{macrocode} +% Afterwards we gobble an extra level of braces if that's what we are +% asked to do. +% \begin{macrocode} + \bool_if:NT \l_KV_remove_one_level_of_braces_bool + { + \toks_set:Nd \l_KV_currkey_toks{ + \exp_after:NN \KV_add_element_aux:w + \toks_use:N \l_KV_currkey_toks \q_nil + } + } +} +\group_end: +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\KV_add_element_aux:w} +% A helper function for fixing braces around keys and values. +% \begin{macrocode} +\def_long_new:Npn \KV_add_element_aux:w#1\q_nil{#1} +% \end{macrocode} +% \end{macro} +% +% +% Parse a list of keyvals, put them into list form with entries like +% |\KV_key_no_value_elt:n{key1}| and |\KV_key_value_elt:nn{key2}{val2}|. +% +% \begin{macro}{\KV_parse_sanitize_aux:n} +% The slow parsing algorithm sanitizes active commas and equal signs +% at the top level first. Then uses |#1| as inspector of each +% element in the comma list. +% \begin{macrocode} +\def_long_new:Npn \KV_parse_sanitize_aux:n #1{ + \group_begin: + \toks_clear:N \l_KV_parse_toks + \tlp_set:Nx\l_KV_tmpa_tlp{\exp_not:n{#1}} + \KV_sanitize_outerlevel_active_equals:N\l_KV_tmpa_tlp + \KV_sanitize_outerlevel_active_commas:N\l_KV_tmpa_tlp + \exp_after:NN \KV_parse_elt:w \exp_after:NN\q_no_value \l_KV_tmpa_tlp,\q_nil, +% \end{macrocode} +% We evaluate the parsed keys and values outside the group so the +% token register is restored to its previous value. +% \begin{macrocode} + \exp_after:NN\group_end: + \toks_use:N \l_KV_parse_toks +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\KV_parse_no_sanitize_aux:n} +% Like above but we don't waste time sanitizing. This is probably +% the one we will use for preamble parsing where catcodes of |=| and +% |,| are as expected! +% \begin{macrocode} +\def_long_new:Npn \KV_parse_no_sanitize_aux:n #1{ + \group_begin: + \toks_clear:N \l_KV_parse_toks + \KV_parse_elt:w \q_no_value #1,\q_nil, + \exp_after:NN\group_end: + \toks_use:N \l_KV_parse_toks +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\KV_parse_elt:w} +% This function will always have a |\q_no_value| stuffed in as the +% rightmost token in |#1|. In case there was a blank entry in the +% comma separated list we just run it again. The |\use_none:n| makes +% sure to gobble the quark |\q_no_value|. A similar test is made to +% check if we hit the end of the recursion. +% \begin{macrocode} +\def_long:Npn \KV_parse_elt:w #1,{ + \tlist_if_blank:oTF{\use_none:n #1} + { \KV_parse_elt:w \q_no_value } + { + \quark_if_nil:oF {\use_arg_ii:nn #1 } +% \end{macrocode} +% If we made it to here we can start parsing the key and value. When +% done try, try again. +% \begin{macrocode} + { + \KV_split_key_value_current:w #1==\q_nil + \KV_parse_elt:w \q_no_value + } + } +} +% \end{macrocode} +% \end{macro} +% +% +% \begin{macro}{\KV_split_key_value_current:w} +% The function called to split the keys and values. +% \begin{macrocode} +\let_new:NN \KV_split_key_value_current:w \ERROR +% \end{macrocode} +% \end{macro} +% +% We provide two functions for splitting keys and values. The reason +% being that most of the time, we should probably be in the special +% coding regime where spaces are ignored. Hence it makes no sense to +% spend time searching for extra space tokens and we can do the +% settings directly. When comparing these two versions (neither doing +% any sanitizing) the |no_space_removal| version is more than 40\% +% faster than |space_removal|. +% +% It is up to functions like |\DeclareTemplate| to check which catcode +% regime is active and then pick up the version best suited for it. +% +% +% +% \begin{macro}{\KV_split_key_value_space_removal:w} +% \begin{macro}{\KV_split_key_value_space_removal_detect_error:wTF} +% \begin{macro}{\KV_split_key_value_space_removal_aux:w} +% The code below removes extraneous spaces around the keys and +% values plus one set of braces around the entire value. +% +% Unlike the version to be used when spaces are ignored, this one +% only grabs the key which is everything up to the first = and save +% the rest for closer inspection. Reason is that if a user has +% entered |mykey={{myval}},| then the outer braces have already been +% removed before we even look at what might come after the key. So +% this is slightly more tedious (but only slightly) but at least it +% always removes only one level of braces. +% \begin{macrocode} +\def_long_new:Npn \KV_split_key_value_space_removal:w #1 = #2\q_nil{ +% \end{macrocode} +% First grab the key. +% \begin{macrocode} + \KV_set_key_element:w#1\q_nil +% \end{macrocode} +% Then we start checking. If only a key was entered, |#2| contains +% |=| and nothing else, so we test for that first. +% \begin{macrocode} + \tlp_set:Nx\l_KV_tmpa_tlp{\exp_not:n{#2}} + \tlp_if_eq:NNTF\l_KV_tmpa_tlp\c_KV_single_equal_sign_tlp +% \end{macrocode} +% Then we just insert the default key. +% \begin{macrocode} + { + \toks_put_right:No\l_KV_parse_toks{ + \exp_after:NN \KV_key_no_value_elt:n + \exp_after:NN {\toks_use:N\l_KV_currkey_toks} + } + } +% \end{macrocode} +% Otherwise we must take a closer look at what is left. The remainder +% of the original list up to the comma is now stored in |#2| plus an +% additional |==|, which wasn't gobbled during the initial reading of +% arguments. If there is an error then we can see at least one more +% |=| so we call an auxiliary function to check for this. +% \begin{macrocode} + { + \KV_split_key_value_space_removal_detect_error:wTF#2\q_no_value\q_nil + {\KV_split_key_value_space_removal_aux:w \q_stop #2} + {\ERROR} + } +} +% \end{macrocode} +% The error test. +% \begin{macrocode} +\def_long_new:Npn + \KV_split_key_value_space_removal_detect_error:wTF#1=#2#3\q_nil{ + \tlist_if_head_eq_meaning:nNTF{#3}\q_no_value +} +% \end{macrocode} +% Now we can start extracting the value. Recall that |#1| here starts +% with |\q_stop| so all braces are still there! First we try to see +% how much is left if we gobble three brace groups from |#1|. If |#1| +% is empty or blank, all three quarks are gobbled. If |#1| consists of +% exactly one token or brace group, only the latter quark is left. +% \begin{macrocode} +\def_long_new:Npn \KV_val_preserve_braces:NnN #1#2#3{{#2}} +\def_long_new:Npn\KV_split_key_value_space_removal_aux:w #1=={ + \tlp_set:Nx\l_KV_tmpa_tlp{\exp_not:o{\use_none:nnn#1\q_nil\q_nil}} + \toks_put_right:No\l_KV_parse_toks{ + \exp_after:NN \KV_key_value_elt:nn + \exp_after:NN {\toks_use:N\l_KV_currkey_toks} + } +% \end{macrocode} +% If there a blank space or nothing at all, |\l_KV_tmpa_tlp| is now +% completely empty. +% \begin{macrocode} + \tlp_if_empty:NTF\l_KV_tmpa_tlp +% \end{macrocode} +% We just put an empty value on the stack. +% \begin{macrocode} + { \toks_put_right:Nn\l_KV_parse_toks{{}} } + { +% \end{macrocode} +% If there was exactly one brace group or token in |#1|, +% |\l_KV_tmpa_tlp| is now equal to |\q_nil|. Then we can just pick it +% up as the second argument of |#1|. This will also take care of any +% spaces which might surround it. +% \begin{macrocode} + \quark_if_nil:NTF\l_KV_tmpa_tlp + { + \bool_if:NTF \l_KV_remove_one_level_of_braces_bool + { + \toks_put_right:No\l_KV_parse_toks{ + \exp_after:NN{\use_arg_ii:nnn #1\q_nil} + } + } + { + \toks_put_right:No\l_KV_parse_toks{ + \exp_after:NN{\KV_val_preserve_braces:NnN #1\q_nil} + } + } + } +% \end{macrocode} +% Otherwise we grab the value. +% \begin{macrocode} + { \KV_add_value_element:w #1\q_nil } + } +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% \end{macro} +% +% \begin{macro}{\KV_split_key_value_no_space_removal:w} +% This version is for when in the special coding regime where spaces +% are ignored so there is no need to do any fancy space hacks, +% however fun they may be. Since there are no spaces, a set of +% braces around a value is automatically stripped by \TeX. +% \begin{macrocode} +\def_long_new:Npn \KV_split_key_value_no_space_removal:w #1#2=#3=#4\q_nil{ + \tlp_set:Nn\l_KV_tmpa_tlp{#4} + \tlp_if_empty:NTF \l_KV_tmpa_tlp + { + \toks_put_right:Nn\l_KV_parse_toks{\KV_key_no_value_elt:n{#2}} + } + { + \tlp_if_eq:NNTF\c_KV_single_equal_sign_tlp\l_KV_tmpa_tlp + { + \toks_put_right:Nn\l_KV_parse_toks{\KV_key_value_elt:nn{#2}{#3}} + } + {\ERROR} + } +} +% \end{macrocode} +% \end{macro} +% +% +% +% \begin{macro}{\KV_key_no_value_elt:n} +% \begin{macro}{\KV_key_value_elt:nn} +% \begin{macrocode} +\def_long_new:Npn \KV_key_no_value_elt:n #1{\ERROR} +\def_long_new:Npn \KV_key_value_elt:nn #1#2{\ERROR} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% +% +% \begin{macro}{\KV_parse_no_space_removal_no_sanitize:n} +% Finally we can put all the things +% together. |\KV_parse_no_space_removal_no_sanitize:n| is the +% version that disallows unmatched conditional and does no space +% removal. +% \begin{macrocode} +\def_new:Npn \KV_parse_no_space_removal_no_sanitize:n { + \let:NN \KV_split_key_value_current:w \KV_split_key_value_no_space_removal:w + \KV_parse_no_sanitize_aux:n +} +% \end{macrocode} +% \end{macro} +% +% \begin{macro}{\KV_parse_space_removal_sanitize:n} +% \begin{macro}{\KV_parse_space_removal_no_sanitize:n} +% The other varieties can be defined in a similar manner. For the +% version needed at the document level, we can use this one. +% \begin{macrocode} +\def_new:Npn \KV_parse_space_removal_sanitize:n { + \let:NN \KV_split_key_value_current:w \KV_split_key_value_space_removal:w + \KV_parse_sanitize_aux:n +} +% \end{macrocode} +% For preamble use by the non-programmer this is probably best. +% \begin{macrocode} +\def_new:Npn \KV_parse_space_removal_no_sanitize:n { + \let:NN \KV_split_key_value_current:w \KV_split_key_value_space_removal:w + \KV_parse_no_sanitize_aux:n +} +% \end{macrocode} +% \end{macro} +% \end{macro} +% +% +% \begin{macrocode} +% +%<*showmemory> +\showMemUsage +% +% \end{macrocode} +% +% \endinput +% +% $Log$ +% Revision 1.4 2006/07/25 22:38:58 morten +% Removed spurious \exp_after:NN in \KV_add_value_element:w. Sigh. +% +% Revision 1.3 2006/07/25 22:34:03 morten +% Fixed silly bug in \KV_set_key_element:w plus clean-up of code +% +% Revision 1.2 2006/07/25 16:21:30 morten +% Allow values to contain unmatched conditionals such as `val +% \fi:'. Provide option to not strip any braces at all. +% +% Revision 1.1 2006/01/27 10:14:24 morten +% Initial version of keyval parser +% diff --git a/Master/texmf-dist/source/latex/expl3/l3messages.dtx b/Master/texmf-dist/source/latex/expl3/l3messages.dtx new file mode 100644 index 00000000000..5aea5a26d35 --- /dev/null +++ b/Master/texmf-dist/source/latex/expl3/l3messages.dtx @@ -0,0 +1,972 @@ +% \iffalse +%% File: l3messages.dtx Copyright (C) 1990-2006 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. +%% +%% ----------------------------------------------------------------------- +% +%\RequirePackage{l3names} +%\RequirePackage{l3basics} +%\RequirePackage{l3tlp} +%\RequirePackage{l3expan} +%\RequirePackage{l3num} +%\RequirePackage{l3io} +%\RequirePackage{l3int} +%\RequirePackage{l3toks} +%<*dtx> +%\fi +\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{% + \def\fileversion{#2}% + \def\filedate{#3/#4/#5}% + \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]% +} +%\iffalse +% +%\fi +\GetIdInfo$Id: l3messages.dtx 573 2006-08-21 20:59:37Z morten $ + {L3 Experimental LaTeX Messages module} +% +% \iffalse +%<*driver> +\documentclass{l3doc} + +\begin{document} +\DocInput{l3messages.dtx} +\end{document} +% +% \fi +% +% +% \section{Communicating with the user} +% +% Sometimes it is necesary to pass information back to the user +% about what is going on. The information can be just that, +% information, or it can be a warning that something might not +% happen to his expectation. It could also be that something has +% gone awry and that processing can't reliably continue without +% some help from the user. In such a case an error is signalled. +% When things are really bad, processing may have to stop as there +% is no way to enter additional commands that put things right +% again. In such a case we have a fatal error and the \LaTeX\ run +% will be aborted. +% +% \subsection{Displaying the information} +% +% First of all we need a couple of fairly low level functions that +% deal with the job of passing the information to the user. +% +% Real information is usually only written to the log file, while +% warnings are displayed on the screen as well. +% \begin{function}{% +% \err_info:nn | +% \err_warn:nn +% } +% \begin{syntax} +% "\err_info:nn" "{" "}" "{""}" +% \end{syntax} +% The will be written to the log file. When it contains +% the command "\err_newline:" a line break will occur and the new +% line will start with the . The function +% "\err_warn:nn" writes the message to the terminal as well. +% \end{function} +% When an erroneous situation is encountered, a message is +% displayed and the user is given the opportunity to enter some +% additional code in an attempt to put things right. He may first +% ask for some help, in which case some extra text will be +% displayed to him. +% \begin{function}{\err_interrupt:NNw} +% \begin{syntax} +% "\err_interrupt:NNw" %<*dtx> - \ProvidesFile{l3names.dtx} +%\fi +\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{% + \def\fileversion{#2}% + \def\filedate{#3/#4/#5}% + \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]% +} +%\iffalse % -%\NeedsTeXFormat{LaTeX2e} -%\ProvidesPackage{l3names} -% \ProvidesFile{l3names.drv} -% \fi -% \ProvidesFile{l3names.dtx} - [1998/04/20 v2.0b L3 Experimental Naming Scheme for TeX Primitives] +%\fi +\GetIdInfo$Id: l3names.dtx 577 2006-11-21 18:10:26Z morten $ + {L3 Experimental Naming Scheme for TeX Primitives} +% % % \iffalse %<*driver> \documentclass{l3doc} - \begin{document} \DocInput{l3names.dtx} \end{document} % % \fi % -% \GetFileInfo{l3names.dtx} % \title{The \textsf{l3names} package\thanks{This file % has version number \fileversion, last % revised \filedate.}\\ @@ -108,7 +159,7 @@ % token without any braces around it. % % \item[w] One or more arguments with ``weird'' syntax that one has -% to know by hard or better leave it alone. +% to know by heart or better leave it alone. % % \item[p] Denotes parameter text specification part, e.g.\^^M % |#1#2\q_stop#3|. @@ -132,9 +183,9 @@ % \end{description} % % One could perhaps envisage an extended system which allocated -% lettters to denote the various primitive argument types available in +% letters to denote the various primitive argument types available in % \TeX, however it seems that this just complicates the system -% withoutadding any real benefit, as these primitives would never be +% without adding any real benefit, as these primitives would never be % used in production code, as higher level packages should offer a % better interface. Thus the following letters, although they were % considered have not been used. ``D'' is used in most cases in @@ -223,17 +274,17 @@ % % \end{description} % -% +% % % \section{Modules} -% +% % Nearly all operations of \LaTeX3 are carried out by calling control % sequences. For better programming concepts many types of functions are % identified and gathered in modules. Functions in such modules starts % with special prefixes, for example "\tlp_" is the prefix for functions % dealing with token list pointers. -% -% +% +% % % \StopEventually{} % @@ -295,7 +346,7 @@ % \begin{macrocode} %<*initex> \long\def\name_undefine:N#1{ - \tex_let:D#1\tex_undefined:} + \tex_let:D#1\c_undefined} % % \end{macrocode} % @@ -303,7 +354,7 @@ %<*package> \DeclareOption{removeoldnames}{ \long\def\name_undefine:N#1{ - \tex_let:D#1\tex_undefined:}} + \tex_let:D#1\c_undefined}} % \end{macrocode} % % \begin{macrocode} @@ -342,7 +393,7 @@ \name_primitive:NN \/ \tex_italiccor:D \name_primitive:NN \- \tex_hyphen:D % \end{macrocode} -% +% % Now all the other primitives. % \begin{macrocode} \name_primitive:NN \let \tex_let:D @@ -473,6 +524,7 @@ \name_primitive:NN \textstyle \tex_textstyle:D \name_primitive:NN \scriptstyle \tex_scriptstyle:D \name_primitive:NN \scriptscriptstyle \tex_scriptscriptstyle:D +\name_primitive:NN \nonscript \tex_nonscript:D \name_primitive:NN \eqno \tex_eqno:D \name_primitive:NN \leqno \tex_leqno:D \name_primitive:NN \abovedisplayshortskip \tex_abovedisplayshortskip:D @@ -568,6 +620,7 @@ \name_primitive:NN \tolerance \tex_tolerance:D \name_primitive:NN \spaceskip \tex_spaceskip:D \name_primitive:NN \xspaceskip \tex_xspaceskip:D +\name_primitive:NN \parfillskip \tex_parfillskip:D \name_primitive:NN \everypar \tex_everypar:D \name_primitive:NN \prevgraf \tex_prevgraf:D \name_primitive:NN \spacefactor \tex_spacefactor:D @@ -667,13 +720,206 @@ \name_primitive:NN \mathcode \tex_mathcode:D % \end{macrocode} % +% +% +% +% Since \LaTeX3 will require at least the \eTeX{} extensions, +% we also rename the additional primitives. These are all +% given the prefix |\etex_|. +% \begin{macrocode} +\name_primitive:NN \ifdefined \etex_ifdefined:D +\name_primitive:NN \ifcsname \etex_ifcsname:D +\name_primitive:NN \unless \etex_unless:D +\name_primitive:NN \eTeXversion \etex_eTeXversion:D +\name_primitive:NN \eTeXrevision \etex_eTeXrevision:D +\name_primitive:NN \marks \etex_marks:D +\name_primitive:NN \topmarks \etex_topmarks:D +\name_primitive:NN \firstmarks \etex_firstmarks:D +\name_primitive:NN \botmarks \etex_botmarks:D +\name_primitive:NN \splitfirstmarks \etex_splitfirstmarks:D +\name_primitive:NN \splitbotmarks \etex_splitbotmarks:D +\name_primitive:NN \unexpanded \etex_unexpanded:D +\name_primitive:NN \detokenize \etex_detokenize:D +\name_primitive:NN \scantokens \etex_scantokens:D +\name_primitive:NN \showtokens \etex_showtokens:D +\name_primitive:NN \readline \etex_readline:D +\name_primitive:NN \tracingassigns \etex_tracingassigns:D +\name_primitive:NN \tracingscantokens \etex_tracingscantokens:D +\name_primitive:NN \tracingnesting \etex_tracingnesting:D +\name_primitive:NN \tracingifs \etex_tracingifs:D +\name_primitive:NN \currentiflevel \etex_currentiflevel:D +\name_primitive:NN \currentifbranch \etex_currentifbranch:D +\name_primitive:NN \currentiftype \etex_currentiftype:D +\name_primitive:NN \tracinggroups \etex_tracinggroups:D +\name_primitive:NN \currentgrouplevel \etex_currentgrouplevel:D +\name_primitive:NN \currentgrouptype \etex_currentgrouptype:D +\name_primitive:NN \showgroups \etex_showgroups:D +\name_primitive:NN \showifs \etex_showifs:D +\name_primitive:NN \interactionmode \etex_interactionmode:D +\name_primitive:NN \lastnodetype \etex_lastnodetype:D +\name_primitive:NN \iffontchar \etex_iffontchar:D +\name_primitive:NN \fontcharht \etex_fontcharht:D +\name_primitive:NN \fontchardp \etex_fontchardp:D +\name_primitive:NN \fontcharwd \etex_fontcharwd:D +\name_primitive:NN \fontcharic \etex_fontcharic:D +\name_primitive:NN \parshapeindent \etex_parshapeindent:D +\name_primitive:NN \parshapelength \etex_parshapelength:D +\name_primitive:NN \parshapedimen \etex_parshapedimen:D +\name_primitive:NN \numexpr \etex_numexpr:D +\name_primitive:NN \dimexpr \etex_dimexpr:D +\name_primitive:NN \glueexpr \etex_glueexpr:D +\name_primitive:NN \muexpr \etex_muexpr:D +\name_primitive:NN \gluestretch \etex_gluestretch:D +\name_primitive:NN \glueshrink \etex_glueshrink:D +\name_primitive:NN \gluestretchorder \etex_gluestretchorder:D +\name_primitive:NN \glueshrinkorder \etex_glueshrinkorder:D +\name_primitive:NN \gluetomu \etex_gluetomu:D +\name_primitive:NN \mutoglue \etex_mutoglue:D +\name_primitive:NN \lastlinefit \etex_lastlinefit:D +\name_primitive:NN \interlinepenalties \etex_interlinepenalties:D +\name_primitive:NN \clubpenalties \etex_clubpenalties:D +\name_primitive:NN \widowpenalties \etex_widowpenalties:D +\name_primitive:NN \displaywidowpenalties \etex_displaywidowpenalties:D +\name_primitive:NN \middle \etex_middle:D +\name_primitive:NN \savinghyphcodes \etex_savinghyphcodes:D +\name_primitive:NN \savingvdiscards \etex_savingvdiscards:D +\name_primitive:NN \pagediscards \etex_pagediscards:D +\name_primitive:NN \splitdiscards \etex_splitdiscards:D +\name_primitive:NN \TeXXETstate \etex_TeXXETstate:D +\name_primitive:NN \beginL \etex_beginL:D +\name_primitive:NN \endL \etex_endL:D +\name_primitive:NN \beginR \etex_beginR:D +\name_primitive:NN \endR \etex_endR:D +\name_primitive:NN \predisplaydirection \etex_predisplaydirection:D +\name_primitive:NN \everyeof \etex_everyeof:D +\name_primitive:NN \protected \etex_protected:D +% \end{macrocode} +% +% +% All major distributions\footnote{At the time of writing MiK\TeX\ +% does not but I have a gut feeling that will change.} use +% pdf\eTeX{} as engine so we add these names as well. Since the +% pdf\TeX{} team has been very good at prefixing most primitives +% with |pdf| (so far only five do not start with |pdf|) we do not +% give then a double |pdf| prefix. The list below covers pdf\TeX +% v~1.30.4. +% \begin{macrocode} +%% integer registers: +\name_primitive:NN \pdfoutput \pdf_output:D +\name_primitive:NN \pdfminorversion \pdf_minorversion:D +\name_primitive:NN \pdfcompresslevel \pdf_compresslevel:D +\name_primitive:NN \pdfdecimaldigits \pdf_decimaldigits:D +\name_primitive:NN \pdfimageresolution \pdf_imageresolution:D +\name_primitive:NN \pdfpkresolution \pdf_pkresolution:D +\name_primitive:NN \pdftracingfonts \pdf_tracingfonts:D +\name_primitive:NN \pdfuniqueresname \pdf_uniqueresname:D +\name_primitive:NN \pdfadjustspacing \pdf_adjustspacing:D +\name_primitive:NN \pdfprotrudechars \pdf_protrudechars:D +\name_primitive:NN \efcode \pdf_efcode:D +\name_primitive:NN \lpcode \pdf_lpcode:D +\name_primitive:NN \rpcode \pdf_rpcode:D +\name_primitive:NN \pdfforcepagebox \pdf_forcepagebox:D +\name_primitive:NN \pdfoptionalwaysusepdfpagebox \pdf_optionalwaysusepdfpagebox:D +\name_primitive:NN \pdfinclusionerrorlevel\pdf_inclusionerrorlevel:D +\name_primitive:NN \pdfoptionpdfinclusionerrorlevel \pdf_optionpdfinclusionerrorlevel:D +\name_primitive:NN \pdfimagehicolor \pdf_imagehicolor:D +\name_primitive:NN \pdfimageapplygamma \pdf_imageapplygamma:D +\name_primitive:NN \pdfgamma \pdf_gamma:D +\name_primitive:NN \pdfimagegamma \pdf_imagegamma:D +%% dimen registers: +\name_primitive:NN \pdfhorigin \pdf_horigin:D +\name_primitive:NN \pdfvorigin \pdf_vorigin:D +\name_primitive:NN \pdfpagewidth \pdf_pagewidth:D +\name_primitive:NN \pdfpageheight \pdf_pageheight:D +\name_primitive:NN \pdflinkmargin \pdf_linkmargin:D +\name_primitive:NN \pdfdestmargin \pdf_destmargin:D +\name_primitive:NN \pdfthreadmargin \pdf_threadmargin:D +%% token registers: +\name_primitive:NN \pdfpagesattr \pdf_pagesattr:D +\name_primitive:NN \pdfpageattr \pdf_pageattr:D +\name_primitive:NN \pdfpageresources \pdf_pageresources:D +\name_primitive:NN \pdfpkmode \pdf_pkmode:D +%% expandable commands: +\name_primitive:NN \pdftexrevision \pdf_texrevision:D +\name_primitive:NN \pdftexbanner \pdf_texbanner:D +\name_primitive:NN \pdfcreationdate \pdf_creationdate:D +\name_primitive:NN \pdfpageref \pdf_pageref:D +\name_primitive:NN \pdfxformname \pdf_xformname:D +\name_primitive:NN \pdffontname \pdf_fontname:D +\name_primitive:NN \pdffontobjnum \pdf_fontobjnum:D +\name_primitive:NN \pdffontsize \pdf_fontsize:D +\name_primitive:NN \pdfincludechars \pdf_includechars:D +\name_primitive:NN \leftmarginkern \pdf_leftmarginkern:D +\name_primitive:NN \rightmarginkern \pdf_rightmarginkern:D +\name_primitive:NN \pdfescapestring \pdf_escapestring:D +\name_primitive:NN \pdfescapename \pdf_escapename:D +\name_primitive:NN \pdfescapehex \pdf_escapehex:D +\name_primitive:NN \pdfunescapehex \pdf_unescapehex:D +\name_primitive:NN \pdfstrcmp \pdf_strcmp:D +\name_primitive:NN \pdfuniformdeviate \pdf_uniformdeviate:D +\name_primitive:NN \pdfnormaldeviate \pdf_normaldeviate:D +\name_primitive:NN \pdfmdfivesum \pdf_mdfivesum:D +\name_primitive:NN \pdffilemoddate \pdf_filemoddate:D +\name_primitive:NN \pdffilesize \pdf_filesize:D +\name_primitive:NN \pdffiledump \pdf_filedump:D +%% read-only integers: +\name_primitive:NN \pdftexversion \pdf_texversion:D +\name_primitive:NN \pdflastobj \pdf_lastobj:D +\name_primitive:NN \pdflastxform \pdf_lastxform:D +\name_primitive:NN \pdflastximage \pdf_lastximage:D +\name_primitive:NN \pdflastximagepages \pdf_lastximagepages:D +\name_primitive:NN \pdflastannot \pdf_lastannot:D +\name_primitive:NN \pdflastxpos \pdf_lastxpos:D +\name_primitive:NN \pdflastypos \pdf_lastypos:D +\name_primitive:NN \pdflastdemerits \pdf_lastdemerits:D +\name_primitive:NN \pdfelapsedtime \pdf_elapsedtime:D +\name_primitive:NN \pdfrandomseed \pdf_randomseed:D +\name_primitive:NN \pdfshellescape \pdf_shellescape:D +%% general commands: +\name_primitive:NN \pdfobj \pdf_obj:D +\name_primitive:NN \pdfrefobj \pdf_refobj:D +\name_primitive:NN \pdfxform \pdf_xform:D +\name_primitive:NN \pdfrefxform \pdf_refxform:D +\name_primitive:NN \pdfximage \pdf_ximage:D +\name_primitive:NN \pdfrefximage \pdf_refximage:D +\name_primitive:NN \pdfannot \pdf_annot:D +\name_primitive:NN \pdfstartlink \pdf_startlink:D +\name_primitive:NN \pdfendlink \pdf_endlink:D +\name_primitive:NN \pdfoutline \pdf_outline:D +\name_primitive:NN \pdfdest \pdf_dest:D +\name_primitive:NN \pdfthread \pdf_thread:D +\name_primitive:NN \pdfstartthread \pdf_startthread:D +\name_primitive:NN \pdfendthread \pdf_endthread:D +\name_primitive:NN \pdfsavepos \pdf_savepos:D +\name_primitive:NN \pdfinfo \pdf_info:D +\name_primitive:NN \pdfcatalog \pdf_catalog:D +\name_primitive:NN \pdfnames \pdf_names:D +\name_primitive:NN \pdfmapfile \pdf_mapfile:D +\name_primitive:NN \pdfmapline \pdf_mapline:D +\name_primitive:NN \pdffontattr \pdf_fontattr:D +\name_primitive:NN \pdftrailer \pdf_trailer:D +\name_primitive:NN \pdffontexpand \pdf_fontexpand:D +%%\name_primitive:NN \vadjust [
]  {  } (h, m)
+\name_primitive:NN \pdfliteral            \pdf_literal:D
+%%\name_primitive:NN \special 
+\name_primitive:NN \pdfresettimer         \pdf_resettimer:D    
+\name_primitive:NN \pdfsetrandomseed      \pdf_setrandomseed:D        
+\name_primitive:NN \pdfnoligatures        \pdf_noligatures:D      
+%    \end{macrocode}
+%
+% What about Omega and Aleph? The status of both are unclear but let's
+% start by adding a single primitive which we can use for testing if
+% we have one of these engines.
+%    \begin{macrocode}
+\name_primitive:NN \textdir             \aleph_textdir:D
+%    \end{macrocode}
 %  \begin{macro}{\CodeStart}
 %  \begin{macro}{\CodeStop}
 %    Here we define functions that are used to turn on and off the
-%    special conventions used in the kernel of \LaTeX3. 
+%    special conventions used in the kernel of \LaTeX3.
 %
 %    First of all, the space, tab and the return characters will all be
-%    ignored inside \LaTeX3 code. When space characters are needed in 
+%    ignored inside \LaTeX3 code. When space characters are needed in
 %    \LaTeX3 code the |~| character will be used for that purpose.
 %
 %    \begin{macrocode}
@@ -701,13 +947,72 @@
 %  \end{macro}
 %  \end{macro}
 %
-%  
+%  \begin{macro}{\NamesStart}
+%  \begin{macro}{\NamesStop}
+%    Sometimes we need to be able to use names from the kernel of
+%    \LaTeX3 without adhering it's conventions according to space
+%    characters. These macros provide the necessary settings.
+%    \begin{macrocode}
+\tex_def:D \NamesStart{
+  \tex_catcode:D `\_=11\scan_stop:
+  \tex_catcode:D `\:=11\scan_stop:
+  }
+\tex_def:D \NamesStop{
+  \tex_catcode:D `\_=8\scan_stop:
+  \tex_catcode:D `\:=12\scan_stop:
+  }
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%
+%    \begin{macrocode}
+%<*initex>
+\tex_def:D\GetIdInfo{\CodeStop\GetIdInfoAux}
+\tex_def:D\GetIdInfoAux$#1~#2.dtx~#3~#4-#5-#6~#7~#8$#9{%
+  \tex_immediate:D\tex_write:D-1{#2;~v#3,~#4/#5/#6;~#9}%
+  \CodeStart
+}
+%
+%    \end{macrocode}
+%
 % Finally some corrections in the case we are running over \LaTeXe.
 %
+% Every single experimental package should start by doing something
+% like this:
+% \begin{verbatim}
+% \RequirePackage{l3names}
+% \GetIdInfo$Id: l3names.dtx 577 2006-11-21 18:10:26Z morten $
+%           {L3 Experimental sequences and stacks}
+% \end{verbatim}
+% \emph{OR}
+% \begin{verbatim}
+% \RequirePackage{l3names}
+% \CodeStart
+% \end{verbatim}
+% Since we have to make |\GetIdInfo| stop the special catcode regime
+% when reading the package in order to get the information extracted
+% correctly, we might as well use it to also issue |\CodeStart|. This
+% also means that we automatically get |\CodeStart| issued at the
+% beginning of every package without tampering with |\ProvidesPackage|
+% which can cause problems when using these experimental packages with
+% code relying on characters having traditional catcodes, noticeably
+% the catcode of the space character. We cannot simply use the code
+% from the top of this file since it contains a call to |\def| which
+% may not exist at this point.
+%    \begin{macrocode}
+%<*package>
+\tex_def:D\GetIdInfo{\CodeStop\GetIdInfoAux}
+\tex_def:D\GetIdInfoAux$#1~#2.dtx~#3~#4-#5-#6~#7~#8$#9{%
+  \tex_def:D \fileversion{#3}%
+  \tex_def:D \filedate{#4/#5/#6}%
+  \ProvidesPackage{#2}[#4/#5/#6~ v#3~ #9]%
+  \CodeStart
+}
+%    \end{macrocode}
+%
 % A few of the `primitives' assigned above have already been stolen
 % by \LaTeX, so assign them by hand to the saved real primitive.
 %    \begin{macrocode}
-%<*package>
 \tex_let:D\tex_input:D        \@@input
 \tex_let:D\tex_underline:D    \@@underline
 \tex_let:D\tex_end:D          \@@end
@@ -723,40 +1028,20 @@
 \tex_let:D\par          \tex_par:D
 %    \end{macrocode}
 %
-% As mentioned above, The \LaTeXe\ package mechanism will insert some code
-% to handle the filename stack, and reset the package options, this
-% code will die if the \TeX\ primitives have gone, so skip past it
-% and insert some equivalent code that will work.
-%
-% First a version of |\ProvidesPackage| that can cope.
-%    \begin{macrocode}
-\tex_def:D\ProvidesPackage{
-  \tex_begingroup:D
-  \CodeStop
-  \package_provides:w}
-%    \end{macrocode}
 %
-%    \begin{macrocode}
-\tex_def:D\package_provides:w#1#2[#3]{
-  \tex_endgroup:D
-  \tex_immediate:D\tex_write:D-1{Package: #1#2 #3}
-  \tex_expandafter:D\tex_xdef:D
-    \tex_csname:D ver@#1.sty\tex_endcsname:D{}}
-%    \end{macrocode}
 %
 %    \begin{macrocode}
 \tex_ifx:D\name_undefine:N\@gobble
 %    \end{macrocode}
 %
 % Normally just set the catcodes, and let \LaTeXe\ handle the
-% package stack. If \LaTeXe\ resets @ reset the white space as well. 
+% package stack. If \LaTeXe\ resets @ reset the white space as well.
 %    \begin{macrocode}
   \tex_def:D\name_pop_stack:w{}
   \g@addto@macro\@popfilename{%
     \tex_ifnum:D12=\tex_the:D\tex_catcode:D`@
       \CodeStop
     \tex_fi:D}
-  \g@addto@macro\@pushfilename{\CodeStart}
 %    \end{macrocode}
 %
 %    \begin{macrocode}
@@ -765,9 +1050,30 @@
 %
 % But if traditional \TeX\ code is disabled, do this\ldots
 %
-% In this case the catcode preserving stack is not maintained and 
+% As mentioned above, The \LaTeXe\ package mechanism will insert some code
+% to handle the filename stack, and reset the package options, this
+% code will die if the \TeX\ primitives have gone, so skip past it
+% and insert some equivalent code that will work.
+%
+% First a version of |\ProvidesPackage| that can cope.
+%    \begin{macrocode}
+\tex_def:D\ProvidesPackage{
+  \tex_begingroup:D
+  \CodeStop
+  \package_provides:w}
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\tex_def:D\package_provides:w#1#2[#3]{
+  \tex_endgroup:D
+  \tex_immediate:D\tex_write:D-1{Package:~#1#2~#3}
+  \tex_expandafter:D\tex_xdef:D
+    \tex_csname:D ver@#1.sty\tex_endcsname:D{#1}}
+%    \end{macrocode}
+%
+% In this case the catcode preserving stack is not maintained and
 % |\CodeStart| conventions stay in force once on. You'll need
-% to turn then off explicitky with |\CodeStop| (although as currently
+% to turn then off explicitly with |\CodeStop| (although as currently
 % built on 2e, nothing except very experimental code will run in
 % this mode!) Also note that |\RequirePackage| is a simple definition, just for
 % one file, with no options.
@@ -791,14 +1097,15 @@
 %    \begin{macrocode}
   \tex_def:D\NeedsTeXFormat#1{}
   \tex_def:D\RequirePackage#1{
-      \tex_expandafter:D\tex_ifx:D
-        \tex_csname:D ver@#1.sty\tex_endcsname:D\tex_relax:D
-          \CodeStart
-          \tex_input:D#1.sty\tex_relax:D
-       \tex_fi:D}
+    \tex_expandafter:D\tex_ifx:D
+      \tex_csname:D ver@#1.sty\tex_endcsname:D\tex_relax:D
+        \CodeStart
+        \tex_input:D#1.sty\tex_relax:D
+    \tex_fi:D}
 \tex_fi:D
 %    \end{macrocode}
 %
+%
 % The |\futurelet| just forces the special end of file marker to vanish,
 % so the argument of |\name_pop_stack:w| does not cause an end-of-file
 % error. (Normally I use |\expandafter| for this trick, but here the next
@@ -808,3 +1115,36 @@
 %
 %    \end{macrocode}
 %
+% \endinput
+%
+%  $Log$
+%  Revision 1.17  2006/01/15 07:55:48  morten
+%  Fixed minor typo
+%
+%  Revision 1.16  2006/01/15 07:17:43  morten
+%  Imported \NamesStart and \NamesStop from l3messages.
+%
+%  Revision 1.15  2005/12/27 10:00:03  morten
+%  Changed RCS information retrieval, code to run as package under 2e
+%  changed slightly to not set special catcodes directly.
+%
+%  Revision 1.14  2005/12/01 22:58:16  morten
+%  Added pdfTeX primitives
+%
+%  Revision 1.13  2005/03/26 21:04:19  morten
+%  Fix typo.
+%
+%  Revision 1.12  2005/03/22 23:23:57  morten
+%  Added an Aleph primitive
+%
+%  Revision 1.11  2005/03/15 23:16:21  braams
+%  Some tweaking with the docstrip guards to get the documentation to
+%  come out right.
+%
+%  Revision 1.10  2005/03/15 22:48:31  braams
+%  Made it possible to load this as the very first file with initex
+%
+%  Revision 1.9  2005/03/11 21:29:56  braams
+%  Fixed the use of RCS information; moved definition of \eTeX
+%  to l3doc.cls
+%
diff --git a/Master/texmf-dist/source/latex/expl3/l3num.dtx b/Master/texmf-dist/source/latex/expl3/l3num.dtx
new file mode 100644
index 00000000000..e74c57db79b
--- /dev/null
+++ b/Master/texmf-dist/source/latex/expl3/l3num.dtx
@@ -0,0 +1,749 @@
+% \iffalse
+%% File: l3num.dtx Copyright (C) 2005-2006 Frank Mittelbach, 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.
+%%
+%% -----------------------------------------------------------------------
+%
+%\RequirePackage{l3names}
+%<*dtx>
+%\fi
+\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{%
+  \def\fileversion{#2}%
+  \def\filedate{#3/#4/#5}%
+  \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]%
+}
+%\iffalse
+%
+%\fi
+\GetIdInfo$Id: l3num.dtx 573 2006-08-21 20:59:37Z morten $
+       {L3 Experimental token numbers}
+%
+% \iffalse
+%<*driver>
+\documentclass{l3doc}
+
+\begin{document}
+\DocInput{l3num.dtx}
+\end{document}
+%
+% \fi
+%
+%
+% \title{The \textsf{l3num} package\thanks{This file
+%         has version number \fileversion, last
+%         revised \filedate.}\\
+% Integer in macros}
+% \author{\Team}
+% \date{\filedate}
+% \maketitle
+%
+% \section{Macro Counters}
+%
+% Instead of using counter registers for manipulation of
+% integer values it is sometimes useful to keep such values in
+% macros. For this \LaTeX3 offers the  type ``num''.
+%
+% One reason is the limited number of registers inside
+% \TeX{}. However, when using \eTeX{} this is no longer an issue. It
+% remains to be seen if there are other compelling reasons to keep
+% this module.
+%
+% It turns out there might be as with a \meta{num} data type, the
+% allocation module can do its bookkeeping without the aid of
+% \meta{int} registers.
+%
+% \subsection{Functions}
+%
+% \begin{function}{%
+%                  \num_new:N |
+%                  \num_new:c |
+% }
+% \begin{syntax}
+%    "\num_new:N"   
+% \end{syntax}
+% Defines  to be a new variable of type "num" (initialized to
+% zero). There is no way to
+% define constant counters with these functions.
+% \end{function}
+%
+% \begin{function}{%
+%                  \num_incr:N |
+%                  \num_incr:c |
+%                  \num_gincr:N |
+%                  \num_gincr:c
+% }
+% \begin{syntax}
+%   "\num_incr:N"   
+% \end{syntax}
+% Increments  by one. For global variables the global versions
+% should be used.
+% \end{function}
+%
+% \begin{function}{%
+%                  \num_decr:N |
+%                  \num_decr:c |
+%                  \num_gdecr:N |
+%                  \num_gdecr:c |
+% }
+% \begin{syntax}
+%   "\num_decr:N"   
+% \end{syntax}
+% Decrements  by one. For global variables the global versions
+% should be used.
+% \end{function}
+%
+% \begin{function}{%
+%                  \num_zero:N |
+%                  \num_zero:c |
+%                  \num_gzero:N |
+%                  \num_gzero:c |
+% }
+% \begin{syntax}
+%   "\num_zero:N"   
+% \end{syntax}
+% Resets  to zero. For global variables the global versions
+% should be used.
+% \end{function}
+%
+% \begin{function}{%
+%                  \num_set:Nn |
+%                  \num_set:cn |
+%                  \num_gset:Nn |
+%                  \num_gset:cn |
+% }
+% \begin{syntax}
+%   "\num_set:Nn"    "{"  "}"
+% \end{syntax}
+% These functions will set the  register to the  value.
+% \end{function}
+%
+% \begin{function}{%
+%                  \num_gset_eq:NN |
+%                  \num_gset_eq:cN |
+%                  \num_gset_eq:Nc |
+%                  \num_gset_eq:cc |
+% }
+% \begin{syntax}
+%   "\num_gset_eq:NN"    
+% \end{syntax}
+% These functions will set the  register equal to .
+% \end{function}
+%
+% \begin{function}{%
+%                  \num_add:Nn |
+%                  \num_gadd:Nn |
+% }
+% \begin{syntax}
+%   "\num_add:Nn"    "{"  "}"
+% \end{syntax}
+% These functions will add to the  register the value .  If
+% the second argument is a  register too, the surrounding braces
+% can be left out.
+%
+% \end{function}
+%
+%
+% \begin{function}{%
+%                  \num_use:N |
+%                  \num_use:c |
+% }
+% \begin{syntax}
+%   "\num_use:N"   
+% \end{syntax}
+% This function returns the integer value kept in  in a way
+% suitable for further processing.
+% \begin{texnote}
+%   Since these s are implemented as macros, the function
+%   "\num_use:N" is effectively a noop and mainly there for
+%   consistency with similar functions in other modules.
+% \end{texnote}
+% \end{function}
+%
+%
+% \begin{function}{%
+%                  \num_eval:n |
+% }
+% \begin{syntax}
+%   "\num_eval:n"   "{"  "}"
+% \end{syntax}
+% Evaluates the integer expression allowing normal mathematical
+% operators like |+-/*|.
+% \end{function}
+%
+%
+% \begin{function}{%
+%                  \num_compare:nNnTF |
+%                  \num_compare:cNcTF |
+%                  \num_compare:nNnT |
+%                  \num_compare:nNnF |
+% }
+% \begin{syntax}
+%   "\num_compare:nNnTF"   "{""}"  "{""}"
+%                          "{""}" "{""}"
+% \end{syntax}
+% These functions test two \m{num} expressions against each other. They
+% are both evaluated by "\num_eval:n".
+% \end{function}
+%
+% \begin{function}{%
+%                  \num_compare_p:nNn |
+% }
+% \begin{syntax}
+%   "\num_compare_p:nNn"   "{""}"  "{""}"
+% \end{syntax}
+% A predicate version of the above functions.
+% \end{function}
+%
+%
+% \subsection{Formatting a counter value}
+%
+% See the \textsf{l3int} module for ways of doing this.
+%
+% \subsection{Variable and constants}
+%
+% \begin{function}{%
+%                  \const_new:Nn |
+% }
+% \begin{syntax}
+%   "\const_new:Nn"  "\c_" "{"  "}"
+% \end{syntax}
+% Defines a constant with . If the constant is negative
+% or very large it requires an  register.
+% \end{function}
+%
+% \begin{variable}{%
+%                  \c_minus_one |
+%                  \c_zero |
+%                  \c_one |
+%                  \c_two |
+%                  \c_three |
+%                  \c_four |
+%                  \c_six |
+%                  \c_seven |
+%                  \c_nine |
+%                  \c_ten |
+%                  \c_eleven |
+%                  \c_sixteen |
+%                  \c_hundred_one |
+%                  \c_twohundred_fifty_five |
+%                  \c_twohundred_fifty_six |
+%                  \c_thousand |
+%                  \c_ten_thousand |
+%                  \c_twenty_thousand 
+% }
+% \\
+% Set of constants denoting useful values.
+% \begin{texnote}
+% Most of these constants have been available under \LaTeX2 under names
+% like \tn{tw@}, \tn{thr@@} etc.
+% \end{texnote}
+% \end{variable}
+%
+% \begin{variable}{%
+%                  \l_tmpa_num |
+%                  \l_tmpb_num |
+%                  \l_tmpc_num |
+%                  \g_tmpa_num |
+%                  \g_tmpb_num |
+% }
+% \\
+% Scratch register for immediate use. They are not used by conditionals
+% or predicate functions.
+% \end{variable}
+%
+% \subsection{Primitive functions}
+%
+%
+% \begin{function}{%
+%                  \num_eval:w |
+% }
+% \begin{syntax}
+%   "\num_eval:w"  "\scan_stop:"
+% \end{syntax}
+% Evaluates . The evaluation stops when an
+% unexpandable token of catcode other than 12 is reached or
+% "\scan_stop:" is read. The latter is gobbled by the scanner
+% mechanism.
+% \begin{texnote}
+% This is the \eTeX{} primitive \tn{numexpr}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+%                  \if_num:w |
+% }
+% \begin{syntax}
+%   "\if_num:w"     "\else:"  "\fi:"
+% \end{syntax}
+% Compare two numbers. It is recommended to use "\num_eval:n" to
+% correctly evaluate and terminate these numbers.  is one of
+% "<", "=" or ">" with catcode 12.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{ifnum}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+%                  \if_num_odd:w |
+% }
+% \begin{syntax}
+%   "\if_num_odd:w"    "\else:"  "\fi:"
+% \end{syntax}
+% Execute  if  is odd,  otherwise.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{ifodd}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+%                  \if_case:w |
+%                  \or: |
+% }
+% \begin{syntax}
+%   "\if_case:w"   "\or:"  "\or:" "..." "\else:"
+%    "\fi:"
+% \end{syntax}
+% Chooses case. If you wish to use negative numbers as well,
+% you can offset them with "\num_eval:n".
+% \begin{texnote}
+% These are the \TeX{} primitives \tn{ifcase} and \tn{or}.
+% \end{texnote}
+% \end{function}
+%
+% \StopEventually{}
+%
+% \subsection{The Implementation}
+%
+%
+%    We start by ensuring that the required packages are loaded.
+%    \begin{macrocode}
+%\RequirePackage{l3expan}\par
+%\RequirePackage{l3chk}\par
+%<*initex|package>
+%    \end{macrocode}
+%
+% \begin{macro}{\num_eval:w}
+% \begin{macro}{\if_num:w}
+% \begin{macro}{\if_num_odd:w}
+% \begin{macro}{\if_case:w}
+% \begin{macro}{\or:}
+%   Here are the remaining primitives for number comparisons and
+%   expressions.
+%    \begin{macrocode}
+\let_new:NN \num_eval:w         \etex_numexpr:D
+\let_new:NN \if_num:w           \tex_ifnum:D
+\let_new:NN \if_num_odd:w       \tex_ifodd:D
+\let_new:NN \if_case:w          \tex_ifcase:D
+\let_new:NN \or:                \tex_or:D
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\use_arg_after_or:w}
+% \begin{macro}{\use_arg_after_else:w}
+% \begin{macro}{\use_arg_after_fi:w}
+%   When you're using the |\if_case:w| primitive it is not as easy as
+%   usual to get the code to be executed past the |\or:|, |\else:| and
+%   |\fi:|. If you know that there is only one token, then prefix it
+%   with |\exp_after:NN|, else you can use these functions. Be sure to
+%   hide any |\if| functions in the skipped text!
+%
+%   All other conditionals are two way switches for which you can just
+%   use the safe methods provided by the TF type functions.
+%    \begin{macrocode}
+\def_long_new:Npn \use_arg_after_or:w #1\or: #2\fi:{\fi: #1}
+\def_long_new:Npn \use_arg_after_else:w #1\else: #2\fi:{\fi: #1}
+\def_long_new:Npn \use_arg_after_fi:w #1\fi:{\fi: #1}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% Functions that support \LaTeX's user accessible counters should be
+% added here, too. But first the internal counters.
+%
+% \begin{macro}{\num_incr:N}
+% \begin{macro}{\num_decr:N}
+% \begin{macro}{\num_gincr:N}
+% \begin{macro}{\num_gdecr:N}
+%    Incrementing and decrementing of integer registers is done with
+%    the following functions.
+%    \begin{macrocode}
+\def:Npn \num_incr:N #1{\num_add:Nn#1 1}
+\def:Npn \num_decr:N #1{\num_add:Nn#1 \c_minus_one}
+\def:Npn \num_gincr:N #1{\num_gadd:Nn#1 1}
+\def:Npn \num_gdecr:N #1{\num_gadd:Nn#1 \c_minus_one}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\num_incr:c}
+% \begin{macro}{\num_decr:c}
+% \begin{macro}{\num_gincr:c}
+% \begin{macro}{\num_gdecr:c}
+%    We also need \ldots
+%    \begin{macrocode}
+\def_new:Npn \num_incr:c {\exp_args:Nc \num_incr:N}
+\def_new:Npn \num_decr:c {\exp_args:Nc \num_decr:N}
+\def_new:Npn \num_gincr:c {\exp_args:Nc \num_gincr:N}
+\def_new:Npn \num_gdecr:c {\exp_args:Nc \num_gdecr:N}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\num_zero:N}
+% \begin{macro}{\num_zero:c}
+% \begin{macro}{\num_gzero:N}
+% \begin{macro}{\num_gzero:c}
+%    We also need \ldots
+%    \begin{macrocode}
+\def_new:Npn \num_zero:N #1 {\num_set:Nn #1 0}
+\def_new:Npn \num_gzero:N #1 {\num_gset:Nn #1 0}
+\def_new:Npn \num_zero:c {\exp_args:Nc \num_zero:N}
+\def_new:Npn \num_gzero:c {\exp_args:Nc \num_gzero:N}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\num_new:N}
+% \begin{macro}{\num_new:c}
+%    Allocate a new \m{num} variable and initialize it with zero.
+%    \begin{macrocode}
+\def_new:Npn \num_new:N #1{\tlp_new:Nn #1{0}}
+\def_new:Npn \num_new:c {\exp_args:Nc \num_new:N}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\num_eval:n}
+% This function enables us to do all the operations without the aid of
+% an \m{int} register.
+%    \begin{macrocode}
+\def_new:Npn \num_eval:n #1{\num_eval:w #1\scan_stop:}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\num_set:Nn}
+% \begin{macro}{\num_set:cn}
+% \begin{macro}{\num_gset:Nn}
+% \begin{macro}{\num_gset:cn}
+% Assigning values to \m{num} registers.
+%    \begin{macrocode}
+\def_new:Npn \num_set:Nn #1#2{
+  \tlp_set:No #1{ \tex_number:D \num_eval:n {#2} }
+}
+\def_new:Npn \num_gset:Nn {\pref_global:D \num_set:Nn}
+\def_new:Npn \num_set:cn {\exp_args:Nc \num_set:Nn }
+\def_new:Npn \num_gset:cn {\exp_args:Nc \num_gset:Nn }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\num_set_eq:NN}
+% \begin{macro}{\num_set_eq:cN}
+% \begin{macro}{\num_set_eq:Nc}
+% \begin{macro}{\num_set_eq:cc}
+% Setting \m{num} registers equal to each other.
+%    \begin{macrocode}
+\let_new:NN \num_set_eq:NN \tlp_set_eq:NN
+\def_new:Npn \num_set_eq:cN {\exp_args:Nc \num_set_eq:NN}
+\def_new:Npn \num_set_eq:Nc {\exp_args:NNc \num_set_eq:NN}
+\def_new:Npn \num_set_eq:cc {\exp_args:Ncc \num_set_eq:NN}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\num_gset_eq:NN}
+% \begin{macro}{\num_gset_eq:cN}
+% \begin{macro}{\num_gset_eq:Nc}
+% \begin{macro}{\num_gset_eq:cc}
+% Setting \m{num} registers equal to each other.
+%    \begin{macrocode}
+\let_new:NN \num_gset_eq:NN \tlp_gset_eq:NN
+\def_new:Npn \num_gset_eq:cN {\exp_args:Nc \num_gset_eq:NN}
+\def_new:Npn \num_gset_eq:Nc {\exp_args:NNc \num_gset_eq:NN}
+\def_new:Npn \num_gset_eq:cc {\exp_args:Ncc \num_gset_eq:NN}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\num_add:Nn}
+% \begin{macro}{\num_gadd:Nn}
+% Adding is easily done as the second argument goes through
+% |\num_eval:n|.
+%    \begin{macrocode}
+\def_new:Npn \num_add:Nn #1#2 {\num_set:Nn #1{#1+#2}}
+\def_new:Npn \num_gadd:Nn {\pref_global:D \num_add:Nn}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\num_use:N}
+% \begin{macro}{\num_use:c}
+%    Here is how num macros are accessed:
+%    \begin{macrocode}
+\let_new:NN\num_use:N \use_arg_i:n
+\let_new:NN\num_use:c \cs_use:c
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\num_compare:nNnTF}
+% \begin{macro}{\num_compare:nNnT}
+% \begin{macro}{\num_compare:nNnF}
+% Simple comparison tests.
+%    \begin{macrocode}
+\def_test_function_new:npn {num_compare:nNn}#1#2#3{
+  \if_num:w \num_eval:n {#1}#2\num_eval:n {#3}
+}
+\def_new:Npn \num_compare:cNcTF { \exp_args:NcNc\num_compare:nNnTF }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\num_compare_p:nNn}
+% A predicate function.
+%    \begin{macrocode}
+\def_new:Npn \num_compare_p:nNn #1#2#3{
+  \if_num:w \num_eval:n {#1}#2\num_eval:n {#3}
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_tmpa_num}
+% \begin{macro}{\l_tmpb_num}
+% \begin{macro}{\l_tmpc_num}
+% \begin{macro}{\g_tmpa_num}
+% \begin{macro}{\g_tmpb_num}
+%    We provide an number local and two global \m{num}s, maybe we
+%    need more or less.
+%    \begin{macrocode}
+\num_new:N \l_tmpa_num
+\num_new:N \l_tmpb_num
+\num_new:N \l_tmpc_num
+\num_new:N \g_tmpa_num
+\num_new:N \g_tmpb_num
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%  \subsubsection{Defining constants}
+%  As stated, most constants can be defined as |\tex_chardef:D| or
+%  |\tex_mathchardef:D| but that's engine dependent. Omega/Aleph
+%  allows |\tex_chardef:D|s up to 65535 which is also the maximum
+%  number of registers of all types.
+%  \begin{macro}{\const_new:Nn}
+%  \begin{macro}{\c_max_register_num}
+%  \begin{macro}{\const_new_aux:Nw}
+%    \begin{macrocode}
+%    \begin{macrocode}
+\engine_aleph:TF
+{
+  \let_new:NN \const_new_aux:Nw \tex_chardef:D
+  \const_new_aux:Nw \c_max_register_num = 65535 \scan_stop:
+}
+{
+  \let_new:NN \const_new_aux:Nw \tex_mathchardef:D
+  \const_new_aux:Nw \c_max_register_num = 32767 \scan_stop:
+}
+\def_new:Npn \const_new:Nn #1#2 {
+  \num_compare:nNnTF  {#2} > \c_minus_one
+  {
+    \num_compare:nNnTF {#2} > \c_max_register_num 
+    {\int_new:N #1 \int_set:Nn #1{#2}}
+    {\chk_new_cs:N #1 \const_new_aux:Nw #1 = #2 \scan_stop: }
+  }
+  {\int_new:N #1 \int_set:Nn #1{#2}}
+}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+% \begin{macro}{\c_minus_one}
+% \begin{macro}{\c_zero}
+% \begin{macro}{\c_one}
+% \begin{macro}{\c_two}
+% \begin{macro}{\c_three}
+% \begin{macro}{\c_four}
+% \begin{macro}{\c_six}
+% \begin{macro}{\c_seven}
+% \begin{macro}{\c_nine}
+% \begin{macro}{\c_ten}
+% \begin{macro}{\c_eleven}
+% \begin{macro}{\c_sixteen}
+% \begin{macro}{\c_thirty_two}
+% \begin{macro}{\c_hundred_one}
+% \begin{macro}{\c_twohundred_fifty_five}
+% \begin{macro}{\c_twohundred_fifty_six}
+% \begin{macro}{\c_thousand}
+% \begin{macro}{\c_ten_thousand}
+% \begin{macro}{\c_ten_thousand_one}
+% \begin{macro}{\c_ten_thousand_two}
+% \begin{macro}{\c_ten_thousand_three}
+% \begin{macro}{\c_ten_thousand_four}
+% \begin{macro}{\c_twenty_thousand}
+%    And the usual constants, others are still missing. Please, make
+%    every constant a real constant at least for the moment. We can
+%    easily convert things in the end when we have found what
+%    constants are used in critical places and what not.
+%    \begin{macrocode}
+ %% \tex_countdef:D \c_minus_one = 10 \scan_stop:
+ %% \c_minus_one = -1 \scan_stop:        %% in l3basics
+ %% \tex_chardef:D \c_sixteen    = 16\scan_stop: %% in l3basics
+\const_new:Nn \c_zero   {0}
+\const_new:Nn \c_one    {1}
+\const_new:Nn \c_two    {2}
+\const_new:Nn \c_three  {3}
+\const_new:Nn \c_four   {4}
+\const_new:Nn \c_six    {6}
+\const_new:Nn \c_seven  {7}
+\const_new:Nn \c_nine   {9}
+\const_new:Nn \c_ten    {10}
+\const_new:Nn \c_eleven {11}
+\const_new:Nn \c_thirty_two {32}
+%    \end{macrocode}
+% The next one may seem a little odd (obviously!) but is useful when
+% dealing with logical operators.
+%    \begin{macrocode}
+\const_new:Nn \c_hundred_one          {101}
+\const_new:Nn \c_twohundred_fifty_five {255}
+\const_new:Nn \c_twohundred_fifty_six {256}
+\const_new:Nn \c_thousand             {1000}
+\const_new:Nn \c_ten_thousand         {10000}
+\const_new:Nn \c_ten_thousand_one     {10001}
+\const_new:Nn \c_ten_thousand_two     {10002}
+\const_new:Nn \c_ten_thousand_three   {10003}
+\const_new:Nn \c_ten_thousand_four    {10004}
+\const_new:Nn \c_twenty_thousand      {20000}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%    \begin{macrocode}
+%
+%    \end{macrocode}
+%
+% \endinput
+%
+% $Log$
+% Revision 1.17  2006/03/20 18:26:37  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.16  2005/12/27 10:03:01  morten
+% Changed RCS information retrieval
+%
+% Revision 1.15  2005/12/06 13:41:02  morten
+% Added a few functions to ease processing with \if_case:w
+%
+% Revision 1.14  2005/12/03 12:57:36  morten
+% Minor touch-ups.
+%
+% Revision 1.13  2005/10/27 22:39:02  morten
+% Forgot to add \if_num_odd:w
+%
+% Revision 1.12  2005/10/27 22:34:26  morten
+% Added \if_num:w, \if_case:w and \or: as they really belong here.
+%
+% Revision 1.11  2005/04/06 22:36:53  braams
+% Missed one occurence of \c_max_register_int
+%
+% Revision 1.10  2005/04/06 21:38:46  morten
+% Removed dependency on l3prg and added a missing function.
+%
+% Revision 1.9  2005/04/05 22:05:38  braams
+% Renamed \c_max_regsiter_int to \c_max_register_num,
+% Fixed const_new to allow 32767 as a value for \tex_mathchardef:D
+% Added \c_ten and \c_eleven as constants
+%
+% Revision 1.8  2005/03/26 21:06:35  morten
+% Update documentation
+%
+% Revision 1.7  2005/03/22 23:21:32  morten
+% Now independent of l3int and can be used as a very primitive module.
+%
+% Revision 1.6  2005/03/16 22:36:20  braams
+% Added the tweaks necessary to be able to load with initex
+%
+% Revision 1.5  2005/03/11 21:39:47  braams
+% Fixed the use of RCS information; added \StopEventually
+%
diff --git a/Master/texmf-dist/source/latex/expl3/l3precom.dtx b/Master/texmf-dist/source/latex/expl3/l3precom.dtx
index 69c1bc4e7cd..de22e1fe5ab 100644
--- a/Master/texmf-dist/source/latex/expl3/l3precom.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3precom.dtx
@@ -1,15 +1,50 @@
 % \iffalse
-%% File: l3precom.dtx Copyright (C) 1990-1998 LaTeX3 project
-%
+%% File: l3precom.dtx Copyright (C) 1990-2006 Frank Mittelbach, 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.
+%%
+%% -----------------------------------------------------------------------
+%
+%\RequirePackage{l3names}
 %<*dtx>
-          \ProvidesFile{l3precom.dtx}
+%\fi
+\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{%
+  \def\fileversion{#2}%
+  \def\filedate{#3/#4/#5}%
+  \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]%
+}
+%\iffalse
 %
-%\NeedsTeXFormat{LaTeX2e}
-%\ProvidesPackage{l3precom}
-% \ProvidesFile{l3precom.drv}
-% \fi
-%         \ProvidesFile{l3precom.dtx}
-          [1998/04/20 v1.0b L3 Experimental precompilation module]
+%\fi
+\GetIdInfo$Id: l3precom.dtx 573 2006-08-21 20:59:37Z morten $
+  {L3 Experimental precompilation module}
 %
 % \iffalse
 %<*driver>
@@ -34,7 +69,7 @@
 % using the roman numeral representation of some special counters
 % together with a prefix of "\l*" (local) or "\g*"( global).
 % \end{function}
-% 
+%
 % \begin{function}{\cs_record_name:N}
 % \begin{syntax}
 %   "\cs_record_name:N" 
@@ -45,7 +80,7 @@
 % internally automatically used to record all symbols generated by
 % "\cs_gen_sym:N" and "\cs_ggen_sym:N".
 % \end{function}
-% 
+%
 % \begin{function}{\cs_load_dump:n}
 % \begin{syntax}
 %   "\cs_load_dump:n" "{"  "}"
@@ -57,7 +92,7 @@
 % scanned. Then all symbols marked for dumping are dumped into .
 % \end{function}
-% 
+%
 % \begin{function}{\cs_dump:}
 % Dumps the symbols  recorded by "\cs_record_name:N" in the file given
 % by the argument in "\cs_load_dump:n". Dumping means that for every
@@ -71,30 +106,31 @@
 %
 %
 % \subsection{Internal variables}
-% 
-% \begin{variable}{\g_gen_sym_fint |
-%                  \g_ggen_sym_fint} Holds the number of the last
+%
+% \begin{variable}{\g_gen_sym_num |
+%                  \g_ggen_sym_num} Holds the number of the last
 % generated symbol by "\cs_gen_sym:N" or "\cs_ggen_sym:N".
 % \end{variable}
-% 
+%
 % \begin{variable}{\g_cs_dump_seq}
 % Sequence in which the symbols to be dumped are stored.
 % \end{variable}
-% 
+%
 % \begin{variable}{\c_cs_dump_stream}
 % Output stream used for writing out the definitions of the
 % recorded .
 % \end{variable}
-% 
-% 
-% 
-%  \section{Precompiling some functions}
+%
+% \StopEventually{}
+%
+%  \subsection{The Implementation}
 %
 %    We start by ensuring that the required packages are loaded.
 %    \begin{macrocode}
-%\RequirePackage{l3int}
+%\RequirePackage{l3num}
 %\RequirePackage{l3io}
 %\RequirePackage{l3seq}
+%\RequirePackage{l3int}
 %    \end{macrocode}
 %
 %    It might speed up the processing of documents when certain parts
@@ -107,7 +143,7 @@
 %    Stream number for the dump.
 %
 %    \begin{macrocode}
-%<*package>
+%<*initex|package>
 %<*precompile>
 \iow_new:N\c_cs_dump_stream
 %    \end{macrocode}
@@ -135,18 +171,18 @@
 %  \begin{macro}{\cs_record_name:N}
 %  \begin{macro}{\cs_record_name:c}
 %    These functions mark a control sequence for dumping into a
-%    precompiled style. 
+%    precompiled style.
 %
 %    When the {\sf trace} `module' is included in the code we also write
 %    information about the control sequence into a |.dmp| file.
 %    \begin{macrocode}
 \def_new:Npn\cs_record_name:N#1{
 %<*trace>
-      \seq_gput_left:Nn
-          \g_cs_trace_seq#1
+\seq_gput_left:Nn
+  \g_cs_trace_seq#1
 %
-      \seq_gput_left:Nn
-          \g_cs_dump_seq#1}
+\seq_gput_left:Nn
+  \g_cs_dump_seq#1}
 \def_new:Npn\cs_record_name:c{\exp_args:Nc\cs_record_name:N}
 %    \end{macrocode}
 %  \end{macro}
@@ -163,49 +199,45 @@
 %    `user' of this fact.
 %    \begin{macrocode}
 \def_new:Npn\cs_dump:{
-  \iow_expanded_term:n{Precompiling~style~into~(\g_cs_dump_name_tlp)}
-  \iow_open:Nn\c_cs_dump_stream{\g_cs_dump_name_tlp}
+\iow_expanded_term:n{Precompiling~style~into~(\g_cs_dump_name_tlp)}
+\iow_open:Nn\c_cs_dump_stream{\g_cs_dump_name_tlp}
 %    \end{macrocode}
 %    The first thing we write on a `dump' file is a command that
-%    allows us to use |*| in control sequences. We also need to be 
+%    allows us to use |*| in control sequences. We also need to be
 %    able to write to (and read from) the file internal control
 %    sequences, containing |_| and |:|.
 %    \begin{macrocode}
-  \iow_expanded:Nn\c_cs_dump_stream
-    {\group_begin:
-     \tex_catcode:D`\token_to_string:N\*=11\scan_stop:
-     \token_to_string:N\CodeStart
-    }
-  \seq_map_inline:Nn
-       \g_cs_dump_seq
-       {\tex_message:D{.}
-        \iow_expanded:Nn\c_cs_dump_stream
+\iow_expanded:Nn\c_cs_dump_stream
+{\group_begin:
+\tex_catcode:D`\token_to_string:N\*=11\scan_stop:
+\token_to_string:N\CodeStart
+}
+\seq_map_inline:Nn
+\g_cs_dump_seq
+{\tex_message:D{.}
+\iow_expanded:Nn\c_cs_dump_stream
 %    \end{macrocode}
 %    We use a direct |\gdef:Npn| to disable any type of local/global
 %    check on the pointers.
 %    \begin{macrocode}
-             {\token_to_string:N\gdef:Npn
-                 \token_to_string:N##1
-                 {\tlp_to_str:N##1}}
-       }
+     {\exp_not:n{\gdef:Npn ##1}
+         {\tlp_to_str:N##1}}
+}
 %    \end{macrocode}
 %    We also need to remember the current values of the
-%    |\g_gen_sym_fint| and |\g_ggen_sym_fint| counters to allow
+%    |\g_gen_sym_num| and |\g_ggen_sym_num| counters to allow
 %    further updates after a database was dumped.
 %    \begin{macrocode}
-  \iow_expanded:Nn
-     \c_cs_dump_stream
-     {\token_to_string:N\fint_gset:Nn
-                        \g_gen_sym_fint
-                        {\fint_use:N\g_gen_sym_fint}^^J
-      \token_to_string:N\fint_gset:Nn
-                        \g_ggen_sym_fint
-                        {\fint_use:N\g_ggen_sym_fint}}
-  \iow_expanded:Nn
-     \c_cs_dump_stream
-     {\group_end:}
-  \iow_close:N\c_cs_dump_stream
-  \tex_message:D{~finished}
+\iow_expanded:Nn \c_cs_dump_stream {\exp_not:n{\num_gset:Nn
+                \g_gen_sym_num}
+                {\num_use:N\g_gen_sym_num}^^J
+\exp_not:n{\num_gset:Nn \g_ggen_sym_num}
+                {\num_use:N\g_ggen_sym_num}}
+\iow_expanded:Nn
+\c_cs_dump_stream
+{\group_end:}
+\iow_close:N\c_cs_dump_stream
+\tex_message:D{~finished}
 }
 %
 %    \end{macrocode}
@@ -218,27 +250,25 @@
 %    dump file.
 %    \begin{macrocode}
 \def_new:Npn\cs_load_dump:n#1{
-  \file_not_found:nTF{#1.cmp}
+\file_not_found:nTF{#1.cmp}
 %<*precompile>
-      {\tlp_gset:Nn\g_cs_dump_name_tlp{#1.cmp}}
+{\tlp_gset:Nn\g_cs_dump_name_tlp{#1.cmp}}
 %
 %<-precompile> {\tex_errmessage:D{Cannot~ dump~ with~ this~ format}}
-      {\input{#1.cmp}
-       \let:NN\cs_dump:\fi:
-       \if_false:}}
+{\input{#1.cmp}
+\let:NN\cs_dump:\fi:
+\if_false:}}
 %    \end{macrocode}
 %  \end{macro}
 %
-% \begin{macro}{\g_gen_sym_fint}
-% \begin{macro}{\g_ggen_sym_fint}
-%    Two counters to make up new local or global {\sl short\/} names
-%    in pointer structures like the {\sc ldb}.
+% \begin{macro}{\g_gen_sym_num}
+% \begin{macro}{\g_ggen_sym_num}
+%    Two counters to make up new local or global \textsl{short} names
+%    in pointer structures like the \textsc{ldb}.
 %    We use a fake counters since operations with them are seldom.
 %    \begin{macrocode}
-\fint_new:N\g_gen_sym_fint
-\fint_gset:Nn\g_gen_sym_fint{0}
-\fint_new:N\g_ggen_sym_fint
-\fint_gset:Nn\g_ggen_sym_fint{0}
+\num_new:N\g_gen_sym_num \num_gset:Nn\g_gen_sym_num{0}
+\num_new:N\g_ggen_sym_num \num_gset:Nn\g_ggen_sym_num{0}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -247,40 +277,40 @@
 % \begin{macro}{\cs_ggen_sym:N}
 %    We need to be able to generate control sequences on the fly.
 %    They will exist of a prefix, either |l*| or |g*|, followed
-%    by the value of the counter |\g_gen_sym_fint| (|\g_ggen_sym_fint|)
+%    by the value of the counter |\g_gen_sym_num| (|\g_ggen_sym_num|)
 %    in roman numeral representation. The generated control sequence
 %    is locally stored in the token that was passed in |#1|.
 %
 %    \begin{macrocode}
 \def_new:Npn\cs_gen_sym:N#1{
-  \fint_gincr:N\g_gen_sym_fint
-  \tlp_set:Nc#1{l*\tex_romannumeral:D\fint_use:N\g_gen_sym_fint}
+\num_gincr:N\g_gen_sym_num
+\tlp_set:Nc#1{l*\tex_romannumeral:D\num_use:N\g_gen_sym_num}
 %<*precompile>
-  \exp_after:NN\cs_record_name:N#1
+\exp_after:NN\cs_record_name:N#1
 %
 %    \end{macrocode}
 %    We still want to define the initial value for the new symbol
 %    globally to make sure that during compilation something is
 %    written to the output file.
 %    \begin{macrocode}
-  \exp_after:NN\tlp_clear_new:N#1}
+\exp_after:NN\tlp_clear_new:N#1}
 %    \end{macrocode}
 %    The global variant
 %    \begin{macrocode}
 \def_new:Npn\cs_ggen_sym:N#1{
-  \fint_gincr:N\g_ggen_sym_fint
-  \tlp_set:Nc#1{g*\tex_romannumeral:D\fint_use:N\g_ggen_sym_fint}
+\num_gincr:N\g_ggen_sym_num
+\tlp_set:Nc#1{g*\tex_romannumeral:D\num_use:N\g_ggen_sym_num}
 %<*precompile>
-  \exp_after:NN\cs_record_name:N#1
+\exp_after:NN\cs_record_name:N#1
 %
-  \exp_after:NN\tlp_clear_new:N#1}
+\exp_after:NN\tlp_clear_new:N#1}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
 %
 %
 %  \begin{macro}{\g_cs_trace_seq}
-%    A sequence which holds the control sequence names that are to 
+%    A sequence which holds the control sequence names that are to
 %    be dumped. They are stored together with their meaning.
 %
 %    ATTENTION: as we currently don't distribute allocation routines
@@ -306,8 +336,8 @@
 %    Function marking a control sequence for dumping with meaning.
 %    \begin{macrocode}
 \def:Npn\cs_record_meaning:N#1{
-      \seq_gput_left:Nn
-          \g_cs_trace_seq#1}
+\seq_gput_left:Nn
+  \g_cs_trace_seq#1}
 %    \end{macrocode}
 %  \end{macro}
 %
@@ -315,8 +345,8 @@
 %    Function marking a register for dumping with value.
 %    \begin{macrocode}
 \def:Npn\register_record_name:N#1{
-      \seq_gput_left:Nn
-          \g_register_trace_seq#1}
+\seq_gput_left:Nn
+  \g_register_trace_seq#1}
 %    \end{macrocode}
 %  \end{macro}
 %
@@ -324,7 +354,7 @@
 % \begin{macro}{\dumpLaTeXstate}
 %    The function |\dumpLaTeXstate| is used to write control sequences
 %    and registers, together with their meaning or value in the |.dmp|
-%    file. We write informational messages to the terminal during the 
+%    file. We write informational messages to the terminal during the
 %    dump.
 %
 %    ATTENTION: as we currently don't distribute allocation routines
@@ -352,7 +382,7 @@
   \tex_message:D{~finished}
 }
 %
-%
+%
 %    \end{macrocode}
 %  \end{macro}
 %
@@ -364,6 +394,26 @@
 %
 %    \end{macrocode}
 %
+% \endinput
+%
+% $Log$
+% Revision 1.7  2006/03/20 18:26:37  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.6  2005/12/27 16:03:21  morten
+% Changed RCS information retrieval plus a few name changes
+%
+% Revision 1.5  2005/04/12 12:06:30  morten
+% Fixed the use of fake integers (now known as "num")
+%
+% Revision 1.4  2005/03/16 22:36:14  braams
+% Added the tweaks necessary to be able to load with initex
+%
+% Revision 1.3  2005/03/11 21:51:50  braams
+% Just another small mistake to be corrected
+%
+% Revision 1.2  2005/03/11 21:21:01  braams
+% Added the header for CVS public read access and fixed the
+% use of RCS data
 %
-
-
diff --git a/Master/texmf-dist/source/latex/expl3/l3prg.dtx b/Master/texmf-dist/source/latex/expl3/l3prg.dtx
new file mode 100644
index 00000000000..43e2e77448a
--- /dev/null
+++ b/Master/texmf-dist/source/latex/expl3/l3prg.dtx
@@ -0,0 +1,1374 @@
+% \iffalse
+%% File: l3prg.dtx Copyright (C) 2005-2006 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.
+%%
+%% -----------------------------------------------------------------------
+%
+%\RequirePackage{l3names}
+%<*dtx>
+%\fi
+\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{%
+  \def\fileversion{#2}%
+  \def\filedate{#3/#4/#5}%
+  \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]%
+}
+%\iffalse
+%
+%\fi
+\GetIdInfo$Id: l3prg.dtx 574 2006-08-21 23:30:10Z morten $
+       {L3 Experimental control structures}
+%
+% \iffalse
+%<*driver>
+\documentclass{l3doc}
+
+\begin{document}
+\DocInput{l3prg.dtx}
+\end{document}
+%
+% \fi
+%
+% \title{The \textsf{l3prg} package\thanks{This file
+%         has version number \fileversion, last
+%         revised \filedate.}\\
+% Program control structures}
+% \author{\Team}
+% \date{\filedate}
+% \maketitle
+%
+%
+% \section{Control structures}
+%
+% \subsection{Choosing modes}
+%
+% \begin{function}{\mode_vertical_p:|
+%                  \mode_vertical:TF |
+%                  \mode_vertical:T |
+%                  \mode_vertical:F
+%                 }
+% \begin{syntax}
+%   "\mode_vertical:TF" "{""}" "{""}"
+% \end{syntax}
+% Determines if \TeX{} is in vertical mode or not and executes either
+%  or  accordingly.
+% \end{function}
+%
+% \begin{function}{\mode_horizontal_p:|
+%                  \mode_horizontal:TF |
+%                  \mode_horizontal:T |
+%                  \mode_horizontal:F
+%                 }
+% \begin{syntax}
+%   "\mode_horizontal:TF" "{""}" "{""}"
+% \end{syntax}
+% Determines if \TeX{} is in horizontal mode or not and executes either
+%  or  accordingly.
+% \end{function}
+%
+%
+% \begin{function}{
+%     \mode_inner_p:|
+%     \mode_inner:TF|
+%     \mode_inner:T|
+%     \mode_inner:F
+%                 }
+% \begin{syntax}
+%   "\mode_inner:TF" "{""}" "{""}"
+% \end{syntax}
+% Determines if \TeX{} is in inner mode or not and executes either
+%  or  accordingly.
+% \end{function}
+%
+% \begin{function}{
+%               \mode_math:TF|
+%               \mode_math:T|
+%               \mode_math:F|
+%                 }
+% \begin{syntax}
+%   "\mode_math:TF" "{""}" "{""}"
+% \end{syntax}
+% Determines if \TeX{} is in math mode or not and executes either
+%  or  accordingly.
+% \begin{texnote}
+% This version will choose the right branch even at the beginning of
+% an alignment cell.
+% \end{texnote}
+% \end{function}
+%
+%
+% \subsubsection{Alignment safe grouping and scanning}
+%
+% \begin{function}{\scan_align_safe_stop:}
+% \begin{syntax}
+%   "\scan_align_safe_stop:"
+% \end{syntax}
+% This function gets \TeX{} on the right track inside an alignment
+% cell but without destroying any kerning.
+% \end{function}
+%
+%
+% \begin{function}{\group_align_safe_begin:|
+%                  \group_align_safe_end:}
+% \begin{syntax}
+%   "\group_align_safe_begin:" <...> "\group_align_safe_end:"
+% \end{syntax}
+% Encloses <...> inside a group but is safe inside an alignment cell.
+% See the implementation of |\peek_token_generic:NNTF| for an
+% application.
+% \end{function}
+%
+%
+% \subsection{Producing $n$ copies}
+% 
+% There are often several different requirements for producing
+% multiple copies of something. Sometimes one might want to produce a
+% number of identical copies of a sequence of tokens whereas at other
+% times the goal is to simulate a for loop as known from most real
+% programming languages.
+%
+% \begin{function}{\prg_replicate:nn }
+% \begin{syntax}
+%   "\prg_replicate:nn" "{"  "}" "{"  "}"
+% \end{syntax}
+% Creates  copies of . Expandable.
+% \end{function}
+%
+%
+% \begin{function}{\prg_stepwise_function:nnnN}
+% \begin{syntax}
+%   "\prg_stepwise_function:nnnN" "{""}" "{""}"
+%   "{""}" 
+% \end{syntax}
+% This function performs  once for each step starting at
+%  and ending once  is passed.  is placed
+% directly in front of a brace group holding the current number so it
+% should usually be a function taking one argument. The
+% |\prg_stepwise_function:nnnN| function is expandable.
+% \end{function}
+%
+% \begin{function}{\prg_stepwise_inline:nnnn}
+% \begin{syntax}
+%   "\prg_stepwise_inline:nnnn" "{""}" "{""}" "{""}"
+%   "{""}"
+% \end{syntax}
+% Same as |\prg_stepwise_function:nnnN| except here  is
+% performed each time with |##1| as a placeholder for the number
+% currently being tested. This function is not expandable and it is
+% nestable.
+% \end{function}
+%
+% \begin{function}{\prg_stepwise_variable:nnnNn}
+% \begin{syntax}
+%   "\prg_stepwise_variable:nnnn" "{""}" "{""}" "{""}"
+%    "{""}"
+% \end{syntax}
+% Same as |\prg_stepwise_inline:nnnn| except here the current value is
+% stored in  and the programmer can use it in . This
+% function is not expandable.
+% \end{function}
+%
+%
+%
+%  \subsection{Conditionals and logical operations}
+%
+%
+%  \LaTeX3 has two primary forms of conditional flow processing. The
+%  one type deals with the truth value of a test directly as in
+%  "\cs_free:NTF" where you test if a control sequence was undefined
+%  and then execute either the \m{true} or \m{false} part depending on
+%  the result and after exiting the underlying "\if...\fi:" structure.
+%  The second type has to do with predicate functions like
+%  "\cs_free_p:N" which return either "\c_true" or "\c_false" to be
+%  used in testing with "\if:w".
+%
+%
+%  This section describes a boolean data type which is closely
+%  connected to both parts as sometimes you want to execute some code
+%  depending on the value of a switch (e.g.,~draft/final) and other
+%  times you perhaps want to use it as a predicate function in an
+%  "\if:w" test. Here \TeX's original concept with "\iffalse" and
+%  "\iftrue" is a little difficult to handle so the easiest is simply
+%  to let a boolean either be "\c_true" or "\c_false". This also means
+%  we get the logical operations And, Or, and Not which can then be
+%  used on both the boolean type and predicate functions. All
+%  functions by the name |\prg_if_predicate_| are expandable and
+%  expect the input to also be fully expandable. More generic
+%  constructs do not contain |predicate| in their names.
+%
+%
+%  \subsubsection{The boolean data type}
+%
+%  \begin{function}{%
+%                   \bool_new:N |
+%                   \bool_new:c |
+%  }
+%  \begin{syntax}
+%     "\bool_new:N"  
+%  \end{syntax}
+%  Define a new boolean variable. The initial value is . A
+%  boolean is actually just either "\c_true" or "\c_false".
+%  \end{function}
+%
+%  \begin{function}{%
+%                   \bool_set_true:N |
+%                   \bool_set_true:c |
+%                   \bool_set_false:N |
+%                   \bool_set_false:c |
+%                   \bool_gset_true:N |
+%                   \bool_gset_true:c |
+%                   \bool_gset_false:N |
+%                   \bool_gset_false:c |
+%  }
+%  \begin{syntax}
+%     "\bool_gset_false:N" 
+%  \end{syntax}
+%  Set  either true or false. We can also do this globally.
+%  \end{function}
+%
+%
+%  \begin{function}{%
+%                   \bool_set_eq:NN |
+%                   \bool_set_eq:Nc |
+%                   \bool_set_eq:cN |
+%                   \bool_set_eq:cc |
+%                   \bool_gset_eq:NN |
+%                   \bool_gset_eq:Nc |
+%                   \bool_gset_eq:cN |
+%                   \bool_gset_eq:cc |
+%
+%  }
+%  \begin{syntax}
+%     "\bool_set_eq:NN"  
+%  \end{syntax}
+%  Set  equal to the value of .
+%  \end{function}
+%
+%  \begin{function}{%
+%                   \bool_if:NTF |
+%                   \bool_if:NT |
+%                   \bool_if:NF |
+%                   \bool_if_p:N |
+%
+%  }
+%  \begin{syntax}
+%     "\bool_if:NTF"  "{"\m{true}"}" "{"\m{false}"}"   \\
+%     "\bool_if_p:N" 
+%  \end{syntax}
+%  Test the truth value of the boolean and execute the \m{true} or
+%  \m{false} code. "\bool_if_p:N" is a predicate function for use in
+%  "\if:w" tests.
+%  \end{function}
+%
+%  \begin{function}{%
+%                   \bool_whiledo:NT |
+%                   \bool_whiledo:NF |
+%                   \bool_dowhile:NT |
+%                   \bool_dowhile:NF |
+%
+%  }
+%  \begin{syntax}
+%     "\bool_whiledo:NT"  "{"\m{true}"}"  \\
+%     "\bool_whiledo:NF"  "{"\m{false}"}"  \\
+%  \end{syntax}
+%  The "T" versions execute the \m{true} code as long as the boolean is
+%  true and the "F" versions execute the \m{false} code as long as the
+%  boolean is false. The "whiledo" functions execute the body after
+%  testing the boolean and the "dowhile" functions executes the body
+%  first and then tests the boolean.
+%  \end{function}
+%
+%
+%  \begin{function}{%
+%                   \l_tmpa_bool |
+%                   \g_tmpa_bool |
+%
+%  }
+%  \begin{syntax}
+%  \end{syntax}
+%  Reserved booleans.
+%  \end{function}
+%
+%  \subsubsection{Logical operations}
+%
+%  Somewhat related to the subject of conditional flow processing is
+%  logical operators as these deal with \m{true} and \m{false}
+%  statements which is precisely what the predicate functions return.
+%
+%
+%  \begin{function}{%
+%                   \prg_if_predicate:nTF |
+%                   \prg_if_predicate:nT |
+%                   \prg_if_predicate:nF |
+%  }
+%  \begin{syntax}
+%    "\prg_if_predicate:nTF" "{""}" "{""}" "{""}" \\
+%  \end{syntax}
+%  The first argument can either be a predicate function like
+%  "\cs_free_p:N \foo" or one of the logic tests below.
+%  \end{function}
+%
+%
+%
+%
+%  \begin{function}{%
+%                   \prg_if_predicate_ors_p:n |
+%                   \prg_if_predicate_or_p:nn |
+%                   \prg_if_predicate_ands_p:n |
+%                   \prg_if_predicate_and_p:nn |
+%                   \prg_if_predicate_not_p:n |
+%  }
+%  \begin{syntax}
+%     "\prg_if_predicate_ors_p:n" "{"  ..."}"  \\
+%     "\prg_if_predicate_or_p:nn" "{""}" "{""}" \\
+%     "\prg_if_predicate_ands_p:n" "{"  ..."}"  \\
+%     "\prg_if_predicate_and_p:nn" "{""}" "{""}" \\
+%     "\prg_if_predicate_not_p:n" "{""}"
+%  \end{syntax}
+%  "\prg_if_predicate_or_p:nn" compares the outcome of two predicate
+%  functions (or other logic tests) and if either turns out to be
+%  \m{true} returns \m{true} itself. "\prg_if_predicate_and_p:nn"
+%  works in a similar way but requires both outcomes to be \m{true} in
+%  order for it to return \m{true} itself. "\prg_if_predicate_not_p:n"
+%  reverses the truth value of a predicate test or a logic
+%  operation. Thus
+%  \begin{quote}
+%  "\prg_if_predicate_not_p:n {\prg_if_predicate_not_p:n {\c_true}}"
+%  \end{quote}
+%  ultimately returns \m{true}.  The argument of the functions
+%  "\prg_if_predicate_ors_p:n" and "\prg_if_predicate_ands_p:n" take a
+%  list of predicate functions (and their arguments) and return either
+%  \m{true} or \m{false}.
+%  \end{function}
+% 
+%  \subsubsection{Generic loops}
+%
+%
+%  \begin{function}{
+%                   \prg_whiledo:nT |
+%                   \prg_whiledo:nF |
+%                   \prg_dowhile:nT |
+%                   \prg_dowhile:nF |
+%
+%  }
+%  \begin{syntax}
+%     "\prg_whiledo:nT" "{""}" "{"\m{true}"}"  \\
+%     "\prg_whiledo:nF" "{""}" "{"\m{false}"}"  
+%  \end{syntax}
+%  The "T" versions execute the \m{true} code as long as  is
+%  true and the "F" versions execute the \m{false} code as long as
+%   is false. The "whiledo" functions execute the body after
+%  testing the boolean and the "dowhile" functions executes the body
+%  first and then tests the boolean. For the "T" versions, 
+%  should end with a function executing only the \meta{true} code for
+%  some test such as |\tlp_if_eq:NNT|. Similarly the "F" types should
+%  end with |\tlp_if_eq:NNF|.
+%  \end{function}
+%
+% \subsection{Sorting}
+%
+%
+%  \begin{function}{
+%                   \prg_quicksort:n |
+%  }
+%  \begin{syntax}
+%    "\prg_quicksort:n" "{" "{""}" "{""}"
+%      \dots\space "{""}" "}"
+%  \end{syntax}
+%  Performs a Quicksort on the token list. The comparisons are
+%  performed by the function |\prg_quicksort_compare:nnTF| which is up
+%  to the programmer to define. When the sorting process is over, all
+%  elements are given as argument to the function
+%  |\prg_quicksort_function:n| which the programmer also controls.
+%  \end{function}
+%
+%  \begin{function}{
+%                   \prg_quicksort_function:n |
+%                   \prg_quicksort_compare:nnTF
+%  }
+%  \begin{syntax}
+%    "\prg_quicksort_function:n" "{""}" \\
+%    "\prg_quicksort_compare:nnTF" "{""}" "{""}"\\
+%  \end{syntax}
+%  The two functions the programmer must define before calling
+%  |\prg_quicksort:n|. As an example we could define
+% \begin{quote}
+% |\def:NNn\prg_quicksort_function:n 1{{#1}}|\\
+% |\def:NNn\prg_quicksort_compare:nnTF 2{\num_compare:nNnTF{#1}>{#2}}|
+% \end{quote}
+% Then the function call
+% \begin{quote}
+% |\prg_quicksort:n {876234520}|
+% \end{quote}
+% would return |{0}{2}{2}{3}{4}{5}{6}{7}{8}|. An alternative example
+% where one sorts a list of words, |\prg_quicksort_compare:nnTF| could
+% be defined as
+% \begin{quote}
+% |\def:NNn\prg_quicksort_compare:nnTF 2{|\\
+% |  \num_compare:nNnTF{\tlist_compare:nn{#1}{#2}}>\c_zero }|
+% \end{quote}
+% 
+%  \end{function}
+%
+%
+% \StopEventually{}
+%
+% \subsection{The Implementation}
+%
+%
+%    We start by ensuring that the required packages are loaded.
+%    \begin{macrocode}
+%<*package>
+\RequirePackage{l3quark}
+\RequirePackage{l3toks}
+\RequirePackage{l3int}
+%
+%<*initex|package>
+%    \end{macrocode}
+%
+%
+%  \subsubsection{Choosing modes}
+%
+%  \begin{macro}{\mode_vertical_p:}
+%  \begin{macro}{\mode_vertical:TF}
+%  \begin{macro}{\mode_vertical:T}
+%  \begin{macro}{\mode_vertical:F}
+%  For testing vertical mode.
+%    \begin{macrocode}
+\def_new:Npn \mode_vertical_p: {
+  \if_mode_vertical: \c_true \else: \c_false\fi:}
+\def_test_function_new:npn{mode_vertical:}{\if_mode_vertical:}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+%  \begin{macro}{\mode_horizontal_p:}
+%  \begin{macro}{\mode_horizontal:TF}
+%  \begin{macro}{\mode_horizontal:T}
+%  \begin{macro}{\mode_horizontal:F}
+%  For testing horizontal mode.
+%    \begin{macrocode}
+\def_new:Npn \mode_horizontal_p: {
+  \if_mode_horizontal: \c_true \else: \c_false\fi:}
+\def_test_function_new:npn{mode_horizontal:}{\if_mode_horizontal:}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+%  \begin{macro}{\mode_inner_p:}
+%  \begin{macro}{\mode_inner:TF}
+%  \begin{macro}{\mode_inner:T}
+%  \begin{macro}{\mode_inner:F}
+%  For testing inner mode.
+%    \begin{macrocode}
+\def_new:Npn \mode_inner_p: {
+  \if_mode_inner: \c_true \else: \c_false\fi:}
+\def_test_function_new:npn{mode_inner:}{\if_mode_inner:}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+%  \begin{macro}{\mode_math:TF}
+%  \begin{macro}{\mode_math:T}
+%  \begin{macro}{\mode_math:F}
+%  For testing math mode. Uses the kern-save |\scan_align_safe_stop:|.
+%    \begin{macrocode}
+\def_test_function_new:npn{mode_math:} {
+  \scan_align_safe_stop:  \if_mode_math: }
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+% \paragraph{Alignment safe grouping and scanning}
+%
+%
+%  \begin{macro}{\group_align_safe_begin:}
+%  \begin{macro}{\group_align_safe_end:}
+%  \TeX's alignment structures present many problems. As Knuth says
+%  himself in \emph{\TeX: The Program}: ``It's sort of a miracle
+%  whenever |\halign| or |\valign| work, [\ldots]'' One problem relates
+%  to commands that internally issues a |\cr| but also peek ahead for
+%  the next character for use in, say, an optional argument. If the
+%  next token happens to be a |&| with category code~4 we will get some
+%  sort of weird error message because the underlying
+%  |\tex_futurelet:D| will store the token at the end of the alignment
+%  template. This could be a |&|$\sb4$ giving a message like
+%  |! Misplaced \cr.| or even worse: it could be the |\endtemplate|
+%  token causing even more trouble! To solve this we have to open a
+%  special group so that \TeX{} still thinks it's on safe ground but at
+%  the same time we don't want to introduce any brace group that may
+%  find its way to the output. The following functions help with this
+%  by using code documented only in Appendix~D of
+%  \emph{The \TeX book}\dots
+%    \begin{macrocode}
+\def_new:Npn \group_align_safe_begin: {\if_false:{\fi:\if_num:w0=`}\fi:}
+\def_new:Npn \group_align_safe_end:   {\if_num:w0=`{\fi:\if_false:}\fi:}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%
+%
+%  \begin{macro}{\scan_align_safe_stop:}
+%  When \TeX{} is in the beginning of an align cell (right after the
+%  |\cr|) it is in a somewhat strange mode as it is looking ahead to
+%  find an |\tex_omit:D| or |\tex_noalign:D| and hasn't looked at the
+%  preamble yet. Thus an |\tex_ifmmode:D| test will always fail unless
+%  we insert |\scan_stop:| to stop \TeX's scanning ahead. On the other
+%  hand we don't want to insert a |\scan_stop:| every time as that will
+%  destroy kerning between letters\footnote{Unless we enforce an extra
+%  pass with an appropriate value of \texttt{\string\pretolerance}.}
+%  Unfortunately there is no way to detect if we're in the beginning of
+%  an alignment cell as they have different characteristics depending
+%  on column number etc. However we \emph{can} detect if we're in an
+%  alignment cell by checking the current group type and we can also
+%  check if the previous node was a character or ligature. What is done
+%  here is that |\scan_stop:| is only inserted iff a)~we're in the
+%  outer part of an alignment cell and b)~the last node \emph{wasn't} a
+%  char node or a ligature node.
+%    \begin{macrocode}
+\def_new:Npn \scan_align_safe_stop: {
+  \num_compare:nNnT \etex_currentgrouptype:D = \c_six
+  {
+    \num_compare:nNnF \etex_lastnodetype:D = \c_zero
+    {
+      \num_compare:nNnF \etex_lastnodetype:D = \c_seven
+        \scan_stop:
+    }
+  }
+}
+%    \end{macrocode}
+%  \end{macro}
+%
+% \subsubsection{Making $n$ copies}
+% 
+% \begin{macro}{\prg_replicate:nn}
+% \begin{macro}{\prg_replicate_aux:N}
+% \begin{macro}{\prg_replicate_first_aux:N}
+% This function uses a cascading csname technique by David Kastrup
+% (who else :-)
+% 
+% The idea is to make the input "25" result in first adding five, and
+% then 20 copies of the code to be replicated. The technique uses
+% cascading csnames which means that we start building several csnames
+% so we end up with a list of functions to be called in reverse
+% order. This is important here (and other places) because it means
+% that we can for instance make the function that inserts five copies
+% of something to also hand down ten to the next function in
+% line. This is exactly what happens here: in the example with "25"
+% then the next function is the one that inserts two copies but it
+% sees the ten copies handed down by the previous function. In order
+% to avoid the last function to insert say, 100 copies of the original
+% argument just to gobble them again we define separate functions to
+% be inserted first. Finally we must ensure that the cascade comes to
+% a peaceful end so we make it so that the original csname \TeX{} is
+% creating is simply "\use_noop:" expanding to nothing.
+%
+% This function has one flaw though: Since it constantly passes down
+% ten copies of its previous argument it will severely affect the main
+% memory once you start demanding hundreds of thousands of copies. Now
+% I don't think this is a real limitation for any ordinary use. An
+% alternative approach is to create a string of "m"'s with
+% "\int_to_roman:w" which can be done with just four macros but that
+% method has its own problems since it can exhaust the string
+% pool. Also, it is considerably slower than what we use here so the
+% few extra csnames are well spent I would say.
+%    \begin{macrocode}
+\def_new:Npn \prg_replicate:nn #1{
+  \cs:w use_noop: 
+  \exp_after:NN\prg_replicate_first_aux:N
+  \int_use:N \int_eval:n{#1} \cs_end: 
+  \cs_end: 
+}
+\def_new:Npn \prg_replicate_aux:N#1{
+  \cs:w prg_replicate_#1:n\prg_replicate_aux:N
+}
+\def_new:Npn \prg_replicate_first_aux:N#1{
+  \cs:w prg_replicate_first_#1:n\prg_replicate_aux:N
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% Then comes all the functions that do the hard work of inserting all
+% the copies.
+%    \begin{macrocode}
+\def_new:Npn      \prg_replicate_ :n #1{}% no, this is not a typo!
+\def_long_new:cpn {prg_replicate_0:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}}
+\def_long_new:cpn {prg_replicate_1:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}#1}
+\def_long_new:cpn {prg_replicate_2:n}#1{\cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1}
+\def_long_new:cpn {prg_replicate_3:n}#1{
+  \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1}
+\def_long_new:cpn {prg_replicate_4:n}#1{
+  \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1}
+\def_long_new:cpn {prg_replicate_5:n}#1{
+  \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1}
+\def_long_new:cpn {prg_replicate_6:n}#1{
+  \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1}
+\def_long_new:cpn {prg_replicate_7:n}#1{
+  \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1}
+\def_long_new:cpn {prg_replicate_8:n}#1{
+  \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1}
+\def_long_new:cpn {prg_replicate_9:n}#1{
+  \cs_end:{#1#1#1#1#1#1#1#1#1#1}#1#1#1#1#1#1#1#1#1}
+%    \end{macrocode}
+%    Users shouldn't ask for something to be replicated once or even
+%    not at all but\dots
+%    \begin{macrocode}
+\def_long_new:cpn {prg_replicate_first_0:n}#1{\cs_end: }
+\def_long_new:cpn {prg_replicate_first_1:n}#1{\cs_end: #1}
+\def_long_new:cpn {prg_replicate_first_2:n}#1{\cs_end: #1#1}
+\def_long_new:cpn {prg_replicate_first_3:n}#1{\cs_end: #1#1#1}
+\def_long_new:cpn {prg_replicate_first_4:n}#1{\cs_end: #1#1#1#1}
+\def_long_new:cpn {prg_replicate_first_5:n}#1{\cs_end: #1#1#1#1#1}
+\def_long_new:cpn {prg_replicate_first_6:n}#1{\cs_end: #1#1#1#1#1#1}
+\def_long_new:cpn {prg_replicate_first_7:n}#1{\cs_end: #1#1#1#1#1#1#1}
+\def_long_new:cpn {prg_replicate_first_8:n}#1{\cs_end: #1#1#1#1#1#1#1#1}
+\def_long_new:cpn {prg_replicate_first_9:n}#1{\cs_end: #1#1#1#1#1#1#1#1#1}
+%    \end{macrocode} 
+%
+%
+%
+%
+% \begin{macro}{\prg_stepwise_function:nnnN}
+% \begin{macro}{\prg_stepwise_function_incr:nnnN}
+% \begin{macro}{\prg_stepwise_function_decr:nnnN}
+%   A stepwise function. Firstly we check the direction of the steps
+%   |#2| since that will depend on which test we should use. If the
+%   step is positive we use a greater than test, otherwise a less than
+%   test.  If the test comes out true exit, otherwise perform |#4|,
+%   add the step to |#1| and try again with this new value of |#1|.
+%    \begin{macrocode}
+\def_long_new:NNn \prg_stepwise_function:nnnN 2{
+  \num_compare:nNnTF{#2}<\c_zero
+  {\exp_args:No\prg_stepwise_function_decr:nnnN }
+  {\exp_args:No\prg_stepwise_function_incr:nnnN }
+  {\int_use:N\int_eval:n{#1}}{#2}
+}
+\def_long_new:NNn \prg_stepwise_function_incr:nnnN 4{
+  \num_compare:nNnF {#1}>{#3}
+  {
+    #4{#1}
+    \exp_args:No \prg_stepwise_function_incr:nnnN 
+    {\int_use:N\int_eval:n{#1 + #2}} 
+    {#2}{#3}{#4}
+  }
+}
+\def_long_new:NNn \prg_stepwise_function_decr:nnnN 4{
+  \num_compare:nNnF {#1}<{#3}
+  {
+    #4{#1}
+    \exp_args:No \prg_stepwise_function_decr:nnnN 
+    {\int_use:N\int_eval:n{#1 + #2}} 
+    {#2}{#3}{#4}
+  }
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\l_prg_inline_level_int}
+% \begin{macro}{\prg_stepwise_inline:nnnn}
+% \begin{macro}{\prg_stepwise_inline_decr:nnnn}
+% \begin{macro}{\prg_stepwise_inline_incr:nnnn}
+%   This function uses the same approach as for instance
+%   |\clist_map_inline:Nn| to allow arbitrary nesting. First construct
+%   the special function and then call an auxiliary one which just
+%   carries the newly constructed csname.
+%    \begin{macrocode}
+\int_new:N\l_prg_inline_level_int
+\def_long_new:NNn\prg_stepwise_inline:nnnn 4{
+  \int_incr:N \l_prg_inline_level_int
+  \def:cpn{prg_stepwise_inline_\int_use:N\l_prg_inline_level_int :n}##1{#4}
+  \num_compare:nNnTF {#2}<\c_zero
+  {\exp_args:Nco \prg_stepwise_inline_decr:Nnnn }
+  {\exp_args:Nco \prg_stepwise_inline_incr:Nnnn }
+  {prg_stepwise_inline_\int_use:N\l_prg_inline_level_int :n} 
+  {\int_use:N\int_eval:n{#1}} {#2} {#3}
+  \int_decr:N \l_prg_inline_level_int
+}
+\def_long_new:NNn \prg_stepwise_inline_incr:Nnnn 4{
+  \num_compare:nNnF {#2}>{#4}
+  {
+    #1{#2}
+    \exp_args:NNo \prg_stepwise_inline_incr:Nnnn #1
+    {\int_use:N\int_eval:n{#2 + #3}} {#3}{#4}
+  }
+}
+\def_long_new:NNn \prg_stepwise_inline_decr:Nnnn 4{
+  \num_compare:nNnF {#2}<{#4}
+  {
+    #1{#2}
+    \exp_args:NNo \prg_stepwise_inline_decr:Nnnn #1
+    {\int_use:N\int_eval:n{#2 + #3}} {#3}{#4}
+  }
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\prg_stepwise_variable:nnnNn}
+% \begin{macro}{\prg_stepwise_variable_decr:nnnNn}
+% \begin{macro}{\prg_stepwise_variable_incr:nnnNn}
+%   Almost the same as above. Just store the value in |#4| and execute
+%   |#5|.
+%    \begin{macrocode}
+\def_long_new:NNn \prg_stepwise_variable:nnnNn 2 {
+  \num_compare:nNnTF {#2}<\c_zero
+  {\exp_args:No\prg_stepwise_variable_decr:nnnNn}
+  {\exp_args:No\prg_stepwise_variable_incr:nnnNn}
+  {\int_use:N\int_eval:n{#1}}{#2}
+}
+\def_long_new:NNn \prg_stepwise_variable_incr:nnnNn 5 {
+  \num_compare:nNnF {#1}>{#3}
+  {
+    \def:Npn #4{#1} #5
+    \exp_args:No \prg_stepwise_variable_incr:nnnNn
+    {\int_use:N\int_eval:n{#1 + #2}}{#2}{#3}#4{#5}
+  }
+}
+\def_long_new:NNn \prg_stepwise_variable_decr:nnnNn 5 {
+  \num_compare:nNnF {#1}<{#3}
+  {
+    \def:Npn #4{#1} #5
+    \exp_args:No \prg_stepwise_variable_decr:nnnNn
+    {\int_use:N\int_eval:n{#1 + #2}}{#2}{#3}#4{#5}
+  }
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsubsection{Booleans}
+%  For normal booleans we set them to either "\c_true" or "\c_false"
+%  and then use "\if:w" to choose the right branch. The functions
+%  return either the TF, T, or F case \emph{after} ending the |\if:w|.
+%  We only define the |N| versions here as the |c| versions can easily
+%  be constructed with the expansion module.
+%
+%  \begin{macro}{\bool_new:N}
+%  \begin{macro}{\bool_new:c}
+%  \begin{macro}{\bool_set_true:N}
+%  \begin{macro}{\bool_set_true:c}
+%  \begin{macro}{\bool_set_false:N}
+%  \begin{macro}{\bool_set_false:c}
+%  \begin{macro}{\bool_gset_true:N}
+%  \begin{macro}{\bool_gset_true:c}
+%  \begin{macro}{\bool_gset_false:N}
+%  \begin{macro}{\bool_gset_false:c}
+%  Defining and setting a boolean is easy.
+%    \begin{macrocode}
+\def_new:Npn \bool_new:N #1   { \let_new:NN #1 \c_false }
+\def_new:Npn \bool_new:c #1   { \let_new:cN #1 \c_false }
+\def_new:Npn \bool_set_true:N   #1 { \let:NN  #1 \c_true }
+\def_new:Npn \bool_set_true:c   #1 { \let:cN  #1 \c_true }
+\def_new:Npn \bool_set_false:N  #1 { \let:NN  #1 \c_false }
+\def_new:Npn \bool_set_false:c  #1 { \let:cN  #1 \c_false }
+\def_new:Npn \bool_gset_true:N   #1 { \glet:NN  #1 \c_true }
+\def_new:Npn \bool_gset_true:c   #1 { \glet:cN  #1 \c_true }
+\def_new:Npn \bool_gset_false:N  #1 { \glet:NN  #1 \c_false }
+\def_new:Npn \bool_gset_false:c  #1 { \glet:cN  #1 \c_false }
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+%  \begin{macro}{\bool_set_eq:NN}
+%  \begin{macro}{\bool_set_eq:Nc}
+%  \begin{macro}{\bool_set_eq:cN}
+%  \begin{macro}{\bool_set_eq:cc}
+%  \begin{macro}{\bool_gset_eq:NN}
+%  \begin{macro}{\bool_gset_eq:Nc}
+%  \begin{macro}{\bool_gset_eq:cN}
+%  \begin{macro}{\bool_gset_eq:cc}
+%  Setting a boolean to another is also pretty easy.
+%    \begin{macrocode}
+\let_new:NN \bool_set_eq:NN \let:NN
+\let_new:NN \bool_set_eq:Nc \let:Nc
+\let_new:NN \bool_set_eq:cN \let:cN
+\let_new:NN \bool_set_eq:cc \let:cc
+\let_new:NN \bool_gset_eq:NN \glet:NN
+\let_new:NN \bool_gset_eq:Nc \glet:Nc
+\let_new:NN \bool_gset_eq:cN \glet:cN
+\let_new:NN \bool_gset_eq:cc \glet:cc
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+%  \begin{macro}{\l_tmpa_bool}
+%  \begin{macro}{\g_tmpa_bool}
+%  A few booleans just if you need them.
+%    \begin{macrocode}
+\bool_new:N \l_tmpa_bool
+\bool_new:N \g_tmpa_bool
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%
+%  \begin{macro}{\bool_if:NTF}
+%  \begin{macro}{\bool_if:NT}
+%  \begin{macro}{\bool_if:NF}
+%  \begin{macro}{\bool_if:cTF}
+%  \begin{macro}{\bool_if:cT}
+%  \begin{macro}{\bool_if:cF}
+%  Straight forward here.
+%    \begin{macrocode}
+\def_test_function_new:npn{bool_if:N}#1{\if:w #1}
+\def_new:Npn \bool_if:cTF{\exp_args:Nc\bool_if:NTF}
+\def_new:Npn \bool_if:cT{\exp_args:Nc\bool_if:NT}
+\def_new:Npn \bool_if:cF{\exp_args:Nc\bool_if:NF}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+%  \begin{macro}{\bool_if_p:N}
+%  \begin{macro}{\bool_if_p:c}
+%  We also make a predicate function for the "bool" data type but since
+%  we use "\c_true" and "\c_false" it's rather simple\dots{}
+%  Not that there's anything wrong in simplicity -- on the contrary!
+%    \begin{macrocode}
+\def_new:Npn \bool_if_p:N #1 { #1 }
+\let_new:NN \bool_if_p:c \cs_use:c
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%
+%
+%  \begin{macro}{\bool_whiledo:NT}
+%  \begin{macro}{\bool_whiledo:cT}
+%  \begin{macro}{\bool_whiledo:NF}
+%  \begin{macro}{\bool_whiledo:cF}
+%  A "while" loop where the boolean is tested before executing the
+%  statement. The "NT" version executes the "T" part as long as the
+%  boolean is true while the "NF" version executes the "F" part as
+%  long as the boolean is false.
+%    \begin{macrocode}
+\def_long_new:Npn \bool_whiledo:NT #1 #2 {
+  \bool_if:NT #1 {#2 \bool_whiledo:NT #1 {#2}}
+}
+\def_new:Npn \bool_whiledo:cT{\exp_args:Nc\bool_whiledo:NT}
+\def_long_new:Npn \bool_whiledo:NF #1 #2 {
+  \bool_if:NF #1 {#2 \bool_whiledo:NF #1 {#2}}
+}
+\def_new:Npn \bool_whiledo:cF{\exp_args:Nc\bool_whiledo:NF}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+%  \begin{macro}{\bool_dowhile:NT}
+%  \begin{macro}{\bool_dowhile:cT}
+%  \begin{macro}{\bool_dowhile:NF}
+%  \begin{macro}{\bool_dowhile:cF}
+%  A "do-while" loop where the body is performed at least once and the
+%  boolean is tested after executing the body. Otherwise identical to
+%  the above functions.
+%    \begin{macrocode}
+\def_long_new:Npn \bool_dowhile:NT #1 #2 {
+  #2 \bool_if:NT #1 {\bool_dowhile:NT #1 {#2}}
+}
+\def_new:Npn \bool_dowhile:cT{\exp_args:Nc\bool_dowhile:NT}
+\def_long_new:Npn \bool_dowhile:NF #1 #2 {
+  #2 \bool_if:NF #1 {\bool_dowhile:NF #1 {#2}}
+}
+\def_new:Npn \bool_dowhiledo:cF{\exp_args:Nc\bool_dowhile:cF}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+%  \begin{macro}{\bool_double_if:NNnnnn}
+%  \begin{macro}{\bool_double_if:cNnnnn}
+%  \begin{macro}{\bool_double_if:Ncnnnn}
+%  \begin{macro}{\bool_double_if:ccnnnn}
+%    Execute |#3| iff TT, |#4| iff TF, |#5| iff FT and |#6| iff
+%    FF. The name isn't that great but I'll have to think about
+%    that. Ideally it should be something with |TF| since only one of
+%    the cases is executed but we haven't got any naming scheme for
+%    this kind of thing so for now I'll just stick to simple |nnnn|.
+%    \begin{macrocode}
+\def_new:Npn \bool_double_if:NNnnnn#1#2{
+  \if_case:w \num_eval:w #1\scan_stop:
+    \if_case:w \num_eval:w #2\scan_stop:
+      \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_i:nnnn
+    \else:
+      \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_ii:nnnn
+    \fi:
+  \else:
+    \if_case:w \num_eval:w #2\scan_stop:
+      \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_iii:nnnn
+    \else:
+      \exp_after:NN\exp_after:NN\exp_after:NN \use_arg_iv:nnnn
+    \fi:
+  \fi:
+}
+\def_new:Npn \bool_double_if:cNnnnn{\exp_args:Nc\bool_double_if:NNnnnn}
+\def_new:Npn \bool_double_if:Ncnnnn{\exp_args:NNc\bool_double_if:NNnnnn}
+\def_new:Npn \bool_double_if:ccnnnn{\exp_args:Ncc\bool_double_if:NNnnnn}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+% \subsubsection{Generic testing}
+%
+% \begin{macro}{\prg_whiledo:nT}
+% \begin{macro}{\prg_whiledo:nF}
+% \begin{macro}{\prg_dowhile:nT}
+% \begin{macro}{\prg_dowhile:nF}
+%   We provide these four generic while loops. |#1| is a test function
+%   and for the |T| functions it should be a test function ending with
+%   just the true case. Similar for the |F| types.
+%    \begin{macrocode}
+\def_long_new:Npn \prg_whiledo:nT #1#2{
+  #1 {#2 \prg_whiledo:nT {#1}{#2}}
+}
+\def_long_new:Npn \prg_whiledo:nF #1#2{
+  #1 {#2 \prg_whiledo:nF {#1}{#2}}
+}
+\def_long_new:Npn \prg_dowhile:nT #1#2{
+  #2 #1 {\prg_dowhile:nT {#1}{#2}}
+}
+\def_long_new:Npn \prg_dowhile:nF #1#2{
+  #2 #1 {\prg_dowhile:nF {#1}{#2}}
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%  \begin{macro}{\prg_if_predicate:nTF}
+%  \begin{macro}{\prg_if_predicate:nT}
+%  \begin{macro}{\prg_if_predicate:nF}
+%  As the boolean type is actually a predicate function, the next ones
+%  are just aliases.
+%    \begin{macrocode}
+\let_new:NN \prg_if_predicate:nTF \bool_if:NTF
+\let_new:NN \prg_if_predicate:nT  \bool_if:NT
+\let_new:NN \prg_if_predicate:nF  \bool_if:NF
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+%
+%  \begin{macro}{\prg_if_predicate_or_p:nn}
+%  \begin{macro}{\prg_if_predicate_and_p:nn}
+%  \begin{macro}{\prg_if_predicate_not_p:n}
+%  The logic operations require a little more work. The idea is to have
+%  the end result of the logic "and" and "or" functions return "00" and
+%  "01" resp.\ to be used in an "\if:w" test. The arguments of the
+%  functions are always something expanding to "\c_true" or "\c_false"
+%  which is usually resulting from a predicate function or from another
+%  logical operation. All the functions start with a "0" and depending
+%  on the results of the tests return either "0" or "1" to the input
+%  stream to form a new true or false statement.
+%
+%  The comments in the following is mostly to convince myseld of the
+%  validity of the code.
+%    \begin{macrocode}
+\def_new:Npn \prg_if_predicate_or_p:nn #1#2{
+%    \end{macrocode}
+% Form a number of the input which is one of "0000", "0001", "0100", or
+% "0101". If the truth value of both tests are false we get the "0101"
+% else we get a number less than that. So we check if the number formed
+% is less than $101$.
+%    \begin{macrocode}
+  \if_num:w #1#2<\c_hundred_one
+%    \end{macrocode}
+% If it is we put a "\c_true" back into the input stream.
+%    \begin{macrocode}
+    \c_true
+  \else:
+%    \end{macrocode}
+% Otherwise we insert "\c_false".
+%    \begin{macrocode}
+    \c_false
+  \fi:
+}
+%    \end{macrocode}
+% The "and" function is a little different. Again we can have input of
+% the types "0000", "0001", "0100", or "0101". As we require both
+% values to be \m{true} in order to continue we simply check if the
+% number formed by the input is "0" or not and then put the
+% corresponding "0" or "1" back in the input stream as above. We could
+% use "\if_num:w" for this test as well but that'll require us to read
+% the additional "=\c_zero" which runs a little slower than using
+% "\if_case:w" directly, so we use the latter.
+%    \begin{macrocode}
+\def_new:Npn \prg_if_predicate_and_p:nn #1#2{
+  \if_case:w #1#2 ~
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+%    \end{macrocode}
+% The "not" function checks a single truth value and reverses it. Here
+% we either get a "00" or "01". If the input equals "0" we put a "1"
+% in the input stream, else we put a "0". Again we use "\if_case:w"
+% because it's slightly faster.
+%    \begin{macrocode}
+\def_new:Npn \prg_if_predicate_not_p:n #1{
+  \if_case:w #1 ~
+    \c_false
+  \or:
+    \c_true
+  \fi:
+}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+%
+%  \begin{macro}{\prg_if_predicate_ors_p:n}
+%  \begin{macro}{\prg_if_predicate_ands_p:n}
+%  \begin{macro}{\prg_if_predicate_andor_aux:NNN}
+%  \begin{macro}{\prg_if_predicate_andor_break:NNN }
+%    For longer lists of predicates we can't rely on such structures
+%    as above. The "\prg_if_predicate_ands_p:n" would have been easy to
+%    program as simply
+%  \begin{verbatim}
+% \def_new:Npn \prg_if_predicate_and_p:n #1 {
+%  0\tex_ifcase:D #1 ~ \exp_after:NN 0 \else: \exp_after:NN 1 \fi:
+% }
+%  \end{verbatim}
+%  but this would fail with a "! Number too big." in case we were
+%  testing six predicate functions where the first was false. This
+%  would mean we would have to first convert the string from binary
+%  into numerical and then check. While challenging and interesting
+%  in itself (See \textsf{binhex}) it still imposes a restriction of
+%  15 predicate functions\footnote{We would probably never hit that
+%  limit but why create a restriction when we can avoid it?} and we
+%  haven't dealt with the "or" case either.
+%
+%  The solution below expands a predicate function until |\c_false| or
+%  |\c_true| are seen and expanded to |01| or |00| respectively. If
+%  we're testing the logical AND operation, all predicate functions
+%  must return \meta{true}; if they don't we can exit and return
+%  \meta{false}. In an OR operation, we just need one predicate
+%  function to return \meta{true}, the rest don't matter. Since every
+%  expansion in the internal loop results in a result of either |00|
+%  or |01|, we can test against this number to decide what to do.
+%
+%  First up is the top level functions.
+%    \begin{macrocode}
+\def_long_new:Npn \prg_if_predicate_ands_p:n #1{
+  \exp_after:NN \prg_if_predicate_andor_aux:NNN \exp_after:NN \c_true
+  \int_to_roman:w -`0 #1 \scan_stop: \scan_stop:
+}
+\def_long_new:Npn \prg_if_predicate_ors_p:n #1{
+  \exp_after:NN \prg_if_predicate_andor_aux:NNN \exp_after:NN \c_false
+  \int_to_roman:w -`0 #1 \scan_stop: \scan_stop:
+}
+%    \end{macrocode}
+% When we reach the inner loop we have already expanded all tokens in
+% the first predicate function as far as possible. This means that
+% either are arguments |#2| and |#3| \emph{both} |\scan_stop:| or else
+% |#2| is |0| and |#3| is |0| if the predicate returned \meta{true} or
+% |1| if it returned \meta{false}. If we reached the end we return
+% \meta{true} for the AND function and \meta{false} for the OR
+% function. If |#3| is |0| and we are doing the OR test, we want to
+% exit and return \meta{true}. If |#3| is |0| and we are in the AND
+% test we must continue to check the remaining predicate functions. If
+% |#3| is |1| and we are in the OR test we continue in case a later
+% predicate function returns \meta{true}. Finally, if |#3| is |1| and
+% we are in the AND test we can exit and return \meta{false} before
+% deciding what to do.
+%    \begin{macrocode}
+\def_new:Npn \prg_if_predicate_andor_aux:NNN #1#2#3{
+  \token_if_eq_meaning:NNTF \scan_stop: #2
+  { #1 }
+  { 
+    \int_compare:nNnTF #3 = #1
+    { \exp_after:NN \prg_if_predicate_andor_aux:NNN } 
+    { \exp_after:NN \prg_if_predicate_andor_break:NNN }
+    \exp_after:NN #1 \int_to_roman:w -`0
+  }
+}
+%    \end{macrocode}
+% The break loop is called when we know what the final outcome
+% is. However we keep expanding because a)~we don't know which tokens
+% we might have left dangling ahead and b)~it also provides error
+% checking on the remaining predicate functions. |#1| is \meta{false}
+% for the OR function and \meta{true} for the AND function so we
+% reverse them here.
+%    \begin{macrocode}
+\def_new:Npn \prg_if_predicate_andor_break:NNN #1#2#3{
+  \token_if_eq_meaning:NNTF \scan_stop: #2
+  { \if:w #1\c_false\else:\c_true\fi: }
+  {
+    \exp_after:NN \prg_if_predicate_andor_break:NNN \exp_after:NN #1
+    \int_to_roman:w -`0 
+  }
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro} 
+%
+% \subsubsection{Sorting}
+%
+%
+% \begin{macro}{\prg_define_quicksort:nnn}
+%   |#1| is the name, |#2| and |#3| are the tokens enclosing the
+%   argument. For the somewhat strange \meta{clist} type which doesn't
+%   enclose the items but uses a separator we define it by hand
+%   afterwards. When doing the first pass, the algorithm wraps all
+%   elements in braces and then uses a generic quicksort which works
+%   on token lists.
+%
+%   As an example
+%   \begin{quote}
+%   |\prg_define_quicksort:nnn{seq}{\seq_elt:w}{\seq_elt_end:w}|  
+%   \end{quote}
+%   defines the user function |\seq_quicksort:n| and furthermore
+%   expects to use the two functions |\seq_quicksort_compare:nnTF|
+%   which compares the items and |\seq_quicksort_function:n| which is
+%   placed before each sorted item. It is up to the programmer to
+%   define these functions when needed. For the |seq| type a sequence
+%   is a token list pointer, so one additionally has to define
+%   \begin{quote}
+%     |\def:Npn \seq_quicksort:N{\exp_args:No\seq_quicksort:n}|
+%   \end{quote}
+%
+%
+%   For details on the implementation see ``Sorting in \TeX's Mouth''
+%   by Bernd Raichle. Firstly we define the function for parsing the
+%   ininital list and then the braced list afterwards.
+%    \begin{macrocode}
+\def_new:NNn \prg_define_quicksort:nnn 3 {
+  \def_long:cNx{#1_quicksort:n}1{
+    \exp_not:c{#1_quicksort_start_partition:w} ##1
+    \exp_not:n{#2\q_nil#3\q_stop}
+  }
+  \def_long:cNx{#1_quicksort_braced:n}1{
+    \exp_not:c{#1_quicksort_start_partition_braced:n} ##1
+    \exp_not:N\q_nil\exp_not:N\q_stop
+  }
+  \def_long:cpx {#1_quicksort_start_partition:w} #2 ##1 #3{
+    \exp_not:N \quark_if_nil:nT {##1}\exp_not:N \use_none_delimit_by_q_stop:w
+    \exp_not:c{#1_quicksort_do_partition_i:nnnw} {##1}{}{} 
+  }
+  \def_long:cNx {#1_quicksort_start_partition_braced:n} 1 {
+    \exp_not:N \quark_if_nil:nT {##1}\exp_not:N \use_none_delimit_by_q_stop:w
+    \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn} {##1}{}{} 
+  }
+%    \end{macrocode}
+% Now for doing the partitions.
+%    \begin{macrocode}
+  \def_long:cpx {#1_quicksort_do_partition_i:nnnw} ##1##2##3 #2 ##4 #3 {
+    \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw}
+    {
+      \exp_not:c{#1_quicksort_compare:nnTF}{##1}{##4}
+      \exp_not:c{#1_quicksort_partition_greater_ii:nnnn}
+      \exp_not:c{#1_quicksort_partition_less_ii:nnnn}
+    }
+    {##1}{##2}{##3}{##4}
+  }
+  \def_long:cNx {#1_quicksort_do_partition_i_braced:nnnn} 4 {
+    \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw}
+    {
+      \exp_not:c{#1_quicksort_compare:nnTF}{##1}{##4}
+      \exp_not:c{#1_quicksort_partition_greater_ii_braced:nnnn}
+      \exp_not:c{#1_quicksort_partition_less_ii_braced:nnnn}
+    }
+    {##1}{##2}{##3}{##4}
+  }
+  \def_long:cpx {#1_quicksort_do_partition_ii:nnnw} ##1##2##3 #2 ##4 #3 {
+    \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw}
+    {
+      \exp_not:c{#1_quicksort_compare:nnTF}{##4}{##1}
+      \exp_not:c{#1_quicksort_partition_less_i:nnnn}
+      \exp_not:c{#1_quicksort_partition_greater_i:nnnn}
+    }
+    {##1}{##2}{##3}{##4}
+  }
+  \def_long:cNx {#1_quicksort_do_partition_ii_braced:nnnn} 4 {
+    \exp_not:N \quark_if_nil:nTF {##4} \exp_not:c {#1_do_quicksort_braced:nnnnw}
+    {
+      \exp_not:c{#1_quicksort_compare:nnTF}{##4}{##1}
+      \exp_not:c{#1_quicksort_partition_less_i_braced:nnnn}
+      \exp_not:c{#1_quicksort_partition_greater_i_braced:nnnn}
+    }
+    {##1}{##2}{##3}{##4}
+  }
+%    \end{macrocode}
+% This part of the code handles the two branches in each
+% sorting. Again we will also have to do it braced.
+%    \begin{macrocode}
+  \def_long:cNx {#1_quicksort_partition_less_i:nnnn} 4{
+    \exp_not:c{#1_quicksort_do_partition_i:nnnw}{##1}{##2}{{##4}##3}}
+  \def_long:cNx {#1_quicksort_partition_less_ii:nnnn} 4{
+    \exp_not:c{#1_quicksort_do_partition_ii:nnnw}{##1}{##2}{##3{##4}}}
+  \def_long:cNx {#1_quicksort_partition_greater_i:nnnn} 4{
+    \exp_not:c{#1_quicksort_do_partition_i:nnnw}{##1}{{##4}##2}{##3}}
+  \def_long:cNx {#1_quicksort_partition_greater_ii:nnnn} 4{
+    \exp_not:c{#1_quicksort_do_partition_ii:nnnw}{##1}{##2{##4}}{##3}}
+  \def_long:cNx {#1_quicksort_partition_less_i_braced:nnnn} 4{
+    \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn}{##1}{##2}{{##4}##3}}
+  \def_long:cNx {#1_quicksort_partition_less_ii_braced:nnnn} 4{
+    \exp_not:c{#1_quicksort_do_partition_ii_braced:nnnn}{##1}{##2}{##3{##4}}}
+  \def_long:cNx {#1_quicksort_partition_greater_i_braced:nnnn} 4{
+    \exp_not:c{#1_quicksort_do_partition_i_braced:nnnn}{##1}{{##4}##2}{##3}}
+  \def_long:cNx {#1_quicksort_partition_greater_ii_braced:nnnn} 4{
+    \exp_not:c{#1_quicksort_do_partition_ii_braced:nnnn}{##1}{##2{##4}}{##3}}
+%    \end{macrocode}
+% Finally, the big kahuna! This is where the sub-lists are sorted.
+%    \begin{macrocode}
+  \def_long:cpx {#1_do_quicksort_braced:nnnnw} ##1##2##3##4\q_stop {
+    \exp_not:c{#1_quicksort_braced:n}{##2}
+    \exp_not:c{#1_quicksort_function:n}{##1}
+    \exp_not:c{#1_quicksort_braced:n}{##3}
+  }
+}
+%    \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\prg_quicksort:n}
+%   A simple version. Sorts a list of tokens, uses the function
+%   |\prg_quicksort_compare:nnTF| to compare items, and places the
+%   function |\prg_quicksort_function:n| in front of each of them.
+%    \begin{macrocode}
+\prg_define_quicksort:nnn {prg}{}{}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prg_quicksort_function:n}
+% \begin{macro}{\prg_quicksort_compare:nnTF}
+%    \begin{macrocode}
+\let:NN \prg_quicksort_function:n \ERROR
+\let:NN \prg_quicksort_compare:nnTF \ERROR
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%  That's it (for now).
+%    \begin{macrocode}
+%
+%<*showmemory>
+\showMemUsage
+%
+%    \end{macrocode}
+%
+% \endinput
+%
+% $Log$
+% Revision 1.19  2006/08/08 10:26:09  morten
+% Fixed bugs in stepwise functions
+%
+% Revision 1.18  2006/07/30 14:41:28  morten
+% Added stepwise functions (loops going from i to k with step of j) plus quicksort.
+%
+% Revision 1.17  2006/07/06 14:57:13  morten
+% Moved code in the `miscellaneus' section to l3basics.
+%
+% Revision 1.16  2006/06/03 18:55:12  morten
+% Added special double boolean switches.
+%
+% Revision 1.15  2006/03/20 18:26:38  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.14  2006/01/19 22:31:56  morten
+% Added \bool_set_eq:NN functions plus made function collection
+% complete.
+%
+% Revision 1.13  2006/01/04 00:58:17  morten
+% Added generic loops. Changed some names plus syntax for some of the
+% logical operations. Added code for defining functions with specified
+% number of arguments.
+%
+% Revision 1.12  2005/12/27 10:01:55  morten
+% Changed RCS information retrieval. Moved tlist code to l3tlp. Added
+% code for inserting n copies of something. Changed \bool_while to
+% \bool_whiledo.
+%
+% Revision 1.11  2005/04/25 15:01:59  morten
+% Fixed some names. Improved \peek_char_generic:NNTF to not use token registers.
+%
+% Revision 1.10  2005/04/23 14:36:12  morten
+% Changed \c_left|right_brace_token to \c_group_begin_token and
+% \c_group_end_token. Fixed definitions of \tlist_if_head_XXX functions.
+% Added example for PR/3080.
+%
+% Revision 1.9  2005/04/09 21:08:43  morten
+% Documentation blunders fixed
+%
+% Revision 1.8  2005/04/06 21:27:15  morten
+% More tlist functions, Moved \engine_aleph:TF to l3basics, new peek-ahead functions, definitions of implicit characters.
+%
+% Revision 1.7  2005/03/26 21:11:14  morten
+% Fix typo in \scan_align_safe_stop:
+%
+% Revision 1.6  2005/03/22 23:23:30  morten
+% Moved \tlist_ functions from l3basics. Added align-safe versions of important functions. Reorganized documentation slightly.
+%
+% Revision 1.5  2005/03/16 22:36:10  braams
+% Added the tweaks necessary to be able to load with initex
+%
+% Revision 1.4  2005/03/11 21:28:20  braams
+% Fixed the use of RCS information; added \StopEventually
+%
diff --git a/Master/texmf-dist/source/latex/expl3/l3prop.dtx b/Master/texmf-dist/source/latex/expl3/l3prop.dtx
index e430507aabf..2315892f1a6 100644
--- a/Master/texmf-dist/source/latex/expl3/l3prop.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3prop.dtx
@@ -1,15 +1,50 @@
 % \iffalse
-%% File: l3prop.dtx Copyright (C) 1990-1998 LaTeX3 project
-%
+%% File: l3prop.dtx Copyright (C) 1990-2006 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.
+%%
+%% -----------------------------------------------------------------------
+%
+%\RequirePackage{l3names}
 %<*dtx>
-          \ProvidesFile{l3prop.dtx}
+%\fi
+\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{%
+  \def\fileversion{#2}%
+  \def\filedate{#3/#4/#5}%
+  \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]%
+}
+%\iffalse
 %
-%\NeedsTeXFormat{LaTeX2e}
-%\ProvidesPackage{l3prop}
-% \ProvidesFile{l3prop.drv}
-% \fi
-%         \ProvidesFile{l3prop.dtx}
-          [1998/05/04 v1.0e L3 Experimental Property Lists]
+%\fi
+\GetIdInfo$Id: l3prop.dtx 581 2006-12-12 12:28:27Z morten $
+          {L3 Experimental Property Lists}
 %
 % \iffalse
 %<*driver>
@@ -22,7 +57,6 @@
 % \fi
 %
 %
-% \GetFileInfo{l3prop.dtx}
 % \title{The \textsf{l3prop} package\thanks{This file
 %         has version number \fileversion, last
 %         revised \filedate.}\\
@@ -34,22 +68,22 @@
 %
 %
 % \section{Property lists}
-% 
+%
 %  \LaTeX3 implements a data structure which allows to store information
 % associated with individual tokens.
-% 
+%
 % \subsection{Functions}
-% 
+%
 % \begin{function}{%
 %                  \prop_new:N |
-%                  \prop_new:O |
+%                  \prop_new:c |
 % }
 % \begin{syntax}
 %    "\prop_new:N" 
 % \end{syntax}
 % Defines  to be a variable of type p-list.
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \prop_clear:N |
 %                  \prop_gclear:N |
@@ -59,15 +93,19 @@
 % \end{syntax}
 % These functions locally or globally clear .
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \prop_put:NNn |
+%                  \prop_put:ccn |
 %                  \prop_gput:NNn |
 %                  \prop_gput:NNo |
 %                  \prop_gput:NOo |
+%                  \prop_gput:Ncn |
 %                  \prop_gput:OOo |
 %                  \prop_gput:NOx |
+%                  \prop_gput:cNn |
 %                  \prop_gput:ccn |
+%                  \prop_gput:cco |
 %                  \prop_gput:ccx |
 % }
 % \begin{syntax}
@@ -77,7 +115,7 @@
 % . If  has already a meaning within  this value is
 % overwritten.
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \prop_gput_if_new:NNn |
 % }
@@ -88,10 +126,13 @@
 %  but only if  has so far no meaning within .
 % overwritten.
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \prop_get:NNN |
+%                  \prop_get:cNN |
 %                  \prop_gget:NNN |
+%                  \prop_gget:NcN |
+%                  \prop_gget:cNN |
 % }
 % \begin{syntax}
 %    "\prop_get:NNN"   
@@ -102,16 +143,19 @@
 %^^A See section \ref{sec:quarks} to test this.
 % The assignment is done either locally or globally.
 % \end{function}
-% 
+%
 % \begin{function}{%
-%                  \prop_set_eq:NN
+%                  \prop_set_eq:NN |
+%                  \prop_set_eq:cc |
+%                  \prop_gset_eq:NN |
+%                  \prop_gset_eq:cc
 % }
 % \begin{syntax}
 %    "\prop_set_eq:NN"  
 % \end{syntax}
 % A fast assignment of s.
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \prop_get_gdel:NNN |
 % }
@@ -121,7 +165,7 @@
 % Like "\prop_get:NNN" but additionally removes  (and its )
 % from .
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \prop_del:NN |
 %                  \prop_gdel:NN |
@@ -132,43 +176,68 @@
 % Locally or globally deletes  and its  from  if
 % found. Otherwise does nothing.
 % \end{function}
-% 
-% \begin{function}{\prop_map:NN |
-%                  \prop_map:cN
+%
+%
+% \begin{function}{\prop_map_function:NN |
+%                  \prop_map_function:cN |
+%                  \prop_map_function:cc |
 % }
 % \begin{syntax}
-%   "\prop_map:NN"  
+%   "\prop_map_function:NN"  
 % \end{syntax}
 % Maps  which should be a function with two arguments (
-% and ) over every   pair of .
+% and ) over every   pair of . Expandable.
 % \end{function}
-% 
+%
 % \begin{function}{\prop_map_inline:Nn |
 %                  \prop_map_inline:cn
 % }
 % \begin{syntax}
 %   "\prop_map_inline:Nn"  "{"  "}"
 % \end{syntax}
-% Just like "\prop_map:NN" but with the function of two arguments
-% supplied as inline code.  Within  refer to the
-% arguments via "##1" () and "##2" ().
-% 
-% Not implemented so far!
+% Just like "\prop_map_function:NN" but with the function of two arguments
+% supplied as inline code. Within  refer to the
+% arguments via "##1" () and "##2" (). Fast but not
+% expandable.
 % \end{function}
-% 
+%
+%
+%  \begin{function}{%
+%                   \prop_map_break:w |
+%  }
+%  \begin{syntax}
+%     "\prop_map_break:w"
+%  \end{syntax}
+%  For breaking out of a loop. To be used inside "TF" type functions.
+%  \end{function}
+%
+%
+%
 % \subsection{Predicates and conditionals}
-% 
-% \begin{function}{\prop_empty:NTF}
+%
+% \begin{function}{\prop_if_empty:NTF}
 % \begin{syntax}
-%   "\prop_empty:NTF"  "{""}{""}"
+%   "\prop_if_empty:NTF"  "{""}{""}"
 % \end{syntax}
 % Set of conditionals that test whether or not a particular 
 % is empty.
 % \end{function}
-% 
+%
+% \begin{function}{\prop_if_eq:NNF |
+%                  \prop_if_eq:ccF
+%                  }
+% \begin{syntax}
+%   "\prop_if_eq:NNF"   "{""}"
+% \end{syntax}
+% Execute  if  doesn't hold the same token list as
+% .
+% \end{function}
+%
+%
 % \begin{function}{%
 %                  \prop_if_in:NNTF |
 %                  \prop_if_in:NOTF |
+%                  \prop_if_in:ccTF |
 % }
 % \begin{syntax}
 %   "\prop_if_in:NNTF" "{""}{""}"
@@ -176,16 +245,16 @@
 % Tests if  is used in  and then either executes 
 % or .
 % \end{function}
-% 
+%
 % \subsection{Internal functions}
-% 
+%
 % \begin{function}{%
 %                  \prop_put_aux:w |
 %                  \prop_put_if_new_aux:w |
 % }
 % Internal functions implementing the put operations.
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \prop_get_aux:w |
 %                  \prop_get_del_aux:w |
@@ -193,26 +262,27 @@
 % }
 % Internal functions implementing the get and delete operations.
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \prop_if_in_aux:w |
 % }
 % Internal function implementing the key test operation.
 % \end{function}
-% 
+%
 % \begin{function}{%
-%                  \prop_map_aux:w |
+%                  \prop_map_function_aux:NNn |
+%                  \prop_map_inline_aux:Nn |
 % }
-% Internal function implementing the map operation.
+% Internal functions implementing the map operations.
 % \end{function}
-% 
+%
 % \begin{function}{%
-%                  \prop_map_funct:Nn |
+%                  \l_prop_inline_level_num |
 % }
-% Internal name for the function that is mapped over p-list during
-% execution of "\prop_map:NN".
+% Fake integer used in internal name for function used inside
+% "\prop_map_inline:NN".
 % \end{function}
-% 
+%
 % \begin{function}{\prop_split_aux:NNn}
 % \begin{syntax}
 %   "\prop_split_aux:NNn"   
@@ -223,20 +293,21 @@
 %  in , then the 2 arg is "\q_no_value " and the 3rd arg is
 % empty; otherwise the 3rd argument has the two extra tokens 
 % "\q_no_value" at the end.
-% 
+%
 % This function is used to implement various get operations.
 % \end{function}
-% 
-% 
-% \section {Implementation}
+%
+% \StopEventually{}
+%
+% \subsection {The Implementation}
 %
 %    We start by ensuring that the required packages are loaded.
 %    \begin{macrocode}
-%\RequirePackage{l3seq}\par
-%<*package>
+%\RequirePackage{l3toks}\par
+%<*initex|package>
 %    \end{macrocode}
-%    
-% A property list is a control sequence whose top-level expansion is
+%
+% A property list is a token register whose contents is
 % of the form `\zz{tok$\sb1$}\zv{val$\sb1$} \ldots{}
 % \zz{tok$\sb{}n$}\zv{val$\sb{}n$}'. The properties have to be single
 % token, the values might be arbitrary token lists they get surrounded
@@ -246,29 +317,39 @@
 % the appropriate functions.
 %
 % \begin{macro}{\prop_new:N}
-% \begin{macro}{\prop_new:O}
 % \begin{macro}{\prop_new:c}
-%    Property lists are a special case of sequences, so allocating
-%    them is the same as allocating sequences.
+%    Property lists are implemented as token lists.
 %    \begin{macrocode}
-\let_new:NN \prop_new:N \seq_new:N
-\let_new:NN \prop_new:O \seq_new:O
-\let_new:NN \prop_new:c \seq_new:c
+\def_new:Npn \prop_new:N #1{\toks_new:N #1}
+\def_new:Npn \prop_new:c {\exp_args:Nc \prop_new:N}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
-% \end{macro}
 %
 % \begin{macro}{\prop_clear:N}
+% \begin{macro}{\prop_clear:c}
 % \begin{macro}{\prop_gclear:N}
+% \begin{macro}{\prop_gclear:c}
 %    The same goes for clearing a property list, either
 %    locally or globally.
 %    \begin{macrocode}
-\let_new:NN \prop_clear:N \seq_clear:N
-\let_new:NN \prop_gclear:N \seq_gclear:N
+\let_new:NN \prop_clear:N \toks_clear:N
+\def_new:Npn \prop_clear:c {\exp_args:Nc\prop_clear:N}
+\let_new:NN \prop_gclear:N \toks_gclear:N
+\def_new:Npn \prop_gclear:c {\exp_args:Nc\prop_gclear:N}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\prop_use:N}
+%    The same goes for clearing a property list, either
+%    locally or globally.
+%    \begin{macrocode}
+\let_new:NN \prop_use:N \toks_use:N
+%    \end{macrocode}
+% \end{macro}
 %
 % \begin{macro}{\prop_split_aux:NNn}
 %   |\prop_split_aux:NNn|\zz{plist}\zz{prop}\zz{cmd} invokes \zz{cmd}
@@ -281,33 +362,42 @@
 %    \begin{macrocode}
 \def_long_new:Npn \prop_split_aux:NNn #1#2#3{
   \def:Npn \tmp:w ##1#2##2##3\q_stop {#3{##1}{##2}{##3}}
-  \exp_after:NN\tmp:w #1#2\q_no_value \q_stop}
+  \exp_after:NN\tmp:w \prop_use:N#1#2\q_no_value \q_stop}
 %    \end{macrocode}
 % \end{macro}
 %
 % \begin{macro}{\prop_get:NNN}
+% \begin{macro}{\prop_get:cNN}
 % \begin{macro}{\prop_get_aux:w}
 %    |\prop_get:NNN |\zz{plist}\zz{prop}\zz{tlp} defines
 %    \zz{tlp} to be the value associated with \zz{prop} in \zz{plist},
 %    |\q_no_value| if not found.
 %    \begin{macrocode}
-\def_long_new:Npn \prop_get:NNN #1#2{\prop_split_aux:NNn
-                                    #1#2\prop_get_aux:w}
-\def_long_new:Npn \prop_get_aux:w #1#2#3#4{\tlp_set:Nn#4{#2}}
+\def_long_new:NNn \prop_get:NNN 2{
+  \prop_split_aux:NNn #1#2\prop_get_aux:w}
+\def_long_new:NNn \prop_get_aux:w 4{\toks_set:Nn#4{#2}}
+\def_new:Npn \prop_get:cNN { \exp_args:Nc \prop_get:NNN }
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\prop_gget:NNN}
+% \begin{macro}{\prop_gget:NcN}
+% \begin{macro}{\prop_gget:cNN}
 % \begin{macro}{\prop_gget_aux:w}
 %    The global version of the previous function.
 %    \begin{macrocode}
-\def_long_new:Npn \prop_gget:NNN #1#2{\prop_split_aux:NNn
-                                    #1#2\prop_gget_aux:w}
-\def_long_new:Npn \prop_gget_aux:w #1#2#3#4{\tlp_gset:Nn#4{#2}}
+\def_long_new:NNn \prop_gget:NNN 2{
+  \prop_split_aux:NNn #1#2\prop_gget_aux:w}
+\def_new:Npn \prop_gget:NcN {\exp_args:NNc \prop_gget:NNN}
+\def_new:Npn \prop_gget:cNN {\exp_args:Nc \prop_gget:NNN}
+\def_long_new:NNn \prop_gget_aux:w 4{\toks_gset:Nn#4{#2}}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
+% \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\prop_get_gdel:NNN}
 % \begin{macro}{\prop_get_del_aux:w}
@@ -316,45 +406,63 @@
 %    from \m{property_list}. One probably also needs the local
 %    variants or only the local one, or\ldots\ We decide this later.
 %    \begin{macrocode}
-\def_long_new:Npn \prop_get_gdel:NNN #1#2#3{\prop_split_aux:NNn
-            #1#2{\prop_get_del_aux:w #3{\tlp_gset:Nn #1}#2}}
-\def_long_new:Npn \prop_get_del_aux:w #1#2#3#4#5#6{
-  \tlp_set:Nn #1{#5}
-  \quark_if_no_value:NF#1
-    {\def:Npn \tmp:w ##1#3\q_no_value {#2{#4##1}}
-     \tmp:w #6}}
+\def_long_new:NNn \prop_get_gdel:NNN 3{
+  \prop_split_aux:NNn #1#2{\prop_get_del_aux:w #3{\toks_gset:Nn #1}#2}}
+\def_long_new:NNn \prop_get_del_aux:w 6{
+  \quark_if_no_value:nF{#5} {
+    \def:Npn \tmp:w ##1#3\q_no_value {#2{#4##1}}
+    \tmp:w #6}
+}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
 %
 % \begin{macro}{\prop_put:NNn}
-% \begin{macro}{\prop_put_aux:w}
+% \begin{macro}{\prop_put:ccn}
 % \begin{macro}{\prop_gput:NNn}
-% \begin{macro}{\prop_gput:NNx}
 % \begin{macro}{\prop_gput:NNo}
+% \begin{macro}{\prop_gput:NNx}
 % \begin{macro}{\prop_gput:NOx}
 % \begin{macro}{\prop_gput:NOo}
+% \begin{macro}{\prop_gput:Ncn}
 % \begin{macro}{\prop_gput:OOo}
+% \begin{macro}{\prop_gput:cNn}
+% \begin{macro}{\prop_gput:ccn}
+% \begin{macro}{\prop_gput:cco}
 % \begin{macro}{\prop_gput:ccx}
+% \begin{macro}{\prop_put_aux:w}
 %    |\prop_put:NNn |\zz{plist}\zz{prop}\zv{val} adds/changes the
 %    value associated with \zz{prop} in \zz{plist} to \zv{val}.
 %    \begin{macrocode}
-\def_long_new:Npn \prop_put:NNn #1#2{\prop_split_aux:NNn
-                                #1#2{\prop_put_aux:w {\tlp_set:Nn #1}#2}}
-\def_long_new:Npn \prop_gput:NNn #1#2{\prop_split_aux:NNn
-                                #1#2{\prop_put_aux:w {\tlp_gset:Nn #1}#2}}
+\def_long_new:NNn \prop_put:NNn 2{
+  \prop_split_aux:NNn #1#2{
+    \toks_clear:N #1
+    \prop_put_aux:w {\toks_put_right:Nn #1}#2}
+}
+\def_new:Npn \prop_put:ccn {\exp_args:Ncc \prop_put:NNn }
+\def_long_new:NNn \prop_gput:NNn 2{
+  \prop_split_aux:NNn #1#2{
+    \toks_gclear:N #1
+    \prop_put_aux:w {\toks_gput_right:Nn #1}#2}
+}
 \def_new:Npn \prop_gput:NNo {\exp_args:NNNo \prop_gput:NNn}
-\def_new:Npn \prop_gput:NOx {\exp_args:Nnox \prop_gput:NNn}
 \def_new:Npn \prop_gput:NNx {\exp_args:Nnnx \prop_gput:NNn}
+\def_new:Npn \prop_gput:NOx {\exp_args:Nnox \prop_gput:NNn}
 \def_new:Npn \prop_gput:NOo {\exp_args:NNOo \prop_gput:NNn}
+\def_new:Npn \prop_gput:Ncn {\exp_args:NNc  \prop_gput:NNn }
 \def_new:Npn \prop_gput:OOo {\exp_args:NOOo \prop_gput:NNn}
+\def_new:Npn \prop_gput:cNn {\exp_args:Nc \prop_gput:NNn}
 \def_new:Npn \prop_gput:ccn {\exp_args:Ncc \prop_gput:NNn}
+\def_new:Npn \prop_gput:cco {\exp_args:Ncco \prop_gput:NNn}
 \def_new:Npn \prop_gput:ccx {\exp_args:Nccx \prop_gput:NNn}
-\def_long_new:Npn \prop_put_aux:w #1#2#3#4#5#6{
-  \quark_if_no_value:nTF {#4}
-    {#1{#2{#6}#3}}
-    {\def:Npn \tmp:w ##1#2\q_no_value {#1{#3#2{#6}##1}}
-     \tmp:w #5}}
+\def_long_new:NNn \prop_put_aux:w 6{
+  #1{#2{#6}#3}
+  \quark_if_no_value:nF {#4}
+  {
+    \def:Npn \tmp:w ##1#2\q_no_value {#1{##1}}
+    \tmp:w #5
+  }
+}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -365,6 +473,11 @@
 % \end{macro}
 % \end{macro}
 % \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\prop_del:NN}
 % \begin{macro}{\prop_gdel:NN}
@@ -372,11 +485,11 @@
 %    |\prop_del:NN |\zz{plist}\zz{prop} deletes the entry for
 %    \zz{prop} in \zz{plist}, if any.
 %    \begin{macrocode}
-\def_long_new:Npn \prop_del:NN #1#2{\prop_split_aux:NNn
-                                #1#2{\prop_del_aux:w {\tlp_set:Nn #1}#2}}
-\def_long_new:Npn \prop_gdel:NN #1#2{\prop_split_aux:NNn
-                                #1#2{\prop_del_aux:w {\tlp_gset:Nn #1}#2}}
-\def_long_new:Npn \prop_del_aux:w #1#2#3#4#5{\quark_if_no_value:nF {#4}
+\def_long_new:NNn \prop_del:NN 2{
+  \prop_split_aux:NNn #1#2{\prop_del_aux:w {\toks_set:Nn #1}#2}}
+\def_long_new:NNn \prop_gdel:NN 2{
+  \prop_split_aux:NNn #1#2{\prop_del_aux:w {\toks_gset:Nn #1}#2}}
+\def_long_new:NNn \prop_del_aux:w 5{\quark_if_no_value:nF {#4}
 %    \end{macrocode}
 %    I see no reason for updating the property list if we don't find
 %    any entry.
@@ -392,20 +505,23 @@
 %
 % \begin{macro}{\prop_if_in:NNTF}
 % \begin{macro}{\prop_if_in:NOTF}
+% \begin{macro}{\prop_if_in:ccTF}
 % \begin{macro}{\prop_if_in_aux:w}
 %    |\prop_if_in:NNTF| \m{property_list} \m{property_key}
 %    \m{true_case} \m{false_case} will check whether or not
 %    \m{property_key} is on the \m{property_list} and then select
 %    either the true or false case.
 %    \begin{macrocode}
-\def_new:Npn \prop_if_in:NNTF #1#2{\prop_split_aux:NNn
-                                #1#2\prop_if_in_aux:w}
+\def_new:NNn \prop_if_in:NNTF 2{
+  \prop_split_aux:NNn #1#2\prop_if_in_aux:w}
 \def_new:Npn \prop_if_in:NOTF {\exp_args:Nno \prop_if_in:NNTF}
-\def_new:Npn \prop_if_in_aux:w #1#2#3{\quark_if_no_value:nTF {#2}}
+\def_new:Npn \prop_if_in:ccTF {\exp_args:Ncc \prop_if_in:NNTF}
+\def_new:NNn \prop_if_in_aux:w 3{\quark_if_no_value:nFT {#2}}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
 % \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\prop_gput_if_new:NNn}
 %    |\prop_gput_if_new:NNn| \m{property_list} \m{property_key}
@@ -423,66 +539,183 @@
 %    F. and Louis A. which makes writing macros sometimes difficult; I
 %    find myself humming instead of working):
 %    \begin{macrocode}
-\def_long_new:Npn \prop_gput_if_new:NNn #1#2{\prop_split_aux:NNn #1#2
-        {\prop_put_if_new_aux:w #1#2}}
-\def_long_new:Npn \prop_put_if_new_aux:w #1#2#3#4#5#6{
+\def_long_new:NNn \prop_gput_if_new:NNn 2{
+  \prop_split_aux:NNn #1#2{\prop_put_if_new_aux:w #1#2}}
+\def_long_new:NNn \prop_put_if_new_aux:w 6{
   \quark_if_no_value:nT {#4}{#1{#2{#6}#3}}}
 %    \end{macrocode}
 % \end{macro}
 %
 %
 % \begin{macro}{\prop_set_eq:NN}
+% \begin{macro}{\prop_set_eq:Nc}
+% \begin{macro}{\prop_set_eq:cN}
+% \begin{macro}{\prop_set_eq:cc}
+% \begin{macro}{\prop_gset_eq:NN}
+% \begin{macro}{\prop_gset_eq:Nc}
+% \begin{macro}{\prop_gset_eq:cN}
+% \begin{macro}{\prop_gset_eq:cc}
 %    This makes two \m{plist}s have the same contents.
 %    \begin{macrocode}
-\let_new:NN\prop_set_eq:NN\tlp_set_eq:NN
+\let_new:NN \prop_set_eq:NN  \toks_set_eq:NN
+\let_new:NN \prop_set_eq:Nc \toks_set_eq:Nc
+\let_new:NN \prop_set_eq:cN  \toks_set_eq:cN
+\let_new:NN \prop_set_eq:cc \toks_set_eq:cc
+\let_new:NN \prop_gset_eq:NN  \toks_gset_eq:NN
+\let_new:NN \prop_gset_eq:Nc \toks_gset_eq:Nc
+\let_new:NN \prop_gset_eq:cN  \toks_gset_eq:cN
+\let_new:NN \prop_gset_eq:cc \toks_gset_eq:cc
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
 %
-% \begin{macro}{\prop_empty:NTF}
+% \begin{macro}{\prop_if_empty_p:N}
+% \begin{macro}{\prop_if_empty_p:c}
+% \begin{macro}{\prop_if_empty:NTF}
+% \begin{macro}{\prop_if_empty:NT}
+% \begin{macro}{\prop_if_empty:NF}
+% \begin{macro}{\prop_if_empty:cTF}
+% \begin{macro}{\prop_if_empty:cT}
+% \begin{macro}{\prop_if_empty:cF}
 %    This conditional takes a \m{plist} as its argument and evaluates
 %    either the true or the false case, depending on whether or not
 %    \m{plist} contains any properties.
 %    \begin{macrocode}
-\let_new:NN \prop_empty:NTF \tlp_empty:NTF
+\let_new:NN \prop_if_empty_p:N \toks_if_empty_p:N
+\let_new:NN \prop_if_empty_p:c \toks_if_empty_p:c
+\let_new:NN \prop_if_empty:NTF \toks_if_empty:NTF
+\let_new:NN \prop_if_empty:NT  \toks_if_empty:NT
+\let_new:NN \prop_if_empty:NF  \toks_if_empty:NF
+\let_new:NN \prop_if_empty:cTF \toks_if_empty:cTF
+\let_new:NN \prop_if_empty:cT  \toks_if_empty:cTF
+\let_new:NN \prop_if_empty:cF  \toks_if_empty:cF
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
 %
+% \begin{macro}{\prop_if_eq:NNTF}
+% \begin{macro}{\prop_if_eq:NNT}
+% \begin{macro}{\prop_if_eq:NNF}
+% \begin{macro}{\prop_if_eq:NcTF}
+% \begin{macro}{\prop_if_eq:NcT}
+% \begin{macro}{\prop_if_eq:NcF}
+% \begin{macro}{\prop_if_eq:cNTF}
+% \begin{macro}{\prop_if_eq:cNT}
+% \begin{macro}{\prop_if_eq:cNF}
+% \begin{macro}{\prop_if_eq:ccTF}
+% \begin{macro}{\prop_if_eq:ccT}
+% \begin{macro}{\prop_if_eq:ccF}
+%    This function test whether the property lists that are in its first
+%    two arguments are equal; if they are not |#3| is executed.
+%    \begin{macrocode}
+\def_new:NNn \prop_if_eq:NNTF 2 {
+  \tlist_if_eq:xxTF{\prop_use:N #1}{\prop_use:N #2}
+}
+\def_new:NNn \prop_if_eq:NNT 2 {
+  \tlist_if_eq:xxT{\prop_use:N #1}{\prop_use:N #2}
+}
+\def_new:NNn \prop_if_eq:NNF 2 {
+  \tlist_if_eq:xxF{\prop_use:N #1}{\prop_use:N #2}
+}
+\def_new:Npn \prop_if_eq:NcTF {\exp_args:NNc \prop_if_eq:NNTF}
+\def_new:Npn \prop_if_eq:NcT {\exp_args:NNc \prop_if_eq:NNT}
+\def_new:Npn \prop_if_eq:NcF {\exp_args:NNc \prop_if_eq:NNF}
+\def_new:Npn \prop_if_eq:cNTF {\exp_args:Nc \prop_if_eq:NNTF}
+\def_new:Npn \prop_if_eq:cNT {\exp_args:Nc \prop_if_eq:NNT}
+\def_new:Npn \prop_if_eq:cNF {\exp_args:Nc \prop_if_eq:NNF}
+\def_new:Npn \prop_if_eq:ccTF {\exp_args:Ncc \prop_if_eq:NNTF}
+\def_new:Npn \prop_if_eq:ccT {\exp_args:Ncc \prop_if_eq:NNT}
+\def_new:Npn \prop_if_eq:ccF {\exp_args:Ncc \prop_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}{\prop_map:NN}
-% \begin{macro}{\prop_map:cN}
-% \begin{macro}{\prop_map_funct:Nn}
+% \begin{macro}{\prop_map_function:NN}
+% \begin{macro}{\prop_map_function:cN}
+% \begin{macro}{\prop_map_function:cc}
+% \begin{macro}{\prop_map_function_aux:NNn}
 %    Maps a function on every entry in the property list.  The
 %    function must take 2 arguments: a key and a value.
 %    \begin{macrocode}
-\let_new:NN \prop_map_funct:Nn \use_none:nn
-\def_new:Npn \prop_map:NN #1#2{
-  \let:NN \prop_map_funct:Nn #2
-  \exp_after:NN\prop_map_aux:w #1\q_stop \q_stop}
-\def_new:Npn \prop_map_aux:w #1#2{
-  \if_meaning:NN#1\q_stop \else:
-    \prop_map_funct:Nn #1{#2}
-    \exp_after:NN\prop_map_aux:w
-  \fi:}
-\def_new:Npn \prop_map:cN { \exp_args:Nc \prop_map:NN }
+\def_new:Npn \prop_map_function:NN #1#2{
+    \exp_after:NN \prop_map_function_aux:NNn
+    \exp_after:NN #2 \prop_use:N #1 \q_nil \q_no_value \q_stop
+}
+\def_new:Npn \prop_map_function_aux:NNn #1#2#3{
+  \if_meaning:NN \q_nil #1
+    \exp_after:NN \prop_map_break:w
+  \fi:
+  #1#2{#3}
+  \prop_map_function_aux:NNn #1
+}
+\def_new:Npn \prop_map_function:cN {\exp_args:Nc \prop_map_function:NN }
+\def_new:Npn \prop_map_function:cc {\exp_args:Ncc \prop_map_function:NN}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
 % \end{macro}
-%
+% \end{macro}
 %
 %  \begin{macro}{\prop_map_inline:Nn}
 %  \begin{macro}{\prop_map_inline:cn}
-%    To be supplied.
+%  \begin{macro}{\prop_map_inline_aux:Nn}
+%  \begin{macro}{\l_prop_inline_level_num}
+%  The inline functions are straight forward. It takes longer
+%  to test if the list is empty than to run it on an empty list so
+%  we don't waste time doing that.
 %    \begin{macrocode}
-\let_new:NN \prop_map_inline:Nn \ERROR
-\let_new:NN \prop_map_inline:cn \ERROR
+\num_new:N \l_prop_inline_level_num
+\def_new:Npn \prop_map_inline:Nn #1#2 {
+  \num_incr:N \l_prop_inline_level_num
+  \def_long:cpn {prop_map_inline_ \num_use:N \l_prop_inline_level_num :n} 
+    ##1##2{#2}
+  \exp_args:NcE \prop_map_function:N
+    {prop_map_inline_ \num_use:N \l_prop_inline_level_num :n} 
+    \prop_use:N #1 
+  \q_nil \q_no_value \q_stop
+  \num_decr:N \l_prop_inline_level_num
+}
+\def_new:Npn \prop_map_inline:cN { \exp_args:Nc \prop_map_inline:NN }
+
 %    \end{macrocode}
 %  \end{macro}
 %  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+%  \begin{macro}{\prop_map_break:w}
+%  The break statement.
+%    \begin{macrocode}
+\let_new:NN \prop_map_break:w \use_none_delimit_by_q_stop:w
+%    \end{macrocode}
+%  \end{macro}
 %
 %    Show token usage:
 %    \begin{macrocode}
-%
+%
 %<*showmemory>
 %\showMemUsage
 %
@@ -596,4 +829,22 @@
 %
 %    \end{macrocode}
 %
-
+% \endinput
+%
+% $Log$
+% Revision 1.15  2006/03/20 18:26:38  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.14  2005/12/27 16:00:44  morten
+% Update map functions and changed RCS information retrieval
+%
+% Revision 1.13  2005/03/22 23:26:14  morten
+% Added more functions, removed dependency of l3seq
+%
+% Revision 1.12  2005/03/16 22:36:04  braams
+% Added the tweaks necessary to be able to load with initex
+%
+% Revision 1.11  2005/03/11 21:40:35  braams
+% Fixed the use of RCS information; added \StopEventually
+%
diff --git a/Master/texmf-dist/source/latex/expl3/l3quark.dtx b/Master/texmf-dist/source/latex/expl3/l3quark.dtx
index 1f95aa6fe71..2511109c1cf 100644
--- a/Master/texmf-dist/source/latex/expl3/l3quark.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3quark.dtx
@@ -1,15 +1,50 @@
 % \iffalse
-%% File: l3quark.dtx Copyright (C) 1990-1998 LaTeX3 project
+%% File: l3quark.dtx Copyright (C) 1990-2006 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.
+%%
+%% -----------------------------------------------------------------------
 %
+%\RequirePackage{l3names}
 %<*dtx>
-          \ProvidesFile{l3quark.dtx}
+%\fi
+\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{%
+  \def\fileversion{#2}%
+  \def\filedate{#3/#4/#5}%
+  \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]%
+}
+%\iffalse
 %
-%\NeedsTeXFormat{LaTeX2e}
-%\ProvidesPackage{l3quark}
-% \ProvidesFile{l3quark.drv}
-% \fi
-%         \ProvidesFile{l3quark.dtx}
-          [1998/05/20 v1.0e L3 Experimental Quark Commands]
+%\fi
+\GetIdInfo$Id: l3quark.dtx 573 2006-08-21 20:59:37Z morten $
+          {L3 Experimental Quark Commands}
 %
 % \iffalse
 %<*driver>
@@ -22,7 +57,6 @@
 % \fi
 %
 %
-% \GetFileInfo{l3quark.dtx}
 % \title{The \textsf{l3quark} package\thanks{This file
 %         has version number \fileversion, last
 %         revised \filedate.}\\
@@ -34,23 +68,25 @@
 %
 % \section{Quarks}
 %^^A \label{sec:quarks}
-% 
-%    
+%
+%
 % A special type of constants in \LaTeX3 are `quarks'. These are control
 % sequences that expand to themselves and should therefore NEVER be
 % executed directly in the code. This would result in an endless loop!
-% 
-% They are meant to be used as delimiter is weird functions (for example
-% as the stop token (i.e., "\q_stop"). They also permit the following
-% ingenious trick: when you pick up a token in a temporary, and you want
-% to know whether you have picked up a particular quark, all you have to
-% do is compare the temporary to the quark using "\if_meaning:NN". A
-% set of special quark testing functions is set up below.
-% 
+%
+% They are meant to be used as delimiter is weird functions (for
+% example as the stop token (i.e., "\q_stop"). They also permit the
+% following ingenious trick: when you pick up a token in a temporary,
+% and you want to know whether you have picked up a particular quark,
+% all you have to do is compare the temporary to the quark using
+% "\if_meaning:NN". A set of special quark testing functions is set up
+% below. All the quark testing functions are expandable although the
+% ones testing only single tokens are much faster.
+%
 % By convention all constants of type quark start out with "\q_".
-% 
+%
 % \subsection{Functions}
-% 
+%
 % \begin{function}{%
 %                  \quark_new:N |
 % }
@@ -59,28 +95,33 @@
 % \end{syntax}
 % Defines  to be a new constant of type "quark".
 % \end{function}
-% 
+%
 % \begin{function}{%
+%                  \quark_if_no_value_p:n |
 %                  \quark_if_no_value:nTF |
 %                  \quark_if_no_value:nF  |
 %                  \quark_if_no_value:nT  |
+%                  \quark_if_no_value_p:N |
 %                  \quark_if_no_value:NTF |
+%                  \quark_if_no_value:NT  |
 %                  \quark_if_no_value:NF  |
 % }
 % \begin{syntax}
-%    "\quark_if_no_value:nTF" "{"  "}"
+%    "\quark_if_no_value:nTF" "{""}"
 %                          "   {""}{""}"
 %    "\quark_if_no_value:NTF" 
 %                          "   {""}{""}"
 % \end{syntax}
 % This tests whether or not  contains only the quark
 % "\q_no_value".
-% 
+%
 % If  to be tested is stored in a token list pointer use
 % "\quark_if_no_value:NTF", or "\quark_if_no_value:NF" or check the
 % value directly with "\if_meaning:NN". All those cases are faster then
-% "\quark_if_no_value:nTF" so should be preferred.
-% 
+% "\quark_if_no_value:nTF" so should be preferred.\footnote{Clarify
+% semantic of the ``n'' case \ldots{} i think it is not implement
+% according to what we originally intended /FMi}
+%
 % \begin{texnote}
 % But  be aware of the fact that "\if_meaning:NN" can result in an
 % overflow of \TeX{}'s parameter stack since it leaves the corresponding
@@ -90,33 +131,75 @@
 % and so allows tail-recursion.
 % \end{texnote}
 % \end{function}
-% 
+%
+% \begin{function}{%
+%                  \quark_if_nil_p:N |
+%                  \quark_if_nil:NTF |
+%                  \quark_if_nil:NT |
+%                  \quark_if_nil:NF  |
+% }
+% \begin{syntax}
+%    "\quark_if_nil:NTF" 
+%                          "  {""}{""}"
+% \end{syntax}
+% This tests whether or not  is equal to the quark
+% "\q_nil".
+%
+% This is a useful test for recursive loops which typically has 
+% "\q_nil" as an end marker.
+% \end{function}
+%
+%
+% \begin{function}{%
+%                  \quark_if_nil_p:n |
+%                  \quark_if_nil:nTF |
+%                  \quark_if_nil:nT |
+%                  \quark_if_nil:nF  |
+%                  \quark_if_nil_p:o |
+%                  \quark_if_nil:oTF |
+%                  \quark_if_nil:oT |
+%                  \quark_if_nil:oF  |
+% }
+% \begin{syntax}
+%    "\quark_if_nil:nTF" "{""}"
+%                        "{""}{""}"
+% \end{syntax}
+% This tests whether or not  is equal to the quark
+% "\q_nil".
+%
+% This is a useful test for recursive loops which typically has
+% "\q_nil" as an end marker.
+% \end{function}
+%
+%
 % \subsection{Constants}
-% 
+%
 % \begin{variable}{\q_no_value} The canonical `missing value quark'
 % that is returned by certain functions to denote that a requested value
 % is not found in the data structure.
 % \end{variable}
-% 
+%
 % \begin{variable}{\q_stop}
 % This constant is used as a a marker in parameter text. This allows a
 % scanning function to find the end of some input string.
 % \end{variable}
-% 
+%
 % \begin{variable}{\q_nil}
 % This constant represent the nil pointer in pointer structures.
 % \end{variable}
-% 
-% \section{Implementation}
+%
+% \StopEventually{}
+%
+% \subsection{The Implementation}
 %
 %    We start by ensuring that the required packages are loaded.
 %    We check for \texttt{l3expan} since this a basic package that is
 %    essential for use of any higher-level package.
 %    \begin{macrocode}
 %\RequirePackage{l3expan}\par
-%<*package>
+%<*initex|package>
 %    \end{macrocode}
-%    
+%
 % \begin{macro}{\quark_new:N}
 %    Allocate a new quark.
 %    \begin{macrocode}
@@ -153,60 +236,193 @@
 % \end{macro}
 %
 %
+% \begin{macro}{\quark_if_no_value_p:N}
 % \begin{macro}{\quark_if_no_value:NTF}
+% \begin{macro}{\quark_if_no_value:NT}
 % \begin{macro}{\quark_if_no_value:NF}
+% \begin{macro}{\quark_if_no_value_p:n}
 % \begin{macro}{\quark_if_no_value:nTF}
 % \begin{macro}{\quark_if_no_value:nT}
 % \begin{macro}{\quark_if_no_value:nF}
+% \begin{macro}{\quark_if_no_value:nFT}
 %    Here we test if we found a special quark as the first argument.
-%    The argument might contain an arbitrary list of tokens, therefore
-%    we have to wrap it up in a token list pointer.
 %    \begin{macrocode}
-\def_new:Npn \quark_if_no_value:NTF #1{
+\def_long_test_function_new:npn {quark_if_no_value:N} #1 {
 %    \end{macrocode}
 %    We better start with |\q_no_value| as the first argument since
 %    the whole thing may otherwise loop if |#1| is wrongly given
 %    a string like |aabc| instead of a single token.\footnote{It may
 %    still loop in special circumstances however!}
 %    \begin{macrocode}
-     \if_meaning:NN\q_no_value#1
-          \exp_after:NN\use_choice_i:nn
-     \else: \exp_after:NN\use_choice_ii:nn \fi:}
+     \if_meaning:NN\q_no_value#1}
+\def_long_new:Npn \quark_if_no_value_p:N #1{
+  \if_meaning:NN \q_no_value #1 \c_true
+  \else: \c_false \fi:
+}
 %    \end{macrocode}
-%    It would be possible to speed up the following commands by
-%    providing individual implementations similar to the one above.
-%    Should perhaps be done if they are used often!
+% We also provide an |n| type. If run under a sufficiently new
+% pdf\eTeX, it uses a built-in primitive for string comparisons,
+% otherwise it uses the slower |\str_if_eq_var_p:nf| function. In the
+% latter case it would be faster to use a temporary token list pointer
+% but it would render the function non-expandable. Using the pdf\eTeX\
+% primitive is the preferred approach. Note that we have to add a
+% manual space token in the first part of the comparison, otherwise it
+% is gobbled by |\str_if_eq_var_p:nf|. The reason for using this
+% function instead of |\str_if_eq_p:nn| is that a sequence like
+% \verb*+ \q_no_value+ will test equal to |\q_no_value| using the
+% latter test function and unfortunately this example turned up in one
+% application.
 %    \begin{macrocode}
-\def_new:Npn \quark_if_no_value:NF #1{\quark_if_no_value:NTF {#1}\use_noop:}
-\def_new:Npn \quark_if_no_value:nTF #1{\tlp_gset:Nn \g_testa_tlp {#1}
-    \quark_if_no_value:NTF\g_testa_tlp}
-\def_new:Npn \quark_if_no_value:nF #1{\quark_if_no_value:nTF {#1}\use_noop:}
-\def_new:Npn \quark_if_no_value:nT #1#2{\quark_if_no_value:nTF {#1}
-        {#2}\use_noop:}
+\cs_if_really_free:cTF{pdf_strcmp:D}{
+  \def_long_new:Npn \quark_if_no_value_p:n #1{
+    \if:w \exp_args:No \str_if_eq_var_p:nf 
+%      {\token_to_string:N\q_no_value\space}
+%      {\token_to_string:N\q_no_value\text_put_sp:}
+      {\tlist_to_str:n{#1}}
+      \c_true
+    \else:
+      \c_false
+    \fi:
+  }
+}
+{
+  \def_long_new:Npn \quark_if_no_value_p:n #1{
+    \if_num:w 
+    \pdf_strcmp:D {\exp_not:N \q_no_value}{\exp_not:n{#1}}=\c_zero 
+    \c_true \else: \c_false \fi:
+  }
+}
+\def_long_test_function_new:npn {quark_if_no_value:n} #1 {
+  \if:w \quark_if_no_value_p:n{#1}}
 %    \end{macrocode}
+% We also define a version where the true and false code is ordered
+% differently.
+%    \begin{macrocode}
+\def_long:Npn \quark_if_no_value:nFT #1{
+  \if:w \quark_if_no_value_p:n{#1}
+      \exp_after:NN\use_arg_ii:nn
+    \else:
+      \exp_after:NN\use_arg_i:nn
+    \fi:
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
 % \end{macro}
 % \end{macro}
 % \end{macro}
 % \end{macro}
 % \end{macro}
 %
+% \begin{macro}{\quark_if_nil_p:N}
 % \begin{macro}{\quark_if_nil:NTF}
+% \begin{macro}{\quark_if_nil:NT}
+% \begin{macro}{\quark_if_nil:NF}
+%    A function to check for the presence of |\q_nil|.
+%    \begin{macrocode}
+\def_long_new:Npn \quark_if_nil_p:N #1{
+  \if_meaning:NN \q_nil #1 \c_true
+  \else: \c_false \fi:
+}
+\def_long_test_function_new:npn {quark_if_nil:N}#1{
+  \if_meaning:NN\q_nil#1}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\quark_if_nil_p:n}
+% \begin{macro}{\quark_if_nil:nTF}
+% \begin{macro}{\quark_if_nil:nT}
+% \begin{macro}{\quark_if_nil:nF}
+% \begin{macro}{\quark_if_nil_p:o}
+% \begin{macro}{\quark_if_nil:oTF}
+% \begin{macro}{\quark_if_nil:oT}
+% \begin{macro}{\quark_if_nil:oF}
 %    A function to check for the presence of |\q_nil|.
 %    \begin{macrocode}
-\def_new:Npn\quark_if_nil:NTF#1{
-  \if_meaning:NN#1\q_nil
-    \exp_after:NN\use_choice_i:nn
-  \else:
-    \exp_after:NN\use_choice_ii:nn\fi:}
+\cs_if_really_free:cTF{pdf_strcmp:D}{
+  \def_long_new:Npn \quark_if_nil_p:n #1{
+    \if:w \exp_args:No \str_if_eq_var_p:nf 
+%      {\token_to_string:N\q_nil\space}
+%      {\token_to_string:N\q_nil\text_put_sp:}
+      {\tlist_to_str:n{#1}}
+      \c_true
+    \else:
+      \c_false
+    \fi:
+  }
+}
+{
+  \def_long_new:Npn \quark_if_nil_p:n #1{
+    \if_num:w 
+    \pdf_strcmp:D {\exp_not:N \q_nil}{\exp_not:n{#1}}=\c_zero 
+    \c_true \else: \c_false \fi:
+  }
+}
+\def_long_test_function_new:npn {quark_if_nil:n} #1 {
+  \if:w \quark_if_nil_p:n{#1}}
+\def_new:Npn \quark_if_nil_p:o{\exp_args:No\quark_if_nil_p:n}
+\def_new:Npn \quark_if_nil:oTF{\exp_args:No\quark_if_nil:nTF}
+\def_new:Npn \quark_if_nil:oT {\exp_args:No\quark_if_nil:nT}
+\def_new:Npn \quark_if_nil:oF {\exp_args:No\quark_if_nil:nF}
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
 %
 %    Show token usage:
 %    \begin{macrocode}
-%
+%
 %<*showmemory>
 \showMemUsage
 %
 %    \end{macrocode}
 %
+% \endinput
+%
+% $Log$
+% Revision 1.22  2006/07/30 14:39:02  morten
+% Changed all quark functions to be expandable regardless of whether
+% \pdfstrcmp is available.
+%
+% Revision 1.21  2006/07/25 15:34:21  morten
+% Added the non-expandable \quark_if_nil:nTF plus variants.
+%
+% Revision 1.20  2006/07/23 13:43:47  morten
+% Fixed minor bug in \quark_if_no_value_p:n
+%
+% Revision 1.19  2006/03/20 18:26:38  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.18  2006/01/04 01:18:31  morten
+% Changed \quark_if_no_value:nTF to be expandable. Added a few predicate
+% functions and updated documentation.
+%
+% Revision 1.17  2005/12/27 10:04:41  morten
+% Minor changes plus changed RCS information retrieval
+%
+% Revision 1.16  2005/10/27 14:12:28  morten
+% Added gobble-until-quark functions.
+%
+% Revision 1.15  2005/07/14 18:50:31  morten
+% Added \quark_if_nil:NF
+%
+% Revision 1.14  2005/04/06 13:55:57  morten
+% Fixed \quark_if_nil:NTF
+%
+% Revision 1.13  2005/03/16 22:35:57  braams
+% Added the tweaks necessary to be able to load with initex
+%
+% Revision 1.12  2005/03/11 21:41:27  braams
+% Fixed the use of RCS information; added \StopEventually
 %
diff --git a/Master/texmf-dist/source/latex/expl3/l3seq.dtx b/Master/texmf-dist/source/latex/expl3/l3seq.dtx
index f3da69642ef..dff922a84d2 100644
--- a/Master/texmf-dist/source/latex/expl3/l3seq.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3seq.dtx
@@ -1,15 +1,51 @@
 % \iffalse
-%% File: l3seq.dtx Copyright (C) 1990-1998 LaTeX3 project
-%
+%% File: l3seq.dtx Copyright (C) 1990-2006 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.
+%%
+%% -----------------------------------------------------------------------
+%
+%\RequirePackage{l3names}
 %<*dtx>
-          \ProvidesFile{l3seq.dtx}
+%\fi
+\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{%
+  \def\fileversion{#2}%
+  \def\filedate{#3/#4/#5}%
+  \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]%
+}
+%\iffalse
 %
-%\NeedsTeXFormat{LaTeX2e}
-%\ProvidesPackage{l3seq}
-% \ProvidesFile{l3seq.drv}
-% \fi
-%         \ProvidesFile{l3seq.dtx}
-          [1998/04/20 v1.0d L3 Experimental Token List Pointers]
+%\fi
+\GetIdInfo$Id: l3seq.dtx 573 2006-08-21 20:59:37Z morten $
+          {L3 Experimental sequences and stacks}
+%
 %
 % \iffalse
 %<*driver>
@@ -22,7 +58,6 @@
 % \fi
 %
 %
-% \GetFileInfo{l3seq.dtx}
 % \title{The \textsf{l3seq} package\thanks{This file
 %         has version number \fileversion, last
 %         revised \filedate.}\\
@@ -33,8 +68,8 @@
 %
 %
 %
-% \section{Sequence}
-% 
+% \section{Sequences}
+%
 % \LaTeX3 implements a data type called `sequences'. These are special
 % token lists that can be accessed via special function on the `left'.
 % Appending tokens is possible at both ends. Appended token lists can be
@@ -43,26 +78,25 @@
 % functions that are used to structure sequences (see section internal
 % functions below).  It is also possible to map functions on such
 % sequences so that they are executed for every item on the sequence.
-% 
-% All functions that return items from a sequence in some  assume
-% that the  is local. See remarks below if you need a global
+%
+% All functions that return items from a sequence in some \m{tlp} assume
+% that the \m{tlp} is local. See remarks below if you need a global
 % returned value.
-% 
+%
 % The defined functions are not orthogonal in the sense that every
 % possible variation possible is actually available. If you need a new
 % variant use the expansion functions described in the package
 % \texttt{l3expan} to build it.
-% 
+%
 % Adding items to the left of a sequence can currently be done with
 % either something like "\seq_put_left:Nn" or with a ``stack'' function
 % like "\seq_push:Nn" which has the same effect. Maybe one should
 % therefore remove the ``left'' functions totally.
-% 
+%
 % \subsection{Functions}
-% 
+%
 % \begin{function}{%
 %                  \seq_new:N |
-%                  \seq_new:O |
 %                  \seq_new:c |
 % }
 % \begin{syntax}
@@ -70,7 +104,7 @@
 % \end{syntax}
 % Defines  to be a variable of type sequences.
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \seq_clear:N |
 %                  \seq_clear:c |
@@ -82,7 +116,7 @@
 % \end{syntax}
 % These functions locally or globally clear .
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \seq_put_left:Nn |
 %                  \seq_put_left:No |
@@ -99,10 +133,11 @@
 % or right of .  might get expanded before
 % appending.
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \seq_gput_left:Nn |
 %                  \seq_gput_right:Nn |
+%                  \seq_gput_right:Nc |
 %                  \seq_gput_right:No |
 %                  \seq_gput_right:cn |
 %                  \seq_gput_right:co |
@@ -114,7 +149,7 @@
 % Globally appends  as a single item to the left
 % or right of .
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \seq_get:NN |
 %                  \seq_get:cN |
@@ -132,7 +167,30 @@
 % But if this kind of construction is used often enough a separate
 % function should be provided.
 % \end{function}
-% 
+%
+% \begin{function}{%
+%                  \seq_set_eq:NN
+% }
+% \begin{syntax}
+%   "\seq_set_eq:NN"  
+% \end{syntax}
+% Function that locally makes  identical to .
+% \end{function}
+%
+%
+%
+% \begin{function}{%
+%                  \seq_gset_eq:NN |
+%                  \seq_gset_eq:cN |
+%                  \seq_gset_eq:Nc |
+%                  \seq_gset_eq:cc
+% }
+% \begin{syntax}
+%   "\seq_gset_eq:NN"  
+% \end{syntax}
+% Function that globally makes  identical to .
+% \end{function}
+%
 % \begin{function}{%
 %                  \seq_gconcat:NNN |
 %                  \seq_gconcat:ccc |
@@ -143,7 +201,19 @@
 % Function that conatenates  and  and globally assigns the
 % result to .
 % \end{function}
-% 
+%
+% \begin{function}{\seq_map_variable:NNn |
+%                  \seq_map_variable:cNn
+% }
+% \begin{syntax}
+%   "\seq_map_variable:NNn"   "{"  "}"
+% \end{syntax}
+% Every element in  is assigned to  and then  is executed. The operation is not expandable which means
+% that it can't be used within write operations etc. However, this
+% function can be nested which the others can't.
+% \end{function}
+%
 % \begin{function}{\seq_map:NN}
 % \begin{syntax}
 %    "\seq_map:NN"  
@@ -153,11 +223,11 @@
 % within a sub-group so that side effects can be achieved locally. The
 % operation is not expandable which means that it can't be used within
 % write operations etc.
-% 
+%
 % In the current implementation the next functions are more efficient and
 % should be preferred.
 % \end{function}
-% 
+%
 % \begin{function}{\seq_map_inline:Nn |
 %                  \seq_map_inline:cn
 % }
@@ -171,34 +241,37 @@
 % The operation is not expandable which means that it can't be used
 % within write operations etc.
 % \end{function}
-% 
+%
 % \subsection{Predicates and conditionals}
-% 
-% \begin{function}{\seq_empty_p:N}
+%
+% \begin{function}{\seq_if_empty_p:N}
 % \begin{syntax}
-%   "\seq_empty_p:N" 
+%   "\seq_if_empty_p:N" 
 % \end{syntax}
 % This predicate returns `true' if  is `empty' i.e., doesn't
 % contain any tokens.
 % \end{function}
-% 
+%
 % \begin{function}{%
-%                  \seq_empty:NTF |
-%                  \seq_empty:cTF |
-%                  \seq_empty:NF |
-%                  \seq_empty:cF |
+%                  \seq_if_empty:NTF |
+%                  \seq_if_empty:cTF |
+%                  \seq_if_empty:NF |
+%                  \seq_if_empty:cF |
 % }
 % \begin{syntax}
-%   "\seq_empty:NTF"  "{"  "}{"  "}"
+%   "\seq_if_empty:NTF"  "{"  "}{"  "}"
 % \end{syntax}
 % Set of conditionals that test whether or not a particular 
 % is empty and if so executes either  or .
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \seq_if_in:NnTF |
 %                  \seq_if_in:cnTF |
 %                  \seq_if_in:coTF |
+%                  \seq_if_in:cxTF |
+%                  \seq_if_in:NnF |
+%                  \seq_if_in:cnF |
 % }
 % \begin{syntax}
 %   "\seq_if_in:NnTF"  "{"  "}{"  "}{"  "}"
@@ -206,16 +279,16 @@
 % Function that tests if  is in . Depending on the result
 % either  or  is executed.
 % \end{function}
-% 
+%
 % \subsection{Internal functions}
-% 
-% \begin{function}{\seq_empty_err:N}
+%
+% \begin{function}{\seq_if_empty_err:N}
 % \begin{syntax}
-%   "\seq_empty_err:N" 
+%   "\seq_if_empty_err:N" 
 % \end{syntax}
 % Signals an \LaTeX3 error if  is empty.
 % \end{function}
-% 
+%
 % \begin{function}{\seq_pop_aux:nnNN}
 % \begin{syntax}
 %   "\seq_pop_aux:nnNN"    
@@ -224,7 +297,7 @@
 %  and assigns the tail to  using . This
 % function could be used to implement a global return function.
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \seq_get_aux:w |
 %                  \seq_pop_aux:w |
@@ -234,7 +307,7 @@
 % Functions used to implement put and get operations. They  are not for
 % meant for direct use.
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \seq_elt:w |
 %                   \seq_elt_end: }
@@ -243,19 +316,71 @@
 % are not supposed to show up as tokens within an item appended to a
 % sequence.
 % \end{function}
-% 
 %
-% \section {Implementation}
+% \section{Sequence Stacks}
+%
+% Special sequences in \LaTeX3 are `stacks' with their usual operations
+% of`push', `pop', and `top'. They are internally implemented as
+% sequences and share some of the functions (like "\seq_new:N" etc.)
+%
+% \subsection{Functions}
+%
+% \begin{function}{%
+%                  \seq_push:Nn |
+%                  \seq_push:No |
+%                  \seq_push:cn |
+%                  \seq_gpush:Nn |
+%                  \seq_gpush:No |
+%                  \seq_gpush:cn |
+% }
+% \begin{syntax}
+%   "\seq_push:Nn"  "{"  "}"
+% \end{syntax}
+% Locally or globally pushes  as a single item onto the
+% .  might get expanded before the operation.
+% \end{function}
+%
+% \begin{function}{%
+%                  \seq_pop:NN |
+%                  \seq_pop:cN |
+%                  \seq_gpop:NN |
+%                  \seq_gpop:cN |
+% }
+% \begin{syntax}
+%    "\seq_pop:NN"  
+% \end{syntax}
+% Functions that assign the top item of  to the token
+% list pointer  and removes it from !
+% \end{function}
+%
+% \begin{function}{%
+%                  \seq_top:NN |
+%                  \seq_top:cN |
+% }
+% \begin{syntax}
+%    "\seq_top:NN"  
+% \end{syntax}
+% Functions that locally assign the top item of  to the token
+% list pointer . Item is not removed from !
+% \end{function}
+%
+% \subsection{Predicates and conditionals}
+%
+% Use "seq" functions.
+%
+% \StopEventually{}
+%
+% \subsection {Implementation}
+%
 %
 %    We start by ensuring that the required packages are loaded.
 %    \begin{macrocode}
-%\RequirePackage{l3toks}
 %\RequirePackage{l3quark}
+%\RequirePackage{l3tlp}
 %\RequirePackage{l3chk}
 %\RequirePackage{l3expan}
-%<*package>
 %    \end{macrocode}
-%    
+%
 % A sequence is a control sequence whose top-level expansion is of the
 % form `|\seq_elt:w| \m{text$\sb1$} |\seq_elt_end:| \ldots{}
 % |\seq_elt:w| \zv{text$\sb{n}$} \ldots'. We use explicit delimiters
@@ -264,27 +389,25 @@
 %
 % \begin{macro}{\seq_elt:w}
 % \begin{macro}{\seq_elt_end:}
-%    We allocate the delimiters and make them noops as default.
+%    We allocate the delimiters and make them errors if executed.
 %    \begin{macrocode}
-\let_new:NN \seq_elt:w \use_noop:
-\let_new:NN \seq_elt_end: \use_noop:
+%<*initex|package>
+\let_new:NN \seq_elt:w \ERROR
+\let_new:NN \seq_elt_end: \ERROR
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
 %
 %
 % \begin{macro}{\seq_new:N}
-% \begin{macro}{\seq_new:O}
 % \begin{macro}{\seq_new:c}
 %    Sequences are implemented using token lists.
 %    \begin{macrocode}
 \def_new:Npn \seq_new:N #1{\tlp_new:Nn #1{}}
 \def_new:Npn \seq_new:c {\exp_args:Nc \seq_new:N}
-\def_new:Npn \seq_new:O {\exp_args:No \seq_new:N}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
-% \end{macro}
 %
 % \begin{macro}{\seq_clear:N}
 % \begin{macro}{\seq_clear:c}
@@ -318,35 +441,30 @@
 % \end{macro}
 % \end{macro}
 %
-% \begin{macro}{\seq_empty_p:N}
+% \begin{macro}{\seq_if_empty_p:N}
 %    A predicate which evaluates to |\c_true| iff the sequence is empty.
 %    \begin{macrocode}
-\let_new:NN \seq_empty_p:N \tlp_empty_p:N
+\let_new:NN \seq_if_empty_p:N \tlp_if_empty_p:N
 %    \end{macrocode}
 % \end{macro}
 %
-% \begin{macro}{\seq_empty:NTF}
-% \begin{macro}{\seq_empty:cTF}
-% \begin{macro}{\seq_empty:NF}
-% \begin{macro}{\seq_empty:cF}
-%    |\seq_empty:NTF|\m{seq}\m{true~case}\m{false~case} will check
+% \begin{macro}{\seq_if_empty:NTF}
+% \begin{macro}{\seq_if_empty:cTF}
+% \begin{macro}{\seq_if_empty:NF}
+% \begin{macro}{\seq_if_empty:cF}
+%    |\seq_if_empty:NTF|\m{seq}\m{true~case}\m{false~case} will check
 %    whether the \m{seq} is empty and then select one of the other
-%    arguments. |seq_empty:cTF| turns its first argument into a 
+%    arguments. |seq_if_empty:cTF| turns its first argument into a
 %    control sequence to get the name of the sequence.
 %    \begin{macrocode}
-\def_new:Npn \seq_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:}
-\def_new:Npn \seq_empty:cTF {\exp_args:Nc\seq_empty:NTF}
+\let_new:NN \seq_if_empty:NTF \tlp_if_empty:NTF
+\def_new:Npn \seq_if_empty:cTF {\exp_args:Nc\seq_if_empty:NTF}
 %    \end{macrocode}
 %    A variant of this, is only to do something if the sequence is
-%    {\em not} empty.
+%    \emph{not} empty.
 %    \begin{macrocode}
-\def_new:Npn \seq_empty:NF #1{
-   \if_meaning:NN#1\c_empty_tlp \exp_after:NN\use_none:n
-   \else: \exp_after:NN\use:n \fi:}
-\def_new:Npn \seq_empty:cF {\exp_args:Nc\seq_empty:NF}
+\let_new:NN \seq_if_empty:NF \tlp_if_empty:NF
+\def_new:Npn \seq_if_empty:cF {\exp_args:Nc\seq_if_empty:NF}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -354,10 +472,10 @@
 % \end{macro}
 %
 %
-% \begin{macro}{\seq_empty_err:N}
+% \begin{macro}{\seq_if_empty_err:N}
 %   Signals an error if the sequence is empty.
 %    \begin{macrocode}
-\def_new:Npn \seq_empty_err:N #1{\if_meaning:NN#1\c_empty_tlp
+\def_new:Npn \seq_if_empty_err:N #1{\if_meaning:NN#1\c_empty_tlp
 %    \end{macrocode}
 %    As I said before, I don't think we need to provide checks for this
 %    kind of error, since it is a severe internal macro package error
@@ -365,7 +483,7 @@
 %    next line of code should be probably removed.
 %    \begin{macrocode}
   \tlp_clear:N \l_testa_tlp % catch prefixes
-  \err_latex_bug:n{Empty~sequence~`\token_to_string:N#1'}\fi:}
+  \err_latex_bug:x{Empty~sequence~`\token_to_string:N#1'}\fi:}
 %    \end{macrocode}
 % \end{macro}
 %
@@ -375,7 +493,7 @@
 %    left_most element of \zz{sequence}.
 %    \begin{macrocode}
 \def_new:Npn \seq_get:NN #1{
-  \seq_empty_err:N #1
+  \seq_if_empty_err:N #1
   \exp_after:NN\seq_get_aux:w #1\q_stop}
 \def_new:Npn \seq_get_aux:w \seq_elt:w #1\seq_elt_end:
                 #2\q_stop #3{\tlp_set:Nn #3{#1}}
@@ -385,18 +503,20 @@
 % \end{macro}
 %
 % \begin{macro}{\seq_pop_aux:nnNN}
+% \begin{macro}{\seq_pop_aux:w}
 %    |\seq_pop_aux:nnNN| \zz{def$\sb1$} \zz{def$\sb2$} \zz{sequence}
 %    \zz{cmd} assigns the left_most element of \zz{sequence} to
 %    \zz{cmd} using \zz{def$\sb2$}, and assigns the tail of
 %    \zz{sequence} to \zz{sequence} using \zz{def$\sb1$}.
 %    \begin{macrocode}
 \def_new:Npn \seq_pop_aux:nnNN #1#2#3{
-  \seq_empty_err:N #3
+  \seq_if_empty_err:N #3
   \exp_after:NN\seq_pop_aux:w #3\q_stop #1#2#3}
 \def_new:Npn \seq_pop_aux:w \seq_elt:w #1\seq_elt_end:
                 #2\q_stop #3#4#5#6{#3#5{#2}#4#6{#1}}
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\seq_put_aux:Nnn}
 %    |\seq_put_aux:Nnn| \zz{sequence} \zv{left} \zv{right} adds the
@@ -430,8 +550,8 @@
 \def_new:Npn \seq_put_left:Nx {\exp_args:Nnx\seq_put_left:Nn}
 \def_new:Npn \seq_put_right:Nn #1#2{
         \seq_put_aux:Nnn #1{}{\seq_elt:w #2\seq_elt_end:}}
-\def_new:Npn \seq_put_right:No {\exp_args:Nno\seq_put_right:Nn}
-\def_new:Npn \seq_put_right:Nx {\exp_args:Nnx\seq_put_right:Nn}
+\def_new:Npn \seq_put_right:No {\exp_args:NNo\seq_put_right:Nn}
+\def_new:Npn \seq_put_right:Nx {\exp_args:NNx\seq_put_right:Nn}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
@@ -443,6 +563,7 @@
 %
 % \begin{macro}{\seq_gput_left:Nn}
 % \begin{macro}{\seq_gput_right:Nn}
+% \begin{macro}{\seq_gput_right:Nc}
 % \begin{macro}{\seq_gput_right:No}
 % \begin{macro}{\seq_gput_right:cn}
 % \begin{macro}{\seq_gput_right:co}
@@ -453,15 +574,16 @@
 %<*check>
    \pref_global_chk:
 %
-%<_check> \pref_global:D
+%<-check> \pref_global:D
    \seq_put_left:Nn}
 \def_new:Npn \seq_gput_right:Nn {
 %<*check>
    \pref_global_chk:
 %
-%<_check> \pref_global:D
+%<-check> \pref_global:D
    \seq_put_right:Nn}
 \def_new:Npn \seq_gput_right:No {\exp_args:NNo \seq_gput_right:Nn}
+\def_new:Npn \seq_gput_right:Nc {\exp_args:NNc \seq_gput_right:Nn}
 \def_new:Npn \seq_gput_right:cn {\exp_args:Nc  \seq_gput_right:Nn}
 \def_new:Npn \seq_gput_right:co {\exp_args:Nco \seq_gput_right:Nn}
 \def_new:Npn \seq_gput_right:cc {\exp_args:Ncc \seq_gput_right:Nn}
@@ -472,6 +594,33 @@
 % \end{macro}
 % \end{macro}
 % \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\seq_map_variable:NNn}
+% \begin{macro}{\seq_map_variable:cNn}
+% \begin{macro}{\seq_map_variable_aux:nw}
+% \begin{macro}{\seq_map_break:w}
+%   Nothing spectacular here. The shuffling of the arguments in
+%   |\seq_map_variable:NNn| below could also be done with
+%   |\exp_args:NNnE|.
+%    \begin{macrocode}
+\def_new:Npn \seq_map_variable_aux:Nnw #1#2\seq_elt:w#3\seq_elt_end:{
+  \tlp_set:Nn #1{#3}
+  \quark_if_nil:NT #1 \seq_map_break:w
+  #2
+  \seq_map_variable_aux:Nnw #1{#2}
+}
+\def_new:Npn \seq_map_variable:NNn #1#2#3{
+  \tlp_set:Nx #2 {\exp_not:n{\seq_map_variable_aux:Nnw #2{#3}}}
+  \exp_after:NN #2 #1 \seq_elt:w \q_nil\seq_elt_end: \q_stop
+}
+\def_new:Npn \seq_map_variable:cNn{\exp_args:Nc\seq_map_variable:Nn}
+\let_new:NN \seq_map_break:w \use_none_delimit_by_q_stop:w
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\seq_map:NN}
 %    |\seq_map:NN| \zz{sequence} \zz{cmd} applies \zz{cmd} to each
@@ -481,7 +630,9 @@
 %    that is delimited by |\seq_elt_end:|.
 %    \begin{macrocode}
 \def_new:Npn \seq_map:NN #1#2{
-    \def:Npn \seq_elt:w ##1\seq_elt_end: {#2{##1}}#1}
+  \def:Npn \seq_elt:w ##1\seq_elt_end: {#2{##1}}#1
+  \let:NN \seq_elt:w \ERROR
+}
 %    \end{macrocode}
 % \end{macro}
 %
@@ -491,21 +642,51 @@
 %    natural.
 %    \begin{macrocode}
 \def_new:Npn \seq_map_inline:Nn #1#2{
-   \gdef:Npn \seq_elt:w ##1\seq_elt_end: {#2}#1}
+  \def:Npn \seq_elt:w ##1\seq_elt_end: {#2}#1
+  \let:NN \seq_elt:w \ERROR
+}
 \def_new:Npn \seq_map_inline:cn{\exp_args:Nc\seq_map_inline:Nn}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
 %
+% \begin{macro}{\seq_set_eq:NN}
+% \begin{macro}{\seq_set_eq:Nc}
+%    We can set one seq equal to another.
+%    \begin{macrocode}
+\let_new:NN  \seq_set_eq:NN \let:NN
+\def_new:Npn \seq_set_eq:Nc {\exp_args:NNc \seq_set_eq:NN}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\seq_gset_eq:NN}
+% \begin{macro}{\seq_gset_eq:cN}
+% \begin{macro}{\seq_gset_eq:Nc}
+% \begin{macro}{\seq_gset_eq:cc}
+%    An of course globally which seems to be needed far more
+%    often.\footnote{To save a bit of space these functions could be made
+%    identical to those from the tlp or clist module.}
+%    \begin{macrocode}
+\let_new:NN \seq_gset_eq:NN \glet:NN
+\def_new:Npn \seq_gset_eq:cN {\exp_args:Nc \seq_gset_eq:NN}
+\def_new:Npn \seq_gset_eq:Nc {\exp_args:NNc \seq_gset_eq:NN}
+\def_new:Npn \seq_gset_eq:cc {\exp_args:Ncc \seq_gset_eq:NN}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
 % \begin{macro}{\seq_gconcat:NNN}
 % \begin{macro}{\seq_gconcat:ccc}
 %    |\seq_gconcat:NNN| \m{seq~1} \m{seq~2} \m{seq~3} will globally
 %    assign \m{seq~1} the concatenation of \m{seq~2} and \m{seq~3}.
 %    \begin{macrocode}
 \def_new:Npn \seq_gconcat:NNN #1#2#3{
-   \l_tmpa_toks \exp_after:NN{#2}
-   \l_tmpb_toks \exp_after:NN{#3}
-   \gdef:Npx #1{\toks_use:N \l_tmpa_toks \toks_use:N \l_tmpb_toks}}
+  \tlp_gset:Nx #1 {\exp_not:o{#2}\exp_not:o{#3}}
+}
 \def_new:Npn \seq_gconcat:ccc{\exp_args:Nccc\seq_gconcat:NNN}
 %    \end{macrocode}
 % \end{macro}
@@ -514,10 +695,13 @@
 % \begin{macro}{\seq_if_in:NnTF}
 % \begin{macro}{\seq_if_in:cnTF}
 % \begin{macro}{\seq_if_in:coTF}
+% \begin{macro}{\seq_if_in:cxTF}
+% \begin{macro}{\seq_if_in:NnF}
+% \begin{macro}{\seq_if_in:cnF}
 %    |\seq_if_in:NnTF| \m{seq}\m{item} \m{true~case} \m{false~case}
 %    will check whether \m{item} is in \m{seq} and then either execute
 %    the \m{true~case} or the \m{false~case}. \m{true~case} and
-%    \m{false~case} may contain incomplete |\if_char_code:w|
+%    \m{false~case} may contain incomplete |\if_charcode:w|
 %    statements.
 %    \begin{macrocode}
 \def_new:Npn \seq_if_in:NnTF #1#2{
@@ -528,9 +712,9 @@
 %    with |\q_no_value|.
 %    \begin{macrocode}
         \if_meaning:NN\q_no_value##2
-          \exp_after:NN\use_choice_ii:nn
+          \exp_after:NN\use_arg_ii:nn
         \else:
-          \exp_after:NN\use_choice_i:nn
+          \exp_after:NN\use_arg_i:nn
         \fi:
       }
   \exp_after:NN
@@ -538,14 +722,23 @@
   #2\seq_elt_end: \q_no_value \q_stop}
 \def_new:Npn \seq_if_in:coTF {\exp_args:Nco \seq_if_in:NnTF}
 \def_new:Npn \seq_if_in:cnTF {\exp_args:Nc \seq_if_in:NnTF}
+\def_new:Npn \seq_if_in:cxTF {\exp_args:Ncx \seq_if_in:NnTF}
 %    \end{macrocode}
+%
+%    \begin{macrocode}
+\def_new:Npn \seq_if_in:NnF #1#2 { \seq_if_in:NnTF #1{#2}\use_noop: }
+\def_new:Npn \seq_if_in:cnF {\exp_args:Nc \seq_if_in:NnF}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
 % \end{macro}
 % \end{macro}
 % \end{macro}
 %
 %
 %
-% \subsection{Stack operations}
+% \subsubsection{Stack operations}
 %
 % We build stacks from sequences,  but here we put the
 % specific functions together.
@@ -577,6 +770,7 @@
 % \begin{macro}{\seq_gpush:Nn}
 % \begin{macro}{\seq_gpush:No}
 % \begin{macro}{\seq_gpush:cn}
+% \begin{macro}{\seq_gpush:NC}
 % \begin{macro}{\seq_gpop:NN}
 % \begin{macro}{\seq_gpop:cN}
 %    I don't agree with Denys that one needs only local stacks,
@@ -587,6 +781,7 @@
 \let_new:NN \seq_gpush:Nn \seq_gput_left:Nn
 \def_new:Npn \seq_gpush:No {\exp_args:NNo \seq_gpush:Nn}
 \def_new:Npn \seq_gpush:cn {\exp_args:Nc \seq_gpush:Nn}
+\def_new:Npn \seq_gpush:NC {\exp_args:NNC \seq_gpush:Nn}
 \def_new:Npn \seq_gpop:NN {\seq_pop_aux:nnNN \tlp_gset:Nn \tlp_set:Nn}
 \def_new:Npn \seq_gpop:cN {\exp_args:Nc \seq_gpop:NN}
 %    \end{macrocode}
@@ -595,6 +790,7 @@
 % \end{macro}
 % \end{macro}
 % \end{macro}
+% \end{macro}
 %
 %
 % \begin{macro}{\seq_top:NN}
@@ -611,12 +807,38 @@
 %
 %    Show token usage:
 %    \begin{macrocode}
-%
+%
 %<*showmemory>
 %\showMemUsage
 %
 %    \end{macrocode}
 %
+% \endinput
 %
+%  $Log$
+%  Revision 1.23  2006/08/09 21:12:50  morten
+%  Minor change in \seq_gconcat:NNN
+%
+%  Revision 1.22  2006/03/20 18:26:39  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.21  2005/12/29 01:28:29  morten
+%  Added a new mapping function (needed in xparse)
+%
+%  Revision 1.20  2005/12/27 10:06:10  morten
+%  Minor changes plus changed RCS information retrieval
+%
+%  Revision 1.19  2005/04/06 21:36:08  morten
+%  Removed dependency on l3toks and added an if_in variant
+%
+%  Revision 1.18  2005/03/22 23:28:05  morten
+%  Fix coding as Benjamin pointed out
+%
+%  Revision 1.17  2005/03/16 22:35:51  braams
+%  Added the tweaks necessary to be able to load with initex
+%
+%  Revision 1.16  2005/03/11 21:42:10  braams
+%  Fixed the use of RCS information; added \StopEventually
+%  Fixed a few documentation typos
 %
-
diff --git a/Master/texmf-dist/source/latex/expl3/l3skip.dtx b/Master/texmf-dist/source/latex/expl3/l3skip.dtx
new file mode 100644
index 00000000000..fee0baa4d0a
--- /dev/null
+++ b/Master/texmf-dist/source/latex/expl3/l3skip.dtx
@@ -0,0 +1,1086 @@
+% \iffalse
+%% File: l3skip.dtx Copyright (C) 2005-2006 Frank Mittelbach, 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.
+%%
+%% -----------------------------------------------------------------------
+%
+%\RequirePackage{l3names}
+%<*dtx>
+%\fi
+\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{%
+  \def\fileversion{#2}%
+  \def\filedate{#3/#4/#5}%
+  \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]%
+}
+%\iffalse
+%
+%\fi
+\GetIdInfo$Id: l3skip.dtx 573 2006-08-21 20:59:37Z morten $
+       {L3 Experimental skip registers}
+%
+% \iffalse
+%<*driver>
+\documentclass{l3doc}
+
+\begin{document}
+\DocInput{l3skip.dtx}
+\end{document}
+%
+% \fi
+%
+%
+% \title{The \textsf{l3skip} package\thanks{This file
+%         has version number \fileversion, last
+%         revised \filedate.}\\
+% Dimension and skip registers}
+% \author{\Team}
+% \date{\filedate}
+% \maketitle
+%
+%
+%  \section{Length registers}
+%
+%
+%  \LaTeX3 knows about two types of length registers for internal use:
+%  rubber lengths ("skip"s) and rigid lengths ("dim"s).
+%
+%  \subsection{Skip registers}
+%
+%
+%
+% \subsubsection{Functions}
+%
+% \begin{function}{%
+%                  \skip_new:N |
+%                  \skip_new:c |
+%                  \skip_new_l:N
+% }
+% \begin{syntax}
+%    "\skip_new:N"   
+% \end{syntax}
+% Defines  to be a new variable of type "skip".
+% \begin{texnote}
+% "\skip_new:N" is the equivalent to plain \TeX{}'s \tn{newskip}.
+% However, the internal register allocation is done differently.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+%                  \skip_zero:N |
+%                  \skip_zero:c |
+%                  \skip_gzero:N |
+%                  \skip_gzero:c |
+% }
+% \begin{syntax}
+%   "\skip_zero:N"   
+% \end{syntax}
+% Locally or globally reset  to zero.
+% For global variables the global versions
+% should be used.
+% \end{function}
+%
+%
+% \begin{function}{%
+%                  \skip_set:Nn |
+%                  \skip_set:cn |
+%                  \skip_gset:Nn |
+%                  \skip_gset:cn |
+% }
+% \begin{syntax}
+%   "\skip_set:Nn"    "{"  "}"
+% \end{syntax}
+% These functions will set the  register to the  value.
+% \end{function}
+%
+%
+% \begin{function}{%
+%                  \skip_add:Nn |
+%                  \skip_add:cn |
+%                  \skip_gadd:Nn |
+% }
+% \begin{syntax}
+%   "\skip_add:Nn"    "{"  "}"
+% \end{syntax}
+% These functions will add to the  register the value .  If
+% the second argument is a  register too, the surrounding braces
+% can be left out.
+% \end{function}
+%
+% \begin{function}{%
+%                  \skip_sub:Nn |
+%                  \skip_gsub:Nn |
+% }
+% \begin{syntax}
+%   "\skip_gsub:Nn"    "{"  "}"
+% \end{syntax}
+% These functions will subtract from the  register the value
+% .  If the second argument is a  register too, the
+% surrounding braces can be left out.
+% \end{function}
+%
+% \begin{function}{%
+%                  \skip_use:N |
+%                  \skip_use:c |
+% }
+% \begin{syntax}
+%   "\skip_use:N"   
+% \end{syntax}
+% This function returns the length value kept in  in a way
+% suitable for further processing.
+% \begin{texnote}
+% The function "\skip_use:N" could be implemented directly as the \TeX{}
+% primitive "\tex_the:D" which is also responsible to produce the values for
+% other internal quantities.  We have chosen to use individual functions
+% for counters, dimensions etc.\ to allow checks and to make the code
+% more self-explanatory.
+% \end{texnote}
+% \end{function}
+%
+%
+% \begin{function}{%
+%                  \skip_horizontal:N |
+%                  \skip_horizontal:c |
+%                  \skip_horizontal:n |
+%                  \skip_vertical:N |
+%                  \skip_vertical:c |
+%                  \skip_vertical:n |
+% }
+% \begin{syntax}
+%   "\skip_horizontal:N"    \\
+%   "\skip_horizontal:n" "{"  "}"
+% \end{syntax}
+% The "hor" functions insert  or  with the \TeX\
+% primitive \tn{hskip}. The "vertical" variants do the same with
+% \tn{vskip}. The "n" versions evaluate  with "\skip_eval:n".
+% \end{function}
+%
+%
+% \begin{function}{%
+%                  \skip_infinite_glue:nTF |
+% }
+% \begin{syntax}
+%   "\skip_infinite_glue:nTF" "{""}" "{""}" "{""}"
+% \end{syntax}
+% Checks if  contains infinite stretch or shrink components
+% and executes either  or . Also works on input like
+% "3pt plus .5in".
+% \end{function}
+%
+%
+%
+% \begin{function}{%
+%                  \skip_split_finite_else_action:nnNN |
+% }
+% \begin{syntax}
+%   "\skip_split_finite_else_action:nnNN" "{""}" "{""}"
+%    
+% \end{syntax}
+% Checks if  contains finite glue. If it does then it assigns
+%  the stretch component and  the shrink component. If
+% it contains infinite glue set  and  to zero and execute
+% "#2" which is usually an error or warning message of some sort.
+% \end{function}
+%
+%
+%
+% \begin{function}{%
+%                  \skip_eval:n |
+% }
+% \begin{syntax}
+%   "\skip_eval:n"   "{""}"
+% \end{syntax}
+%  Evaluates the value of  so that
+%  "\skip_eval:n {5pt plus 3fil + 3pt minus 1fil}" puts
+%  "8.0pt plus 3.0fil minus 1.0fil" back into the input stream.
+%  Expandable.
+% \begin{texnote}
+% This is the \eTeX{} primitive \tn{glueexpr} turned into a function
+% taking an argument.
+% \end{texnote}
+% \end{function}
+%
+%
+% \subsubsection{Formatting a skip register value}
+%
+%
+% \subsubsection{Variable and constants}
+%
+% \begin{variable}{%
+%                  \c_max_skip |
+% }
+% Constant that denotes the maximum value which can be stored in a 
+% register.
+% \end{variable}
+%
+% \begin{variable}{%
+%                  \c_zero_skip |
+% }
+% Set of constants denoting useful values.
+% \end{variable}
+%
+% \begin{variable}{%
+%                  \l_tmpa_skip |
+%                  \l_tmpb_skip |
+%                  \l_tmpc_skip |
+%                  \g_tmpa_skip |
+%                  \g_tmpb_skip |
+% }
+% Scratch register for immediate use.
+% \end{variable}
+%
+%
+%
+%
+%
+% \subsection{Dim registers}
+%
+%
+% \subsubsection{Functions}
+%
+%
+%
+%
+% \begin{function}{%
+%                  \dim_new:N |
+%                  \dim_new:c |
+%                  \dim_new_l:N
+% }
+% \begin{syntax}
+%    "\dim_new:N"   
+% \end{syntax}
+% Defines  to be a new variable of type "dim".
+% \begin{texnote}
+% "\dim_new:N" is the equivalent to plain \TeX{}'s \tn{newdimen}.
+% However, the internal register allocation is done differently.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+%                  \dim_zero:N |
+%                  \dim_zero:c |
+%                  \dim_gzero:N |
+%                  \dim_gzero:c |
+% }
+% \begin{syntax}
+%   "\dim_zero:N"   
+% \end{syntax}
+% Locally or globally reset  to zero.
+% For global variables the global versions
+% should be used.
+% \end{function}
+%
+%
+% \begin{function}{%
+%                  \dim_set:Nn |
+%                  \dim_set:cn |
+%                  \dim_gset:Nn |
+%                  \dim_gset:cn |
+% }
+% \begin{syntax}
+%   "\dim_set:Nn"    "{"  "}"
+% \end{syntax}
+% These functions will set the  register to the  value.
+% \end{function}
+%
+%
+% \begin{function}{%
+%                  \dim_add:Nn |
+%                  \dim_add:cn |
+%                  \dim_gadd:Nn |
+% }
+% \begin{syntax}
+%   "\dim_add:Nn"    "{"  "}"
+% \end{syntax}
+% These functions will add to the  register the value .  If
+% the second argument is a  register too, the surrounding braces
+% can be left out.
+% \end{function}
+%
+% \begin{function}{%
+%                  \dim_sub:Nn |
+%                  \dim_gsub:Nn |
+% }
+% \begin{syntax}
+%   "\dim_gsub:Nn"    "{"  "}"
+% \end{syntax}
+% These functions will subtract from the  register the value
+% .  If the second argument is a  register too, the
+% surrounding braces can be left out.
+% \end{function}
+%
+% \begin{function}{%
+%                  \dim_use:N |
+%                  \dim_use:c |
+% }
+% \begin{syntax}
+%   "\dim_use:N"   
+% \end{syntax}
+% This function returns the length value kept in  in a way
+% suitable for further processing.
+% \begin{texnote}
+% The function "\dim_use:N" could be implemented directly as the \TeX{}
+% primitive "\tex_the:D" which is also responsible to produce the values for
+% other internal quantities.  We have chosen to use individual functions
+% for counters, dimensions etc.\ to allow checks and to make the code
+% more self-explanatory.
+% \end{texnote}
+% \end{function}
+%
+%
+%
+% \begin{function}{%
+%                  \dim_eval:n |
+% }
+% \begin{syntax}
+%   "\dim_eval:n"   "{""}"
+% \end{syntax}
+%  Evaluates the value of a dimension expression so that
+%  "\dim_eval:n {5pt+3pt}" puts "8pt" back into the input stream.
+%  Expandable.
+% \begin{texnote}
+% This is the \eTeX{} primitive \tn{dimexpr} turned into a function
+% taking an argument.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+%                  \if_dim:w |
+% }
+% \begin{syntax}
+%   "\if_dim:w"     "\else:"  "\fi:"
+% \end{syntax}
+% Compare two dimensions. It is recommended to use "\dim_eval:n" to
+% correctly evaluate and terminate these numbers.  is one of
+% "<", "=" or ">" with catcode 12.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{ifdim}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+%                  \dim_compare:nNnTF |
+%                  \dim_compare:nNnT |
+%                  \dim_compare:nNnF |
+% }
+% \begin{syntax}
+%   "\dim_compare:nNnTF"   "{""}"  "{""}"
+%                         "{""}" "{""}"
+% \end{syntax}
+% These functions test two dimension expressions against each other. They
+% are both evaluated by "\dim_eval:n". Note that if both expressions
+% are normal dimension variables as in
+% \begin{verbatim}
+% \dim_compare:nNnTF \l_temp_dim < \c_zero_skip {negative}{non-negative}
+% \end{verbatim}
+% you can safely omit the braces.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{ifdim} turned into a function.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+%                  \dim_compare_p:nNn |
+% }
+% \begin{syntax}
+%   "\dim_compare_p:nNn"   "{""}"  "{""}"
+% \end{syntax}
+% Predicate version of the above functions.
+% \end{function}
+%
+% \begin{function}{%
+%                  \dim_while:nNnT |
+%                  \dim_while:nNnF |
+%                  \dim_dowhile:nNnT |
+%                  \dim_dowhile:nNnF |
+% }
+% \begin{syntax}
+%   "\dim_while:nNnT"      
+% \end{syntax}
+%  "\dim_while:nNnT" tests the dimension expressions and if true performs
+%  the body "T" until the test fails. "\dim_dowhile:nNnT" is similar
+%  but executes the body first and then performs the check, thus
+%  ensuring that the body is executed at least once. The "F" versions
+%  are similar but continue the loop as long as the test is false.
+% \end{function}
+%
+%
+%
+% \subsubsection{Variable and constants}
+%
+% \begin{variable}{%
+%                  \c_max_dim |
+% }
+% Constant that denotes the maximum value which can be stored in a 
+% register.
+% \end{variable}
+%
+% \begin{variable}{%
+%                  \c_zero_dim |
+% }
+% Set of constants denoting useful values.
+% \end{variable}
+%
+% \begin{variable}{%
+%                  \l_tmpa_dim |
+%                  \l_tmpb_dim |
+%                  \l_tmpc_dim |
+%                  \l_tmpd_dim |
+%                  \g_tmpa_dim |
+%                  \g_tmpb_dim |
+% }
+% Scratch register for immediate use.
+% \end{variable}
+%
+% \subsection{Muskips}
+%
+% \begin{function}{%
+%                  \muskip_new:N |
+%                  \muskip_new_l:N
+% }
+% \begin{syntax}
+%    "\muskip_new:N"   
+% \end{syntax}
+% Defines  to be a new variable of type "muskip".
+% \begin{texnote}
+% "\muskip_new:N" is the equivalent to plain \TeX{}'s \tn{newmuskip}.
+% However, the internal register allocation is done differently.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+%                  \muskip_set:Nn |
+%                  \muskip_gset:Nn |
+% }
+% \begin{syntax}
+%   "\muskip_set:Nn"    "{"  "}"
+% \end{syntax}
+% These functions will set the  register to the 
+% value.
+% \end{function}
+%
+%
+% \begin{function}{%
+%                  \muskip_add:Nn |
+%                  \muskip_gadd:Nn |
+% }
+% \begin{syntax}
+%   "\muskip_add:Nn"    "{"  "}"
+% \end{syntax}
+% These functions will add to the  register the value
+% .  If the second argument is a  register too, the
+% surrounding braces can be left out.
+% \end{function}
+%
+% \begin{function}{%
+%                  \muskip_sub:Nn |
+%                  \muskip_gsub:Nn |
+% }
+% \begin{syntax}
+%   "\muskip_gsub:Nn"    "{"  "}"
+% \end{syntax}
+% These functions will subtract from the  register the value
+% .  If the second argument is a  register too, the
+% surrounding braces can be left out.
+% \end{function}
+%
+%
+% \StopEventually{}
+%
+% \subsection{The Implementation}
+%
+%
+%    We start by ensuring that the required packages are loaded.
+%    \begin{macrocode}
+%\RequirePackage{l3int}
+%\RequirePackage{l3prg}
+%\RequirePackage{l3chk}
+%<*initex|package>
+%    \end{macrocode}
+%
+% \subsubsection{Skip registers}
+%
+% \begin{macro}{\skip_new:N}
+% \begin{macro}{\skip_new:c}
+% \begin{macro}{\skip_new_l:N}
+%    Allocation of a new internal registers.
+%    \begin{macrocode}
+%<*initex>
+\alloc_setup_type:nnn {skip} \c_zero \c_max_register_num
+\def_new:Npn\skip_new:N   #1 {\alloc_reg:NnNN g {skip} \tex_skipdef:D #1 }
+\def_new:Npn\skip_new_l:N #1 {\alloc_reg:NnNN l {skip} \tex_skipdef:D #1 }
+%
+%\let:NN \skip_new:N \newskip
+\def_new:Npn \skip_new:c {\exp_args:Nc \skip_new:N}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\skip_set:Nn}
+% \begin{macro}{\skip_set:cn}
+% \begin{macro}{\skip_gset:Nn}
+% \begin{macro}{\skip_gset:cn}
+%    Setting skips is again something that I would like to make
+%    uniform at the moment to get a better overview.
+%    \begin{macrocode}
+\def_new:Npn \skip_set:Nn #1#2{#1\skip_eval:n{#2}
+%<*check>
+\chk_local_or_pref_global:N #1
+%
+}
+\def_new:Npn \skip_gset:Nn {
+%<*check>
+   \pref_global_chk:
+%
+%<-check> \pref_global:D
+   \skip_set:Nn }
+\def_new:Npn \skip_set:cn {\exp_args:Nc \skip_set:Nn }
+\def_new:Npn \skip_gset:cn {\exp_args:Nc \skip_gset:Nn }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\skip_zero:N}
+% \begin{macro}{\skip_gzero:N}
+% \begin{macro}{\skip_zero:c}
+% \begin{macro}{\skip_gzero:c}
+%    Reset the register to zero.
+%    \begin{macrocode}
+\def_new:Npn \skip_zero:N #1{#1\c_zero_skip \scan_stop:
+%<*check>
+        \chk_local_or_pref_global:N #1
+%
+}
+\def_new:Npn \skip_gzero:N {
+%    \end{macrocode}
+%    We make sure that a local variable is not updated globally by
+%    changing the internal test (i.e.\ |\chk_local_or_pref_global:N|) before
+%    making the assignment. This is done by |\pref_global_chk:| which also
+%    issues the necessary |\pref_global:D|. This is not very efficient, but
+%    this code will be only included for debugging purposes. Using
+%    |\pref_global:D| in front of the local function is better in the
+%    production versions.
+%    \begin{macrocode}
+%<*check>
+   \pref_global_chk:
+%
+%<-check> \pref_global:D
+   \skip_zero:N}
+\def_new:Npn \skip_zero:c  {\exp_args:Nc \skip_zero:N}
+\def_new:Npn \skip_gzero:c {\exp_args:Nc \skip_gzero:N}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\skip_add:Nn}
+% \begin{macro}{\skip_add:cn}
+% \begin{macro}{\skip_gadd:Nn}
+% \begin{macro}{\skip_sub:Nn}
+% \begin{macro}{\skip_gsub:Nn}
+%    Adding and subtracting to and from s
+%    \begin{macrocode}
+\def_new:Npn \skip_add:Nn #1#2{
+%    \end{macrocode}
+%    We need to say |by| in case the first argment is a register
+%    accessed by its number, e.g., |\skip23|.
+%    \begin{macrocode}
+    \tex_advance:D#1 by \skip_eval:n{#2}
+%<*check>
+    \chk_local_or_pref_global:N #1
+%
+}
+\def_new:Npn\skip_add:cn{\exp_args:Nc\skip_add:Nn}
+\def_new:Npn \skip_sub:Nn #1#2{
+    \tex_advance:D#1-\skip_eval:n{#2}
+%<*check>
+\chk_local_or_pref_global:N #1
+%
+}
+\def_new:Npn \skip_gadd:Nn {
+%<*check>
+   \pref_global_chk:
+%
+%<-check> \pref_global:D
+   \skip_add:Nn }
+\def_new:Npn \skip_gsub:Nn {
+%<*check>
+   \pref_global_chk:
+%
+%<-check> \pref_global:D
+   \skip_sub:Nn }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\skip_horizontal:N}
+% \begin{macro}{\skip_horizontal:c}
+% \begin{macro}{\skip_horizontal:n}
+% \begin{macro}{\skip_vertical:N}
+% \begin{macro}{\skip_vertical:c}
+% \begin{macro}{\skip_vertical:n}
+%    Inserting skips.
+%    \begin{macrocode}
+\let_new:NN \skip_horizontal:N \tex_hskip:D
+\def_new:Npn \skip_horizontal:c {\exp_args:Nc\skip_horizontal:N}
+\def_new:Npn \skip_horizontal:n #1{\skip_horizontal:N \skip_eval:n{#1}}
+\let_new:NN \skip_vertical:N \tex_vskip:D
+\def_new:Npn \skip_vertital:c {\exp_args:Nc\skip_vertical:N}
+\def_new:Npn \skip_vertical:n #1{\skip_vertical:N \skip_eval:n{#1}}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\skip_use:N}
+% \begin{macro}{\skip_use:c}
+%    Here is how skip registers are accessed:
+%    \begin{macrocode}
+\let_new:NN \skip_use:N \tex_the:D
+\def_new:Npn \skip_use:c #1{\exp_args:Nc\skip_use:N}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\skip_eval:n}
+% Evaluating a calc expression.
+%    \begin{macrocode}
+\def_new:Npn \skip_eval:n #1 {\etex_glueexpr:D #1 \scan_stop:}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_tmpa_skip}
+% \begin{macro}{\l_tmpb_skip}
+% \begin{macro}{\l_tmpc_skip}
+% \begin{macro}{\g_tmpa_skip}
+% \begin{macro}{\g_tmpb_skip}
+%    We provide three local and two global scratch registers, maybe we
+%    need more or less.
+%    \begin{macrocode}
+%%\chk_new_cs:N \l_tmpa_skip
+%%\tex_skipdef:D\l_tmpa_skip 255  %currently taken up by \skip@
+\skip_new:N \l_tmpa_skip
+\skip_new:N \l_tmpb_skip
+\skip_new:N \l_tmpc_skip
+\skip_new:N \g_tmpa_skip
+\skip_new:N \g_tmpb_skip
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\c_zero_skip}
+% \begin{macro}{\c_max_skip}
+%    \begin{macrocode}
+%<*!package>
+\skip_new:N \c_zero_skip
+\skip_set:Nn \c_zero_skip {0pt}
+\skip_new:N \c_max_skip
+\skip_set:Nn \c_max_skip {16383.99999pt}
+%
+%<*!initex>
+\let:NN \c_zero_skip \z@
+\let:NN \c_max_skip  \maxdimen
+%
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%  \begin{macro}{\skip_infinite_glue:nTF}
+%  With \eTeX{} we all of a sudden get access to a lot information we
+%  should otherwise consider ourselves lucky to get. One is
+%  the stretch and shrink components of a skip register and the order
+%  or those components. "\skip_infinite_glue:nTF" tests it directly by
+%  looking at the stretch and shrink order. If either of the predicate
+%  functions return \m{true} "\prg_logic_or_p:nn" will return \m{true}
+%  and the logic test will take the true branch.
+%    \begin{macrocode}
+\def_new:Npn \skip_infinite_glue:nTF #1{
+  \prg_logic_test:nTF {
+    \prg_logic_or_p:nn
+      { \int_compare_p:nNn {\etex_gluestretchorder:D #1 } > \c_zero }
+      { \int_compare_p:nNn {\etex_glueshrinkorder:D #1 } > \c_zero }
+  }
+}
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%  \begin{macro}{\skip_split_finite_else_action:nnNN}
+%  This macro is useful when performing error checking in certain
+%  circumstances. If the \m{skip} register holds finite glue it sets
+%  "#3" and "#4" to the stretch and shrink component resp. If it holds
+%  infinite glue set "#3" and "#4" to zero and issue the special action
+%  "#2" which is probably an error message.
+%  Assignments are global.
+%    \begin{macrocode}
+\def_new:Npn \skip_split_finite_else_action:nnNN #1#2#3#4{
+  \skip_infinite_glue:nTF {#1}
+  {
+    #3 = \c_zero_skip
+    #4 = \c_zero_skip
+    #2
+  }
+  {
+    #3 = \etex_gluestretch:D #1 \scan_stop:
+    #4 = \etex_glueshrink:D  #1 \scan_stop:
+  }
+}
+%    \end{macrocode}
+%  \end{macro}
+%
+%
+%
+% \subsubsection{Dimen registers}
+%
+% \begin{macro}{\dim_new:N}
+% \begin{macro}{\dim_new:c}
+% \begin{macro}{\dim_new_l:N}
+%    Allocating \meta{dim} registers...
+%    \begin{macrocode}
+%<*initex>
+\alloc_setup_type:nnn {dimen} \c_zero \c_max_register_num
+\def_new:Npn \dim_new:N   #1 {\alloc_reg:NnNN g {dimen} \tex_dimendef:D #1 }
+\def_new:Npn \dim_new_l:N #1 {\alloc_reg:NnNN l {dimen} \tex_dimendef:D #1 }
+%
+%\let:NN \dim_new:N \newdimen
+\def_new:Npn \dim_new:c {\exp_args:Nc \dim_new:N}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\dim_set:Nn}
+% \begin{macro}{\dim_gset:Nn}
+% \begin{macro}{\dim_set:cn}
+% \begin{macro}{\dim_set:Nc}
+% \begin{macro}{\dim_gset:cn}
+% \begin{macro}{\dim_gset:Nc}
+% \begin{macro}{\dim_gset:cc}
+% We add |\dim_eval:n| in order to allow simple arithmetic
+% and a space just for those using |\dimen1| or alike. See OR!
+%    \begin{macrocode}
+\def_new:Npn \dim_set:Nn #1#2{#1~ \dim_eval:n{#2}}
+\def_new:Npn \dim_gset:Nn {\pref_global:D \dim_set:Nn }
+\def_new:Npn \dim_set:cn {\exp_args:Nc \dim_set:Nn }
+\def_new:Npn \dim_set:Nc {\exp_args:NNc \dim_set:Nn }
+\def_new:Npn \dim_gset:cn {\exp_args:Nc \dim_gset:Nn }
+\def_new:Npn \dim_gset:Nc {\exp_args:NNc \dim_gset:Nn }
+\def_new:Npn \dim_gset:cc {\exp_args:Ncc \dim_gset:Nn }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\dim_zero:N}
+% \begin{macro}{\dim_gzero:N}
+% \begin{macro}{\dim_zero:c}
+% \begin{macro}{\dim_gzero:N}
+% Resetting.
+%    \begin{macrocode}
+\def_new:Npn \dim_zero:N #1{#1\c_zero_skip}
+\def_new:Npn \dim_gzero:N {\pref_global:D \dim_zero:N}
+\def_new:Npn \dim_zero:c  {\exp_args:Nc \dim_zero:N}
+\def_new:Npn \dim_gzero:c {\exp_args:Nc \dim_gzero:N}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\dim_add:Nn}
+% \begin{macro}{\dim_add:cn}
+% \begin{macro}{\dim_add:Nc}
+% \begin{macro}{\dim_gadd:Nn}
+% Addition.
+%    \begin{macrocode}
+\def_new:Npn \dim_add:Nn #1#2{
+%    \end{macrocode}
+%    We need to say |by| in case the first argment is a register
+%    accessed by its number, e.g., |\dimen23|.
+%    \begin{macrocode}
+    \tex_advance:D#1 by \dim_eval:n{#2}\scan_stop:
+}
+\def_new:Npn\dim_add:cn{\exp_args:Nc\dim_add:Nn}
+\def_new:Npn\dim_add:Nc{\exp_args:NNc\dim_add:Nn}
+\def_new:Npn \dim_gadd:Nn { \pref_global:D \dim_add:Nn }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\dim_sub:Nn}
+% \begin{macro}{\dim_sub:cn}
+% \begin{macro}{\dim_sub:Nc}
+% \begin{macro}{\dim_gsub:Nn}
+% Subtracting.
+%    \begin{macrocode}
+\def_new:Npn \dim_sub:Nn #1#2{\tex_advance:D#1-#2\scan_stop:}
+\def_new:Npn\dim_sub:cn{\exp_args:Nc\dim_sub:Nn}
+\def_new:Npn\dim_sub:Nc{\exp_args:NNc\dim_sub:Nn}
+\def_new:Npn \dim_gsub:Nn {\pref_global:D \dim_sub:Nn }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\dim_use:N}
+% \begin{macro}{\dim_use:c}
+% Accessing a \meta{dim}.
+%    \begin{macrocode}
+\let_new:NN \dim_use:N \tex_the:D
+\def_new:Npn \dim_use:c {\exp_args:Nc\dim_use:N}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\l_tmpa_dim}
+% \begin{macro}{\l_tmpb_dim}
+% \begin{macro}{\l_tmpc_dim}
+% \begin{macro}{\l_tmpd_dim}
+% \begin{macro}{\g_tmpa_dim}
+% \begin{macro}{\g_tmpb_dim}
+% Some scratch registers.
+%    \begin{macrocode}
+\dim_new:N \l_tmpa_dim
+\dim_new:N \l_tmpb_dim
+\dim_new:N \l_tmpc_dim
+\dim_new:N \l_tmpd_dim
+\dim_new:N \g_tmpa_dim
+\dim_new:N \g_tmpb_dim
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\c_zero_dim}
+% \begin{macro}{\c_max_dim}
+% Just aliases.
+%    \begin{macrocode}
+\let_new:NN \c_zero_dim \c_zero_skip
+\let_new:NN \c_max_dim \c_max_skip
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\dim_eval:n}
+% Evaluating a calc expression.
+%    \begin{macrocode}
+\def_new:Npn \dim_eval:n #1 {\etex_dimexpr:D #1 \scan_stop:}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\if_dim:w}
+% The comparison primitive.
+%    \begin{macrocode}
+\let_new:NN \if_dim:w \tex_ifdim:D
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\dim_compare:nNnTF}
+% \begin{macro}{\dim_compare:nNnT}
+% \begin{macro}{\dim_compare:nNnF}
+% Check the expression and choose branch.
+%    \begin{macrocode}
+\def_new:Npn \dim_compare:nNnTF #1#2#3{
+  \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3}
+    \exp_after:NN \use_arg_i:nn
+  \else:
+    \exp_after:NN \use_arg_ii:nn
+  \fi:
+}
+\def_new:Npn \dim_compare:nNnT #1#2#3{
+  \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3}
+    \exp_after:NN \use_arg_ii:nn
+  \fi:
+  \use_none:n
+}
+\def_new:Npn \dim_compare:nNnF #1#2#3{
+  \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3}
+    \exp_after:NN \use_none:n
+  \else:
+    \exp_after:NN \use_arg_i:n
+  \fi:
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\dim_compare_p:nNn}
+% A predicate function.
+%    \begin{macrocode}
+\def_new:Npn \dim_compare_p:nNn #1#2#3{
+  \if_dim:w \dim_eval:n {#1} #2 \dim_eval:n {#3}
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\dim_while:nNnT}
+% \begin{macro}{\dim_while:nNnF}
+% \begin{macro}{\dim_dowhile:nNnT}
+% \begin{macro}{\dim_dowhile:nNnF}
+% "while" and "do-while" functions for dimensions. Same as for the
+% "int" type only the names have changed.
+%    \begin{macrocode}
+\def_new:Npn \dim_while:nNnT #1#2#3#4{
+  \dim_compare:nNnT {#1}#2{#3}{#4 \dim_while:nNnT {#1}#2{#3}{#4}}
+}
+\def_new:Npn \dim_while:nNnF #1#2#3#4{
+  \dim_compare:nNnF {#1}#2{#3}{#4 \dim_while:nNnF {#1}#2{#3}{#4}}
+}
+\def_new:Npn \dim_dowhile:nNnT #1#2#3#4{
+  #4 \dim_compare:nNnT {#1}#2{#3}{\dim_dowhile:nNnT {#1}#2{#3}{#4}}
+}
+\def_new:Npn \dim_dowhile:nNnF #1#2#3#4{
+  #4 \dim_compare:nNnF {#1}#2{#3}{\dim_dowhile:nNnF {#1}#2{#3}{#4}}
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsubsection{Muskips}
+%
+% \begin{macro}{\muskip_new:N}
+% \begin{macro}{\muskip_new_l:N}
+% And then we add muskips.
+%    \begin{macrocode}
+%<*initex>
+\alloc_setup_type:nnn {muskip} \c_zero \c_max_register_num
+\def_new:Npn \muskip_new:N   #1{\alloc_reg:NnNN g {muskip} \tex_muskipdef:D #1}
+\def_new:Npn \muskip_new_l:N #1{\alloc_reg:NnNN l {muskip} \tex_muskipdef:D #1}
+%
+%\let_new:NN \muskip_new:N \newmuskip     % nicked from LaTeX
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\muskip_set:Nn}
+% \begin{macro}{\muskip_gset:Nn}
+% \begin{macro}{\muskip_add:Nn}
+% \begin{macro}{\muskip_gadd:Nn}
+% \begin{macro}{\muskip_sub:Nn}
+% \begin{macro}{\muskip_gsub:Nn}
+% Simple functions for muskips.
+%    \begin{macrocode}
+\def_new:Npn \muskip_set:Nn#1#2{#1\etex_muexpr:D#2\scan_stop:}
+\def_new:Npn \muskip_gset:Nn{\pref_global:D\muskip_set:Nn}
+\def_new:Npn \muskip_add:Nn#1#2{\tex_advance:D#1\etex_muexpr:D#2\scan_stop:}
+\def_new:Npn \muskip_gadd:Nn{\pref_global:D\muskip_add:Nn}
+\def_new:Npn \muskip_sub:Nn#1#2{\tex_advance:D#1-\etex_muexpr:D#2\scan_stop:}
+\def_new:Npn \muskip_gsub:Nn{\pref_global:D\muskip_sub:Nn}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%    \begin{macrocode}
+%
+%    \end{macrocode}
+%
+% \endinput
+%
+% $Log$
+% Revision 1.18  2006/03/20 18:26:40  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.17  2006/01/27 11:22:38  morten
+% Added \muskip_set:Nn and friends (since l3calc uses them).
+%
+% Revision 1.16  2006/01/17 22:46:37  morten
+% Moved \skip_eval:n earlier to avoid error.
+%
+% Revision 1.15  2006/01/17 22:05:35  morten
+% Minor updates
+%
+% Revision 1.14  2006/01/14 19:13:16  morten
+% Added operations for \vskip and \hskip
+%
+% Revision 1.13  2005/12/27 15:54:44  morten
+% Changed RCS information retrieval
+%
+% Revision 1.12  2005/10/27 22:56:15  morten
+% Moved \if_dim:w to this module.
+%
+% Revision 1.11  2005/04/12 12:07:10  morten
+% Added muskips
+%
+% Revision 1.10  2005/04/09 21:09:48  morten
+% Both documentation  and implementation cleaned up.
+%
+% Revision 1.9  2005/04/06 22:35:57  braams
+% Now we have register allocation fitted
+%
+% Revision 1.8  2005/03/26 21:05:42  morten
+% Make \c_zero_skip different from \c_zero
+%
+% Revision 1.7  2005/03/16 22:35:47  braams
+% Added the tweaks necessary to be able to load with initex
+%
+% Revision 1.6  2005/03/11 21:42:48  braams
+% Fixed the use of RCS information; added \StopEventually
+%
diff --git a/Master/texmf-dist/source/latex/expl3/l3tlp.dtx b/Master/texmf-dist/source/latex/expl3/l3tlp.dtx
index ecc51de9b20..9cf83e3912b 100644
--- a/Master/texmf-dist/source/latex/expl3/l3tlp.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3tlp.dtx
@@ -1,20 +1,54 @@
 % \iffalse
-%% File: l3tlp.dtx Copyright (C) 1990-1998 LaTeX3 project
+%% File: l3tlp.dtx Copyright (C) 1990-2006 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.
+%%
+%% -----------------------------------------------------------------------
 %
+%\RequirePackage{l3names}
 %<*dtx>
-          \ProvidesFile{l3tlp.dtx}
+%\fi
+\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{%
+  \def\fileversion{#2}%
+  \def\filedate{#3/#4/#5}%
+  \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]%
+}
+%\iffalse
 %
-%\NeedsTeXFormat{LaTeX2e}
-%\ProvidesPackage{l3tlp}
-% \ProvidesFile{l3tlp.drv}
-% \fi
-%         \ProvidesFile{l3tlp.dtx}
-          [1998/04/20 v1.0d L3 Experimental Token List Pointers]
+%\fi
+\GetIdInfo$Id: l3tlp.dtx 581 2006-12-12 12:28:27Z morten $
+          {L3 Experimental Token List Pointers}
 %
 % \iffalse
 %<*driver>
 \documentclass{l3doc}
-
 \begin{document}
 \DocInput{l3tlp.dtx}
 \end{document}
@@ -22,7 +56,6 @@
 % \fi
 %
 %
-% \GetFileInfo{l3tlp.dtx}
 % \title{The \textsf{l3tlp} package\thanks{This file
 %         has version number \fileversion, last
 %         revised \filedate.}\\
@@ -34,43 +67,65 @@
 %
 %
 % \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:Nn}
+%
+% \begin{function}{\tlp_new:Nn |
+%                  \tlp_new:cn |
+%                  \tlp_new:Nx }
 % \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.
+% 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_use:N |
+%                  \tlp_use:c
+% }
+% \begin{syntax}
+%   "\tlp_use:N" 
+% \end{syntax}
+% Function that inserts the  into the processing stream.
+% \end{function}
+%
 % \begin{function}{%
 %                  \tlp_set:Nn |
 %                  \tlp_set:Nc |
 %                  \tlp_set:No |
+%                  \tlp_set:Nf |
 %                  \tlp_set:Nx |
 %                  \tlp_gset:Nn |
 %                  \tlp_gset:Nc |
 %                  \tlp_gset:No |
-%                  \tlp_gset:Nx}
+%                  \tlp_gset:Nx |
+%                  \tlp_gset:cn |
+%                  \tlp_gset:cx }
 % \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
+% 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 |
@@ -84,10 +139,12 @@
 % generate a control sequence name which is then interpreted as
 %  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" 
@@ -95,28 +152,37 @@
 % 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_gput_left:Nx |
 %                  \tlp_put_right:Nn |
 %                  \tlp_put_right:cc |
 %                  \tlp_gput_right:Nn |
-%                  \tlp_gput_right:No
+%                  \tlp_gput_right:No|
+%                  \tlp_gput_right:cn|
+%                  \tlp_gput_right:co|
 % }
 % \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.
+% . Assignment is done either locally or globally and  might be subject to expansion before assignment.
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \tlp_set_eq:NN |
-%                  \tlp_gset_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"  
@@ -127,7 +193,7 @@
 % \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
 % }
@@ -137,36 +203,240 @@
 % 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{function}{\tlp_if_empty_p:N|
+%                  \tlp_if_empty_p:c
+%                  }
 % \begin{syntax}
-%   "\tlp_empty_p:N" 
+%   "\tlp_if_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{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_empty:NF"  "{""}"
+%   "\tlp_if_empty:NTF"  "{""}""{""}"
 % \end{syntax}
-% Execute  if  is empty.
-% contain any tokens.
+% Execute  if  is empty and  if it
+% contains any tokens.
 % \end{function}
-% 
-% \begin{function}{\tlp_eq:NNF}
+%
+% \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_eq:NNF"   "{""}"
+%   "\tlp_if_eq_p:NN"   
 % \end{syntax}
-% Execute  if  doesn't hold the same token list as
-% .
+% Predicate function which returns `true' if the two token list
+% pointers are identical and `false' otherwise.
 % \end{function}
-% 
-% \subsection{Variable and constants}
-% 
+%
+% \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"   "{""}""{""}"
+% \end{syntax}
+% Execute  if  holds the same token list as 
+% and  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" "{""}" "{""}" "{""}" "{""}"
+% \end{syntax}
+% Execute  if the two token lists  and  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" "{""}" "{""}" "{""}"
+% \end{syntax}
+% Execute  if  doesn't contain any tokens and  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" "{""}" "{""}" "{""}"
+% \end{syntax}
+% Execute  if  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" "{""}"
+% \end{syntax}
+% "\tlist_to_lowercase:n" converts all tokens in  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" "{""}"
+% \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" "{""}"  \\
+%     "\tlp_map_function:NN"  
+%  \end{syntax}
+%  Runs through all elements in a |tlist| from left to right and places
+%   in front of each element. As this function will also pick
+%  up elements in brace groups, the element is returned with braces and
+%  hence  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
+%   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" "{""}" "{""}" \\
+%     "\tlp_map_inline:Nn"  "{""}"
+%  \end{syntax}
+%  Allows a syntax like "\tlist_map_inline:nn" "{""}"
+%  "{\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" "{""}"  "{""}" \\
+%     "\tlp_map_variable:NNn"   "{""}"
+%  \end{syntax}
+%  Assigns  to each element on  and executes .
+%  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" "{"..."}"
+%  \end{syntax}
+%  Reverse the token list to result in
+%  \dots. 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  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}
@@ -175,19 +445,19 @@
 % 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 |
@@ -197,26 +467,200 @@
 % 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}
+%
+% \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_put_left_aux:w}
 % Used by "\tlp_put_left:Nn" and its variants.
 % \end{function}
-% 
-% \begin{function}{\tlp_to_str:aux}
+%
+% \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"  "{"  "}{"  "}{"
+%      "}"
+% \end{syntax}
+% Function that tests if  is in . Depending on the result
+% either  or  is executed. Note that 
+% 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"  "{"  "}{"  "}"
+% \end{syntax}
+% Replaces the leftmost occurrence of  in  with
+%  if present, otherwise the  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"  "{"  "}{"  "}"
+% \end{syntax}
+% Replaces \emph{all} occurrences of  in  with
+% .
+% \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"  "{"  "}"
+% \end{syntax}
+% Removes the leftmost occurrence of  from  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"  "{"  "}"
+% \end{syntax}
+% Removes \emph{all} occurrences of  from .
+% \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"  "{" ... "}" \\
+%   "\tlist_tail: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  and "\tlist_tail:n"
+% would return \dots. "\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" "{"  "}" 
+%   "{""}""{""}"
+% \end{syntax}
+% Returns  if the first token in  is equal to
+%  and  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" "{"  "}" 
+%   "{""}""{""}"
+% \end{syntax}
+% Returns  if the first token in  is equal to
+%  and  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" "{"  "}" 
+%   "{""}""{""}"
+% \end{syntax}
+% Returns  if the first token in  is equal to
+%  and  otherwise. This version uses |\if_catcode:w| for
+% the test but is otherwise identical to the |charcode| version.
+% \end{function}
+%
+%
 % \StopEventually{}
 %
-%    \section{The code}
-%    
+%    \subsection{The Implementation}
+%
 %    We start by ensuring that the required packages are loaded.
 %    \begin{macrocode}
-%\RequirePackage{l3basics}\par
-%\RequirePackage{l3chk}\par
-%<*package>
+%\RequirePackage{l3basics}
+%\RequirePackage{l3chk}
+%    \end{macrocode}
+%    \begin{macrocode}
+%<*initex|package>
 %    \end{macrocode}
 %
 % A token list pointer is a control sequence that holds tokens.  The
@@ -224,142 +668,184 @@
 % 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}
+% \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}
-%<*check>
 \def_long_new:Npn \tlp_new:Nn #1#2{
-      \chk_new_cs:N #1
-      \chk_var_or_const:N #1
+  \chk_new_cs: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.
+%  If checking we don't allow constants to be defined.
 %    \begin{macrocode}
-      \gdef:Npn #1{#2}}
+%<*check>
+  \chk_var_or_const:N #1
 %
-%<-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}
+%    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
+% \chk_var_or_const:N #1
+  \gdef:Npx #1{#2}
+}
 %    \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{macro}{\tlp_use:N}
+% \begin{macro}{\tlp_use:c}
+% Perhaps this should just be enabled when checking?
 %    \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}
+\def_new:Npn \tlp_use:N #1 {
+  \if_meaning:NN #1 \scan_stop:
 %    \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.
+%  If \m{tlp} equals |\scan_stop:| it is probably stemming from a
+%  |\cs:w ... \cd_end:| that was created by mistake somewhere.
 %    \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}
+     \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_gclear_new:N}
-% \begin{macro}{\tlp_gclear_new:c}
-%    These are the global versions of the above.
+%
+% \begin{macro}{\tlp_set:Nn}
+% \begin{macro}{\tlp_set:No}
+% \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: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_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}
+\def_long_new:Npn \tlp_set:Nn #1#2{
+  \chk_exist_cs:N #1  \def:Npn #1{#2}
 %    \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).
+%    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}
-\def_long_new:Npn \tlp_put_left:Nn #1{\exp_after:NN
+  \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}
-%    We need expanding over a brace to ensure that if |#1| contains
-%    just one token within braces the braces are preserved.
+%  The the global versions.
 %    \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:
+\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> \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|.
+%    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>
-        \chk_local_or_pref_global:N #2
-%
-}
+%<*!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}}
+%
+%    \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: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: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}
-%
-% \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.
+% \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}
-\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}
+%<*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
+}
+%
+%    \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
+%
+%    \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}
@@ -368,74 +854,99 @@
 % \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{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_long_new:Npn \tlp_set:Nn #1#2{
-       \chk_exist_cs:N #1
-       \def:Npn #1{#2}
+\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>\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}
-%    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.
+% \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}
-        \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>
+\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>\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}
-%    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.
+% \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_gput_left:Nx}
+% \begin{macro}{\tlp_put_left_aux:w}
+%    We can add tokens to the left (either globally or locally).
 %    \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
+\def_new:Npn \tlp_put_left:Nn #1{
+%    \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}
+  \exp_args:No \tlp_put_left_aux:w {#1}#1}
+\def_new:Npn\tlp_put_left:No{\exp_args:NNo\tlp_put_left:Nn}
+\def_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_new:Npn\tlp_gput_left:Nx{\exp_args:NNx\tlp_gput_left:Nn}
+\def_long_new:Npn \tlp_put_left_aux:w #1#2#3{\tlp_set:Nn #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}
@@ -443,8 +954,39 @@
 % \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: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_gput_right:cn {\exp_args:Nc \tlp_gput_right:Nn}
+\def_new:Npn \tlp_gput_right:co {\exp_args:Nco \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}
+% \end{macro}
+% \end{macro}
+%
 %
 %
 % \begin{macro}{\tlp_gset:Nc}
@@ -459,10 +1001,10 @@
 %    \begin{macrocode}
 \def_new:Npn \tlp_gset:Nc {
 %<*check>
-   \pref_global_chk:
+  \pref_global_chk:
 %
 %<-check> \pref_global:D
-   \tlp_set:Nc}
+  \tlp_set:Nc}
 %    \end{macrocode}
 %    |\pref_global_chk:| will turn the variable check in |\tlp_set:No|
 %    into a  global check.
@@ -478,46 +1020,97 @@
 % end, as explained elsewhere.
 %
 %
-% \begin{macro}{\tlp_empty_p:N}
+% \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_empty_p:N #1{
+\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_empty:NF}
-% \begin{macro}{\tlp_empty:NTF}
-%    These functions check whether the token list in the argument is 
+% \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_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:}
+\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_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{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_eq:NNF #1#2{
- \if_meaning:NN#1#2
-    \exp_after:NN\use_none:nn
- \fi:
- \use:n}
+\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}
@@ -528,10 +1121,9 @@
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
-
 % \begin{macro}{\g_tmpa_tlp}
 % \begin{macro}{\g_tmpb_tlp}
-%    Global temporary token list pointers.  
+%    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.
@@ -543,14 +1135,13 @@
 % \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. 
+%    when calling test routines.
 %    \begin{macrocode}
 \tlp_new:Nn \l_testa_tlp {}
 \tlp_new:Nn \l_testb_tlp {}
@@ -562,7 +1153,6 @@
 % \end{macro}
 % \end{macro}
 %
-
 % \begin{macro}{\l_tmpa_tlp}
 % \begin{macro}{\l_tmpb_tlp}
 %    These are local temporary token list pointers.
@@ -573,16 +1163,15 @@
 % \end{macro}
 % \end{macro}
 %
-%
 % \begin{macro}{\tlp_to_str:N}
 % \begin{macro}{\tlp_to_str:c}
-% \begin{macro}{\tlp_to_str:aux}
+% \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
-    \token_to_meaning:N}
-\def_new:Npn \tlp_to_str:aux #1>{}
+\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}
@@ -590,11 +1179,724 @@
 % \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_nil \q_stop
+}
+\def_new:Npn \tlp_map_function:NN #1#2{
+  \exp_after:NN \tlist_map_function_aux:Nn
+  \exp_after:NN #2 #1 \q_nil \q_stop
+}
+\def_long_new:Npn \tlist_map_function_aux:Nn #1#2{
+  \quark_if_nil:nT{#2} \tlist_map_break:w
+  #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_nil\q_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_nil\q_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_nil \q_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_nil:NT #1 \tlist_map_break:w
+  #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_stop:w
+\let_new:NN \tlp_map_break:w \tlist_map_break:w
+%    \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: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:Npn\tlist_compare:xx #1#2{\ERROR}
+}
+%    \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:nFT{##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: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: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: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_nil\q_stop
+}
+\def_long_new:Npn \tlist_reverse_aux:nN #1#2{
+  \quark_if_nil:NT #2
+  { \use_arg_i_delimit_by_q_stop:nw {#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}
+%\RequirePackage{l3expan}
+%\RequirePackage{l3num}\par
+%    \end{macrocode}
 %    Show token usage:
 %    \begin{macrocode}
-%
+%
 %<*showmemory>
 \showMemUsage
 %
 %    \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
+%
diff --git a/Master/texmf-dist/source/latex/expl3/l3token.dtx b/Master/texmf-dist/source/latex/expl3/l3token.dtx
new file mode 100644
index 00000000000..43e8a4b5e81
--- /dev/null
+++ b/Master/texmf-dist/source/latex/expl3/l3token.dtx
@@ -0,0 +1,2004 @@
+% \iffalse
+%% File: l3token.dtx Copyright (C) 2005-2006 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.
+%%
+%% -----------------------------------------------------------------------
+%\RequirePackage{l3names}
+%<*dtx>
+%\fi
+\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{%
+  \def\fileversion{#2}%
+  \def\filedate{#3/#4/#5}%
+  \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]%
+}
+%\iffalse
+%
+%\fi
+\GetIdInfo$Id: l3token.dtx 578 2006-11-21 18:13:24Z morten $
+       {L3 Experimental token investigation and manipulation}
+%
+% \iffalse
+%<*driver>
+\documentclass{l3doc}
+
+\begin{document}
+\DocInput{l3token.dtx}
+\end{document}
+%
+% \fi
+%
+% \title{The \textsf{l3token} package\thanks{This file
+%         has version number \fileversion, last
+%         revised \filedate.}\\
+% Basic Definitions}
+% \author{\Team}
+% \date{\filedate}
+% \maketitle
+%
+%
+% \section{A token of my appreciation\dots}
+%
+% This module deals with tokens. Now this is perhaps not the most
+% precise description so let's try with a better description: When
+% programming in \TeX, it is often desirable to know just what a
+% certain token is: is it a control sequence or something
+% else. Similarly one often needs to know if a control sequence is
+% expandable or not, a macro or a primitive, how many arguments it
+% takes etc. Another thing of great importance (especially when it
+% comes to document commands) is looking ahead in the token stream to
+% see if a certain character is present and maybe even remove it or
+% disregard other tokens while scanning. This module provides
+% functions for both and as such will have two primary function
+% categories: |\token| for anything that deals with tokens and
+% |\peek| for looking ahead in the token stream.
+%
+% Most of the time we will be using the term `token' but most of the
+% time the function we're describing can equally well by used on a
+% control sequence as such one is one token as well.
+%
+%
+% We shall refer to list of tokens as |tlist|s and such lists
+% represented py a single control sequence is a `token list pointer'
+% |tlp|. Functions for these two types are found in the \textsf{l3tlp}
+% module.
+%
+% \subsection{Character tokens}
+%
+% Setting category codes of characters.
+%
+%
+% \begin{function}{
+%     \char_set_catcode:nn |
+%     \char_set_catcode:w  |
+%     \char_value_catcode:n |
+%     \char_value_catcode:w |
+%     \char_show_value_catcode:n |
+%     \char_show_value_catcode:w 
+% }
+%   \begin{syntax}
+%     "\char_set_catcode:nn" "{""}" "{""}"\\
+%     "\char_set_catcode:w"  =  \\
+%     "\char_value_catcode:n" "{""}" \\
+%     "\char_show_value_catcode:n" "{""}"
+%   \end{syntax}
+%   "\char_set_catcode:nn" sets the category code of a character,
+%   "\char_value_catcode:n" returns its value for use in integer tests
+%   and "\char_show_value_catcode:n" prints the value on the terminal
+%   and in the log file. The ":w" should be avoided unless you have to
+%   fiddle with the catcode of "{" or "}".
+% \begin{texnote}
+% "\char_set_catcode:w" is the \TeX\ primitive \tn{catcode} renamed.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{
+%     \char_set_lccode:nn |
+%     \char_set_lccode:w  |
+%     \char_value_lccode:n |
+%     \char_value_lccode:w |
+%     \char_show_value_lccode:n |
+%     \char_show_value_lccode:w 
+% }
+%   \begin{syntax}
+%     "\char_set_lccode:nn" "{""}" "{""}" \\
+%     "\char_set_lccode:w"  =  \\
+%     "\char_value_lccode:n" "{""}"\\
+%     "\char_show_value_lccode:n" "{""}"
+%   \end{syntax}
+%   Set the lower caser representation of  for when  is
+%   being converted in "\tlist_to_lowercase:n". As above, the
+%   ":w" form is only for people who really, really know what they are
+%   doing.
+% \begin{texnote}
+% "\char_set_lccode:w" is the \TeX\ primitive \tn{lccode} renamed.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{
+%     \char_set_uccode:nn |
+%     \char_set_uccode:w  |
+%     \char_value_uccode:n |
+%     \char_value_uccode:w |
+%     \char_show_value_uccode:n |
+%     \char_show_value_uccode:w 
+% }
+%   \begin{syntax}
+%     "\char_set_uccode:nn" "{""}" "{""}"\\
+%     "\char_set_uccode:w"  =  \\
+%     "\char_value_uccode:n" "{""}"\\
+%     "\char_show_value_uccode:n" "{""}"
+%   \end{syntax} 
+%   Set the uppercase representation of  for when  is being
+%   converted in "\tlist_to_uppercase:n". As above, the ":w"
+%   form is only for people who really, really know what they are
+%   doing.
+% \begin{texnote}
+% "\char_set_uccode:w" is the \TeX\ primitive \tn{uccode} renamed.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{
+%     \char_set_sfcode:nn |
+%     \char_set_sfcode:w  |
+%     \char_value_sfcode:n |
+%     \char_value_sfcode:w |
+%     \char_show_value_sfcode:n |
+%     \char_show_value_sfcode:w 
+% }
+%   \begin{syntax}
+%     "\char_set_sfcode:nn" "{""}" "{""}"\\
+%     "\char_set_sfcode:w"  =  \\
+%     "\char_value_sfcode:n" "{""}"\\
+%     "\char_show_value_sfcode:n" "{""}"
+%   \end{syntax} 
+%   Set the space factor for .
+% \begin{texnote}
+% "\char_set_sfcode:w" is the \TeX\ primitive \tn{sfcode} renamed.
+% \end{texnote}
+% \end{function}
+%
+%
+% \subsection{Generic tokens}
+%
+%  \begin{function}{%
+%                   \token_new:Nn |
+%  }
+%  \begin{syntax}
+%     "\token_new:Nn"  "{""}"
+%  \end{syntax}
+%  Defines  to globally be a snapshot of . This will
+%  be an implicit representation of .
+%  \end{function}
+%
+%  \begin{variable}{%
+%                   \c_group_begin_token |
+%                   \c_group_end_token |
+%                   \c_math_shift_token |
+%                   \c_alignment_tab_token |
+%                   \c_parameter_token |
+%                   \c_math_superscript_token |
+%                   \c_math_subscript_token |
+%                   \c_space_token |
+%                   \c_letter_token |
+%                   \c_other_char_token |
+%                   \c_active_char_token |
+%  }
+%  \begin{syntax}
+%  \end{syntax}
+%  Some useful constants. They have category codes~1, 2, 3, 4, 6, 7,
+%  8, 10, 11, 12, and 13 respectively. They are all implicit tokens.
+%  \end{variable}
+%
+% \begin{function}{
+%     \token_if_group_begin_p:N |
+%     \token_if_group_begin:NTF |
+%     \token_if_group_begin:NT |
+%     \token_if_group_begin:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_group_begin:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is a begin group token.
+% \end{function}
+%
+% \begin{function}{
+%     \token_if_group_end_p:N |
+%     \token_if_group_end:NTF |
+%     \token_if_group_end:NT |
+%     \token_if_group_end:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_group_end:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is an end group token.
+% \end{function}
+%
+% \begin{function}{
+%     \token_if_math_shift_p:N |
+%     \token_if_math_shift:NTF |
+%     \token_if_math_shift:NT |
+%     \token_if_math_shift:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_math_shift:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is a math shift token.
+% \end{function}
+%
+%
+% \begin{function}{
+%     \token_if_aligment_tab_p:N |
+%     \token_if_aligment_tab:NTF |
+%     \token_if_aligment_tab:NT |
+%     \token_if_aligment_tab:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_aligment_tab:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is an aligment tab token.
+% \end{function}
+%
+% \begin{function}{
+%     \token_if_parameter_p:N |
+%     \token_if_parameter:NTF |
+%     \token_if_parameter:NT |
+%     \token_if_parameter:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_parameter:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is a parameter token.
+% \end{function}
+%
+% \begin{function}{
+%     \token_if_math_superscript_p:N |
+%     \token_if_math_superscript:NTF |
+%     \token_if_math_superscript:NT |
+%     \token_if_math_superscript:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_math_superscript:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is a math superscript token.
+% \end{function}
+%
+% \begin{function}{
+%     \token_if_math_subscript_p:N |
+%     \token_if_math_subscript:NTF |
+%     \token_if_math_subscript:NT |
+%     \token_if_math_subscript:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_math_subscript:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is a math subscript token.
+% \end{function}
+%
+% \begin{function}{
+%     \token_if_space_p:N |
+%     \token_if_space:NTF |
+%     \token_if_space:NT |
+%     \token_if_space:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_space:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is a space token.
+% \end{function}
+%
+%
+% \begin{function}{
+%     \token_if_letter_p:N |
+%     \token_if_letter:NTF |
+%     \token_if_letter:NT |
+%     \token_if_letter:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_letter:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is a letter token.
+% \end{function}
+%
+%
+% \begin{function}{
+%     \token_if_other_char_p:N |
+%     \token_if_other_char:NTF |
+%     \token_if_other_char:NT |
+%     \token_if_other_char:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_other_char:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is an other char token.
+% \end{function}
+%
+% \begin{function}{
+%     \token_if_active_char_p:N |
+%     \token_if_active_char:NTF |
+%     \token_if_active_char:NT |
+%     \token_if_active_char:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_active_char:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is an active char token.
+% \end{function}
+%
+%
+%  \begin{function}{%
+%                   \token_if_eq_meaning_p:NN |
+%                   \token_if_eq_meaning:NNTF |
+%                   \token_if_eq_meaning:NNT |
+%                   \token_if_eq_meaning:NNF 
+%  }
+%  \begin{syntax}
+%   "\token_if_eq_meaning:NNTF"  "{""}""{""}"
+%  \end{syntax}
+%  Check if the meaning of two tokens are identical.
+%  \end{function}
+%
+%  \begin{function}{%
+%                   \token_if_eq_catcode_p:NN |
+%                   \token_if_eq_catcode:NNTF |
+%                   \token_if_eq_catcode:NNT |
+%                   \token_if_eq_catcode:NNF 
+%  }
+%  \begin{syntax}
+%   "\token_if_eq_catcode:NNTF"  "{""}""{""}"
+%  \end{syntax}
+%  Check if the category codes of two tokens are equal. If both tokens
+%  are control sequences the test will be true.
+%  \end{function}
+%
+%  \begin{function}{%
+%                   \token_if_eq_charcode_p:NN |
+%                   \token_if_eq_catcode:NNTF |
+%                   \token_if_eq_catcode:NNT |
+%                   \token_if_eq_catcode:NNF 
+%  }
+%  \begin{syntax}
+%   "\token_if_eq_catcode:NNTF"  "{""}""{""}"
+%  \end{syntax}
+%  Check if the character codes of two tokens are equal. If both tokens
+%  are control sequences the test will be true.
+%  \end{function}
+%
+% \begin{function}{
+%     \token_if_macro_p:N |
+%     \token_if_macro:NTF |
+%     \token_if_macro:NT |
+%     \token_if_macro:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_macro:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is a macro.
+% \end{function}
+%
+%
+% \begin{function}{
+%     \token_if_cs_p:N |
+%     \token_if_cs:NTF |
+%     \token_if_cs:NT |
+%     \token_if_cs:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_cs:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is a control sequence or not. This can be useful
+%   for situations where the next token in the input stream is being
+%   looked at and you want to determine what should be done to it.
+% \end{function}
+%
+%
+%
+%
+% \begin{function}{
+%     \token_if_expandable_p:N |
+%     \token_if_expandable:NTF |
+%     \token_if_expandable:NT |
+%     \token_if_expandable:NF 
+% }
+%   \begin{syntax}
+%     "\token_if_expandable:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is expandable or not. Note that  can very
+%   well be an active character.
+% \end{function}
+%
+% The next set of functions here are for picking apart control
+% sequences. Sometimes it is useful to know if a control sequence has
+% arguments and if so, how many. Similarly its status with respect to
+% "\long" or "\protected" is good to have. Finally it can be very
+% useful to know if a control sequence is of a certain type: Is this
+% \m{toks} register we're trying to to something with really a
+% \m{toks} register at all? 
+%
+% \begin{function}{
+%     \token_if_long_macro_p:N |
+%     \token_if_long_macro:NTF |
+%     \token_if_long_macro:NT |
+%     \token_if_long_macro:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_long_macro:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is a ``long'' macro.
+% \end{function}
+%
+%
+% \begin{function}{
+%     \token_if_protected_macro_p:N |
+%     \token_if_protected_macro:NTF |
+%     \token_if_protected_macro:NT |
+%     \token_if_protected_macro:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_long_macro:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is a ``protected'' macro. This test does \emph{not}
+%   return  if the macro is also ``long'', see below.
+% \end{function}
+%
+% \begin{function}{
+%     \token_if_protected_long_macro_p:N |
+%     \token_if_protected_long_macro:NTF |
+%     \token_if_protected_long_macro:NT |
+%     \token_if_protected_long_macro:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_protected_long_macro:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is a ``protected long'' macro.
+% \end{function}
+%
+% \begin{function}{
+%     \token_if_chardef_p:N |
+%     \token_if_chardef:NTF |
+%     \token_if_chardef:NT |
+%     \token_if_chardef:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_chardef:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is defined to be a chardef.
+% \end{function}
+%
+% \begin{function}{
+%     \token_if_mathchardef_p:N |
+%     \token_if_mathchardef:NTF |
+%     \token_if_mathchardef:NT |
+%     \token_if_mathchardef:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_mathchardef:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is defined to be a mathchardef.
+% \end{function}
+%
+% \begin{function}{
+%     \token_if_int_register_p:N |
+%     \token_if_int_register:NTF |
+%     \token_if_int_register:NT |
+%     \token_if_int_register:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_int_register:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is defined to be an integer register.
+% \end{function}
+%
+% \begin{function}{
+%     \token_if_dim_register_p:N |
+%     \token_if_dim_register:NTF |
+%     \token_if_dim_register:NT |
+%     \token_if_dim_register:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_dim_register:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is defined to be a dimension register.
+% \end{function}
+%
+% \begin{function}{
+%     \token_if_skip_register_p:N |
+%     \token_if_skip_register:NTF |
+%     \token_if_skip_register:NT |
+%     \token_ifskip_register:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_skip_register:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is defined to be a skip register.
+% \end{function}
+%
+% \begin{function}{
+%     \token_if_toks_register_p:N |
+%     \token_if_toks_register:NTF |
+%     \token_if_toks_register:NT |
+%     \token_if_toks_register:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_toks_register:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is defined to be a toks register.
+% \end{function}
+%
+%
+% \begin{function}{
+%     \token_get_prefix_spec:N |
+%     \token_get_arg_spec:N |
+%     \token_get_replacement_spec:N
+% }
+%   \begin{syntax}
+%     "\token_get_arg_spec:N"  
+%   \end{syntax}
+%   If token is a macro with definition |\def_long:Npn||\next|
+%   |#1#2{x`#1--#2'y}|, the |prefix| function will return the string
+%   |\long|, the |arg| function returns the string |#1#2| and the
+%   |replacement| function returns the string |x`#1--#2'y|. If 
+%   isn't a macro, these functions return the |\scan_stop:| token.
+% \end{function}
+% 
+% \subsubsection{Useless code: because we can!}
+%
+% \begin{function}{
+%     \token_if_primitive_p:N |
+%     \token_if_primitive:NTF |
+%     \token_if_primitive:NT |
+%     \token_if_primitive:NF |
+% }
+%   \begin{syntax}
+%     "\token_if_primitive:NTF"  "{""}" "{""}"
+%   \end{syntax}
+%   Check if  is a primitive. Probably not a very useful function.
+% \end{function}
+%
+%
+%  \subsection{Peeking ahead at the next token}
+%
+%
+%
+%
+%
+%  \begin{variable}{%
+%                   \l_peek_token |
+%                   \g_peek_token |
+%                   \l_peek_search_token |
+%  }
+%  \begin{syntax}
+%  \end{syntax}
+%  Some useful variables. Initially they are set to "?".
+%  \end{variable}
+%
+%
+%  \begin{function}{%
+%                   \peek_after:NN |
+%                   \peek_gafter:NN |
+%  }
+%  \begin{syntax}
+%     "\peek_after:NN" 
+%  \end{syntax}
+%  Assign  to "\l_peek_token" and then run  which
+%  should perform some sort of test on this token. Leaves  in
+%  the input stream. "\peek_gafter:NN" does this globally to the token
+%  "\g_peek_token".
+%  \begin{texnote}
+%  This is the primitive \tn{futurelet} turned into a function.
+%  \end{texnote}
+%  \end{function}
+%
+%  \begin{function}{%
+%                   \peek_meaning:NTF |
+%                   \peek_meaning_ignore_spaces:NTF |
+%                   \peek_meaning_remove:NTF |
+%                   \peek_meaning_remove_ignore_spaces:NTF
+%  }
+%  \begin{syntax}
+%    "\peek_meaning:NTF"  "{""}""{""}"
+%  \end{syntax}
+%  "\peek_meaning:NTF" checks (by using "\if_meaning:NN") if 
+%  equals the next token in the input stream and executes either  or  accordingly. "\peek_meaning_remove:NTF" does
+%  the same but additionally removes the token if found. The
+%  "ignore_spaces" versions skips blank spaces before making the
+%  decision.
+%  \end{function}
+%
+%  \begin{function}{%
+%                   \peek_charcode:NTF |
+%                   \peek_charcode_ignore_spaces:NTF |
+%                   \peek_charcode_remove:NTF |
+%                   \peek_charcode_remove_ignore_spaces:NTF
+%  }
+%  \begin{syntax}
+%    "\peek_charcode:NTF"  "{""}""{""}"
+%  \end{syntax}
+%  Same as for the "\peek_meaning:NTF" functions above but these use
+%  "\if_charcode:w" to compare the tokens.
+%  \end{function}
+%
+%  \begin{function}{%
+%                   \peek_catcode:NTF |
+%                   \peek_catcode_ignore_spaces:NTF |
+%                   \peek_catcode_remove:NTF |
+%                   \peek_catcode_remove_ignore_spaces:NTF
+%  }
+%  \begin{syntax}
+%    "\peek_catcode:NTF"  "{""}""{""}"
+%  \end{syntax}
+%  Same as for the "\peek_meaning:NTF" functions above but these use
+%  "\if_catcode:w" to compare the tokens.
+%  \end{function}
+%
+%
+%  \begin{function}{%
+%                   \peek_token_generic:NNTF |
+%                   \peek_token_remove_generic:NNTF
+%  }
+%  \begin{syntax}
+%     "\peek_token_generic:NNTF"  "{""}""{""}"
+%  \end{syntax}
+%  "\peek_token_generic:NNTF" looks ahead and checks if the next token
+%  in the input stream is equal to . It uses  to make
+%  that decision. "\peek_token_remove_generic:NNTF" does the same
+%  thing but additionally removes  from the input stream if it
+%  is found. This also works if  is either
+%  "\c_group_begin_token" or "\c_group_end_token".
+%  \end{function}
+%
+%  \begin{function}{%
+%                   \peek_execute_branches_meaning: |
+%                   \peek_execute_branches_charcode: |
+%                   \peek_execute_branches_catcode: |
+%  }
+%  \begin{syntax}
+%     "\peek_execute_branches_meaning:" 
+%  \end{syntax}
+%  These functions compare the token we are searching for with the
+%  token found (after optional ignoring of specific tokens). They come
+%  in the usual three versions when \TeX{} is comparing tokens:
+%  meaning, character code, and category code.
+%  \end{function}
+%
+%
+%
+%
+%  \subsubsection{Internal functions}
+%
+%  \begin{variable}{%
+%                   \l_peek_true_tlp |
+%                   \l_peek_false_tlp |
+%  }
+%  \begin{syntax}
+%  \end{syntax}
+%  These token list pointers are used internally when choosing either
+%  the true or false branches of a test.
+%  \end{variable}
+%
+%  \begin{function}{%
+%                   \peek_tmp:w |
+%  }
+%  \begin{syntax}
+%  \end{syntax}
+%  Scratch function used to gobble tokens from the input stream.
+%  \end{function}
+%
+%  \begin{variable}{%
+%                   \l_peek_true_aux_tlp |
+%                   \l_peek_true_remove_next_tlp |
+%  }
+%  \begin{syntax}
+%  \end{syntax}
+%  These token list pointers are used internally when choosing either
+%  the true or false branches of a test.
+%  \end{variable}
+%
+%  \begin{function}{%
+%                   \peek_ignore_spaces_execute_branches: |
+%                   \peek_ignore_spaces_aux: |
+%  }
+%  \begin{syntax}
+%  \end{syntax}
+%  Functions used to ignore space tokens in the input stream.
+%  \end{function}
+%
+%
+%
+% \StopEventually{}
+%
+%
+% \subsection{Implementation}
+% First a few required packages to get this going.
+%    \begin{macrocode}
+%\RequirePackage{l3prg}
+%\RequirePackage{l3int}
+%<*initex|package>
+%    \end{macrocode}
+%
+% \subsubsection{Character tokens}
+%
+%    \begin{macro}{\char_set_catcode:w}
+%    \begin{macro}{\char_set_catcode:nn}
+%    \begin{macro}{\char_value_catcode:w}
+%    \begin{macro}{\char_value_catcode:n}
+%    \begin{macro}{\char_show_value_catcode:w}
+%    \begin{macro}{\char_show_value_catcode:n}  
+%    \begin{macrocode}
+\let_new:NN \char_set_catcode:w \tex_catcode:D
+\def_new:Npn \char_set_catcode:nn #1#2{
+  \char_set_catcode:w #1 = \int_eval:n{#2}
+}
+\def_new:Npn \char_value_catcode:w {\int_use:N\tex_catcode:D}
+\def_new:Npn \char_value_catcode:n #1{\char_value_catcode:w \int_eval:n{#1}}
+\def_new:Npn \char_show_value_catcode:w {\tex_showthe:D\tex_catcode:D}
+\def_new:Npn \char_show_value_catcode:n #1{
+  \char_show_value_catcode:w \int_eval:n{#1}}
+%    \end{macrocode}
+%    \end{macro}
+%    \end{macro}
+%    \end{macro}
+%    \end{macro}
+%    \end{macro}
+%    \end{macro}
+%
+%    \begin{macro}{\char_set_lccode:w}
+%    \begin{macro}{\char_set_lccode:nn}
+%    \begin{macro}{\char_value_lccode:w}
+%    \begin{macro}{\char_value_lccode:n}
+%    \begin{macro}{\char_show_value_lccode:w}
+%    \begin{macro}{\char_show_value_lccode:n}  
+%    \begin{macrocode}
+\let_new:NN \char_set_lccode:w \tex_lccode:D
+\def_new:Npn \char_set_lccode:nn #1#2{
+  \char_set_lccode:w #1 = \int_eval:n{#2}
+}
+\def_new:Npn \char_value_lccode:w {\int_use:N\tex_lccode:D}
+\def_new:Npn \char_value_lccode:n #1{\char_value_lccode:w \int_eval:n{#1}}
+\def_new:Npn \char_show_value_lccode:w {\tex_showthe:D\tex_lccode:D}
+\def_new:Npn \char_show_value_lccode:n #1{
+  \char_show_value_lccode:w \int_eval:n{#1}}
+%    \end{macrocode}
+%    \end{macro}
+%    \end{macro}
+%    \end{macro}
+%    \end{macro}
+%    \end{macro}
+%    \end{macro}
+%
+%    \begin{macro}{\char_set_uccode:w}
+%    \begin{macro}{\char_set_uccode:nn}
+%    \begin{macro}{\char_value_uccode:w}
+%    \begin{macro}{\char_value_uccode:n}
+%    \begin{macro}{\char_show_value_uccode:w}
+%    \begin{macro}{\char_show_value_uccode:n}  
+%    \begin{macrocode}
+\let_new:NN \char_set_uccode:w \tex_uccode:D
+\def_new:Npn \char_set_uccode:nn #1#2{
+  \char_set_uccode:w #1 = \int_eval:n{#2}
+}
+\def_new:Npn \char_value_uccode:w {\int_use:N\tex_uccode:D}
+\def_new:Npn \char_value_uccode:n #1{\char_value_uccode:w \int_eval:n{#1}}
+\def_new:Npn \char_show_value_uccode:w {\tex_showthe:D\tex_uccode:D}
+\def_new:Npn \char_show_value_uccode:n #1{
+  \char_show_value_uccode:w \int_eval:n{#1}}
+%    \end{macrocode}
+%    \end{macro}
+%    \end{macro}
+%    \end{macro}
+%    \end{macro}
+%    \end{macro}
+%    \end{macro}
+%
+%    \begin{macro}{\char_set_sfcode:w}
+%    \begin{macro}{\char_set_sfcode:nn}
+%    \begin{macro}{\char_value_sfcode:w}
+%    \begin{macro}{\char_value_sfcode:n}
+%    \begin{macro}{\char_show_value_sfcode:w}
+%    \begin{macro}{\char_show_value_sfcode:n}  
+%    \begin{macrocode}
+\let_new:NN \char_set_sfcode:w \tex_sfcode:D
+\def_new:Npn \char_set_sfcode:nn #1#2{
+  \char_set_sfcode:w #1 = \int_eval:n{#2}
+}
+\def_new:Npn \char_value_sfcode:w {\int_use:N\tex_uccode:D}
+\def_new:Npn \char_value_sfcode:n #1{\char_value_sfcode:w \int_eval:n{#1}}
+\def_new:Npn \char_show_value_sfcode:w {\tex_showthe:D\tex_sfcode:D}
+\def_new:Npn \char_show_value_sfcode:n #1{
+  \char_show_value_sfcode:w \int_eval:n{#1}}
+%    \end{macrocode}
+%    \end{macro}
+%    \end{macro}
+%    \end{macro}
+%    \end{macro}
+%    \end{macro}
+%    \end{macro}
+%
+% \subsubsection{Generic tokens}
+%
+%
+%  \begin{macro}{\token_new:Nn}
+%  Creates a new token.
+%    \begin{macrocode}
+\def_new:Npn \token_new:Nn #1#2{\glet_new:NN #1#2}
+%    \end{macrocode}
+%  \end{macro}
+%  \begin{macro}{\c_group_begin_token}
+%  \begin{macro}{\c_group_end_token}
+%  \begin{macro}{\c_math_shift_token}
+%  \begin{macro}{\c_alignment_tab_token}
+%  \begin{macro}{\c_parameter_token}
+%  \begin{macro}{\c_math_superscript_token}
+%  \begin{macro}{\c_math_subscript_token}
+%  \begin{macro}{\c_space_token}
+%  \begin{macro}{\c_letter_token}
+%  \begin{macro}{\c_other_char_token}
+%  \begin{macro}{\c_active_char_token}
+%  We define these useful tokens. We have to do it by hand with the
+%  brace tokens for obvious reasons.
+%    \begin{macrocode}
+\let_new:NN \c_group_begin_token {
+\let_new:NN \c_group_end_token }
+\group_begin:
+\char_set_catcode:nn{`\*}{3}
+\token_new:Nn \c_math_shift_token {*}
+\char_set_catcode:nn{`\*}{4}
+\token_new:Nn \c_alignment_tab_token {*}
+\token_new:Nn \c_parameter_token {#}
+\token_new:Nn \c_math_superscript_token {^}
+\char_set_catcode:nn{`\*}{8}
+\token_new:Nn \c_math_subscript_token {*}
+\token_new:Nn \c_space_token {~}
+\token_new:Nn \c_letter_token {a}
+\token_new:Nn \c_other_char_token {1}
+\char_set_catcode:nn{`\*}{13}
+\token_new:Nn \c_active_char_token {*}
+\group_end:
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+% \begin{macro}{\token_if_group_begin_p:N}
+% \begin{macro}{\token_if_group_begin:NTF}
+% \begin{macro}{\token_if_group_begin:NT}
+% \begin{macro}{\token_if_group_begin:NF}
+%   Check if token is a begin group token. We use the constant
+%   "\c_group_begin_token" for this.
+%    \begin{macrocode}
+\def_new:Npn \token_if_group_begin_p:N #1{
+  \if_catcode:w \exp_not:N #1\c_group_begin_token
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+\def_test_function_new:npn {token_if_group_begin:N} #1{
+  \if:w\token_if_group_begin_p:N #1}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\token_if_group_end_p:N}
+% \begin{macro}{\token_if_group_end:NTF}
+% \begin{macro}{\token_if_group_end:NT}
+% \begin{macro}{\token_if_group_end:NF}
+%   Check if token is a end group token. We use the constant
+%   "\c_group_end_token" for this.
+%    \begin{macrocode}
+\def_new:Npn \token_if_group_end_p:N #1{
+  \if_catcode:w \exp_not:N #1\c_group_end_token
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+\def_test_function_new:npn {token_if_group_end:N} #1{
+  \if:w\token_if_group_end_p:N #1}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\token_if_math_shift_p:N}
+% \begin{macro}{\token_if_math_shift:NTF}
+% \begin{macro}{\token_if_math_shift:NT}
+% \begin{macro}{\token_if_math_shift:NF}
+%   Check if token is a math shift token. We use the constant
+%   "\c_math_shift_token" for this.
+%    \begin{macrocode}
+\def_new:Npn \token_if_math_shift_p:N #1{
+  \if_catcode:w \exp_not:N #1\c_math_shift_token
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+\def_test_function_new:npn {token_if_math_shift:N} #1{
+  \if:w\token_if_math_shift_p:N#1}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\token_if_alignment_tab_p:N}
+% \begin{macro}{\token_if_alignment_tab:NTF}
+% \begin{macro}{\token_if_alignment_tab:NT}
+% \begin{macro}{\token_if_alignment_tab:NF}
+%   Check if token is an alignment tab token. We use the constant
+%   "\c_alignment_tab_token" for this.
+%    \begin{macrocode}
+\def_new:Npn \token_if_alignment_tab_p:N #1{
+  \if_catcode:w \exp_not:N #1\c_alignment_tab_token
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+\def_test_function_new:npn {token_if_alignment_tab:N} #1{
+  \if:w\token_if_alignment_tab_p:N#1}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\token_if_parameter_p:N}
+% \begin{macro}{\token_if_parameter:NTF}
+% \begin{macro}{\token_if_parameter:NT}
+% \begin{macro}{\token_if_parameter:NF}
+%   Check if token is a parameter token. We use the constant
+%   "\c_parameter_token" for this. We have to trick \TeX{} a bit to
+%   avoid an error message.
+%    \begin{macrocode}
+\def_new:Npn \token_if_parameter_p:N #1{
+  \exp_after:NN\if_catcode:w \cs:w c_parameter_token\cs_end:\exp_not:N #1
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+\def_test_function_new:npn {token_if_parameter:N} #1{
+  \if:w\token_if_parameter_p:N#1}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\token_if_math_superscript_p:N}
+% \begin{macro}{\token_if_math_superscript:NTF}
+% \begin{macro}{\token_if_math_superscript:NT}
+% \begin{macro}{\token_if_math_superscript:NF}
+%   Check if token is a math superscript token. We use the constant
+%   "\c_math_superscript_token" for this.
+%    \begin{macrocode}
+\def_new:Npn \token_if_math_superscript_p:N #1{
+  \if_catcode:w \exp_not:N #1\c_math_superscript_token
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+\def_test_function_new:npn {token_if_math_superscript:N} #1{
+  \if:w\token_if_math_superscript_p:N #1}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\token_if_math_subscript_p:N}
+% \begin{macro}{\token_if_math_subscript:NTF}
+% \begin{macro}{\token_if_math_subscript:NT}
+% \begin{macro}{\token_if_math_subscript:NF}
+%   Check if token is a math subscript token. We use the constant
+%   "\c_math_subscript_token" for this.
+%    \begin{macrocode}
+\def_new:Npn \token_if_math_subscript_p:N #1{
+  \if_catcode:w \exp_not:N #1\c_math_subscript_token
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+\def_test_function_new:npn {token_if_math_subscript:N} #1{
+  \if:w\token_if_math_subscript_p:N #1}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\token_if_space_p:N}
+% \begin{macro}{\token_if_space:NTF}
+% \begin{macro}{\token_if_space:NT}
+% \begin{macro}{\token_if_space:NF}
+%   Check if token is a space token. We use the constant
+%   "\c_space_token" for this.
+%    \begin{macrocode}
+\def_new:Npn \token_if_space_p:N #1{
+  \if_catcode:w \exp_not:N #1\c_space_token
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+\def_test_function_new:npn {token_if_space:N} #1{
+  \if:w\token_if_space_p:N #1}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \begin{macro}{\token_if_letter_p:N}
+% \begin{macro}{\token_if_letter:NTF}
+% \begin{macro}{\token_if_letter:NT}
+% \begin{macro}{\token_if_letter:NF}
+%   Check if token is a letter token. We use the constant
+%   "\c_letter_token" for this.
+%    \begin{macrocode}
+\def_new:Npn \token_if_letter_p:N #1{
+  \if_catcode:w \exp_not:N #1\c_letter_token
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+\def_test_function_new:npn {token_if_letter:N} #1{
+  \if:w\token_if_letter_p:N #1}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\token_if_other_char_p:N}
+% \begin{macro}{\token_if_other_char:NTF}
+% \begin{macro}{\token_if_other_char:NT}
+% \begin{macro}{\token_if_other_char:NF}
+%   Check if token is an other char token. We use the constant
+%   "\c_other_char_token" for this.
+%    \begin{macrocode}
+\def_new:Npn \token_if_other_char_p:N #1{
+  \if_catcode:w \exp_not:N #1\c_other_char_token
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+\def_test_function_new:npn {token_if_other_char:N} #1{
+  \if:w\token_if_other_char_p:N #1}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\token_if_active_char_p:N}
+% \begin{macro}{\token_if_active_char:NTF}
+% \begin{macro}{\token_if_active_char:NT}
+% \begin{macro}{\token_if_active_char:NF}
+%   Check if token is an active char token. We use the constant
+%   "\c_active_char_token" for this.
+%    \begin{macrocode}
+\def_new:Npn \token_if_active_char_p:N #1{
+  \if_catcode:w \exp_not:N #1\c_active_char_token
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+\def_test_function_new:npn {token_if_active_char:N} #1{
+  \if:w\token_if_active_char_p:N #1}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%  \begin{macro}{\token_if_eq_meaning_p:NN}
+%  \begin{macro}{\token_if_eq_meaning:NNTF}
+%  \begin{macro}{\token_if_eq_meaning:NNT}
+%  \begin{macro}{\token_if_eq_meaning:NNF}
+%  Check if the tokens |#1| and |#2| have same meaning.
+%    \begin{macrocode}
+\def_new:Npn \token_if_eq_meaning_p:NN #1#2 {
+  \if_meaning:NN  #1  #2
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+\def_test_function_new:npn {token_if_eq_meaning:NN}#1#2{
+  \if_meaning:NN  #1  #2}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%  \begin{macro}{\token_if_eq_catcode_p:NN}
+%  \begin{macro}{\token_if_eq_catcode:NNTF}
+%  \begin{macro}{\token_if_eq_catcode:NNT}
+%  \begin{macro}{\token_if_eq_catcode:NNF}
+%  Check if the tokens |#1| and |#2| have same category code.
+%    \begin{macrocode}
+\def_new:Npn \token_if_eq_catcode_p:NN #1#2 {
+  \if_catcode:w \exp_not:N #1 \exp_not:N #2
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+\def_test_function_new:npn {token_if_eq_catcode:NN}#1#2{
+  \if:w\token_if_eq_catcode_p:NN#1#2}
+%    \end{macrocode}
+%  \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%  \begin{macro}{\token_if_eq_charcode_p:NN}
+%  \begin{macro}{\token_if_eq_charcode:NNTF}
+%  \begin{macro}{\token_if_eq_charcode:NNT}
+%  \begin{macro}{\token_if_eq_charcode:NNF}
+%  Check if the tokens |#1| and |#2| have same character code.
+%    \begin{macrocode}
+\def_new:Npn \token_if_charcode_eq_p:NN #1#2 {
+  \if_charcode:w \exp_not:N #1 \exp_not:N #2
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+\def_test_function_new:npn {token_if_eq_charcode:NN}#1#2{
+  \if:w\token_if_eq_charcode_p:NN#1#2}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\token_if_macro_p:N}
+% \begin{macro}{\token_if_macro_p_aux:w}
+% \begin{macro}{\token_if_macro:NTF}
+% \begin{macro}{\token_if_macro:NT}
+% \begin{macro}{\token_if_macro:NF}
+%   When a token is a macro, "\token_to_meaning:N" will always output
+%   something like "\long macro:#1->#1" so we simply check to see if
+%   the meaning contains "->". Argument "#2" in the code below will be
+%   empty if the string "->" isn't present, proof that the token was
+%   not a macro (which is why we reverse the emptiness test). However
+%   this function will fail on its own auxiliary function (and a few
+%   other private functions as well) but that should certainly never
+%   be a problem!
+%    \begin{macrocode}
+\def_new:Npn \token_if_macro_p:N #1 {
+  \exp_after:NN \token_if_macro_p_aux:w \token_to_meaning:N #1 -> \q_nil
+}
+\def_new:Npn \token_if_macro_p_aux:w #1 -> #2 \q_nil{
+  \if:w \tlist_if_empty_p:n{#2} \c_false \else: \c_true \fi:
+}
+\def_test_function_new:npn {token_if_macro:N} #1{\if:w\token_if_macro_p:N#1}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+% \begin{macro}{\token_if_cs_p:N}
+% \begin{macro}{\token_if_cs:NTF}
+% \begin{macro}{\token_if_cs:NT}
+% \begin{macro}{\token_if_cs:NF}
+%   Check if token has same catcode as a control sequence. We use
+%   "\scan_stop:" for this.
+%    \begin{macrocode}
+\def_new:Npn \token_if_cs_p:N {\token_if_eq_catcode_p:NN \scan_stop:}
+\def_test_function_new:npn {token_if_cs:N} #1{
+  \if:w \token_if_eq_catcode_p:NN \scan_stop: #1}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\token_if_expandable_p:N}
+% \begin{macro}{\token_if_expandable:NTF}
+% \begin{macro}{\token_if_expandable:NT}
+% \begin{macro}{\token_if_expandable:NF}
+%   Check if token is expandable. We use the fact that \TeX\ will
+%   temporarily convert "\exp_not:N" \m{token} into "\scan_stop:" if
+%   \m{token} is expandable.
+%    \begin{macrocode}
+\def_new:Npn \token_if_expandable_p:N #1{
+  \exp_after:NN \if_token_eq:NN \exp_not:N #1 \scan_stop:
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+\def_test_function_new:npn {token_if_expandable:N} #1{
+  \if:w\token_if_expandable_p:N#1}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\token_if_chardef_p:N}
+% \begin{macro}{\token_if_chardef_p_aux:w}
+% \begin{macro}{\token_if_mathchardef_p:N}
+% \begin{macro}{\token_if_mathchardef_p_aux:w}
+% \begin{macro}{\token_if_int_register_p:N}
+% \begin{macro}{\token_if_int_register_p_aux:w}
+% \begin{macro}{\token_if_skip_register_p:N}
+% \begin{macro}{\token_if_skip_register_p_aux:w}
+% \begin{macro}{\token_if_dim_register_p:N}
+% \begin{macro}{\token_if_dim_register_p_aux:w}
+% \begin{macro}{\token_if_toks_register_p:N}
+% \begin{macro}{\token_if_toks_register_p_aux:w}
+% \begin{macro}{\token_if_protected_macro_p:N}
+% \begin{macro}{\token_if_protected_macro_p_aux:w}
+% \begin{macro}{\token_if_long_macro_p:N}
+% \begin{macro}{\token_if_long_macro_p_aux:w}
+% \begin{macro}{\token_if_protected_long_macro_p:N}
+% \begin{macro}{\token_if_protected_long_macro_p_aux:w}
+%   Most of these functions have to check the meaning of the token in
+%   question so we need to do some checkups on which characters are
+%   output by |\token_to_meaning:N|. As usual, these characters have
+%   catcode 12 so we must do some serious substitutions in the code
+%   below\dots
+%    \begin{macrocode}
+\group_begin:
+  \char_set_lccode:nn {`\X}{`\n} 
+  \char_set_lccode:nn {`\Y}{`\t}
+  \char_set_lccode:nn {`\Z}{`\d}
+  \char_set_lccode:nn {`\?}{`\\}
+  \tlist_map_inline:nn{\X\Y\Z\M\T\C\H\A\R\O\U\S\K\I\P\L\G\P\E}
+    {\char_set_catcode:nn {`#1}{12}}
+%    \end{macrocode}
+% We convert the token list to lowercase and restore the catcode and
+% lowercase code changes.
+%    \begin{macrocode}
+\tlist_to_lowercase:n{
+  \group_end:
+%    \end{macrocode}
+% First up is checking if something has been defined with
+% |\tex_chardef:D| or |\tex_mathchardef:D|. This is easy since \TeX\
+% thinks of such tokens as hexadecimal so it stores them as
+% |\char"|\meta{hex~number} or |\mathchar"|\meta{hex~number}.
+%    \begin{macrocode}
+\def_new:Npn \token_if_chardef_p:N #1 {
+  \exp_after:NN \token_if_chardef_p_aux:w
+  \token_to_meaning:N #1?CHAR"\q_nil
+}
+\def_new:Npn \token_if_chardef_p_aux:w #1?CHAR"#2\q_nil{
+  \tlist_if_empty_p:n{#1}
+}
+\def_new:Npn \token_if_mathchardef_p:N #1 {
+  \exp_after:NN \token_if_mathchardef_p_aux:w
+  \token_to_meaning:N #1?MAYHCHAR"\q_nil
+}
+\def_new:Npn \token_if_mathchardef_p_aux:w #1?MAYHCHAR"#2\q_nil{
+  \tlist_if_empty_p:n{#1}
+}
+%    \end{macrocode}
+% Integer registers are a little more difficult since they expand to
+% |\count|\meta{number} and there is also a primitive |\countdef|. So
+% we have to check for that primitive as well.
+%    \begin{macrocode}
+\def:Npn \token_if_int_register_p:N #1{
+  \if_meaning:NN \tex_countdef:D #1 
+    \c_false
+  \else:
+    \exp_after:NN \token_if_int_register_p_aux:w
+      \token_to_meaning:N #1?COUXY\q_nil
+  \fi:
+}
+\def_new:Npn \token_if_int_register_p_aux:w #1?COUXY#2\q_nil{
+  \tlist_if_empty_p:n{#1}
+}
+%    \end{macrocode}
+% Skip registers are done the same way as the integer registers.
+%    \begin{macrocode}
+\def:Npn \token_if_skip_register_p:N #1{
+  \if_meaning:NN \tex_skipdef:D #1 
+  \c_false
+  \else:
+  \exp_after:NN \token_if_skip_register_p_aux:w
+  \token_to_meaning:N #1?SKIP\q_nil
+  \fi:
+}
+\def_new:Npn \token_if_skip_register_p_aux:w #1?SKIP#2\q_nil{
+  \tlist_if_empty_p:n{#1}
+}
+%    \end{macrocode}
+% Dim registers. No news here
+%    \begin{macrocode}
+\def:Npn \token_if_dim_register_p:N #1{
+  \if_meaning:NN \tex_dimendef:D #1 
+    \c_false
+  \else:
+    \exp_after:NN \token_if_dim_register_p_aux:w
+    \token_to_meaning:N #1?ZIMEX\q_nil 
+  \fi:
+}
+\def_new:Npn \token_if_dim_register_p_aux:w #1?ZIMEX#2\q_nil{
+  \tlist_if_empty_p:n{#1}
+}
+%    \end{macrocode}
+% Toks registers. Ho-hum.
+%    \begin{macrocode}
+\def:Npn \token_if_toks_register_p:N #1{
+  \if_meaning:NN \tex_toksdef:D #1 
+    \c_false
+  \else:
+    \exp_after:NN \token_if_toks_register_p_aux:w
+    \token_to_meaning:N #1?YOKS\q_nil
+  \fi:
+}
+\def_new:Npn \token_if_toks_register_p_aux:w #1?YOKS#2\q_nil{
+  \tlist_if_empty_p:n{#1}
+}
+%    \end{macrocode}
+% Protected macros.
+%    \begin{macrocode}
+\def_new:Npn \token_if_protected_macro_p:N #1 {
+  \exp_after:NN \token_if_protected_macro_p_aux:w
+  \token_to_meaning:N #1?PROYECYEZ~MACRO\q_nil
+}
+\def_new:Npn \token_if_protected_macro_p_aux:w #1?PROYECYEZ~MACRO#2\q_nil{
+  \tlist_if_empty_p:n{#1}
+}
+%    \end{macrocode}
+% Long macros.
+%    \begin{macrocode}
+\def_new:Npn \token_if_long_macro_p:N #1 {
+  \exp_after:NN \token_if_long_macro_p_aux:w
+  \token_to_meaning:N #1?LOXG~MACRO\q_nil
+}
+\def_new:Npn \token_if_long_macro_p_aux:w #1?LOXG~MACRO#2\q_nil{
+  \tlist_if_empty_p:n{#1}
+}
+%    \end{macrocode}
+% Finally protected long macros where we for once don't have to add an
+% extra test since there is no primitive for the combined prefixes.
+%    \begin{macrocode}
+\def_new:Npn \token_if_protected_long_macro_p:N #1 {
+  \exp_after:NN \token_if_protected_long_macro_p_aux:w 
+  \token_to_meaning:N #1?PROYECYEZ~?LOXG~MACRO\q_nil
+}
+\def_new:Npn \token_if_protected_long_macro_p_aux:w #1
+  ?PROYECYEZ~?LOXG~MACRO#2\q_nil{
+  \tlist_if_empty_p:n{#1}
+}
+%    \end{macrocode}
+% Finally the |\tlist_to_lowercase:n| ends!
+%    \begin{macrocode}
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\token_if_chardef:NTF}
+% \begin{macro}{\token_if_chardef:NT}
+% \begin{macro}{\token_if_chardef:NF}
+%    \begin{macrocode}
+\def_test_function_new:npn {token_if_chardef:N} {\if:w \token_if_chardef_p:N}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\token_if_mathchardef:NTF}
+% \begin{macro}{\token_if_mathchardef:NT}
+% \begin{macro}{\token_if_mathchardef:NF}
+%    \begin{macrocode}
+\def_test_function_new:npn {token_if_mathchardef:N} {
+  \if:w \token_if_mathchardef_p:N}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\token_if_long_macro:NTF}
+% \begin{macro}{\token_if_long_macro:NT}
+% \begin{macro}{\token_if_long_macro:NF}
+%    \begin{macrocode}
+\def_test_function_new:npn {token_if_long_macro:N} {
+  \if:w \token_if_long_macro_p:N}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\token_if_protected_macro:NTF}
+% \begin{macro}{\token_if_protected_macro:NT}
+% \begin{macro}{\token_if_protected_macro:NF}
+%    \begin{macrocode}
+\def_test_function_new:npn {token_if_protected_macro:N} {
+  \if:w \token_if_protected_macro_p:N}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\token_if_protected_long_macro:NTF}
+% \begin{macro}{\token_if_protected_long_macro:NT}
+% \begin{macro}{\token_if_protected_long_macro:NF}
+%    \begin{macrocode}
+\def_test_function_new:npn {token_if_protected_long_macro:N} {
+  \if:w \token_if_protected_long_macro_p:N}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\token_if_dim_register:NTF}
+% \begin{macro}{\token_if_dim_register:NT}
+% \begin{macro}{\token_if_dim_register:NF}
+%    \begin{macrocode}
+\def_test_function_new:npn {token_if_dim_register:N} {
+  \if:w \token_if_dim_register_p:N}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\token_if_skip_register:NTF}
+% \begin{macro}{\token_if_skip_register:NT}
+% \begin{macro}{\token_if_skip_register:NF}
+%    \begin{macrocode}
+\def_test_function_new:npn {token_if_skip_register:N} {
+  \if:w \token_if_skip_register_p:N}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\token_if_int_register:NTF}
+% \begin{macro}{\token_if_int_register:NT}
+% \begin{macro}{\token_if_int_register:NF}
+%    \begin{macrocode}
+\def_test_function_new:npn {token_if_int_register:N} {
+  \if:w \token_if_int_register_p:N}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\token_if_toks_register:NTF}
+% \begin{macro}{\token_if_toks_register:NT}
+% \begin{macro}{\token_if_toks_register:NF}
+%    \begin{macrocode}
+\def_test_function_new:npn {token_if_toks_register:N} {
+  \if:w \token_if_toks_register_p:N}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+% We do not provide a function for testing if a control sequence is
+% ``outer'' since we don't use that in \LaTeX3.
+%
+% \begin{macro}{\token_get_prefix_arg_replacement_aux:w}
+% \begin{macro}{\token_get_prefix_spec:N}
+% \begin{macro}{\token_get_arg_spec:N}
+% \begin{macro}{\token_get_replacement_spec:N}
+%   In the \textsf{xparse} package we sometimes want to test if a
+%   control sequence can be expanded to reveal a hidden
+%   value. However, we cannot just expand the macro blindly as it may
+%   have arguments and none might be present. Therefore we define
+%   these functions to pick either the prefix(es), the argument
+%   specification, or the replacement text from a macro. All of this
+%   information is returned as characters with catcode~12. If the
+%   token in question isn't a macro, the token |\scan_stop:| is
+%   returned instead.
+%    \begin{macrocode}
+\group_begin:
+\char_set_lccode:nn {`\?}{`\:}
+\char_set_catcode:nn{`\M}{12}
+\char_set_catcode:nn{`\A}{12}
+\char_set_catcode:nn{`\C}{12}
+\char_set_catcode:nn{`\R}{12}
+\char_set_catcode:nn{`\O}{12}
+\tlist_to_lowercase:n{
+  \group_end:
+  \def_new:Npn \token_get_prefix_arg_replacement_aux:w #1MACRO?#2->#3\q_nil#4{
+    #4{#1}{#2}{#3}
+  }
+  \def_new:Npn\token_get_prefix_spec:N #1{
+    \token_if_macro:NTF #1{
+      \exp_after:NN \token_get_prefix_arg_replacement_aux:w
+      \token_to_meaning:N #1\q_nil\use_arg_i:nnn
+    }{\scan_stop:}
+  }
+  \def_new:Npn\token_get_arg_spec:N #1{
+    \token_if_macro:NTF #1{
+      \exp_after:NN \token_get_prefix_arg_replacement_aux:w
+      \token_to_meaning:N #1\q_nil\use_arg_ii:nnn
+    }{\scan_stop:}
+  }
+  \def_new:Npn\token_get_replacement_spec:N #1{
+    \token_if_macro:NTF #1{
+      \exp_after:NN \token_get_prefix_arg_replacement_aux:w
+      \token_to_meaning:N #1\q_nil\use_arg_iii:nnn
+    }{\scan_stop:}
+  }
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% 
+% \paragraph{Useless code: because we can!}
+%
+% \begin{macro}{\token_if_primitive_p:N}
+% \begin{macro}{\token_if_primitive_p_aux:N}
+% \begin{macro}{\token_if_primitive:NTF}
+% \begin{macro}{\token_if_primitive:NT}
+% \begin{macro}{\token_if_primitive:NF} 
+%   It is rather hard to determine if a token is a primitive. First we
+%   can check if it is a control sequence or active character. If
+%   either, we check if it is a macro. Then we can go through a
+%   tedious process of testing for different register types\dots{} I
+%   don't actually think this function is useful but you never know.
+%    \begin{macrocode}
+\def_new:Npn \token_if_primitive_p:N #1{
+  \if:w \token_if_cs_p:N #1\scan_stop:
+    \if:w \token_if_macro_p:N #1 
+      \c_false 
+    \else: 
+      \token_if_primitive_p_aux:N #1 
+    \fi:
+  \else:
+    \if:w \token_if_active_p:N #1
+      \if:w \token_if_macro_p:N #1 
+        \c_false 
+      \else: 
+        \token_if_primitive_p_aux:N #1
+      \fi:
+    \else:
+      \c_false
+    \fi:
+  \fi:
+}
+\def_new:Npn \token_if_primitive_p_aux:N #1{
+  \if:w \token_if_chardef_p:N #1 \c_false
+  \else:
+    \if:w \token_if_mathchardef_p:N #1 \c_false
+    \else: 
+      \if:w \token_if_int_register_p:N #1 \c_false
+      \else: 
+        \if:w \token_if_skip_register_p:N #1 \c_false
+        \else: 
+          \if:w \token_if_dim_register_p:N #1 \c_false
+          \else: 
+            \if:w   \token_if_toks_register_p:N #1 \c_false
+            \else: 
+%    \end{macrocode}
+% We made it!
+%    \begin{macrocode}
+              \c_true
+            \fi:
+          \fi:
+        \fi:
+      \fi:
+    \fi:
+  \fi:
+}
+\def_test_function_new:npn {token_if_primitive:N} #1{
+  \if:w\token_if_primitive_p:N#1}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%  \subsubsection{Peeking ahead at the next token}
+%
+%
+%
+%
+%
+%
+%  \begin{macro}{\l_peek_token}
+%  \begin{macro}{\g_peek_token}
+%  \begin{macro}{\l_peek_search_token}
+%  We define some other tokens which will initially be the character
+%  |?|.
+%    \begin{macrocode}
+\token_new:Nn \l_peek_token {?}
+\token_new:Nn \g_peek_token {?}
+\token_new:Nn \l_peek_search_token {?}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+%
+%  \begin{macro}{\peek_after:NN}
+%  \begin{macro}{\peek_gafter:NN}
+%  |\peek_after:NN| takes two argument where the first is a function
+%  acting on |\l_peek_token| and the second is the next token in the
+%  input stream which |\l_peek_token| is set equal to.
+%  |\peek_gafter:NN| does the same globally to |\g_peek_token|.
+%    \begin{macrocode}
+\def_new:Npn \peek_after:NN {\tex_futurelet:D \l_peek_token }
+\def_new:Npn \peek_gafter:NN {
+  \pref_global:D \tex_futurelet:D \g_peek_token
+}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%
+%  For normal purposes there are four main cases:
+%  \begin{enumerate}
+%     \item peek at the next token.
+%     \item peek at the next non-space token.
+%     \item peek at the next token and remove it.
+%     \item peek at the next non-space token and remove it.
+%  \end{enumerate}
+%
+%
+%  The generic functions will take four arguments: The token to search
+%  for, the test function to run on it and the true/false cases.
+%  The general algorithm is this:
+%  \begin{enumerate}
+%    \item
+%    Store the token to search for in |\l_peek_search_token|.
+%    \item
+%    In order to avoid doubling of hash marks where it seems unnatural
+%    we put the \meta{true} and \meta{false} cases through an |x| type
+%    expansion but using |\exp_not:n| to avoid any expansion. This has
+%    the same effect as putting it through a \meta{toks} register but
+%    is faster. Also put in a special alignment safe group end.
+%    \item
+%    Put in an alignment safe group begin.
+%    \item
+%    Peek ahead and call the function which will act on the next token
+%    in the input stream.
+%  \end{enumerate}
+%
+%  \begin{macro}{\l_peek_true_tlp}
+%  \begin{macro}{\l_peek_false_tlp}
+%  Two dedicated token list pointers that store the true and false
+%  cases.
+%    \begin{macrocode}
+\tlp_new:Nn \l_peek_true_tlp {}
+\tlp_new:Nn \l_peek_false_tlp {}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%
+%  \begin{macro}{\peek_tmp:w}
+%    Scratch function used for storing the token to be removed if
+%    found.
+%    \begin{macrocode}
+\def_new:Npn \peek_tmp:w{}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\l_peek_search_tlp}
+%    We also use this token list pointer for storing the token we want
+%    to compare. This turns out to be useful.
+%    \begin{macrocode}
+\tlp_new:Nn \l_peek_search_tlp{}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\peek_token_generic:NNTF}
+%    |#1| is the function to execute (obey or ignore spaces, etc.),
+%    |#2| is the special token we're looking for, and |#3| and |#4|
+%    are the \meta{true} and \meta{false} branches.
+%    \begin{macrocode}
+\def_long_new:Npn \peek_token_generic:NNTF #1#2#3#4{
+  \let:NN \l_peek_search_token #2
+  \tlp_set:Nn \l_peek_search_tlp {#2}
+  \tlp_set:Nx \l_peek_true_tlp {\exp_not:n{\group_align_safe_end: #3}}
+  \tlp_set:Nx \l_peek_false_tlp {\exp_not:n{\group_align_safe_end: #4}}
+  \group_align_safe_begin:
+    \peek_after:NN #1
+}
+%    \end{macrocode}
+%  \end{macro}
+%  \begin{macro}{\peek_token_remove_generic:NNTF}
+%    If we want to be able to remove any character from the input
+%    stream we might as well do it the same way for all characters so
+%    we define this as little differently from above.
+%    \begin{macrocode}
+\def_long_new:Npn \peek_token_remove_generic:NNTF #1#2#3#4{
+  \let:NN \l_peek_search_token #2
+  \tlp_set:Nn \l_peek_search_tlp {#2}
+  \tlp_set:Nx \l_peek_true_aux_tlp { \exp_not:n{ #3 } }
+  \tlp_set_eq:NN \l_peek_true_tlp \c_peek_true_remove_next_tlp
+  \tlp_set:Nx \l_peek_false_tlp {\exp_not:n{\group_align_safe_end: #4}}
+  \group_align_safe_begin:
+    \peek_after:NN #1
+}
+%    \end{macrocode}
+%  \end{macro}
+%  \begin{macro}{\l_peek_true_aux_tlp}
+%  \begin{macro}{\l_peek_true_remove_next_tlp}
+%    Two token list pointers to help with removing the character from
+%    the input stream.
+%    \begin{macrocode}
+\tlp_new:Nn \l_peek_true_aux_tlp {}
+\tlp_new:Nn \c_peek_true_remove_next_tlp {\group_align_safe_end: 
+  \tex_afterassignment:D \l_peek_true_aux_tlp \let:NN \peek_tmp:w 
+}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%
+%  \begin{macro}{\peek_execute_braches_meaning:}
+%  \begin{macro}{\peek_execute_braches_catcode:}
+%  \begin{macro}{\peek_execute_braches_charcode:}
+%  \begin{macro}{\peek_execute_branches_charcode_aux:NN}
+%    There are three major tests between tokens in \TeX: meaning,
+%    catcode and charcode. Hence we define three basic test functions
+%    that set in after the ignoring phase is over and done with.
+%    \begin{macrocode}
+\def_new:Npn \peek_execute_branches_meaning: {
+  \if_meaning:NN \l_peek_token \l_peek_search_token
+    \exp_after:NN \l_peek_true_tlp
+  \else:
+    \exp_after:NN \l_peek_false_tlp
+  \fi:
+}
+\def_new:Npn \peek_execute_branches_catcode: {
+  \if_catcode:w \exp_not:N\l_peek_token \exp_not:N\l_peek_search_token
+    \exp_after:NN \l_peek_true_tlp
+  \else:
+    \exp_after:NN \l_peek_false_tlp
+  \fi:
+}
+%    \end{macrocode}
+% For the charcode version we do things a little differently. We want
+% to check the token directly but if we do this we face problems if
+% the next thing in the input stream is a braced group or a space
+% token. The braced group would be read as a complete argument and the
+% space would be gobbled by \TeX's argument reading routines. Hence we
+% test for both of these and if one of them is found we just execute
+% the false result directly since no one should ever try to use the
+% |charcode| function for searching for |\c_group_begin_token| or
+% |\c_space_token|.
+%    \begin{macrocode}
+\def_new:Npn \peek_execute_branches_charcode: {
+  \prg_if_predicate:nTF {
+    \prg_if_predicate_or_p:nn 
+    {\token_if_eq_catcode_p:NN \l_peek_token \c_group_begin_token}
+    {\token_if_eq_meaning_p:NN \l_peek_token \c_space_token}
+  }
+  { \l_peek_false_tlp  }
+%    \end{macrocode}
+% Otherwise we call a small auxiliary function that just grabs the
+% next token. We can do that because it really is a single token; we
+% just have insert it again afterwards. Also we stored the token we
+% were looking for in the token list pointer |\l_peek_search_tlp| so
+% we unpack it again for this function.
+%    \begin{macrocode}
+  { \exp_after:NN \peek_execute_branches_charcode_aux:NN \l_peek_search_tlp }
+}
+%    \end{macrocode}
+% Then we just do the usual |\if_charcode:w| comparison. We also
+% remember to insert |#2| again after executing the true or false
+% branches.
+%    \begin{macrocode}
+\def_long_new:Npn \peek_execute_branches_charcode_aux:NN #1#2{
+  \if_charcode:w \exp_not:N #1\exp_not:N#2
+    \exp_after:NN \l_peek_true_tlp
+  \else:
+    \exp_after:NN \l_peek_false_tlp
+  \fi:
+  #2
+}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+% \begin{macro}{\peek_meaning:NTF}
+% \begin{macro}{\peek_meaning_ignore_spaces:NTF}
+% \begin{macro}{\peek_meaning_remove:NTF}
+% \begin{macro}{\peek_meaning_remove_ignore_spaces:NTF}
+% Here we use meaning comparison with |\if_meaning:NN|.
+%    \begin{macrocode}
+\def_new:Npn \peek_meaning:NTF {
+  \peek_token_generic:NNTF \peek_execute_branches_meaning:
+}
+\def_new:Npn \peek_meaning_ignore_spaces:NTF {
+  \let:NN \peek_execute_branches: \peek_execute_branches_meaning:
+  \peek_token_generic:NNTF \peek_ignore_spaces_execute_branches:
+}
+\def_new:Npn \peek_meaning_remove:NTF {
+  \peek_token_remove_generic:NNTF \peek_execute_branches_meaning:
+}
+\def_new:Npn \peek_meaning_remove_ignore_spaces:NTF {
+  \let:NN \peek_execute_branches: \peek_execute_branches_meaning:
+  \peek_token_remove_generic:NNTF \peek_ignore_spaces_execute_branches:
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\peek_catcode:NTF}
+% \begin{macro}{\peek_catcode_ignore_spaces:NTF}
+% \begin{macro}{\peek_catcode_remove:NTF}
+% \begin{macro}{\peek_catcode_remove_ignore_spaces:NTF}
+% Here we use catcode comparison with |\if_catcode:w|.
+%    \begin{macrocode}
+\def_new:Npn \peek_catcode:NTF {
+  \peek_token_generic:NNTF \peek_execute_branches_catcode:
+}
+\def_new:Npn \peek_catcode_ignore_spaces:NTF {
+  \let:NN \peek_execute_branches: \peek_execute_branches_catcode:
+  \peek_token_generic:NNTF \peek_ignore_spaces_execute_branches:
+}
+\def_new:Npn \peek_catcode_remove:NTF {
+  \peek_token_remove_generic:NNTF \peek_execute_branches_catcode:
+}
+\def_new:Npn \peek_catcode_remove_ignore_spaces:NTF {
+  \let:NN \peek_execute_branches: \peek_execute_branches_catcode:
+  \peek_token_remove_generic:NNTF \peek_ignore_spaces_execute_branches:
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\peek_charcode:NTF}
+% \begin{macro}{\peek_charcode_ignore_spaces:NTF}
+% \begin{macro}{\peek_charcode_remove:NTF}
+% \begin{macro}{\peek_charcode_remove_ignore_spaces:NTF}
+% Here we use charcode comparison with |\if_charcode:w|.
+%    \begin{macrocode}
+\def_new:Npn \peek_charcode:NTF {
+  \peek_token_generic:NNTF \peek_execute_branches_charcode:
+}
+\def_new:Npn \peek_charcode_ignore_spaces:NTF {
+  \let:NN \peek_execute_branches: \peek_execute_branches_charcode:
+  \peek_token_generic:NNTF \peek_ignore_spaces_execute_branches:
+}
+\def_new:Npn \peek_charcode_remove:NTF {
+  \peek_token_remove_generic:NNTF \peek_execute_branches_charcode:
+}
+
+\def_new:Npn \peek_charcode_remove_ignore_spaces:NTF {
+  \let:NN \peek_execute_branches: \peek_execute_branches_charcode:
+  \peek_token_remove_generic:NNTF \peek_ignore_spaces_execute_branches:
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\peek_ignore_spaces_aux:}
+% \begin{macro}{\peek_ignore_spaces_execute_branches:}
+%   Throw away a space token and search again. We could define this in
+%   a more devious way where the auxiliary function gobbles the space
+%   token but then what do we do if we decide that a certain function
+%   should ignore more than one specific token? For example someone
+%   might find it interesting to define a |\peek_| function that
+%   ignores |a|'s and |b|'s! Or maybe different kinds of ``funny
+%   spaces''\dots{} Therefore I have decided to use this version which
+%   uses |\tex_afterassignment:D| to call the auxiliary function after
+%   the next token has been removed by |\let:NN|. That way it is
+%   easily extensible.
+% \begin{macrocode}
+\def_new:Npn \peek_ignore_spaces_aux: {
+  \peek_after:NN \peek_ignore_spaces_execute_branches:
+}
+\def_new:Npn \peek_ignore_spaces_execute_branches: {
+  \token_if_eq_meaning:NNTF \l_peek_token \c_space_token
+  {  \tex_afterassignment:D \peek_ignore_spaces_aux: 
+     \let:NN \peek_tmp:w
+  } 
+  \peek_execute_branches:
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+%
+%    \begin{macrocode}
+%
+%<*showmemory>
+\showMemUsage
+%
+%    \end{macrocode}
+%
+% \endinput
+%
+%  $Log$
+%  Revision 1.6  2006/03/20 18:26:40  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.5  2006/01/19 22:33:53  morten
+%  Minor changes in \char_set_XXXcode:nn functions.
+%
+%  Revision 1.4  2006/01/04 01:28:06  morten
+%  Fixed \peek_execute_branches_charcode: properly.
+%
+%  Revision 1.3  2005/12/29 12:17:32  morten
+%  Fixed \peek_execute_branches_charcode: plus minor bugs elsewhere
+%
+%  Revision 1.2  2005/12/27 15:48:41  morten
+%  Fixing initial boo-boos. Updated documentation to reflect current code
+%  included
+%
+%  Revision 1.1  2005/12/27 09:54:58  morten
+%  New module
+%
diff --git a/Master/texmf-dist/source/latex/expl3/l3toks.dtx b/Master/texmf-dist/source/latex/expl3/l3toks.dtx
index 7e233e725fc..fd37864c815 100644
--- a/Master/texmf-dist/source/latex/expl3/l3toks.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3toks.dtx
@@ -1,15 +1,50 @@
 % \iffalse
-%% File: l3toks.dtx Copyright (C) 1990-1998 LaTeX3 project
+%% File: l3toks.dtx Copyright (C) 1990-2006 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.
+%%
+%% -----------------------------------------------------------------------
 %
+%\RequirePackage{l3names}
 %<*dtx>
-          \ProvidesFile{l3toks.dtx}
+%\fi
+\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{%
+  \def\fileversion{#2}%
+  \def\filedate{#3/#4/#5}%
+  \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]%
+}
+%\iffalse
 %
-%\NeedsTeXFormat{LaTeX2e}
-%\ProvidesPackage{l3toks}
-% \ProvidesFile{l3toks.drv}
-% \fi
-%         \ProvidesFile{l3toks.dtx}
-          [1998/05/14 v1.0g L3 Experimental Token Registers]
+%\fi
+\GetIdInfo$Id: l3toks.dtx 580 2006-11-26 15:56:47Z morten $
+          {L3 Experimental Token Registers}
 %
 % \iffalse
 %<*driver>
@@ -22,7 +57,6 @@
 % \fi
 %
 %
-% \GetFileInfo{l3toks.dtx}
 % \title{The \textsf{l3toks} package\thanks{This file
 %         has version number \fileversion, last
 %         revised \filedate.}\\
@@ -32,38 +66,46 @@
 % \maketitle
 %
 % \section {Token Registers}
-% 
+%
 % There is a second form beside token list pointers in which \LaTeX3
 % stores token lists, namely the internal \TeX{} token registers.
 % Functions dealing with these registers got the prefix "\toks_". Unlike
 % token list pointers we have an accessing function as one can see
 % below.
-% 
-% The main difference between  (token registers) and  (token
-% list pointers) is their behavior regarding expansion. While 's
+%
+% The main difference between \m{toks} (token registers) and \m{tlp} (token
+% list pointers) is their behavior regarding expansion. While \m{tlp}'s
 % expand fully (i.e., until only unexpandable tokens are left) inside
 % an argument that is subject to expansion (i.e., denote by |x|)
-% 's expand always only up to one level, i.e., passing their
+% \m{toks}'s expand always only up to one level, i.e., passing their
 % contents without further expansion.
-% 
+%
 % \subsection{Functions}
-% 
-% \begin{function}{\toks_new:N}
+%
+% \begin{function}{%
+%                  \toks_new:N |
+%                  \toks_new:c |
+%                  \toks_new_l:N}
 % \begin{syntax}
 %    "\toks_new:N" 
 % \end{syntax}
 % Defines  to be a new token list register.
-% token list pointer.
 % \begin{texnote}
 % This is the \LaTeX3 allocation for what was called \tn{newtoks} in
 % plain \TeX.
 % \end{texnote}
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \toks_set:Nn |
 %                  \toks_set:No |
+%                  \toks_set:Nd |
+%                  \toks_set:Nf |
 %                  \toks_set:Nx |
+%                  \toks_set:cn |
+%                  \toks_set:co |
+%                  \toks_set:cf |
+%                  \toks_set:cx |
 %                  \toks_gset:Nn |
 %                  \toks_gset:No |
 %                  \toks_gset:Nx}
@@ -83,7 +125,7 @@
 % \TeX.
 % \end{texnote}
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \toks_gset_eq:NN |
 % }
@@ -94,7 +136,7 @@
 % "\toks_gset:Nn" for this purpose if the second argument is also a
 % token register.
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \toks_clear:N |
 %                  \toks_gclear:N |
@@ -104,12 +146,15 @@
 % \end{syntax}
 % The  is locally or globally cleared.
 % \end{function}
-% 
+%
 % \begin{function}{%
 %                  \toks_put_left:Nn |
 %                  \toks_gput_left:Nn |
 %                  \toks_put_right:Nn |
+%                  \toks_put_right:No |
+%                  \toks_put_right:Nx |
 %                  \toks_gput_right:Nn |
+%                  \toks_gput_right:No |
 %                  \toks_gput_right:Nx |
 % }
 % \begin{syntax}
@@ -119,7 +164,7 @@
 % . Assignment is done either locally or globally. If possible
 % append to the right since this operation is faster.
 % \end{function}
-% 
+%
 % \begin{function}{\toks_use:N}
 % \begin{syntax}
 %   "\toks_use:N" 
@@ -130,7 +175,7 @@
 % Something like \tn{the} .
 % \end{texnote}
 % \end{function}
-% 
+%
 % \begin{function}{\toks_use_clear:N |
 %                  \toks_use_gclear:N}
 % \begin{syntax}
@@ -143,22 +188,31 @@
 % function is not exactly the same as calling "\toks_use:N" 
 % "\toks_clear:N"  in sequence.
 % \end{function}
-% 
-% \subsection{Predicates}
-% 
-% \begin{function}{\toks_empty:NTF}
+%
+% \subsection{Predicates and conditionals}
+%
+% \begin{function}{
+%                  \toks_if_empty_p:N|
+%                  \toks_if_empty:NTF|
+%                  \toks_if_empty:NT |
+%                  \toks_if_empty:NF|
+%                  \toks_if_empty_p:c|
+%                  \toks_if_empty:cTF |
+%                  \toks_if_empty:cT |
+%                  \toks_if_empty:cF 
+% }
 % \begin{syntax}
-%   "\toks_empty:NTF"  "{""}{""}"
+%   "\toks_if_empty:NTF"  "{""}{""}"
 % \end{syntax}
 % Tests if  is empty.
 % \end{function}
-% 
+%
 % \subsection{Variable and constants}
-% 
+%
 % \begin{variable}{\c_empty_toks}
 % Constant that is always empty.
 % \end{variable}
-% 
+%
 % \begin{variable}{%
 %                  \l_tmpa_toks |
 %                  \l_tmpb_toks |
@@ -168,24 +222,24 @@
 % Scratch register for immediate use. They are not used by conditionals
 % or predicate functions.
 % \end{variable}
-% 
+%
 % \subsubsection{Internal functions}
-% 
+%
 % \begin{function}{\toks_put_left_aux:w}
 % Used by "\toks_put_left:Nn" and its variants.
 % \end{function}
-% 
-% \begin{function}{\def_toks:D}
+%
+% \begin{function}{\tex_toksdef:D}
 % Primitive function for defining a  to correspond to a token
 % register should not be used by a programmer.
 % \begin{texnote}
 % This function was named \tn{toksdef}.
 % \end{texnote}
 % \end{function}
-% 
+%
 % \StopEventually{}
 %
-%    \section{The code}
+%    \subsection{The Implementation}
 %
 %    We start by ensuring that the required packages are loaded.
 %    We check for \texttt{l3expan} since this a basic package that is
@@ -193,16 +247,25 @@
 %    \begin{macrocode}
 %\RequirePackage{l3chk}\par
 %\RequirePackage{l3expan}\par
-%<*package>
+%<*initex|package>
 %    \end{macrocode}
 %
 % \begin{macro}{\toks_new:N}
+% \begin{macro}{\toks_new_l:N}
+% \begin{macro}{\toks_new:c}
 %    Allocates a new token register. This function is already defined above.
 %    \begin{macrocode}
-\def_new:Npn \toks_new:N {}
-\let:NN \toks_new:N \newtoks   % nick from LaTeX for the moment
+%<*initex>
+\alloc_setup_type:nnn {toks} \c_zero \c_max_register_num
+\def_new:Npn \toks_new:N   #1{\alloc_reg:NnNN g {toks} \tex_toksdef:D #1}
+\def_new:Npn \toks_new_l:N #1{\alloc_reg:NnNN l {toks} \tex_toksdef:D #1}
+%
+%\let:NN \toks_new:N \newtoks   % nick from LaTeX for the moment
+\def_new:Npn \toks_new:c {\exp_args:Nc\toks_new:N}
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\toks_clear:N}
 % \begin{macro}{\toks_gclear:N}
@@ -224,11 +287,14 @@
 % \end{macro}
 %
 % \begin{macro}{\toks_use:N}
+% \begin{macro}{\toks_use:c}
 %    This function just returns the contents of a token register.
 %    \begin{macrocode}
 \let_new:NN \toks_use:N \the_internal:D
+\def_new:Npn \toks_use:c {\exp_args:Nc\toks_use:N}
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\toks_use_clear:N}
 % \begin{macro}{\toks_use_gclear:N}
@@ -258,24 +324,35 @@
 % \end{macro}
 %
 % \begin{macro}{\toks_put_left:Nn}
+% \begin{macro}{\toks_put_left:No}
 % \begin{macro}{\toks_gput_left:Nn}
-%    |\toks_put_left:Nn |\zz{toks}\zv{stuff\/} adds the tokens of {\sl
-%    stuff\/} on the `left-side' of the token register \m{toks}.
+% \begin{macro}{\toks_gput_left:Nx}
+% \begin{macro}{\toks_put_left_aux:w}
+%   |\toks_put_left:Nn |\zz{toks}\zv{stuff\/} adds the tokens of
+%   \textsl{stuff} on the `left-side' of the token register
+%   \m{toks}. |\toks_put_left:No| does the same, but expands the
+%   tokens once. We need to look out for brace stripping so we add a
+%   token, which is then later removed.
 %    \begin{macrocode}
-\def_new:Npn \toks_put_left:Nn #1{\exp_after:NN\toks_put_left_aux:w
+\def_new:Npn \toks_put_left:Nn #1{
+  \exp_after:NN\toks_put_left_aux:w\exp_after:NN\q_mark
                         \toks_use:N #1\q_stop #1}
+\def_new:Npn \toks_put_left:No {\exp_args:NNo \toks_put_left:Nn}
 \def_new:Npn \toks_gput_left:Nn {
 %<*check>
    \pref_global_chk:
 %
 %<-check> \pref_global:D
    \toks_put_left:Nn}
+\def_new:Npn \toks_gput_left:Nx {\exp_args:NNx \toks_gput_left:Nn}
 %    \end{macrocode}
-%    A helper function for |\toks_put_left:Nn|. Its arguments are 
-%    subsequently the tokens of \zv{stuff\/}, the token register
-%    \zz{toks} and the current contents of \zz{toks}.
+% A helper function for |\toks_put_left:Nn|. Its arguments are
+% subsequently the tokens of \zv{stuff\/}, the token register
+% \zz{toks} and the current contents of \zz{toks}. We make sure to
+% remove the token we inserted earlier.
 %    \begin{macrocode}
-\def_long_new:Npn \toks_put_left_aux:w #1\q_stop #2#3{#2{#3#1}
+\def_long_new:Npn \toks_put_left_aux:w #1\q_stop #2#3{
+  #2\exp_after:NN{\use_arg_i:nn{#3}#1}
 %<*check>
      \chk_local_or_pref_global:N #2
 %
@@ -283,9 +360,17 @@
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
 %
 % \begin{macro}{\toks_put_right:Nn}
 % \begin{macro}{\toks_gput_right:Nn}
+% \begin{macro}{\toks_put_right:No}
+% \begin{macro}{\toks_put_right:Nd}
+% \begin{macro}{\toks_put_right:Nf}
+% \begin{macro}{\toks_put_right:Nx}
+% \begin{macro}{\toks_gput_right:No}
 % \begin{macro}{\toks_gput_right:Nx}
 %    These macros add a list of tokens to the right of a token register.
 %    \begin{macrocode}
@@ -303,15 +388,43 @@
 %    \end{macrocode}
 %    |\toks_gput_right:Nx| expands its (second) argument.
 %    \begin{macrocode}
-\def_new:Npn \toks_gput_right:Nx {\exp_args:Nnx\toks_gput_right:Nn}
+%\def_new:Npn \toks_put_right:No {\exp_args:NNo \toks_put_right:Nn }
+%<-check>\def_long_new:Npn\toks_put_right:No#1#2{#1\exp_after:NN\exp_after:NN
+%<-check>\exp_after:NN{\exp_after:NN\toks_use:N\exp_after:NN #1#2}}
+%\def_new:Npn \toks_put_right:Nd {\exp_args:NNd \toks_put_right:Nn }
+%<-check>\def_long_new:Npn\toks_put_right:Nd#1#2{
+%<-check>  \exp_after:NN\toks_put_right:No\exp_after:NN#1\exp_after:NN{#2}}
 %    \end{macrocode}
+% We implement |\toks_put_right:Nf| by hand because I think I might
+% use it in the \textsf{l3keyval} module in which case it is going to
+% be used a lot.
+%    \begin{macrocode}
+%\def_new:Npn \toks_put_right:Nf {\exp_args:NNf \toks_put_right:Nn }
+%<-check>\def_long_new:Npn \toks_put_right:Nf #1#2{
+%<-check>  #1\exp_after:NN\exp_after:NN\exp_after:NN{
+%<-check>    \exp_after:NN\toks_use:N\exp_after:NN #1\int_to_roman:w -`0#2}}
+\def_new:Npn \toks_put_right:Nx {\exp_args:NNx \toks_put_right:Nn }
+\def_new:Npn \toks_gput_right:No {\exp_args:NNo\toks_gput_right:Nn}
+\def_new:Npn \toks_gput_right:Nx {\exp_args:NNx\toks_gput_right:Nn}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
 % \end{macro}
 % \end{macro}
 % \end{macro}
 %
 % \begin{macro}{\toks_set:Nn}
 % \begin{macro}{\toks_set:No}
+% \begin{macro}{\toks_set:Nd}
+% \begin{macro}{\toks_set:Nf}
 % \begin{macro}{\toks_set:Nx}
+% \begin{macro}{\toks_set:cn}
+% \begin{macro}{\toks_set:co}
+% \begin{macro}{\toks_set:cf}
+% \begin{macro}{\toks_set:cx}
 %    |\toks_set:Nn|\m{toks}\m{stuff} stores \m{stuff} without expansion
 %    in \m{toks}. |\toks_set:No| and |\toks_set:Nx| expand \m{stuff} once
 %    and fully.
@@ -320,13 +433,34 @@
 \def_new:Npn \toks_set:Nn #1{\chk_local:N #1#1}
 %
 %    \end{macrocode}
-%    If we don't check if \m{toks} is a local register then the 
+%    If we don't check if \m{toks} is a local register then the
 %    |\toks_set:Nn| function has nothing to do.
 %    \begin{macrocode}
 %<-check> \let_new:NN \toks_set:Nn\use_noop:
-\def_new:Npn \toks_set:No {\exp_args:NNo \toks_set:Nn}
+%<-check> \def_long_new:Npn \toks_set:No#1#2{#1\exp_after:NN{#2}}
+%<-check> \def_long_new:Npn \toks_set:Nd#1#2{
+%<-check> #1\exp_after:NN\exp_after:NN\exp_after:NN{#2}}
+% \def_new:Npn \toks_set:No {\exp_args:NNo \toks_set:Nn}
+% \def_new:Npn \toks_set:Nd {\exp_args:NNd \toks_set:Nn}
 \def_new:Npn \toks_set:Nx {\exp_args:NNx \toks_set:Nn}
 %    \end{macrocode}
+% We implement |\toks_set:Nf| by hand when not checking because this
+% is going to be used \emph{extensively} in keyval processing!
+%    \begin{macrocode}
+%\def_new:Npn \toks_set:Nf {\exp_args:NNf \toks_set:Nn}
+%<-check>\def_long_new:Npn\toks_set:Nf #1#2{
+%<-check>  #1\exp_after:NN{\int_to_roman:w -`0#2}}
+\def_new:Npn \toks_set:cf {\exp_args:Nc\toks_set:Nf}
+\def_new:Npn \toks_set:cn {\exp_args:Nc\toks_set:Nn}
+\def_new:Npn \toks_set:co {\exp_args:Nc\toks_set:No}
+\def_new:Npn \toks_set:cx {\exp_args:Nc\toks_set:Nx}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
 % \end{macro}
 % \end{macro}
 % \end{macro}
@@ -334,6 +468,9 @@
 % \begin{macro}{\toks_gset:Nn}
 % \begin{macro}{\toks_gset:No}
 % \begin{macro}{\toks_gset:Nx}
+% \begin{macro}{\toks_gset:cn}
+% \begin{macro}{\toks_gset:co}
+% \begin{macro}{\toks_gset:cx}
 %    These functions are the global variants of the above.
 %    \begin{macrocode}
 %<*check>
@@ -342,13 +479,25 @@
 %<-check> \let_new:NN \toks_gset:Nn\pref_global:D
 \def_new:Npn \toks_gset:No {\exp_args:NNo \toks_gset:Nn}
 \def_new:Npn \toks_gset:Nx {\exp_args:NNx \toks_gset:Nn}
+\def_new:Npn \toks_gset:cn {\exp_args:Nc \toks_gset:Nn}
+\def_new:Npn \toks_gset:co {\exp_args:Nc \toks_gset:No}
+\def_new:Npn \toks_gset:cx {\exp_args:Nc \toks_gset:Nx}
 %    \end{macrocode}
 % \end{macro}
 % \end{macro}
 % \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
 %
 %  \begin{macro}{\toks_set_eq:NN}
+%  \begin{macro}{\toks_set_eq:Nc}
+%  \begin{macro}{\toks_set_eq:cN}
+%  \begin{macro}{\toks_set_eq:cc}
 %  \begin{macro}{\toks_gset_eq:NN}
+%  \begin{macro}{\toks_gset_eq:Nc}
+%  \begin{macro}{\toks_gset_eq:cN}
+%  \begin{macro}{\toks_gset_eq:cc}
 %    |\toks_set_eq:NN|\m{toks1}\m{toks2} copies the contents of \m{toks2}
 %    in \m{toks1}.
 %    \begin{macrocode}
@@ -364,20 +513,102 @@
 %
 %<-check> \let_new:NN \toks_set_eq:NN  \use_noop:
 %<-check> \let_new:NN \toks_gset_eq:NN \pref_global:D
+\def_new:Npn \toks_set_eq:Nc {\exp_args:NNc\toks_set_eq:NN}
+\def_new:Npn \toks_set_eq:cN {\exp_args:Nc\toks_set_eq:NN}
+\def_new:Npn \toks_set_eq:cc {\exp_args:Ncc\toks_set_eq:NN}
+\def_new:Npn \toks_gset_eq:Nc {\exp_args:NNc\toks_gset_eq:NN}
+\def_new:Npn \toks_gset_eq:cN {\exp_args:Nc\toks_gset_eq:NN}
+\def_new:Npn \toks_gset_eq:cc {\exp_args:Ncc\toks_gset_eq:NN}
 %    \end{macrocode}
 %  \end{macro}
 %  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
 %
-% \begin{macro}{\toks_empty:NTF}
-%    |\toks_empty:NTF|\m{toks}\m{true code}\m{false code} tests if 
-%    a token register is empty and executes either \m{true code} or 
-%    \m{false code}.
+% \begin{macro}{\toks_if_empty_p:N}
+% \begin{macro}{\toks_if_empty_p:c}
+% \begin{macro}{\toks_if_empty:NTF}
+% \begin{macro}{\toks_if_empty:cTF}
+% \begin{macro}{\toks_if_empty:NT}
+% \begin{macro}{\toks_if_empty:cT}
+% \begin{macro}{\toks_if_empty:NF}
+% \begin{macro}{\toks_if_empty:cF}
+%   |\toks_if_empty:NTF|\m{toks}\m{true code}\m{false code} tests if a
+%   token register is empty and executes either \m{true code} or
+%   \m{false code}. This test had the advantage of being
+%   expandable. Otherwise one has to do an |x| type expansion in order
+%   to prevent problems with parameter tokens.
 %    \begin{macrocode}
-\def_new:Npn\toks_empty:NTF#1{
-   \tlp_set:No\l_testa_tlp{\toks_use:N#1}
-   \tlp_empty:NTF\l_testa_tlp}
+\def_new:Npn\toks_if_empty_p:N#1{
+  \if:w \tlist_if_empty_p:o{\toks_use:N #1}
+    \c_true
+  \else:
+    \c_false
+  \fi:
+}
+\def_test_function_new:npn{toks_if_empty:N}#1{\if:w \toks_if_empty_p:N #1}
+\def_new:Npn\toks_if_empty:cTF{\exp_args:Nc\toks_if_empty:NTF}
+\def_new:Npn\toks_if_empty:cT{\exp_args:Nc\toks_if_empty:NT}
+\def_new:Npn\toks_if_empty:cF{\exp_args:Nc\toks_if_empty:NF}
 %    \end{macrocode}
 % \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\toks_if_eq:NNTF}
+% \begin{macro}{\toks_if_eq:NNT}
+% \begin{macro}{\toks_if_eq:NNF}
+% \begin{macro}{\toks_if_eq:NcTF}
+% \begin{macro}{\toks_if_eq:NcT}
+% \begin{macro}{\toks_if_eq:NcF}
+% \begin{macro}{\toks_if_eq:cNTF}
+% \begin{macro}{\toks_if_eq:cNT}
+% \begin{macro}{\toks_if_eq:cNF}
+% \begin{macro}{\toks_if_eq:ccTF}
+% \begin{macro}{\toks_if_eq:ccT}
+% \begin{macro}{\toks_if_eq:ccF}
+%    This function test whether two token registers contain the same.
+%    \begin{macrocode}
+\def_new:NNn \toks_if_eq:NNTF 2 {
+  \tlist_if_eq:xxTF{\toks_use:N #1}{\toks_use:N #2}
+}
+\def_new:NNn \toks_if_eq:NNT 2 {
+  \tlist_if_eq:xxT{\toks_use:N #1}{\toks_use:N #2}
+}
+\def_new:NNn \toks_if_eq:NNF 2 {
+  \tlist_if_eq:xxF{\toks_use:N #1}{\toks_use:N #2}
+}
+\def_new:Npn \toks_if_eq:NcTF {\exp_args:NNc \toks_if_eq:NNTF}
+\def_new:Npn \toks_if_eq:NcT {\exp_args:NNc \toks_if_eq:NNT}
+\def_new:Npn \toks_if_eq:NcF {\exp_args:NNc \toks_if_eq:NNF}
+\def_new:Npn \toks_if_eq:cNTF {\exp_args:Nc \toks_if_eq:NNTF}
+\def_new:Npn \toks_if_eq:cNT {\exp_args:Nc \toks_if_eq:NNT}
+\def_new:Npn \toks_if_eq:cNF {\exp_args:Nc \toks_if_eq:NNF}
+\def_new:Npn \toks_if_eq:ccTF {\exp_args:Ncc \toks_if_eq:NNTF}
+\def_new:Npn \toks_if_eq:ccT {\exp_args:Ncc \toks_if_eq:NNT}
+\def_new:Npn \toks_if_eq:ccF {\exp_args:Ncc \toks_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}{\l_tmpa_toks}
 % \begin{macro}{\l_tmpb_toks}
@@ -388,6 +619,7 @@
 %    Some scratch register \ldots
 %    \begin{macrocode}
 \tex_toksdef:D \l_tmpa_toks = 255
+%\seq_put_right:Nn \g_toks_allocation_seq {255}
 \toks_new:N \l_tmpb_toks
 \toks_new:N \l_tmpc_toks
 \toks_new:N \g_tmpa_toks
@@ -408,10 +640,81 @@
 %    \end{macrocode}
 % \end{macro}
 %
+% \begin{macro}{\toks_remove_extra_brace_group:N}
+% \begin{macro}{\toks_remove_extra_brace_group_aux:NNw}
+%   Small function for removing an extra brace group if present. Hmm,
+%   not really needed anymore.
+%    \begin{macrocode}
+\def_new:Npn \toks_remove_extra_brace_group:N #1{
+  \exp_after:NN \toks_remove_extra_brace_group_aux:NNw
+  \exp_after:NN \toks_set:Nn \exp_after:NN #1
+  \toks_use:N#1\q_nil
+}
+\def_long_new:Npn\toks_remove_extra_brace_group_aux:NNw #1#2#3\q_nil{#1#2{#3}}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
 %    Show token usage:
 %    \begin{macrocode}
-%
+%
 %<*showmemory>
 \showMemUsage
 %
 %    \end{macrocode}
+%
+% \endinput
+%
+% $Log$
+% Revision 1.25  2006/08/01 01:54:12  morten
+% Prevent brace stripping in \toks_put_left:Nn and friends.
+%
+% Revision 1.24  2006/03/20 18:26:40  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.23  2006/02/16 23:32:49  braams
+% Imported \toks_put_left:No from l3messages
+%
+% Revision 1.22  2006/01/21 11:43:20  morten
+% Tuned some of the \toks_set and \toks_put_right functions since they
+% are going to be used intensively in the l3keyval module which is again
+% going to be heavily used.
+%
+% Revision 1.21  2006/01/20 12:22:44  morten
+% Minor changes plus added \toks_remove_extra_brace_group:N for l3keyval
+% module
+%
+% Revision 1.20  2005/12/27 10:03:39  morten
+% Changed RCS information retrieval
+%
+% Revision 1.19  2005/12/23 13:24:39  morten
+% Added a few functions from template
+%
+% Revision 1.18  2005/12/21 20:44:04  morten
+% Corrected typo.
+%
+% Revision 1.17  2005/12/02 15:56:48  morten
+% Added some more functions and improved test for emptiness.
+%
+% Revision 1.16  2005/04/12 13:22:37  morten
+% More functions added
+%
+% Revision 1.15  2005/04/07 08:18:17  morten
+% Only put 255 in the toks stack when running initex
+%
+% Revision 1.14  2005/04/06 22:35:50  braams
+% Now we have register allocation fitted
+%
+% Revision 1.13  2005/04/06 21:37:50  morten
+% Added some more functions
+%
+% Revision 1.12  2005/03/15 23:39:21  braams
+% Some fiddling to get it loaded by initex; needs a way to allocate
+% token registers for it to work.
+%
+% Revision 1.11  2005/03/11 21:25:06  braams
+% Changed copyright year, fixed use of RCS values;
+% fixed a few typos in the documentation;
+% \c_if_empty_toks had to be \c_empty_toks
+%
diff --git a/Master/texmf-dist/source/latex/expl3/l3vers.dtx b/Master/texmf-dist/source/latex/expl3/l3vers.dtx
new file mode 100644
index 00000000000..06f9d44c694
--- /dev/null
+++ b/Master/texmf-dist/source/latex/expl3/l3vers.dtx
@@ -0,0 +1,145 @@
+% \iffalse
+%% File: l3vers.dtx Copyright (C) 1990-2005 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.
+%%
+%% -----------------------------------------------------------------------
+%\RequirePackage{l3names}
+%<*dtx>
+%\fi
+\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{%
+  \def\fileversion{#2}%
+  \def\filedate{#3/#4/#5}%
+  \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]%
+}
+%\iffalse
+%
+%\fi
+\GetIdInfo$Id: l3vers.dtx 573 2006-08-21 20:59:37Z morten $
+       {L3 Experimental LaTeX format version}
+%
+% \iffalse
+%<*driver>
+\documentclass{l3doc}
+
+\begin{document}
+\DocInput{l3vers.dtx}
+\end{document}
+%
+% \fi
+%
+% \section{Version Identification}
+% Here we identify the date and version number of this release of
+% \LaTeX3, and set |\tex_everyjob:D| so that it is printed at the start of
+% every \LaTeX3 run.
+%
+% \StopEventually{}
+%
+%
+% \begin{macro}{\c_format_name}
+% \begin{macro}{\c_format_date}
+%    \begin{macrocode}
+%<*initex>
+\def:Npn\c_format_name{Experimental~ LaTeX3}
+\def:Npn\c_format_date{2005/12/25}
+%^^A\def:Npx\c_format_version{--release--date--goes--here--}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\c_fmt_too_old}
+% \begin{macro}{\chk_format_age:w}
+% Check that the format being made is not too old. While in development
+% it should be a rather small number.
+%    \begin{macrocode}
+\const_new:Nn \c_fmt_too_old{12}
+\def:Npn\chk_format_age:w #1/#2/#3\q_stop{
+%    \end{macrocode}
+%  We just calculate the age of this file in months and give a warning
+%  if deemed too old.
+%    \begin{macrocode}
+  \num_compare:nNnT{(\tex_year:D-#1)*12+\tex_month:D-#2}>\c_fmt_too_old
+  {\iow_expanded_term:n{^^J
+  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J
+  !~~You~are~attempting~to~make~an~experimental~LaTeX3~format~from^^J
+  !~~source~files~that~are~more~than~
+     \num_use:N\num_eval:n{\c_fmt_too_old}~months~old.^^J
+  !^^J
+  !~~If~you~enter~~to~scroll~past~this~message~then~the~format^^J
+  !~~will~be~built,~but~please~consider~obtaining~newer~source~files^^J
+  !~~before~continuing~to~build~an~experimental~LaTeX3~format.^^J
+    !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!^^J
+  }
+  \tex_errhelp:D{
+    To~avoid~this~error~message,~obtain~new~Experimental~LaTeX3~sources.}
+  \tex_errmessage:D{
+    Experimental~LaTeX3~source~files~are~more~than~
+    \num_use:N\num_eval:n{\c_fmt_too_old}~months~old!}
+  }
+}
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% Then we execute it.
+%    \begin{macrocode}
+\exp_after:NN\chk_format_age:w\c_format_date\q_stop
+%    \end{macrocode}
+% And since it's no longer needed we remove it again.
+%    \begin{macrocode}
+\cs_gundefine:N \chk_format_age:w
+%    \end{macrocode}
+%
+% This startup banner may be further modified by the code in
+% |ltfinal.dtx| if a patch file is present.
+%    \begin{macrocode}
+\tex_everyjob:D{\io_put_term:x{\c_format_name,~<\c_format_date>}}
+\io_put_term:x{\c_format_name,~<\c_format_date>}
+%
+%    \end{macrocode}
+%
+% \endinput
+%
+% $Log$
+% Revision 1.5  2005/12/27 15:54:15  morten
+% Changed RCS information retrieval
+%
+% Revision 1.4  2005/04/13 09:52:47  morten
+% Fix spaces in messages, make fast calculation of format age, fixed \DocInput, added \endinput
+%
+% Revision 1.3  2005/04/12 22:42:22  braams
+% Removed a few redundant lines with docstrip instructions
+%
+% Revision 1.2  2005/04/11 22:46:47  braams
+% Translated this file into the ltx3 lingo
+% This file may need further cleanup at a later stage
+%
+% Revision 1.1  2005/03/11 21:26:31  braams
+% File copied from 2e for now, to hold the format version identification
+%
diff --git a/Master/texmf-dist/source/latex/expl3/l3xref.dtx b/Master/texmf-dist/source/latex/expl3/l3xref.dtx
new file mode 100644
index 00000000000..2f03bf8b387
--- /dev/null
+++ b/Master/texmf-dist/source/latex/expl3/l3xref.dtx
@@ -0,0 +1,379 @@
+% \iffalse
+%% File: l3xref.dtx Copyright (C) 2006 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.
+%%
+%% -----------------------------------------------------------------------
+%
+%\RequirePackage{l3names}
+%<*dtx|testfile>
+%\fi
+\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{%
+  \def\fileversion{#2}%
+  \def\filedate{#3/#4/#5}%
+%\iffalse
+%  \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]%
+%<-dtx>  \ProvidesFile{\jobname.tex}[#3/#4/#5 v#2 #8]%
+%\fi
+}
+%\iffalse
+%
+%\fi
+\GetIdInfo$Id: l3xref.dtx 579 2006-11-25 23:38:03Z morten $
+       {L3 Experimental cross referencing}
+%
+% \iffalse
+%<*driver>
+\documentclass{l3doc}
+
+\begin{document}
+\DocInput{l3xref.dtx}
+\end{document}
+%
+% \fi
+%
+% \title{The \textsf{l3xref} package\thanks{This file
+%         has version number \fileversion, last
+%         revised \filedate.}\\
+% Cross references}
+% \author{\Team}
+% \date{\filedate}
+% \maketitle
+%
+%
+% \section{Cross references}
+%
+% \begin{function}{\xref_set_label:n}
+%   \begin{syntax}
+%     "\xref_set_label:n" "{""}"
+%   \end{syntax}
+%   Sets a label in the text. Note that this function does not do
+%   anything else than setting the correct labels. In particular, it
+%   does not try to fix any spacing around the write node; this is a
+%   task for the \textsf{galley2} module.
+% \end{function}
+%
+% \begin{function}{\xref_new:nn}
+%   \begin{syntax}
+%     "\xref_new:nn" "{""}" "{""}"
+%   \end{syntax}
+%   Defines a new cross reference type . This defines the token
+%   list pointer |\l_xref_curr_||_tlp| with default value
+%    which gets written fully expanded when |\xref_set_label:n|
+%   is called.
+% \end{function}
+%
+%
+% \begin{function}{\xref_deferred_new:nn}
+%   \begin{syntax}
+%     "\xref_deferred_new:nn" "{""}" "{""}"
+%   \end{syntax}
+%   Same as |\xref_new:n| except for this one, the value written
+%   happens when \TeX\ ships out the page. Page numbers use this one
+%   obviously.
+% \end{function}
+%
+% \begin{function}{\xref_get_value:nn}
+%   \begin{syntax}
+%     "\xref_get_value:nn" "{""}" "{""}"
+%   \end{syntax}
+%   Extracts the cross reference information of type  for the
+%   label . This operation is expandable.
+% \end{function}
+%
+%
+% \StopEventually{}
+%
+% \subsection{Implementation}
+%
+%
+%    We start by ensuring that the required packages are loaded.
+%    \begin{macrocode}
+%<*package>
+\RequirePackage{l3quark}
+\RequirePackage{l3toks}
+\RequirePackage{l3io}
+\RequirePackage{l3prop}
+\RequirePackage{l3int}
+\RequirePackage{l3token}
+%
+%<*initex|package>
+%    \end{macrocode}
+%
+%
+%
+% There are two kinds of information, namely information which is
+% \emph{immediate} like a section title and then there's \emph{deferred}
+% information like page numbers. Each reference type belong to one of
+% these categories, which we save internally as the property lists
+% |\g_xref_all_curr_immediate_fields_plist| and
+% |\g_xref_all_curr_deferred_fields_plist| and the reference type
+% \meta{xyz} exists as the key-info pair |\xref_|\meta{xyz}|_key|
+% |{\l_xref_curr_|\meta{xyz}|_tlp}| on one of these lists. This way each
+% new entry type is just added as another key-info pair. 
+%
+% When the cross references are generated at the beginning of the
+% document each will turn into a control sequence. Thus |\label{mylab}|
+% will internally refer to the property list |\g_xref_mylab_plist|.
+%
+% The extraction of values from this property list can be done in
+% several different ways but we want to keep the operation
+% expandable. Therefore we use a dedicated function for each type of
+% cross reference, which looks like this:
+% \begin{verbatim}
+% \xref_get_value_xyz_aux:w -> #1 \xref_xyz_key #2#3\q_nil{#2}
+% \end{verbatim}
+% This will throw away all the bits we don't need. In case |xyz| is
+% the first on the |mylab| property list |#1| is empty, if it's the
+% last key-info pair |#3| is empty. The value of the field can be
+% extracted with the function |\xref_get_value:nn| where the first
+% argument is the type and the second the label name so here it would
+% be |\xref_get_value:nn| |{xyz}| |{mylab}|.
+%
+%  \begin{macro}{\g_xref_all_curr_immediate_fields_plist}
+%  \begin{macro}{\g_xref_all_curr_deferred_fields_plist}
+%    The two main property lists for storing information. They contain
+%    key-info pairs for all known types.
+%    \begin{macrocode}
+\prop_new:N \g_xref_all_curr_immediate_fields_plist
+\prop_new:N \g_xref_all_curr_deferred_fields_plist
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%
+%  \begin{macro}{\xref_new:nn}
+%  \begin{macro}{\xref_deferred_new:nn}
+%  \begin{macro}{\xref_new_aux:nnn}
+%  Setting up a new cross reference type is fairly straight forward
+%  when we follow the game plan mentioned earlier.
+%    \begin{macrocode}
+\def_new:Npn \xref_new:nn {\xref_new_aux:nnn{immediate}}
+\def_new:Npn \xref_deferred_new:nn {\xref_new_aux:nnn{deferred}}
+\def_new:Npn \xref_new_aux:nnn #1#2#3{
+%    \end{macrocode}
+%  First put the new type in the relevant property list.
+%    \begin{macrocode}
+  \prop_gput:ccx {g_xref_all_curr_ #1 _fields_plist}
+  { xref_ #2 _key }
+  { \exp_not:c {l_xref_curr_#2_tlp }}
+%    \end{macrocode}
+% Then define the key to be a protected macro.\footnote{We could also
+%   set it equal to \cs{scan_stop:} but this just feels ``cleaner''.}
+%    \begin{macrocode}
+  \def_protected:cpn { xref_#2_key }{}
+  \tlp_new:cn{l_xref_curr_#2_tlp}{#3}
+%    \end{macrocode}
+% Now for the function extracting the value of a reference. We could
+% do this with a simple |\prop_if_in| thing put since we want to do
+% things in an expandable way we make a separate grabber for each
+% type---this is also faster. The grabber function can be defined by
+% using an intricate construction of |\exp_after:NN| and other goodies
+% but I prefer readable code. The end result for the input |xyz| is
+% \begin{verbatim}
+% \def:Npn\xref_get_value_xyz_aux:w #1\xref_xyz_key #2#3\q_nil{#2}
+% \end{verbatim}
+%    \begin{macrocode}
+  \toks_set:Nx \l_tmpa_toks {
+    \exp_not:n { \def:cpn {xref_get_value_#2_aux:w} ##1 }
+    \exp_not:c { xref_#2_key }
+  }
+  \toks_use:N \l_tmpa_toks ##2 ##3\q_nil {##2}
+}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%  \end{macro}
+%
+%
+% \begin{macro}{\xref_get_value:nn}
+%   Getting the correct value for a given label-type pair is a matter
+%   of connecting the correct grabber functions and property list.
+%    \begin{macrocode}
+\def_new:Npn \xref_get_value:nn #1#2 {
+  \cs_if_really_free:cTF{g_xref_#2_plist}
+  {??}
+  {
+%    \end{macrocode}
+% This next expansion may look a little weird but it isn't if you
+% think about it!
+%    \begin{macrocode}
+    \exp_args:NcNc \exp_after:NN {xref_get_value_#1_aux:w}
+    \prop_use:N {g_xref_#2_plist}
+%    \end{macrocode}
+%  Better put in the stop marker.
+%    \begin{macrocode}
+    \q_nil
+  }
+}
+\def:NNn \exp_after:cc 2 {
+  \exp_after:NN \exp_after:NN
+  \cs:w #1\exp_after:NN\cs_end: \cs:w #2\cs_end:
+}
+%    \end{macrocode}
+%  \end{macro}
+%
+%  \begin{macro}{\xref_define_label:nn}
+%  \begin{macro}{\xref_define_label_aux:nn}
+%    Define the property list for each label. We better do this in two
+%    steps because the special catcode regime is in effect and since
+%    some of the info fields are very likely to contain actual text,
+%    we better make sure spaces aren't ignored! As for the meaning of
+%    other characters then it is a possibility to also have a field
+%    containing catcode instructions which can then be activated with
+%    |\etex_scantokens:D|. 
+%    \begin{macrocode}
+\def_protected_new:Npn \xref_define_label:nn {
+  \group_begin:
+    \char_set_catcode:nn {`\ }\c_ten
+    \xref_define_label_aux:nn
+}
+%    \end{macrocode}
+% If the label is already taken we have a multiply defined label and
+% we should do something about it. For now we don't do anything
+% spectacular.
+%    \begin{macrocode}
+\def_new:Npn \xref_define_label_aux:nn #1#2 {
+    \cs_if_really_free:cTF{g_xref_#1_plist}
+    {\prop_new:c{g_xref_#1_plist}}{\WARNING}
+    \toks_gset:cn{g_xref_#1_plist}{#2}
+  \group_end:
+}
+%    \end{macrocode}
+%  \end{macro}
+%  \end{macro}
+%
+%
+% \begin{macro}{\xref_set_label:n}
+%   Then the generic command for setting a label. We expand the
+%   immediate labels fully before calling the write function but make
+%   sure the deferred fields aren't expanded just yet. Due to property
+%   lists being implemented as token list registers we must expand the
+%   `immediate' fields twice.
+%    \begin{macrocode}
+\def:Npn \xref_set_label:n #1{
+  \def:Npx \tmp:w{\prop_use:N\g_xref_all_curr_immediate_fields_plist}
+  \exp_args:NNx\iow_deferred_expanded:Nn \xref_write{
+    \xref_define_label:nn {#1} { 
+      \tmp:w 
+      \prop_use:N \g_xref_all_curr_deferred_fields_plist
+    }
+  }
+}
+%    \end{macrocode}
+%  \end{macro}
+%
+% \begin{macro}{\xref_write}
+%   A stream for writing cross references although they do not require
+%   to be in a separate file.
+%    \begin{macrocode}
+\iow_new:N \xref_write
+%    \end{macrocode}
+%  \end{macro}
+%
+%  That's it (for now).
+%    \begin{macrocode}
+%
+%<*showmemory>
+\showMemUsage
+%
+%    \end{macrocode}
+%
+%
+%    \begin{macrocode}
+%<*testfile>
+\documentclass{article}
+\usepackage{l3xref}
+\CodeStart
+\def:Npn \startrecording {\iow_open:Nn \xref_write {\jobname.xref}}
+\def:Npn \DefineCrossReferences {
+  \group_begin:
+    \NamesStart
+    \InputIfFileExists{\jobname.xref}{}{}
+  \group_end:
+}
+\AtBeginDocument{\DefineCrossReferences\startrecording}
+
+\xref_new:nn {name}{}
+\def:Npn \setname{\tlp_set:Nn\l_xref_curr_name_tlp}
+\def:Npn \getname{\xref_get_value:nn{name}}
+
+\xref_deferred_new:nn {page}{\thepage}
+\def:Npn \getpage{\xref_get_value:nn{page}}
+
+\xref_deferred_new:nn {valuepage}{\number\value{page}}
+\def:Npn \getvaluepage{\xref_get_value:nn{valuepage}}
+
+\let:NN \setlabel \xref_set_label:n
+
+\CodeStop
+\begin{document}
+\pagenumbering{roman}
+
+Text\setname{This is a name}\setlabel{testlabel1}.  More
+text\setname{This is another name}\setlabel{testlabel2}. \clearpage
+
+Text\setname{This is a third name}\setlabel{testlabel3}. More
+text\setname{Hello World!}\setlabel{testlabel4}. \clearpage
+
+\pagenumbering{arabic}
+
+Text\setname{Name 5}\setlabel{testlabel5}. More text\setname{Name
+  6}\setlabel{testlabel6}. \clearpage
+
+Text\setname{Name 7}\setlabel{testlabel 7}. More text\setname{Name
+  8}\setlabel{testlabel8}. \clearpage
+
+Now let's extract some values. \getname{testlabel1} on page
+\getpage{testlabel1} with value \getvaluepage{testlabel1}.
+
+Now let's extract some values. \getname{testlabel 7} on page
+\getpage{testlabel 7} with value \getvaluepage{testlabel 7}.
+\end{document}
+%
+%    \end{macrocode}
+%
+%
+% \endinput
+%
+% $Log$
+% Revision 1.4  2006/03/20 18:26:42  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.3  2006/01/16 11:26:57  morten
+% Minor changes
+%
+% Revision 1.2  2006/01/15 14:07:31  braams
+% Activated \StopEventually{}
+%
+% Revision 1.1  2006/01/15 07:55:06  morten
+% New cross reference module including test file.
+%
+%
\ No newline at end of file
diff --git a/Master/texmf-dist/source/latex/expl3/readme.txt b/Master/texmf-dist/source/latex/expl3/readme.txt
deleted file mode 100644
index ae888d040d9..00000000000
--- a/Master/texmf-dist/source/latex/expl3/readme.txt
+++ /dev/null
@@ -1,224 +0,0 @@
-
-   Experimental Packages Demonstrating
-   A Possible LaTeX3 Programming Convention
-   ========================================
-
-   1998/04/20
-
-
-OVERVIEW
---------
-
-The packages in this directory implement a possible language for `low
-level' programming in TeX.  The syntax conventions described here are NOT
-intended either for use in documents or for use in describing design
-layouts in document class files.
-
-All aspects of these package are *experimental*. The names of the
-packages, and the names of any commands that they define, may change
-at any time.  They are being released in this form to allow public
-discussion and comment.
-
-Currently all the code is distributed in a format suitable for running
-as LaTeX2e packages.  Further documentation may be produced by processing
-the .dtx files with LaTeX2e.  The packages may be installed by processing
-l3.ins with plain TeX or LaTeX.
-
-This code has be developed over time and has been used in previous
-versions for prototype implementations, experiments, etc. Its internal
-documentation (in the .dtx files) reflects the age of parts of it; it
-often contains personal comments and it sometimes refers to parts that
-not at present distributed.  We kindly ask you to overlook its
-deficiencies and inaccuracies --- if we had tried to clean this up it
-would never have surfaced and, for the purpose of discussions and
-comments, we hope its present form is adequate.
-
-
-NOTE (docstrip version)
------------------------
-  
-If   latex l3.ins
-produces the `docstrip interactive mode' prompt:
-
-  * First type the extension of your input file(s):  *
-  \infileext=
-
-Then your version of docstrip is too old.
-Quit (eg by hitting `enter' to all questions) and get a newer
-docstrip.tex. It must be at least version 2.4.
-
-A suitable docstrip.tex may be found from `CTAN' archives such as
-ftp.dante.de   tex-archive/macros/latex/unpacked/docstrip.tex
-
-Docstrip is part of the base LaTeX distribution, so if you have
-an old docstrip then your LaTeX is out of date and you may consider
-getting the whole of that directory and re-installing LaTeX.
-However you need to fetch only the file docstrip.tex to unpack
-this expl3 distribution with your existing format.
-
-
-
-THE GUILTY PERSONS
-------------------
-
-   Frank Mittelbach, Denys Duchier, Johannes Braams, Michael Downes,
-   David Carlisle, Alan Jeffrey, Chris Rowley, Rainer Schoepf 
-
-
-DISCUSSION
-----------
-
-Discussion concerning the approach, suggestions for improvements, changes,
-additions, etc. should be addressed to the list LATEX-L. 
-
-You can subscribe to this list by sending mail to
-
-  listserv@urz.uni-heidelberg.de
-
-with the body containing
-
-  subscribe LATEX-L   
-
-
-BUGS
-----
-
-If you find a real bug that makes a package stop working you can
-report it via the standard latexbug.tex mechanism of the LaTeX
-distribution (see bugs.txt there) using the category "l3exp". 
-However please do *not* use this method for suggestions / comments /
-improvements / etc. For this the list LATEX-L should be used instead.
-
-Also please don't expect these package to work with *any* code that
-floats around in the LaTeX2e world. :-)
-
-
-
-MANIFEST
---------
-
-The following packages are in this release:
-
-
-l3names
-=======
-
-Documents the general naming scheme, and gives new names to all the TeX
-primitives.
-
-If this package is used with the option [removeoldnames] then the
-original TeX primitive names (\hbox, \def, ...) are made *undefined* and
-so free to be defined for other purposes if needed. Of course this
-breaks almost all existing LaTeX2 code, but it may be used for testing
-purposes, see test2.tex.
-
-l3basics
-========
-
-Some basic definitions that are used by the other packages.
-
-l3chk
-=====
-
-Functions that check definitions.
-(Comparable to LaTeX2's \newcommand/\renewcommand.)
-
-l3tlp
-=====
-
-Token List Pointers. A basic LaTeX3 datatype for storing token lists.
-(These are essentially macros with no arguments.)
-(Package can be compiled with checking enabled.)
-
-l3expan
-=======
-
-The argument expansion module. One of the main features of the language
-proposed here is a systematic treatment of the handling of argument
-expansion. The basic functions for preprocessing command arguments are
-defined here.
-
-l3quark
-=======
-
-A `quark' is a command that is defined to expand to itself. So it may
-not be directly used (it would generate an infinite loop) but has many
-uses as special markers within LaTeX code.
-
-l3seq
-=====
-
-A module implementing the basic list and stack datatypes.
-
-l3prop
-======
-
-Property lists are the datatype for handling key/value assignments.
-
-l3int
-=====
-
-Integer and fake integer registers. With eTeX/Omega becoming more and
-more accessible this module is, at least in parts only of historical
-significance.  (Can be compiled with checking enabled)
-
-l3toks
-======
-
-TeX's token registers.  (Can be compiled with checking enabled)
-
-l3io
-====
-
-Low-level input and ouput.
-
-l3precom
-=========
-
-Low-level pointer-related code, with further checking and tracing.
-
-
-=====================================================================
-
-Install file
-=============
-
-l3.ins
-======
-
-Process with plain TeX or LaTeX2e to generate the experimental
-packages.
-
-=====================================================================
-
-Test Files
-==========
-
-Two test files show the expansion module at work.
-
-test1.tex
-=========
-
-Test document showing the expansion module at work.
-
-test2.tex
-=========
-
-The same test as the file test1, but this time the l3names package is
-loaded with [removeoldnames]. This is useful for testing, but as it
-breaks all LaTeX2 code, it is not so useful for documents.  (For
-example {document} would generate an error.)  In this mode
-\RequirePackage may be used to load further packages, as demonstrated
-in this file, but any other LaTeX2 command is likely to fail.
-
-test3.tex
-=========
-
-This tests the io and precomp modules.
-
-
-=====================================================================
-
---- Copyright 1998
-    The LaTeX3 Project.  All rights reserved ---
-
diff --git a/Master/texmf-dist/source/latex/expl3/test1.dmp b/Master/texmf-dist/source/latex/expl3/test1.dmp
deleted file mode 100644
index ecb21f24572..00000000000
--- a/Master/texmf-dist/source/latex/expl3/test1.dmp
+++ /dev/null
@@ -1 +0,0 @@
-\dumpLaTeXstate macro:#1->\iow_expanded_term:n {Dumping commands into (#1.dmp)}\iow_open:Nn \c_cs_dump_stream {#1.dmp}\seq_map_inline:Nn \g_cs_trace_seq {\tex_message:D {.}\iow_expanded:Nn \c_cs_dump_stream {\token_to_string:N ##1 \token_to_meaning:N ##1}}\tex_message:D { registers}\seq_map_inline:Nn \g_register_trace_seq {\tex_message:D {.}\iow_expanded:Nn \c_cs_dump_stream {\token_to_string:N ##1\the_internal:D ##1}}\tex_message:D { finished}
diff --git a/Master/texmf-dist/source/latex/expl3/test2.dmp b/Master/texmf-dist/source/latex/expl3/test2.dmp
deleted file mode 100644
index 3a93bfcdb53..00000000000
--- a/Master/texmf-dist/source/latex/expl3/test2.dmp
+++ /dev/null
@@ -1,2 +0,0 @@
-\dumpLaTeXstate macro:#1->\iow_expanded_term:n {Dumping commands into (#1.dmp)}\iow_open:Nn \c_cs_dump_stream {#1.dmp}\seq_map_inline:Nn \g_cs_trace_seq {\tex_message:D {.}\iow_expanded:Nn \c_cs_dump_stream {\token_to_string:N ##1 \token_to_meaning:N ##1}}\tex_message:D { registers}\seq_map_inline:Nn \g_register_trace_seq {\tex_message:D {.}\iow_expanded:Nn \c_cs_dump_stream {\token_to_string:N ##1\the_internal:D ##1}}\tex_message:D { finished}
-\l_my_int42
diff --git a/Master/texmf-dist/source/latex/expl3/test3.dmp b/Master/texmf-dist/source/latex/expl3/test3.dmp
deleted file mode 100644
index de4c6f395bc..00000000000
--- a/Master/texmf-dist/source/latex/expl3/test3.dmp
+++ /dev/null
@@ -1,2 +0,0 @@
-\dumpLaTeXstate macro:#1->\iow_expanded_term:n {Dumping commands into (#1.dmp)}\iow_open:Nn \c_cs_dump_stream {#1.dmp}\seq_map_inline:Nn \g_cs_trace_seq {\tex_message:D {.}\iow_expanded:Nn \c_cs_dump_stream {\token_to_string:N ##1 \token_to_meaning:N ##1}}\tex_message:D { registers}\seq_map_inline:Nn \g_register_trace_seq {\tex_message:D {.}\iow_expanded:Nn \c_cs_dump_stream {\token_to_string:N ##1\the_internal:D ##1}}\tex_message:D { finished}
-\l_my_int0
diff --git a/Master/texmf-dist/source/latex/expl3/testdump.cmp b/Master/texmf-dist/source/latex/expl3/testdump.cmp
deleted file mode 100644
index 081751f9871..00000000000
--- a/Master/texmf-dist/source/latex/expl3/testdump.cmp
+++ /dev/null
@@ -1,7 +0,0 @@
-\group_begin: \tex_catcode:D `\*=11\scan_stop: \CodeStart
-\gdef:Npn\g*i{bar}
-\gdef:Npn\l*i{foo}
-\gdef:Npn\foo{somefoo}
-\fint_gset:Nn\g_gen_sym_fint {1}
-\fint_gset:Nn\g_ggen_sym_fint {1}
-\group_end: 
-- 
cgit v1.2.3