summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/expl3
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2007-05-22 17:46:23 +0000
committerKarl Berry <karl@freefriends.org>2007-05-22 17:46:23 +0000
commitf4eb27d3314d15838f674a3872000159d029f88b (patch)
tree6e9ab33c5a2d702912b4a969ade4e4e2ac586d62 /Master/texmf-dist/source/latex/expl3
parent14af3f447439750920f754792b89f113d019076a (diff)
update expl3
git-svn-id: svn://tug.org/texlive/trunk@4335 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/expl3')
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3.ins38
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3alloc.dtx276
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3basics.dtx2792
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3box.dtx933
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3calc.dtx930
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3chk.dtx154
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3clist.dtx1082
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3expan.dtx530
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3final.dtx129
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3format.ins72
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3int.dtx1222
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3io.dtx179
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3keyval.dtx666
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3messages.dtx972
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3names.dtx446
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3num.dtx749
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3precom.dtx228
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3prg.dtx1374
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3prop.dtx503
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3quark.dtx326
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3seq.dtx412
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3skip.dtx1086
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3tlp.dtx1726
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3token.dtx2004
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3toks.dtx421
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3vers.dtx145
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3xref.dtx379
-rw-r--r--Master/texmf-dist/source/latex/expl3/readme.txt224
-rw-r--r--Master/texmf-dist/source/latex/expl3/test1.dmp1
-rw-r--r--Master/texmf-dist/source/latex/expl3/test2.dmp2
-rw-r--r--Master/texmf-dist/source/latex/expl3/test3.dmp2
-rw-r--r--Master/texmf-dist/source/latex/expl3/testdump.cmp7
32 files changed, 17973 insertions, 2037 deletions
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.
+%%
+%% -----------------------------------------------------------------------
+%
+%<package>\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
+%</dtx>
+%\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}
+%</driver>
+% \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" <type> <g_start_num> <l_start_num>
+% \end{syntax}
+% Sets up the storage needed for the administration of registers of
+% type <type>.\\
+% <type> should be a token list in braces, it can be one of
+% "int", "dimen", "skip", "muskip", "box", "toks", "ior", "iow",
+% "pattern", or "ins".\\
+% <g_start_num> is the number of the first not allocated global
+% register, it will be incremented by 1 when the allocation is done.
+% <l_start_num> 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" <g-l> <type> <alloc_cmd> <cs>
+% \end{syntax}
+% Performs the allocation of a register of type <type> to copntrol
+% sequence <cs>, using the command <alloc_cmd>. 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
+% "\"<type>"_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}
+%<package>\RequirePackage{l3expan}
+%<package>\RequirePackage{l3num}
+%<package>\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_<g/l>| 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
+%</showmemory>
+%</initex|package>
+% \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.
+%%
+%% -----------------------------------------------------------------------
+%<package>\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
%</dtx>
-%<package>\NeedsTeXFormat{LaTeX2e}
-%<package>\ProvidesPackage{l3basics}
-%<driver> \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 @@
%</driver>
% \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}
-%<package>\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" <cs>
+% "\if_true:" <true code> "\else:" <false code> "\fi:" \\
+% "\if_false:" <true code> "\else:" <false code> "\fi:" \\
+% "\reverse_if:N" <primitive conditional>
% \end{syntax}
-% This function return the name of <cs> as a sequence of letters with
-% the escape character removed.
+% "\if_true:" always executes <true code>, while "\if_false:" always
+% executes <false code>. "\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" <tlp>
+% "\if_meaning:NN" <cs1> <cs2> <true code> "\else:" <false code>
+% "\fi:" \\
+% "\if_cs_meaning_eq:NN" <cs1> <cs2> <true code> "\else:"
+% <false code> "\fi:" \\
+% "\if_token_eq:NN" <token1> <token2> <true code> "\else:" <false
+% code> "\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 <tlp> 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 <true code> when the replacement text,
+% i.e., the expansion of <cs1> and <cs2> are the same, otherwise it
+% executes <false code>. 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" <cs1> <cs2> <true code> "\else:" <false code> "\fi:"
+% "\if:w" <token1> <token2> <true code> "\else:" <false code> "\fi:" \\
+% "\if_catcode:w" <token1> <token2> <true code> "\else:" <false
+% code> "\fi:"
% \end{syntax}
-% This conditional executes <true code> when the replacement text, i.e.,
-% the expansion of <cs1> and <cs2> are the same, otherwise it executes
-% <false code>.
-% \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}{%
-% \cs_eq_p:NN |
+% \if_cs_exist:N |
+% \if_cs_exist:w
% }
% \begin{syntax}
-% "\cs_eq_p:NN" <cs1> <cs2>
+% "\if_cs_exist:N" <cs> <true code> "\else:" <false code> "\fi:" \\
+% "\if_cs_exist:w" <tokens> "\cs_end:" <true code> "\else:" <false
+% code> "\fi:"
+% \end{syntax}
+% Check if <cs> appears in the hash table or if the control sequence
+% that can be formed from <tokens> 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:" <true code> "\else:" <false code> "\fi:"
+% \end{syntax}
+% Execute <true code> if currently in horizontal mode, otherwise
+% execute <false code>. Similar for the other functions.
+% \end{function}
+%
+% \subsubsection{Non-primitive conditionals}
+%
+% \begin{function}{%
+% \cs_if_eq_p:NN
+% }
+% \begin{syntax}
+% "\cs_if_eq_p:NN" <cs1> <cs2>
% \end{syntax}
% Returns `true' if <cs1> and <cs2> 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_if_eq:NNTF" <cs1> <cs2> "{"<true code>"}{"<false code>"}"
+% \end{syntax}
+% These functions check if <cs1> and <cs2> have same meaning and then
+% execute either <true code> or <false code>.
+% \end{function}
+%
+%
+% \begin{function}{%
+% \cs_if_free_p:N
% }
% \begin{syntax}
-% "\cs_free_p:N" <cs>
+% "\cs_if_free_p:N" <cs>
% \end{syntax}
% Returns `true' if <cs> is either undefined or equal to "\scan_stop:".
% However, it returns `false' if <cs> 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> "{"<true code>"}{"<false code>"}"
+% "\cs_if_free:NTF" <cs> "{"<true code>"}{"<false code>"}"
% \end{syntax}
% These functions check if <cs> is free and then execute either <true
% code> or <false code>.
% \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>
+% "\cs_if_really_free:cTF" "{"<tokens>"}" "{"<true code>"} {"<false
+% code>"}"
% \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" <cs>
+% \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" <cs> "{"<true code>"}{"<false code>"}"
+% \end{syntax}
+% These functions check if <cs> exists and then execute either <true
+% code> or <false code>. 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" "{"<tokens>"}" "{"<true code>"} {"<false
+% code>"}"
+% \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" <cs>
@@ -155,14 +315,136 @@
% This function checks that <cs> 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" "{"<arg1>"}"\\
+% "\use_none:nn" "{"<arg1>"}{"<arg2>"}"
+% \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" "{" <code1> "}"
+% \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" "{" <code1> "}{" <code2> "}"
+% \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" "{" <arg1> "}{" <arg2> "}{" <arg3> "}"
+% \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" "{" <arg1> "}{" <arg2> "}{" <arg3> "}{" <arg4> "}"
+% \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" <balanced text> "\q_nil"
+% \end{syntax}
+% Gobbles <balanced text>. 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" "{"<arg>"}" <balanced text> "\q_nil"
+% \end{syntax}
+% Gobbles <balanced text> and executes <arg> 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" "{"<arg>"}" "\fi:"
+% "\use_arg_i_after_else:nw" "{"<arg>"}" "\else:" <balanced text> "\fi:"
+% "\use_arg_i_after_or:nw" "{"<arg>"}" "\or:" <balanced text> "\fi:"
+% \end{syntax}
+% Executes <arg> after executing closing out "\fi:".
+% \end{function}
+%
% \subsection{Internal functions}
-%
+%
% \begin{function}{%
% \cs:w |
-% \cs_end: |
-% }
+% \cs_end:
+% }
% \begin{syntax}
% "\cs:w" <tokens> "\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" "{" <code1> "}{" <code2> "}"
-% \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" "{" <arg1> "}{" <arg2> "}{" <arg2> "}"
+% "\io_put_log:x" "{"<message>"}"
+% "\io_put_deferred:Nx" <write_stream> "{"<message>"}"
% \end{syntax}
-% Functions that pick up one of three arguments and execute them after
-% removing the surrounding braces. Should be described somewhere else.
+% Writes <message> to either to log or the terminal.
% \end{function}
%
-% \begin{function}{\use:n}
-% \begin{syntax}
-% "\use:n" "{" <code1> "}"
-% \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,15 +526,117 @@
% \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.
-%
+%
+%
+% \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:NNn" <cs> <num> "{" <code> "}"
+% \end{syntax}
+% Defines a new function, making sure that <cs> is unused so far.
+% <num> 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. <code> is either passed literally or may
+% be subject to expansion (under the "x" variants).
+% \end{function}
+%
+% \begin{function}{\gdef_new:NNn |
+% \gdef_new:cNn |
+% \gdef_new:NNx |
+% \gdef_new:cNx
+% }
+% \begin{syntax}
+% "\gdef_new:NNn" <cs> <num> "{" <code> "}"
+% \end{syntax}
+% Like "\def_new:NNn" but defines the new function globally.
+% \end{function}
+%
+% \begin{function}{\def_long_new:NNn |
+% \def_long_new:NNx |
+% \def_long_new:cNn |
+% \def_long_new:cNx
+% }
+% \begin{syntax}
+% "\def_long_new:NNn" <cs> <num> "{" <code> "}"
+% \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:NNn |
+% \gdef_long_new:NNx |
+% \gdef_long_new:cNn |
+% \gdef_long_new:cNx
+% }
+% \begin{syntax}
+% "\gdef_long_new:NNn" <cs> <num> "{" <code> "}"
+% \end{syntax}
+% Global versions of the above functions.
+% \end{function}
+%
+% \begin{function}{\def_protected_new:NNn |
+% \def_protected_new:NNx |
+% \def_protected_new:cNn |
+% \def_protected_new:cNx
+% }
+% \begin{syntax}
+% "\def_protected_new:NNn" <cs> <num> "{" <code> "}"
+% \end{syntax}
+% Defines a function that does not expand when inside an |x| type
+% expansion.
+% \end{function}
+%
+% \begin{function}{\gdef_protected_new:NNn |
+% \gdef_protected_new:NNx |
+% \gdef_protected_new:cNn |
+% \gdef_protected_new:cNx
+% }
+% \begin{syntax}
+% "\gdef_protected_new:NNn" <cs> <num> "{" <code> "}"
+% \end{syntax}
+% Global versions of the above functions.
+% \end{function}
+%
+% \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_protected_long_new:NNn" <cs> <num> "{" <code> "}"
+% \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:NNn |
+% \gdef_protected_long_new:NNx |
+% \gdef_protected_long_new:cNn |
+% \gdef_protected_long_new:cNx
+% }
+% \begin{syntax}
+% "\gdef_protected_long_new:NNn" <cs> <num> "{" <code> "}"
+% \end{syntax}
+% Global versions of the above functions.
+% \end{function}
+%
+%
+%
+%
+%
+% 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 |
@@ -274,7 +653,10 @@
% (under the "x" variants).
% \end{function}
%
-% \begin{function}{\gdef_new:Npn
+% \begin{function}{\gdef_new:Npn |
+% \gdef_new:cpn |
+% \gdef_new:Npx |
+% \gdef_new:cpx
% }
% \begin{syntax}
% "\gdef_new:Npn" <cs> <parms> "{" <code> "}"
@@ -282,8 +664,11 @@
% 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" <cs> <parms> "{" <code> "}"
@@ -291,23 +676,198 @@
% 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" <cs> <parms> "{" <code> "}"
+% \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" <cs> <parms> "{" <code> "}"
+% \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" <cs> <parms> "{" <code> "}"
+% \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" <cs> <parms> "{" <code> "}"
+% \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" <cs> <parms> "{" <code> "}"
+% \end{syntax}
+% Global versions of the above functions.
+% \end{function}
+%
% \begin{function}{\let_new:NN |
-% \glet_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" <cs1> <cs2>
% \end{syntax}
% Gives the function <cs1> the current meaning of <cs2>. Again, we may
-% do this alway globally.
+% do this always globally.
% \end{function}
-%
-% \subsection{Defining internal functions (no checks)}
-%
+%
+%
+%
+% \subsubsection{Undefining functions}
+%
+% \begin{function}{ \cs_gundefine:N
+% }
+% \begin{syntax}
+% "\cs_gundefine:N" <cs>
+% \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" <cs> <num> "{" <code> "}"
+% \end{syntax}
+% Like "\def_new:NNn" etc.\ but does not check the <cs> name.
+% \end{function}
+%
+% \begin{function}{\gdef:NNn |
+% \gdef:NNx |
+% \gdef:cNn |
+% \gdef:cNx |
+% }
+% \begin{syntax}
+% "\gdef:NNn" <cs> <num> "{" <code> "}"
+% \end{syntax}
+% Like "\def:NNn" but defines the <cs> globally.
+% \end{function}
+%
+%
+% \begin{function}{\def_long:NNn |
+% \def_long:NNx |
+% \def_long:cNn |
+% \def_long:cNx |
+% }
+% \begin{syntax}
+% "\def_long:NNn" <cs> <num> "{" <code> "}"
+% \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" <cs> <num> "{" <code> "}"
+% \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" <cs> <num> "{" <code> "}"
+% \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" <cs> <num> "{" <code> "}"
+% \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" <cs> <num> "{" <code> "}"
+% \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" <cs> <num> "{" <code> "}"
+% \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 |
@@ -323,7 +883,7 @@
% known in \LaTeX2 as \tn{@namedef}. "\def:cpx" has no equivalent.
% \end{texnote}
% \end{function}
-%
+%
% \begin{function}{\gdef:Npn |
% \gdef:Npx |
% \gdef:cpn |
@@ -338,21 +898,12 @@
% and \tn{xdef}.
% \end{texnote}
% \end{function}
-%
-% \begin{function}{\def:No |
-% \gdef:No
-% }
-% \begin{syntax}
-% "\def:No" <cs> "{" <code> "}"
-% \end{syntax}
-% Local and global variant that expands code once before defining <cs>.
-% The function may not take <parms> as the others do. Perhaps this
-% should be changed.
-% \end{function}
-%
+%
+%
% \begin{function}{\def_long:Npn |
% \def_long:Npx |
% \def_long:cpn |
+% \def_long:cpx |
% }
% \begin{syntax}
% "\def_long:Npn" <cs> <parms> "{" <code> "}"
@@ -360,21 +911,77 @@
% 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" <cs> <parms> "{" <code> "}"
% \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" <cs> <parms> "{" <code> "}"
+% \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" <cs> <parms> "{" <code> "}"
+% \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" <cs> <parms> "{" <code> "}"
+% \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" <cs> <parms> "{" <code> "}"
+% \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" <cs1> <cs2>
@@ -382,7 +989,7 @@
% Gives the function <cs1> the current meaning of <cs2>. Again, we may
% always do this globally.
% \end{function}
-%
+%
% \begin{function}{\let:NwN}
% \begin{syntax}
% "\let:NwN" <cs1> <cs2>
@@ -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"}" <parms> "{"<test>"}"
+% \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" <cs>
+% \end{syntax}
+% This function return the name of <cs> as a sequence of letters with
+% the escape character removed.
+% \end{function}
+%
+% \begin{function}{\token_to_string:N}
+% \begin{syntax}
+% "\token_to_string:N" <arg>
+% \end{syntax}
+% This function return the name of <arg> as a sequence of letters
+% including the escape character.
+% \end{function}
+%
+% \begin{function}{\token_to_meaning:N}
+% \begin{syntax}
+% "\token_to_meaning:N" <arg>
+% \end{syntax}
+% This function returns the type and definition of <arg> 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" "{"<true code>"}" "{"<false code>"}"
+% \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>
+%<*initex|package>
\tex_let:D \let:NwN \tex_let:D
-\let:NwN \def:Npn \tex_def:D
-\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
+% \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 \exp_after:NN \tex_expandafter: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 \exp_not:N \tex_noexpand: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}
%
-%
-% \section {Defining and checking (new) functions}
+% \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 \gdef:Npx \tex_xdef: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}
%
-% 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.
+% 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.
%
+% \begin{macro}{\c_true}
+% \begin{macro}{\c_false}
+% Here are the canonical boolean values.
% \begin{macrocode}
-\let:NwN\c_minus_one\m@ne
-\tex_chardef:D \c_one = 1\scan_stop:
+\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}
+%<*!initex>
+\let:NwN \c_minus_one\m@ne
+%</!initex>
+%<*!package>
+\tex_countdef:D \c_minus_one = 10 \scan_stop:
+\c_minus_one = -1 \scan_stop:
+%</!package>
\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{}
%</trace>
% \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}
%</trace>
- }
+}
% \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
+% \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_exist_cs:N #1 {
- \if:w \cs_exist_p:N #1
+\def:Npn \chk_if_exist_cs:N #1 {
+ \if:w \cs_if_exist_p:N #1
\else:
- \err_latex_bug:n{Command~ `\token_to_string:N #1'~
+ \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_free_p:N}
+% \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
+% 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_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:
+\def:Npn \cs_if_free_p:N #1{
+ \if_cs_exist:N #1
\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:}
+ \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}
%
-% \subsection{More new definitions}
%
-% \begin{macro}{\let:NN}
-% \begin{macro}{\let:cN}
-% \begin{macro}{\let:Nc}
-% \begin{macro}{\let: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.
+% \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}
-\tex_long:D\def:Npn \let:NN #1{
+\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}
-% 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 |=|
+% \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}
- \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.
+\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:Npn \def_new:Npn #1{\chk_new_cs:N #1
+\def_protected: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_protected:Npn \def_new:Npx #1{\chk_new_cs:N #1
\def:Npx #1}
-\def_new:Npn \let_new:NN #1{\chk_new_cs:N #1
- \let:NN #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}
+% \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}{\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.).
+%
+% \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 \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
-% the definition.
% \begin{macrocode}
-\def_new:Npn \def:No{\exp_args:NNo\def:Npn}
+\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}
+% \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}
+%
+%
+% \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_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}{\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_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}
+%
+%
+% \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.
+% \begin{macrocode}
+\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_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 \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}
+\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}
-
-% \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{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \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}
+\def_new:Npn \gdef:No {\exp_args:NNo\gdef:Npn}
% \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}
%
-% \begin{macro}{\gundefine:N }
+% \subsubsection{Freeing memory}
+%
+% \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: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_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}
+% \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}
%
-% \subsection{Scratch functions}
+%
+% \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: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}
+%
+%
+% \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 <true arg> or the <false
-% arg>. 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 <true code> and/or <false
-% code> 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}
+%</initex|package>
+%<*showmemory>
+\showMemUsage
+%</showmemory>
+% \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:<args>
+% 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}
-%</package>
-%<*showmemory>
-\showMemUsage
-%</showmemory>
-% \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.
+%%
+%% -----------------------------------------------------------------------
+%
+%<package>\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
+%</dtx>
+%\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}
+%</driver>
+% \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" <box>
+% \end{syntax}
+% Defines <box> 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" <box> <true code>"\else:" <false code>"\fi:"
+% "\if_box_empty:N" <box> <true code>"\else:" <false code>"\fi:"
+% \end{syntax}
+% "\if_hbox:N" and "\if_vbox:N" check if <box> is an horizontal or
+% vertical box resp. "\if_box_empty:N" tests if <box> 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" <box> "{"\m{true code}"}" "{"\m{false code}"}"
+% \end{syntax}
+% Tests if <box> 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" <box1> <box2>
+% \end{syntax}
+% Sets <box1> equal to <box2>. Note that this eradicates the contents
+% of <box2> 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" <box1> <box2>
+% \end{syntax}
+% Globally sets <box1> equal to <box2>.
+% \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" <box>
+% \end{syntax}
+% Sets <box> 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" "{"<dimen>"}" "{"<box function>"}"
+% \end{syntax}
+% Moves <box function> <dimen> in the direction specified. <box
+% function> 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" <box>
+% \end{syntax}
+% Clears <box> 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> \\
+% "\box_use_clear:N" <box>
+% \end{syntax}
+% "\box_use:N" puts a copy of <box> 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" <box>
+% \end{syntax}
+% Returns the height, depth, and width of <box> 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" <box>
+% \end{syntax}
+% Writes the contents of <box> 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" "{"<contents>"}"
+% \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" <box> "{"\m{contents}"}"
+% \end{syntax}
+% Sets <box> 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" <box> "{"\m{dimen}"}" "{"\m{contents}"}"
+% \end{syntax}
+% Sets <box> to contain \m{contents} and have width <dimen>.
+% "\hbox_gset_to_wd:Nn" does it globally.
+% \end{function}
+%
+%
+% \begin{function}{%
+% \hbox_to_wd:nn |
+% }
+% \begin{syntax}
+% "\hbox_to_wd:nn" "{"<dimen>"}" <contents>
+% \end{syntax}
+% Places a <box> of width <dimen> containing <contents>.
+% \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" <box> <contents>
+% "\hbox_set_inline_end:"
+% \end{syntax}
+% Sets <box> to contain <contents>. 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" <box>
+% \end{syntax}
+% "\hbox_unpack:N" unpacks the contents of the <box> register and
+% "\hbox_unpack_clear:N" also clears the <box> 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" <box> "{"\m{contents}"}"
+% \end{syntax}
+% Sets <box> 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" <box> "{"\m{dimen}"}" "{"\m{contents}"}"
+% \end{syntax}
+% Sets <box> to contain \m{contents} and have total height <dimen>.
+% "\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" <box> <contents>
+% "\vbox_set_inline_end:"
+% \end{syntax}
+% Sets <box> 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" <box1> <box2> "{"<dimen>"}"
+% \end{syntax}
+% Sets <box1> to contain the top <dimen> part of <box2>.
+% \begin{texnote}
+% This is the \TeX{} primitive \tn{vsplit}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+% \vbox:n |
+% }
+% \begin{syntax}
+% "\vbox:n" "{"<contents>"}"
+% \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" "{"<dimen>"}" <contents> \\
+% "\vbox_to_zero:n" <contents>
+% \end{syntax}
+% Places a <box> of size <dimen> containing <contents>.
+% \end{function}
+%
+%
+% \begin{function}{%
+% \vbox_unpack:N |
+% \vbox_unpack_clear:N |
+% }
+% \begin{syntax}
+% "\vbox_unpack:N" <box>
+% \end{syntax}
+% "\vbox_unpack:N" unpacks the contents of the <box> register and
+% "\vbox_unpack_clear:N" also clears the <box> 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}
+%<package&!check>\RequirePackage{l3prg}\par
+%<package&check>\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}
+%</initex>
+% \end{macrocode}
+% When we run on top of \LaTeX, we just use its allocation
+% mechanism.
+% \begin{macrocode}
+%<package>\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}
+%<package>\let:NN \c_empty_box \voidb@x
+%<package>\let_new:NN \l_tmpa_box \@tempboxa
+%<initex>\box_new:N \c_empty_box
+%<initex>\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}
+%</initex|package>
+%<*showmemory>
+\showMemUsage
+%</showmemory>
+% \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.
+%%
+%% -----------------------------------------------------------------------
+%<package>\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
+%</dtx>
+%\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}
+%</driver>
+% \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" <int> "{"<calc expression>"}"
+% \end{syntax}
+% Evaluates <calc expression> and either adds or subtracts it from
+% <int> or sets <int> 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" <dim> "{"<calc expression>"}"
+% \end{syntax}
+% Evaluates <calc expression> and either adds or subtracts it from
+% <dim> or sets <dim> 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" <skip> "{"<calc expression>"}"
+% \end{syntax}
+% Evaluates <calc expression> and either adds or subtracts it from
+% <skip> or sets <skip> 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" <muskip> "{"<calc expression>"}"
+% \end{syntax}
+% Evaluates <calc expression> and either adds or subtracts it from
+% <muskip> or sets <muskip> to it. These operations can also be
+% global.
+% \end{function}
+%
+%
+% \begin{function}{
+% \calc_calculate_box_size:nnn |
+% }
+% \begin{syntax}
+% "\calc_calculate_box_size:nnn" "{"<dim-set>"}" \\
+% "{"<item 1> <item 2> ... <item n>"}" "{"<contents>"}"
+% \end{syntax}
+% Sets <contents> in a temporary box "\l_tmpa_box". Then <dim-set>
+% 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}
+%</package>
+%<*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}
+%</initex|package>
+%<*showmemory>
+\showMemUsage
+%</showmemory>
+% \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.
+%%
+%% -----------------------------------------------------------------------
+%%
+%<package>\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
%</dtx>
-%<package>\NeedsTeXFormat{LaTeX2e}
-%<package>\ProvidesPackage{l3chk}
-%<driver> \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 @@
%</driver>
% \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" <cs>
@@ -47,10 +81,12 @@
% Checks that <cs> 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" <cs>
@@ -58,7 +94,7 @@
% Checks that <cs> 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}
%<package>\RequirePackage{l3basics}
-%<package>\RequirePackage{l3int}
-%<*package>
+%<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>
%<-trace>\let_new:NN\traceon\use_none:n
%<-trace>\let_new:NN\traceoff\use_none:n
-%</package>
+%</initex|package>
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -356,3 +395,22 @@
%</showmemory>
% \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.
+%%
+%% -----------------------------------------------------------------------
+%
+%<package>\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
+%</dtx>
+%\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}
+%</driver>
+% \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" <comma-list>
+% \end{syntax}
+% Defines <comma-list> 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" <comma-list>
+% \end{syntax}
+% These functions locally or globally clear <comma-list>.
+% \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" <comma-list> <token list>
+% \end{syntax}
+% Locally appends <token list> as a single item to the left
+% or right of <comma-list>. <token list> 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" <comma-list> <token list>
+% \end{syntax}
+% Globally appends <token list> as a single item to the left
+% or right of <comma-list>.
+% \end{function}
+%
+% \begin{function}{%
+% \clist_get:NN |
+% \clist_get:cN |
+% }
+% \begin{syntax}
+% "\clist_get:NN" <comma-list> <tlp>
+% \end{syntax}
+% Functions that locally assign the left-most item of <comma-list> to the
+% token list pointer <tlp>. Item is not removed from <comma-list>! If you
+% need a global return value you need to code something like this:
+% \begin{quote}
+% "\clist_get:NN" <comma-list> "\l_tmpa_tlp" \\
+% "\tlp_gset_eq:NN" <global tlp> "\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" <clist1> <clist2>
+% \end{syntax}
+% Function that locally makes <clist1> identical to <clist2>.
+% \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" <clist1> <clist2>
+% \end{syntax}
+% Function that globally makes <clist1> identical to <clist2>.
+% \end{function}
+%
+%
+% \begin{function}{%
+% \clist_concat:NNN |
+% \clist_gconcat:NNN |
+% \clist_gconcat:NNc |
+% \clist_gconcat:ccc |
+% }
+% \begin{syntax}
+% "\clist_gconcat:NNN" <clist1> <clist2> <clist3>
+% \end{syntax}
+% Function that concatenates <clist2> and <clist3> and globally assigns the
+% result to <clist1>.
+% \end{function}
+%
+%
+% \begin{function}{%
+% \clist_remove_duplicates:N |
+% \clist_gremove_duplicates:N |
+% }
+% \begin{syntax}
+% "\clist_gremove_duplicates:N" <clist>
+% \end{syntax}
+% Function that removes any duplicate entries in <clist>.
+% \end{function}
+%
+% \begin{function}{%
+% \clist_use:N |
+% \clist_use:c
+% }
+% \begin{syntax}
+% "\clist_use:N" <clist>
+% \end{syntax}
+% Function that inserts the <clist> into the processing stream. Mainly
+% useful if one knows what the <clist> 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" <comma-list> <function>
+% \end{syntax}
+% This function applies <function> (which must be a function with one
+% argument) to every item of <comma-list>. <function> 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" <comma-list> "{" <inline function> "}"
+% \end{syntax}
+% Applies <inline function> (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 <comma-list>. <inline function> 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" <comma-list> <temp-var> "{" <action> "}"
+% \end{syntax}
+% Assigns <temp-var> to each element in <clist> and then executes
+% <action> which should contain <temp-var>. 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" <comma-list>
+% \end{syntax}
+% This predicate returns `true' if <comma-list> 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" <comma-list> "{" <true code> "}{" <false code> "}"
+% \end{syntax}
+% Set of conditionals that test whether or not a particular <comma-list>
+% is empty and if so executes either <true code> or <false code>.
+% \end{function}
+%
+% \begin{function}{%
+% \clist_if_eq:NNTF |
+% }
+% \begin{syntax}
+% "\clist_if_eq:NNTF" <comma-list1> <comma-list2> "{" <true code>
+% "}{" <false code> "}"
+% \end{syntax}
+% Check if <comma-list1> and <comma-list2> are equal and execute
+% either <true code> or <false code> 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" <comma-list> "{" <item> "}{" <true code> "}{"
+% <false code> "}"
+% \end{syntax}
+% Function that tests if <item> is in <comma-list>. Depending on the result
+% either <true code> or <false code> is executed.
+% \end{function}
+%
+% \subsection{Internal functions}
+%
+% \begin{function}{\clist_if_empty_err:N}
+% \begin{syntax}
+% "\clist_if_empty_err:N" <comma-list>
+% \end{syntax}
+% Signals an \LaTeX3 error if <comma-list> is empty.
+% \end{function}
+%
+% \begin{function}{\clist_pop_aux:nnNN}
+% \begin{syntax}
+% "\clist_pop_aux:nnNN" <assign1> <assign2> <comma-list> <tlp>
+% \end{syntax}
+% Function that assigns the left-most item of <comma-list> to <tlp> using
+% <assign1> and assigns the tail to <comma-list> using <assign2>. 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 <clist> 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 <clist>s and remove duplicate
+% elements from a <clist>.
+% \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" <stack> "{" <token list> "}"
+% \end{syntax}
+% Locally or globally pushes <token list> as a single item onto the
+% <stack>. <token list> 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" <stack> <tlp>
+% \end{syntax}
+% Functions that assign the top item of <stack> to the token
+% list pointer <tlp> and removes it from <stack>!
+% \end{function}
+%
+% \begin{function}{%
+% \clist_top:NN |
+% \clist_top:cN |
+% }
+% \begin{syntax}
+% "\clist_top:NN" <stack> <tlp>
+% \end{syntax}
+% Functions that locally assign the top item of <stack> to the token
+% list pointer <tlp>. Item is not removed from <stack>!
+% \end{function}
+%
+% \StopEventually{}
+%
+% Use "clist" functions.
+%
+%
+% \subsection {The Implementation}
+%
+% We start by ensuring that the required packages are loaded.
+% \begin{macrocode}
+%<*package>
+\NeedsTeXFormat{LaTeX2e}
+%<!check>\RequirePackage{l3prg,l3quark}
+%<check>\RequirePackage{l3chk}
+%</package>
+%<*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}
+%</initex|package>
+%<*showmemory>
+%\showMemUsage
+%</showmemory>
+% \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.
+%%
+%% -----------------------------------------------------------------------
+%
+%<package>\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
%</dtx>
-%<package>\NeedsTeXFormat{LaTeX2e}
-%<package>\ProvidesPackage{l3expan}
-%<driver> \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 <funct>. <funct> 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 <funct> as the first argument. <funct> may have
% more than one argument---all others are passed unchanged.
% \end{function}
-%
+%
% \begin{function}{%
% \exp_args:NC
% }
@@ -224,7 +318,7 @@
% passed to <funct> as the first argument. <funct> 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" <funct> <arg1> <arg2> "..."
+% \end{syntax}
+% The first argument of <funct> (i.e., <arg1>) undergoes full
+% expansion until the first unexpandable token is encountered, the
+% result is surrounded by braces and passed to <funct>. <funct> 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" <funct> <arg1> <arg2> "..."
+% "\exp_args:Nnx" <funct> <arg1> <arg2> "..."
% \end{syntax}
% The above functions all manipulate the first two arguments of <funct>.
% 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" <funct> <arg1> <arg2> "..."
% \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" <funct> <arg1> <arg2> <arg3> "..."
+% "\exp_args:Nnnx" <funct> <arg1> <arg2> <arg3> "..."
% \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" <funct> <arg1> <arg2> <arg3> "..."
@@ -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" <token1> <token2>
@@ -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" <token>
+% "\exp_not:n" "{" <token list> "}"
% \end{syntax}
% This function will prohibit the expansion of <token> in situation
% where <token> 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" <token>
+% "\exp_not:o" "{"<token list>"}"
% \end{syntax}
+% Same as "\exp_not:n" except <token list> 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" <token>
+% \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 <token> and
-% then issues an "\exp_not:N" to prohibit further expansion of the
-% first token in the replacement text of <token>. This means that if the
-% replacement text of <token> 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 <token>
+% and then issues an "\exp_not:N" to prohibit further expansion of the
+% first token in the replacement text of <token>. This means that if
+% the replacement text of <token> 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}
-%<package>\RequirePackage{l3basics}
%<package>\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}
-%</package>
+%</initex|package>
%<*showmemory>
\showMemUsage
%</showmemory>
% \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.
+%%
+%% -----------------------------------------------------------------------
+%
+%<package>\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
+%</dtx>
+%\fi
+%<*!ini>
+\GetIdInfo$Id: l3final.dtx 573 2006-08-21 20:59:37Z morten $
+ {L3 Experimental final module}
+%</!ini>
+%
+% \iffalse
+%<*driver>
+\documentclass{l3doc}
+
+\begin{document}
+\DocInput{l3final.dtx}
+\end{document}
+%</driver>
+% \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}
+%</initex>
+% \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}
+%</ini>
+% \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.
+%%
+%% -----------------------------------------------------------------------
+%
+%<package>\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
%</dtx>
-%<package>\NeedsTeXFormat{LaTeX2e}
-%<package>\ProvidesPackage{l3int}
-%<driver> \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" <int>
-% "\fint_new:N" <fint>
% \end{syntax}
-% Defines <int> to be a new variable of type "int". There is no way to
-% define constant counters with these functions.
+% Globally defines <int> 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 <int> 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" <int>
-% "\fint_incr:N" <fint>
% \end{syntax}
% Increments <int> 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" <int>
-% "\fint_decr:N" <fint>
% \end{syntax}
% Decrements <int> 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" <int> "{" <integer> "}"
-% "\fint_set:Nn" <fint> "{" <integer> "}"
+% "\int_set:Nn" <int> "{" <integer expr> "}"
% \end{syntax}
-% These functions will set the <int> register to the <integer> value.
+% These functions will set the <int> register to the <integer expr>
+% 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" <fint1> <fint2>
+% "\int_zero:N" <int>
% \end{syntax}
-% Fast form for
-% \begin{syntax}
-% "\fint_set:No" <fint1> "{\fint_use:N" <fint2> "}"
-% \end{syntax}
-% when <fint2> 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 <int> instead of "{"<integer>"}" value.
+% These functions sets the <int> 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" <int> "{" <integer> "}"
-% "\fint_add:Nn" <fint> "{" <integer> "}"
+% "\int_add:Nn" <int> "{" <integer expr> "}"
% \end{syntax}
-% These functions will add to the <int> register the value <integer>. If
-% the second argument is a <int> register too, the surrounding braces
-% can be left out.
-%
-% It not allowed to use a <fint> instead of the <integer>. If a fake
-% counter should be used as the second argument one needs to turn the
-% <fint> first into an <integer> by applying "\fint_use:N".
+% These functions will add to the <int> register the value <integer
+% expr>. If the second argument is a <int> 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" <int> "{" <integer> "}"
-% "\fint_gsub:Nn" <fint> "{" <integer> "}"
+% "\int_gsub:Nn" <int> "{" <integer expr> "}"
% \end{syntax}
% These functions will subtract from the <int> register the value
-% <integer>. If the second argument is a <int> register too, the
+% <integer expr>. If the second argument is a <int> register too, the
% surrounding braces can be left out.
-%
-% It is not allowed to use a <fint> instead of the <integer>. If a fake
-% counter should be used as the second argument one needs to turn the
-% <fint> first into an <integer> by applying "\fint_use:N".
% \end{function}
%
% \begin{function}{%
% \int_use:N |
% \int_use:c |
-% \fint_use:N |
% }
% \begin{syntax}
% "\int_use:N" <int>
-% "\fint_use:N" <fint>
% \end{syntax}
% This function returns the integer value kept in <int> 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" "{" <integer> "}"
% "\int_to_alph:n" <int>
-% "\int_to_alph:n" "{" "\fint_use:N" <fint> "}"
% \end{syntax}
% If some <integer> or the the current value of a <int> 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 <integer>, they can be omitted in case of a <int>.
-%
-% To format <fint>s with these functions it is necessary to turn the
-% value of the <fint> first into an <integer> by applying "\fint_use:N"
-% within the argument braces.
+% numerals) these function can be used. We need braces if the
+% argument is a simple <integer>, they can be omitted in case of a
+% <int>. 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" <integer> <space> \textit{or} <non-expandable token>
+% \end{syntax}
+% Converts <integer> 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 <int>
-% or <fint> register.
-% \end{variable}
+% \begin{syntax}
+% "\int_roman_lcuc_mapping:Nnn" <roman_char> "{"<licr>"}" "{"<LICR>"}"
+% "\int_to_roman_lcuc:NN" <roman_char> <char>
+% \end{syntax}
+% "\int_roman_lcuc_mapping:Nnn" specifies how the roman
+% numeral <roman\_ char> (i, v, x, l, c, d, or m) should be
+% interpreted when converting the number. <licr> is the lower case and
+% <LICR> 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" "{"<int1>"}" "{"<int2>"}" <function>
+% "\int_alph_default_conversion_rule:n" "{"<int>"}"
+% \end{syntax}
+% "\int_convert_number_with_rule:nnN" converts <int1> into letters,
+% symbols, whatever as defined by <function>. <int2> 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
+% <int> 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~expr>"}" \\
+% "\int_div_truncate:n" "{"<int~expr>"}" "{"<int~expr>"}" \\
+% "\int_mod:nn" "{"<int~expr>"}" "{"<int~expr>"}"
+% \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" "{"<int~expr>"}" <rel> "{"<int~expr>"}"
+% "{"<true>"}" "{"<false>"}"
+% \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" "{"<int~expr>"}" <rel> "{"<int~expr>"}"
+% \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" "{"<int~expr>"}" "{"<true>"}" "{"<false>"}"
+% \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" <int expr> <rel> <int~expr> "{"<true>"}"
+% \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" "{"<number>"}""{"<base>"}"
+% \end{syntax}
+% Converts the base~10 number <number> into its equivalent
+% representation written in base~<base>. Expandable.
+% \end{function}
+%
+%
+% \begin{function}{%
+% \int_convert_to_base_ten:nn |
+% }
+% \begin{syntax}
+% "\int_convert_to_base_ten:nn" "{"<number>"}""{"<base>"}"
+% \end{syntax}
+% Converts the base~<base> number <number> into its equivalent
+% representation written in base~10. <number> 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}
-%<package&!check>\RequirePackage{l3basics}\par
-%<package&check>\RequirePackage{l3chk}\par
-%<*package>
+%<package&!check>\RequirePackage{l3num}
+%<package&check>\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
%</check>
}
-\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
%</check>
@@ -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}
+%</initex>
+%<package>\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
%</check>
@@ -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
%</check>
}
\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
%</check>
@@ -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}
-%</package>
-%<*showmemory>
-\showMemUsage
-%</showmemory>
+\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
-%</check>
+ \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>
-%<-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
-%</check>
+\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>
-%<-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>
-%<-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>
-%<-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
-%</check>
+\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
-%</check>
+% \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>
-%<-check> \pref_global:D
- \fint_incr:N}
-\def_new:Npn \fint_gdecr:N {
-%<*check>
- \pref_global_chk:
-%</check>
-%<-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}
-%</package>
+%</initex|package>
%<*showmemory>
\showMemUsage
%</showmemory>
% \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.
+%%
+%% -----------------------------------------------------------------------
+%
+%<package>\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
%</dtx>
-%<package>\NeedsTeXFormat{LaTeX2e}
-%<package>\ProvidesPackage{l3io}
-%<driver> \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}
%<package&check>\RequirePackage{l3chk}\par
%<package>\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}
+%</initex>
+%<package>\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}
+%</initex>
+%<package>\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}
-%</package>
+%</initex|package>
%<*showmemory>
\showMemUsage
%</showmemory>
% \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.
+%%
+%% -----------------------------------------------------------------------
+%<package>\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
+%</dtx>
+%\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}
+%</driver>
+% \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" "{"<keyval list>"}"
+% \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" "{"<keyval list>"}"
+% \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" "{"<keyval list>"}"
+% \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" "{"<key>"}" \\
+% "\KV_key_value_elt:n" "{"<key>"}" "{"<value>"}"
+% \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}
+%</package>
+%<*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}
+%</initex|package>
+%<*showmemory>
+\showMemUsage
+%</showmemory>
+% \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.
+%%
+%% -----------------------------------------------------------------------
+%
+%<package>\RequirePackage{l3names}
+%<package>\RequirePackage{l3basics}
+%<package>\RequirePackage{l3tlp}
+%<package>\RequirePackage{l3expan}
+%<package>\RequirePackage{l3num}
+%<package>\RequirePackage{l3io}
+%<package>\RequirePackage{l3int}
+%<package>\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
+%</dtx>
+%\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}
+%</driver>
+% \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" "{" <message> "}" "{"<continuation>"}"
+% \end{syntax}
+% The <message> 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 <continuation>. 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" <err id> <label> <more args>
+% \end{syntax}
+% This function signals a user error by searching the error file
+% denoted by <err id> for an error message associated with <label>,
+% i.e., specified by a corresponding "\err_interrupt_new:NNNnnn"
+% command. Depending on the number of arguments specified as
+% <argno> when the error message was defined, further arguments are
+% read. Then the error message is displayed as explained in
+% "\err_interrupt_new:NNNnnn".
+% \end{function}
+%
+% Finally, when something really serious occurs, \LaTeX\ will tell
+% the user about it and abort the run.
+% \begin{function}{\err_fatal:nn}
+% \begin{syntax}
+% "\err_fatal:nn" "{" <message> "}" "{"<continuation>"}"
+% \end{syntax}
+% Just displays the <message> and then aborts the \LaTeX\ run.
+% \end{function}
+%
+% \begin{function}{\err_newline:}
+% \begin{syntax}
+% "\err_newline:"
+% \end{syntax}
+% Is used to break an informational, warning or error message up
+% into multiple lines. May be defined in such a way that the new
+% line starts with a standard <continuation>.
+% \end{function}
+%
+% \subsection{Storing the information}
+%
+% The informational and warning messages are usually short and can
+% be stored as part of a macro; but error messages need to be more
+% verbose. Therefor error messages are stored in external files
+% which are read and searched for the correct error message at the
+% time of the error. In this way it is possible to write extensive
+% help texts without cluttering \TeX{}'s main memory.
+%
+% \subsubsection{Dealing with the error file}
+%
+% \begin{function}{\err_file_new:Nn}
+% \begin{syntax}
+% "\err_file_new:Nn" <err id> "{"<err file name>"}"
+% \end{syntax}
+% Opens a new error file to write errors to. <err id> is a unique
+% identifier for the external <err file name>. By convention <err
+% id> is declared as a constant (i.e., starts with "\c_") und ends
+% with "_tlp". If this command is issued while some other error
+% file is open we get an internal error message.
+% \end{function}
+%
+% \begin{function}{\err_file_close:N}
+% \begin{syntax}
+% "\err_file_close:N" <err id>
+% \end{syntax}
+% Closes the currently open error file and checks that it matches
+% <err id>, i.e., that everything is alright in the code.
+% \end{function}
+%
+% \subsubsection{Declaring an error message in the error file}
+% \begin{function}{\err_interrupt_new:NNNnnn}
+% \begin{syntax}
+% "\err_interrupt_new:NNNnnn" <err id> <label> <argno>
+% "{" <short msg> "}"
+% "{" <long msg> "}"
+% "{" <recovery code> "}"
+% \end{syntax}
+% This function declares an new error message which can be
+% addressed via "\err_interrupt:NNw". The pair (<err id>, <label>)
+% has to be unique where <label> can be some otherwise arbitrary
+% token (usually the function name in which the error routine is
+% called. Actually, the pair (<err id>, expansion of <label>) has
+% to be unique since for reasons of speed, tests are carried out
+% using "\if_meaning:NN".
+%
+% <argno> specifies the number of extra arguments that will be
+% supplied to the error routine when "\err_interrupt:NNw" is
+% called. These arguments can be used within <short msg>, <long
+% msg>, and/or <recovery code> to provide further information to
+% the user. They are denoted with "#1", "#2", etc.\ within these
+% arguments.
+%
+% The <short msg> is displayed directly on the terminal if the
+% error occurs, <long msg> is displayed when the user types "h" in
+% response to the error prompt of \TeX{}, and <recovery code> is
+% executed afterwards. This means that <recovery code> is inserted
+% after any deletions or insertions given by the user. All three
+% arguments are expanded while they are written to the error file,
+% therefore one has to prevent expansion of tokens with
+% "\token_to_string:N" that should be expanded when the error is
+% triggered.
+% \end{function}
+%
+% \subsection{Internal functions}
+%
+% \begin{function}{\err_display_aux:w}
+% This function is constructed on the fly while reading the error file.
+% It grabs following arguments from the code (if any) and then displays
+% the error message and inserts the <recovery code>.
+% \end{function}
+%
+% \begin{function}{\err_interrupt_new_aux:w}
+% Helper function used to write the error message info onto the error
+% file.
+% \end{function}
+%
+% \begin{function}{\err_msgline_aux:NNnnn}
+% \begin{syntax}
+% "\err_msgline_aux:NNnnn" <argno> <label> "{"<short>"}"
+% "{"<long msg>"}{"<recovery code>"}"
+% \end{syntax}
+% Function written in front of every error message on the error file. It
+% will be executed when the error file is read back in comparing <label>
+% to "\l_err_label_token". If they are the same, "\err_display_aux:w"
+% will be defined and the reading process will stop.
+% \end{function}
+%
+% \begin{function}{\err_message:x}
+% \begin{syntax}
+% "\err_message:x" "{"<error message>"}"
+% \end{syntax}
+% Function that directly triggers \TeX{}'s error handler. It should
+% not be used directly.
+% \begin{texnote}
+% This is the \LaTeX3 name for the \tn{errormessage} primitive.
+% \end{texnote}
+% \end{function}
+%
+% \subsection{Kernel specific functions}
+%
+% For a number of the functions described above specific variants
+% are provided that are used in the kernel of \LaTeX3.
+%
+% \begin{function}{%
+% \err_kernel_info:n |
+% \err_kernel_warn:n |
+% \err_kernel_fatal:n
+% }
+% \begin{syntax}
+% "\err_kernel_info:n" "{"<message>"}"
+% \end{syntax}
+% \end{function}
+% \begin{function}{%
+% \err_kernel_interrupt:Nw |
+% \err_kernel_interrupt_new:NNnnn |
+% }
+% Abbrivations for writing and accessing kernel error messages that
+% go to the error file "\c_kernel_err_tlp".
+% \end{function}
+%
+% \begin{function}{\err_latex_bug:x}
+% \begin{syntax}
+% "\err_latex_bug:x" "{"<error message>"}"
+% \end{syntax}
+% Creates an internal error message. This is intended to be used in
+% places that should not be reached in normal operation. Something is
+% wrong with the code.
+% \end{function}
+%
+% \subsection{Variables and constants}
+%
+% \begin{variable}{\iow_newline}
+% Identifier denoting the character that triggers a line break in
+% the output.
+% \end{variable}
+%
+% \begin{variable}{\c_iow_err_stream}
+% Output stream used to access the error files during their
+% generation.
+% \end{variable}
+%
+% \begin{variable}{\c_kernel_err_tlp}
+% Identifier denoting the kernel error file. (Its contents is the
+% name of the external file.)
+% \end{variable}
+%
+% \begin{variable}{\g_err_curr_fname}
+% Global variable containing the name of the currently open error
+% file. Empty when no such file is open for writing.
+% \end{variable}
+%
+% \begin{variable}{\tex_errorcontextlines:D}
+% Variable determining the amount of macro expansion contents shown
+% to the user when an error is triggered. \LaTeX3 sets this to -1
+% since to the average user this contents is of no interest.
+% \begin{texnote}
+% This is the \LaTeX3 name for the \TeX3 primitive
+% \tn{errorcontextlines}.
+% \end{texnote}
+% \end{variable}
+%
+% \begin{variable}{\g_err_help_toks}
+% Token register that holds the message that will be shown if the
+% user types "h" in response to an error message that was produced
+% by "\err_message:x".
+% \begin{texnote}
+% This is the \LaTeX3 name for the \TeX\ primitive \tn{errhelp}.
+% \end{texnote}
+% \end{variable}
+%
+% \begin{variable}{\l_err_label_token}
+% Variable holding the <label> to look up in an error file.
+% \end{variable}
+%
+% \StopEventually{}
+%
+% \subsection{The implementation}
+%
+% \begin{macrocode}
+%<*initex|package>
+% \end{macrocode}
+%
+% \subsubsection{Code to be moved to other modules}
+%
+% \begin{macro}{\g_file_curr_name_tlp}
+% This variable is used to store the name of the file currently
+% being processed. It should be part of the code that defines the
+% higher level I/O commands.
+% \begin{macrocode}
+\tlp_new:Nn \g_file_curr_name_tlp {no~file}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\err_message:x}
+% The \LaTeX3 name for a \TeX\ primitive. This should perhaps move
+% to \texttt{l3names.dtx}.
+% \begin{macrocode}
+\let_new:NN \err_message:x \tex_errmessage:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\text_put_sp:}
+% \begin{macro}{\text_put_four_sp:}
+% We need these functions for certain error and warning messages
+% right away. They put one and four spaces into the message stream.
+% \begin{macrocode}
+\def_new:Npn \text_put_sp: {~}
+\def_new:Npn \text_put_four_sp: {\text_put_sp: \text_put_sp:
+ \text_put_sp: \text_put_sp: }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cmd_arg_list_build}
+% This macro takes a digit as its argument and creates a string of
+% |#| characters and argument numbers, such as |##1##2##3|. This
+% list can then later be used in defining a new macro.
+% To do this it locally uses a count register and a token
+% register.
+%
+% \begin{macrocode}
+\def:Npn\cmd_arg_list_build#1{
+% \end{macrocode}
+% First we need to make sure that the token register we will be
+% using for temporary storage is empty.
+% \begin{macrocode}
+ \toks_clear:N\l_tmpb_toks
+% \end{macrocode}
+% Then we can store the argument in a count register that will be
+% decremented untill it's value is zero. Beacuse of the use of the
+% result of this macro, the argument needs to be between 1 and 9;
+% this could be tested, but such a test is not (yet) added.
+% \begin{macrocode}
+ \int_set:Nn \l_tmpa_int {#1}
+ \int_while:nNnT \l_tmpa_int > \c_zero {
+% \end{macrocode}
+% In the loop we first add the value of our counter to the contents
+% of the token register;
+% \begin{macrocode}
+ \toks_put_left:No \l_tmpb_toks {\the_internal:D\l_tmpa_int}
+% \end{macrocode}
+% and precede it with two hash marks.
+% \begin{macrocode}
+ \toks_put_left:Nn \l_tmpb_toks {##}
+% \end{macrocode}
+% Now the count register is decremented and another iteration will
+% follow so long as zero isn't reached.
+% \begin{macrocode}
+ \int_decr:N\l_tmpa_int
+ }
+% \end{macrocode}
+% Finally the contents of the token register needs to be copied as
+% the expansion of a local variable.
+% \begin{macrocode}
+ \def:Npx\l_cmd_arg_list{\the_internal:D\l_tmpb_toks}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\cmd_declare:Nnn}
+% This macro is a first replacement for \LaTeXe's |\newcommand|. It
+% takes the name of a new macro as its first argument, the number
+% of arguments for the new macro is taken as the second argument.
+% \begin{macrocode}
+\def:Npn\cmd_declare:Nnn#1[#2]{
+ \cmd_arg_list_build{#2}
+ \exp_args:NNO\def:Npn#1\l_cmd_arg_list
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\io_show_file_lineno:}
+% A function to add the number of the line and the name of the file
+% to a message as an indication of where the message was triggered.
+% \begin{macrocode}
+\def_new:Npn \io_show_file_lineno:{
+ on~line~\the_internal:D\tex_inputlineno:D\text_put_sp:~of~
+ file~\g_file_curr_name_tlp}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Variables and constants}
+%
+% \begin{macro}{\g_err_help_toks}
+% A token register to store the help text for an error message in.
+% \begin{macrocode}
+\let:NwN \g_err_help_toks \tex_errhelp:D
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\l_err_label_token}
+% This will hold the current error label.
+% \begin{macrocode}
+\def_new:Npn \l_err_label_token {}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\tex_errorcontextlines:D}
+% Since we are producing our own error and help messages we can
+% turn off the nasty stack information coming from \TeX{}'s
+% stomach.
+% \begin{macrocode}
+\int_set:Nn\tex_errorcontextlines:D\c_minus_one
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Displaying the information}
+%
+% Here we define the fairly low level commands needed to
+% communicate with the user.
+%
+% \begin{macro}{\err_info:nn}
+% \begin{macro}{\err_warn:nn}
+% Write a message to the log file ("\err_info:nn") or to both the
+% log file and the terminal ("\err_warn:nn").
+% \begin{macrocode}
+\def_new:Npn \err_info:nn #1#2{
+% \end{macrocode}
+% Make sure that the \emph{continuation} is part of "\err_newline:".
+% \begin{macrocode}
+ \def:Npn\err_newline:{\iow_newline#2}
+% \end{macrocode}
+% Then write the message.
+% \begin{macrocode}
+ \io_put_log:x {#1~\io_show_file_lineno:}}
+\def_new:Npn \err_warn:nn #1#2{
+ \def:Npn\err_newline:{\iow_newline#2}
+ \io_put_term:x {#1~\io_show_file_lineno:}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\err_info_noline:nn}
+% \begin{macro}{\err_warn_noline:nn}
+% These variants of the above two functions don't add the
+% linenumber to the message.
+% \begin{macrocode}
+\def_new:Npn \err_info_noline:nn #1#2{
+ \def:Npn\err_newline:{\iow_newline#2}
+ \io_put_log:x {#1}}
+\def_new:Npn \err_warn_noline:nn #1#2{
+ \def:Npn\err_newline:{\iow_newline#2}
+ \io_put_term:x {#1}}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\err_interrupt:NNw}
+% |\err_interrupt:NNw| is the function that is called when some error
+% occurs in the code. It takes at least two arguments, the
+% \m{errfile} which is a token list that holds the name of the file
+% where the error message should be fetched from, and the label to
+% identify the error message in the error file. However, it may
+% have additional arguments that are picked up by the error handler
+% extracted from the error file. This is specified in the third
+% argument to |\err_interrupt_new:NNNnnn|.
+% \begin{macrocode}
+\def_new:Npn \err_interrupt:NNw #1#2{\let:NwN \l_err_label_token #2
+ \group_begin:
+% \end{macrocode}
+% For some reason we get some |\par|s into the file if we use the
+% current definition of |\iow_long_unxepanded:N| to write the messages.
+% This is probably a consequence of using token registers to
+% prohibit the expansion of code.
+% \begin{macrocode}
+ \let:NwN \par\use_noop:
+% \end{macrocode}
+% We want to ensure that we are not in programmer's mode (no spaces)
+% but we want to switch on internal naming conventions.
+% \begin{macrocode}
+ \CodeStop
+ \NamesStart:
+% \end{macrocode}
+% We better clear all short references that are active, otherwise
+% we may get surprising results.
+% \begin{macrocode}
+ %\clearshortrefmaps
+ \tex_input:D #1~\err_display_aux:w}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\err_fatal:nn}
+% \begin{macro}{\err_fatal_noline:nn}
+% Write a message to the log file and to the terminal.
+% \begin{macrocode}
+\def_new:Npn \err_fatal:nn #1#2{
+% \end{macrocode}
+% Make sure that the \emph{continuation} is part of "\err_newline".
+% \begin{macrocode}
+ \def:Npn\err_newline:{\iow_newline#2}
+% \end{macrocode}
+% Then write the message.
+% \begin{macrocode}
+ \io_put_term:x {#1~\io_show_file_lineno:}
+% \end{macrocode}
+% Finally abort the \LaTeX{} run.
+% \begin{macrocode}
+ \tex_end:D
+ }
+% \end{macrocode}
+% A variant that doesn't include the line number where the error
+% occured.
+% \begin{macrocode}
+\def_new:Npn \err_fatal_noline:nn #1#2{
+ \def:Npn\err_newline:{\iow_newline#2}
+ \io_put_term:x {#1}
+ \tex_end:D
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\err_newline:}
+% |\err_newline:| is used to introduce a new line in an error
+% message. I would like to use |\\| but this would mean
+% redefinition which should be avoided to make the error message
+% the last action before control is given to the user (otherwise
+% something like |\group_end:| would interfere with
+% insertions/deletions by the user). "\err_newline:" will be
+% redefined by the various functions displaying messages to include
+% the correct \emph{continuation}.
+% \begin{macrocode}
+\def_new:Npn \err_newline: {^^J}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Dealing with the error file}
+%
+% This section contains code that combines Michaels original thoughts
+% on the the subject with Denys' further ideas.
+%
+% \begin{macro}{\c_iow_err_stream}
+% Error messages are logged using the output stream
+% |\c_iow_err_stream|.
+% \begin{macrocode}
+\iow_new:N \c_iow_err_stream
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\g_err_curr_fname}
+% A nick name for the currently open error file. It is empty
+% if no error file is currently open.
+% \begin{macrocode}
+\tlp_new:Nn \g_err_curr_fname{}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\err_file_new:Nn}
+% This function defines a new error file. The first argument is a
+% token list which should hold the name of the error file, the second
+% argument is the name of the error file. The token list should be
+% a constant defined by this function.
+% \begin{macrocode}
+\def_new:Npn \err_file_new:Nn #1#2{
+ \tlp_if_empty:NF\g_err_curr_fname
+ {\err_latex_bug:x{Unclosed~error~file~`\g_err_curr_fname'}}
+ \iow_open:Nn \c_iow_err_stream {#2}
+ \err_kernel_info:n{Errorfile~`#2'~opened~for~output}
+ \tlp_gset:Nn \g_err_curr_fname{#2}
+ \tlp_new:Nn #1{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\err_file_close:N}
+% This function closes the current error file.
+% \begin{macrocode}
+\def_new:Npn \err_file_close:N#1{
+% \end{macrocode}
+% Before we close the stream, we write out a final error handler
+% that catches mismatch within error message labels and their
+% calls. Actually this should be integrated into
+% |\err_file_new:Nn|, too.
+% \begin{macrocode}
+ \tlp_if_eq:NNF#1\g_err_curr_fname
+ {\err_latex_bug:x{You~closed~the~wrong~error~file~`#1'.~
+ Open~is~`\g_err_curr_fname'.}}
+ \iow_long_unexpanded:Nn \c_iow_err_stream {\err_latex_bug:x{Didn't~find~the~
+ correct~error~message~to~show.\iow_newline
+ Was~searching~for~a~function~
+ with~the~following~meaning:\iow_newline
+ \token_to_string:N\token_to_meaning:N
+ \token_to_string:N\l_err_label_token}
+% \end{macrocode}
+% The |\group_end:| here matches the one from |\err_interrupt:NNw| that
+% is used to hide changes to |\par| etc.
+% \begin{macrocode}
+ \group_end:}
+ \iow_close:N \c_iow_err_stream
+ \err_kernel_info:n{Errorfile~`\g_err_curr_fname'~closed}
+ \tlp_gset_eq:NN\g_err_curr_fname\c_empty_tlp
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Declaring an error message in the error file}
+%
+% \begin{macro}{\err_interrupt_new:NNNnnn}
+% This function declares a new error message.
+% |\err_interrupt_new:NNNnnn| \m{errfile} \m{errlabel} \m{argno}
+% \m{errmsg} \m{helpmsg} \m{code}. That error message is fetched
+% from the error file \m{errfile}. The label to search for is
+% \m{errlabel}, the error handler has \m{argno} number of arguments
+% (actually \m{argno} + 3 since the \m{errmsg}, \m{helpmsg} and
+% \m{code} are also arguments), and \m{errmsg} is the message to
+% display, \m{helpmsg} is the message that is displayed when the
+% user enters |h|, while \m{code} is extra code to perform when the
+% error occurs. \m{code} is perhaps not necessary, we will see.
+%
+% We have to check that the label associated with the error message
+% is unique. This means that its replacement text (labels are
+% simply arbitrary functions) is different from the replacement
+% text of any other label in the same error set.
+% \begin{macrocode}
+\def_new:Npn \err_interrupt_new:NNNnnn #1{
+% \end{macrocode}
+% Both \m{errmsg} and \m{code} might contain hashmarks denoting
+% arguments to the error handler.
+% \begin{macrocode}
+ \group_begin: \tex_catcode:D`\#\c_other_char_code
+% \end{macrocode}
+% We also have to check that output goes to the correct error file.
+% \begin{macrocode}
+ \if_meaning:NN#1\g_err_curr_fname
+ \else:
+ \err_latex_bug:x{Error~text~goes~to~wrong~err~file:~
+ `\g_err_curr_fname'~is~open~but~you~requested~
+ `#1'}
+ \fi:
+ \err_interrupt_new_aux:w}
+\def_long_new:Npn \err_interrupt_new_aux:w #1#2#3#4#5{
+ \iow_long_unexpanded:Nn \c_iow_err_stream
+ {\err_msgline_aux:NNnnn #1#2{#3}{#4}{#5}\use_noop:}
+ \group_end:}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\err_msgline_aux:NNnnn}
+% This function is executed when an error file is read back by
+% |\err_interrupt:NNw|. It compares its first argument against
+% |\l_err_label_token| using |\if_meaning:NN| and if this fails the
+% function does nothing; otherwise it defines |\err_display_aux:w| in
+% a way that it will pick up the arguments (if any) from the code and
+% generates a suitable error message.
+% \begin{macrocode}
+\def_new:Npn \err_msgline_aux:NNnnn #1#2#3#4#5{
+ \if_meaning:NN#1\l_err_label_token
+% \end{macrocode}
+% At the moment we simply use the old \LaTeX{} error code and
+% |\renewcommand| to generate the error handler. After displaying
+% the error message we insert error code this can be manipulated by
+% the user with the deletion/insertion facility of \TeX{}'s error
+% mechanism.
+%
+% The |\group_end:| at the very beginning matches the
+% |\group_begin:| when the file starts.
+% \begin{macrocode}
+ \cmd_declare:Nnn\err_display_aux:w [#2]{
+ \group_end:
+ \toks_gset:Nx\g_err_help_toks{#4}
+ \io_put_term:x{LaTeX~error~\io_show_file_lineno:.\iow_newline
+ \text_put_sp:\text_put_four_sp: \text_put_sp:
+ See~LaTeX~manual~for~explanation.\iow_newline
+ \text_put_sp:\text_put_four_sp: \text_put_sp:
+ Type~\text_put_sp: H~<return>~\text_put_sp: for~
+ immediate~help.}
+ \err_message:x{#3}
+ #5}
+ \tex_endinput:D
+ \fi:}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\err_display_aux:w}
+% We should make sure that this function is definable.
+% \begin{macrocode}
+\def_new:Npn \err_display_aux:w {}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsubsection{Kernel specific functions}
+%
+% \begin{macro}{\err_kernel_interrupt:Nw}
+% |\err_kernel_interrupt:Nw | is just the abbreviation to read from
+% the standard system error file.
+% \begin{macrocode}
+\def_new:Npn \err_kernel_interrupt:Nw {\err_interrupt:NNw \c_kernel_err_tlp}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\err_kernel_interrupt_new:NNnnn}
+% To ease the coding in case of system messages that should all go
+% to one and the same error file (if!) we also have the following
+% function.
+% \begin{macrocode}
+\def_new:Npn \err_kernel_interrupt_new:NNnnn {
+ \err_interrupt_new:NNNnnn \c_kernel_err_tlp}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\err_kernel_info:n}
+% \begin{macro}{\err_kernel_warn:n}
+% \begin{macro}{\err_kernel_fatal:n}
+% \begin{macro}{\err_kernel_info_noline:n}
+% \begin{macro}{\err_kernel_warn_noline:n}
+% \begin{macro}{\err_kernel_fatal_noline:n}
+% These variants are specific for the \LaTeX\ kernel.
+% \begin{macrocode}
+\def_new:Npn \err_kernel_info:n #1 {
+ \err_info:nn {LaTeX~Info:~#1}
+ {\text_put_four_sp:\text_put_four_sp:\text_put_four_sp:}
+ }
+\def_new:Npn \err_kernel_warn:n #1 {
+ \err_warn:nn {LaTeX~Warning:~#1}
+ {\text_put_sp:\text_put_sp:\text_put_sp:
+ \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:}
+ }
+\def_new:Npn \err_kernel_fatal:n #1 {
+ \err_fatal:nn {LaTeX~Fatal:~#1}
+ {\text_put_sp:
+ \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:}
+ }
+\def_new:Npn \err_kernel_info_noline:n #1 {
+ \err_info_noline:nn {LaTeX~Info:~#1}
+ {\text_put_four_sp:\text_put_four_sp:\text_put_four_sp:}
+ }
+\def_new:Npn \err_kernel_warn_noline:n #1 {
+ \err_warn_noline:nn {LaTeX~Warning:~#1}
+ {\text_put_sp:\text_put_sp:\text_put_sp:
+ \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:}
+ }
+\def_new:Npn \err_kernel_fatal_noline:n #1 {
+ \err_fatal_noline:nn {LaTeX~Fatal:~#1}
+ {\text_put_sp:
+ \text_put_four_sp:\text_put_four_sp:\text_put_four_sp:}
+ }
+%</initex|package>
+% \end{macrocode}
+% At a later stage variants may be provided for what in \LaTeXe{}
+% used to be called document classes and packages.
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\c_kernel_err_tlp}
+% Most error messages will go to the system error file; it's name is
+% stored in |\c_kernel_err_tlp|.
+% \begin{macrocode}
+%<initex>\err_file_new:Nn \c_kernel_err_tlp {ltxkernel.err}
+%<package>\err_file_new:Nn \c_kernel_err_tlp {l3in2e.err}
+% \end{macrocode}
+% \end{macro}
+%
+% The code below is a temporary implementation of a few of
+% \LaTeX209 error messages with the new syntax. They are only
+% included in the package as the \LaTeX3 kernel will certainly have
+% it's own error message definitions that differ from \LaTeXe's way
+% of signalling errors. These primarily serve as an example on how
+% to use this concept of dealing with errors.
+%
+% First we declare a couple of helper macros that contain texts
+% that are used frequently throughout \LaTeX.
+% \begin{macrocode}
+%<*package>
+\def:Npn\err_help_ignored: {
+ Your~command~was~ignored.\iow_newline
+ Type \text_put_sp: I~<command>~<return>
+ \text_put_sp: to~replace~it~with~another~command,\iow_newline
+ or~\text_put_sp: <return> \text_put_sp: to~continue~without~it.}
+
+\def:Npn\err_help_textlost: {
+ You've~lost~some~text.\text_put_sp: \err_help_return_or_X:}
+
+\def:Npn\err_help_return_or_X: {
+ Try~typing\text_put_sp: <return>
+ \text_put_sp: to~proceed.\iow_newline
+ If~that~doesn't~work,~type
+ \text_put_sp: X~<return>\text_put_sp: to~quit.}
+
+\def:Npn\err_help_trouble: {
+ You're~ in~ trouble~ here.
+ \text_put_sp:\err_help_return_or_X:}
+% \end{macrocode}
+%
+% Below are the definitions of the complete messages
+% \begin{macrocode}
+
+\err_kernel_interrupt_new:NNnnn\cs_free_p:N{1}
+ {Command~name~`\tex_string:D#1'~already~used}
+ {You~tried~to~define~a~command~which~already~has~
+ a~meaning.\iow_newline
+ If~you~really~want~to~redefine~it~try~
+ \token_to_string:N\cmd_declare:Nnn\text_put_sp:
+ next~time.\iow_newline
+ For~this~run~I~will~ignore~your~definition.}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\newline{0}
+ {There's~no~line~here~to~end}
+ {You~tried~to~end~a~line~at~a~place~where~I~thought~
+ we~were~already~between~paragraphs.}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\newcnt{0}
+ {No~such~counter}
+ {The~counter~name~mentioned~in~the~operation~is~not~
+ known~to~me.\iow_newline
+ Check~the~spelling.}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\nodocument{0}
+ {Missing~\token_to_string:N\begin{document}}
+ {\err_help_trouble:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\badmath{0}
+ {Bad~math~environment~delimiter}
+ {\err_help_ignored:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\toodeep{0}
+ {Too~deeply~nested}
+ {\err_help_trouble:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\badpoptabs{0}
+ {\token_to_string:N\pushtabs \text_put_sp:
+ and~\token_to_string:N\poptabs
+ \text_put_sp: don't~match}
+ {\err_help_trouble:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\badtab{0}
+ {Undefined~tab~position}
+ {\err_help_trouble:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\preamerr{}
+ {\if_case:w #1~Illegal~character\or:
+ Missing~@-exp\or: Missing~p-arg\fi:\text_put_sp:
+ in~array~arg}
+ {\err_help_trouble:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\badlinearg{}
+ {Bad~\token_to_string:N\line
+ \text_put_sp: or~\token_to_string:N\vector
+ \text_put_sp: argument}
+ {\err_help_textlost:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\parmoderr{0}
+ {Not~in~outer~par~mode}
+ {\err_help_textlost:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\fltovf{0}
+ {Too~many~unprocessed~floats}
+ {\err_help_textlost:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\badcrerr{0}
+ {Bad~use~of~\token_to_string:N\\}
+ {\err_help_return_or_X:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\noitemerr{0}
+ {Something's~wrong--perhaps~a~missing~
+ \token_to_string:N\item}
+ {\err_help_return_or_X:}
+ {}
+
+\err_kernel_interrupt_new:NNnnn\notprerr{0}
+ {Can~be~used~only~in~preamble}
+ {\err_help_ignored:}
+ {}
+
+\err_file_close:N\c_kernel_err_tlp
+%<package>
+% \end{macrocode}
+%
+%
+% Show token usage:
+% \begin{macrocode}
+%<*showmemory>
+\showMemUsage
+%</showmemory>
+% \end{macrocode}
+%
+% \endinput
+%
+% $Log$
+% Revision 1.9 2006/03/19 15:07:47 braams
+% Moved some code to other modules, where it belongs;
+% reverted \c_io_newline to \iow_newline (it'scontents might need to be
+% modified sometine)
+% Example messages are not part of the kernel, only for the package.
+%
+% Revision 1.8 2006/02/15 23:45:46 braams
+% Rearranged the file;
+% implemented \err_fatal:nn and \err_fatal_noline:nn
+% Recode the remaining error definitions for testing purposes
+%
+% Revision 1.7 2006/01/15 09:48:54 braams
+% Mostly textual changes
+%
+% Revision 1.6 2005/12/27 16:01:27 morten
+% Changed RCS information retrieval plus a few minor changes
+%
+% Revision 1.5 2005/05/05 23:45:49 braams
+% Worked on the documentation;
+% added commands \err_info:nn, \err_warn:nn and kernel specific versions
+% of these.
+% Changed \iow_newline: into \c_io_newline; introduced \err_newline: to
+% be used in messages with multiple lines to provide a continuation
+% string.
+% Renamed \style_names_start and \style_names_stop: into \NamesStart:
+% and \NamesStop:.
+%
+% Revision 1.4 2005/05/03 23:34:52 braams
+% Added code that performs the basic function of the old \renewcommand
+% Added a couple of new functions that need to live in other modules
+% Documentation still needs to be corrected
+% The module now basically works
+%
+% Revision 1.3 2005/04/29 22:39:47 braams
+% Another one
+%
+% Revision 1.2 2005/04/29 22:34:39 braams
+% Small typo in the RCS tags
+%
+% Revision 1.1 2005/04/29 22:30:44 braams
+% first version that can be loaded without producing errors.
+% Just a translation from the old stuff, haven't looked at the docu yet \ No newline at end of file
diff --git a/Master/texmf-dist/source/latex/expl3/l3names.dtx b/Master/texmf-dist/source/latex/expl3/l3names.dtx
index 1f981eb2d45..e9345ce37e0 100644
--- a/Master/texmf-dist/source/latex/expl3/l3names.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3names.dtx
@@ -1,27 +1,78 @@
% \iffalse
-%% File: l3names.dtx Copyright (C) 1990-1997 LaTeX3 project
-%
+%% File: l3names.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.
+%%
+%% -----------------------------------------------------------------------
+%^^A We need some basic initial character codes to be set up
+%^^A immediately.
+%<*initex>
+\catcode`\{=1 % left brace is begin-group character
+\catcode`\}=2 % right brace is end-group character
+\catcode`\#=6 % hash mark is macro parameter character
+\catcode`\^=7 %
+\catcode`\^^I=10 % ascii tab is a blank space
+\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{%
+ \immediate\write-1{#1; v#2, #3/#4/#5; #8}%
+}
+%</initex>
+%<*package>
+\def\GetIdInfo$Id: #1.dtx #2 #3-#4-#5 #6 #7$#8{%
+ \def\fileversion{#2}%
+ \def\filedate{#3/#4/#5}%
+ \ProvidesPackage{#1}[#3/#4/#5 v#2 #8]%
+}
+%</package>
%<*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
%</dtx>
-%<package>\NeedsTeXFormat{LaTeX2e}
-%<package>\ProvidesPackage{l3names}
-%<driver> \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}
%</driver>
% \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}
%</initex>
% \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 [<pre spec>] <filler> { <vertical mode material> } (h, m)
+\name_primitive:NN \pdfliteral \pdf_literal:D
+%%\name_primitive:NN \special <pdfspecial spec>
+\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
+}
+%</initex>
+% \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 @@
%</package>
% \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.
+%%
+%% -----------------------------------------------------------------------
+%
+%<package>\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
+%</dtx>
+%\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}
+%</driver>
+% \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" <num>
+% \end{syntax}
+% Defines <num> 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" <num>
+% \end{syntax}
+% Increments <num> 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" <num>
+% \end{syntax}
+% Decrements <num> 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" <num>
+% \end{syntax}
+% Resets <num> 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" <num> "{" <integer> "}"
+% \end{syntax}
+% These functions will set the <num> register to the <integer> 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" <num1> <num2>
+% \end{syntax}
+% These functions will set the <num1> register equal to <num2>.
+% \end{function}
+%
+% \begin{function}{%
+% \num_add:Nn |
+% \num_gadd:Nn |
+% }
+% \begin{syntax}
+% "\num_add:Nn" <num> "{" <integer> "}"
+% \end{syntax}
+% These functions will add to the <num> register the value <integer>. If
+% the second argument is a <num> register too, the surrounding braces
+% can be left out.
+%
+% \end{function}
+%
+%
+% \begin{function}{%
+% \num_use:N |
+% \num_use:c |
+% }
+% \begin{syntax}
+% "\num_use:N" <num>
+% \end{syntax}
+% This function returns the integer value kept in <num> in a way
+% suitable for further processing.
+% \begin{texnote}
+% Since these <num>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" "{" <integer-expr> "}"
+% \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" "{"<num~expr>"}" <rel> "{"<num~expr>"}"
+% "{"<true>"}" "{"<false>"}"
+% \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" "{"<num~expr>"}" <rel> "{"<num~expr>"}"
+% \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_"<value> "{" <value> "}"
+% \end{syntax}
+% Defines a constant with <value>. If the constant is negative
+% or very large it requires an <int> 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" <integer expression> "\scan_stop:"
+% \end{syntax}
+% Evaluates <integer expression>. 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" <number1> <rel> <number2> <true> "\else:" <false> "\fi:"
+% \end{syntax}
+% Compare two numbers. It is recommended to use "\num_eval:n" to
+% correctly evaluate and terminate these numbers. <rel> 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" <number> <true> "\else:" <false> "\fi:"
+% \end{syntax}
+% Execute <true> if <number> is odd, <false> 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" <number> <case0> "\or:" <case1> "\or:" "..." "\else:"
+% <default> "\fi:"
+% \end{syntax}
+% Chooses case<number>. 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}
+%<package&!check>\RequirePackage{l3expan}\par
+%<package&check>\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}
+%</initex|package>
+% \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.
+%%
+%% -----------------------------------------------------------------------
+%
+%<package>\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
%</dtx>
-%<package>\NeedsTeXFormat{LaTeX2e}
-%<package>\ProvidesPackage{l3precom}
-%<driver> \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" <cs>
@@ -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" "{" <file name> "}"
@@ -57,7 +92,7 @@
% scanned. Then all symbols marked for dumping are dumped into <file
% name>.
% \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 <tlp>.
% \end{variable}
-%
-%
-%
-% \section{Precompiling some functions}
+%
+% \StopEventually{}
+%
+% \subsection{The Implementation}
%
% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
-%<package>\RequirePackage{l3int}
+%<package>\RequirePackage{l3num}
%<package>\RequirePackage{l3io}
%<package>\RequirePackage{l3seq}
+%<package>\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
%</trace>
- \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}
}
%</precompile>
% \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>
%<-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
%</precompile>
% \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
%</precompile>
- \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}
}
%</trace>
-%</package>
+%</initex|package>
% \end{macrocode}
% \end{macro}
%
@@ -364,6 +394,26 @@
%</showmemory>
% \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.
+%%
+%% -----------------------------------------------------------------------
+%
+%<package>\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
+%</dtx>
+%\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}
+%</driver>
+% \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" "{"<true code>"}" "{"<false code>"}"
+% \end{syntax}
+% Determines if \TeX{} is in vertical mode or not and executes either
+% <true code> or <false code> accordingly.
+% \end{function}
+%
+% \begin{function}{\mode_horizontal_p:|
+% \mode_horizontal:TF |
+% \mode_horizontal:T |
+% \mode_horizontal:F
+% }
+% \begin{syntax}
+% "\mode_horizontal:TF" "{"<true code>"}" "{"<false code>"}"
+% \end{syntax}
+% Determines if \TeX{} is in horizontal mode or not and executes either
+% <true code> or <false code> accordingly.
+% \end{function}
+%
+%
+% \begin{function}{
+% \mode_inner_p:|
+% \mode_inner:TF|
+% \mode_inner:T|
+% \mode_inner:F
+% }
+% \begin{syntax}
+% "\mode_inner:TF" "{"<true code>"}" "{"<false code>"}"
+% \end{syntax}
+% Determines if \TeX{} is in inner mode or not and executes either
+% <true code> or <false code> accordingly.
+% \end{function}
+%
+% \begin{function}{
+% \mode_math:TF|
+% \mode_math:T|
+% \mode_math:F|
+% }
+% \begin{syntax}
+% "\mode_math:TF" "{"<true code>"}" "{"<false code>"}"
+% \end{syntax}
+% Determines if \TeX{} is in math mode or not and executes either
+% <true code> or <false code> 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" "{" <number> "}" "{" <arg> "}"
+% \end{syntax}
+% Creates <number> copies of <arg>. Expandable.
+% \end{function}
+%
+%
+% \begin{function}{\prg_stepwise_function:nnnN}
+% \begin{syntax}
+% "\prg_stepwise_function:nnnN" "{"<start>"}" "{"<step>"}"
+% "{"<end>"}" <function>
+% \end{syntax}
+% This function performs <action> once for each step starting at
+% <start> and ending once <end> is passed. <function> 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" "{"<start>"}" "{"<step>"}" "{"<end>"}"
+% "{"<action>"}"
+% \end{syntax}
+% Same as |\prg_stepwise_function:nnnN| except here <action> 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" "{"<start>"}" "{"<step>"}" "{"<end>"}"
+% <temp-var> "{"<action>"}"
+% \end{syntax}
+% Same as |\prg_stepwise_inline:nnnn| except here the current value is
+% stored in <temp-var> and the programmer can use it in <action>. 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" <bool>
+% \end{syntax}
+% Define a new boolean variable. The initial value is <false>. 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" <bool>
+% \end{syntax}
+% Set <bool> 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" <bool1> <bool2>
+% \end{syntax}
+% Set <bool1> equal to the value of <bool2>.
+% \end{function}
+%
+% \begin{function}{%
+% \bool_if:NTF |
+% \bool_if:NT |
+% \bool_if:NF |
+% \bool_if_p:N |
+%
+% }
+% \begin{syntax}
+% "\bool_if:NTF" <bool> "{"\m{true}"}" "{"\m{false}"}" \\
+% "\bool_if_p:N" <bool>
+% \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" <bool> "{"\m{true}"}" \\
+% "\bool_whiledo:NF" <bool> "{"\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" "{"<predicate>"}" "{"<true>"}" "{"<false>"}" \\
+% \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" "{"<predicate> <predicate> ..."}" \\
+% "\prg_if_predicate_or_p:nn" "{"<predicate>"}" "{"<predicate>"}" \\
+% "\prg_if_predicate_ands_p:n" "{"<predicate> <predicate> ..."}" \\
+% "\prg_if_predicate_and_p:nn" "{"<predicate>"}" "{"<predicate>"}" \\
+% "\prg_if_predicate_not_p:n" "{"<predicate>"}"
+% \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" "{"<test>"}" "{"\m{true}"}" \\
+% "\prg_whiledo:nF" "{"<test>"}" "{"\m{false}"}"
+% \end{syntax}
+% The "T" versions execute the \m{true} code as long as <test> is
+% true and the "F" versions execute the \m{false} code as long as
+% <test> 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, <test>
+% 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" "{" "{"<element~1>"}" "{"<element~2>"}"
+% \dots\space "{"<element~n>"}" "}"
+% \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" "{"<element>"}" \\
+% "\prg_quicksort_compare:nnTF" "{"<element 1>"}" "{"<element 2>"}"\\
+% \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}
+%</package>
+%<*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}
+%</initex|package>
+%<*showmemory>
+\showMemUsage
+%</showmemory>
+% \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.
+%%
+%% -----------------------------------------------------------------------
+%
+%<package>\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
%</dtx>
-%<package>\NeedsTeXFormat{LaTeX2e}
-%<package>\ProvidesPackage{l3prop}
-%<driver> \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" <plist>
% \end{syntax}
% Defines <plist> 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 <plist>.
% \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 @@
% <plist>. If <key> has already a meaning within <plist> this value is
% overwritten.
% \end{function}
-%
+%
% \begin{function}{%
% \prop_gput_if_new:NNn |
% }
@@ -88,10 +126,13 @@
% <plist> but only if <key> has so far no meaning within <plist>.
% 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" <plist> <key> <tlp>
@@ -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" <plist 1> <plist 2>
% \end{syntax}
% A fast assignment of <plist>s.
% \end{function}
-%
+%
% \begin{function}{%
% \prop_get_gdel:NNN |
% }
@@ -121,7 +165,7 @@
% Like "\prop_get:NNN" but additionally removes <key> (and its <info>)
% from <plist>.
% \end{function}
-%
+%
% \begin{function}{%
% \prop_del:NN |
% \prop_gdel:NN |
@@ -132,43 +176,68 @@
% Locally or globally deletes <key> and its <info> from <plist> 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" <plist> <function>
+% "\prop_map_function:NN" <plist> <function>
% \end{syntax}
% Maps <function> which should be a function with two arguments (<key>
-% and <info>) over every <key> <info> pair of <plist>.
+% and <info>) over every <key> <info> pair of <plist>. Expandable.
% \end{function}
-%
+%
% \begin{function}{\prop_map_inline:Nn |
% \prop_map_inline:cn
% }
% \begin{syntax}
% "\prop_map_inline:Nn" <plist> "{" <inline function> "}"
% \end{syntax}
-% Just like "\prop_map:NN" but with the function of two arguments
-% supplied as inline code. Within <inline function> refer to the
-% arguments via "##1" (<key>) and "##2" (<info>).
-%
-% Not implemented so far!
+% Just like "\prop_map_function:NN" but with the function of two arguments
+% supplied as inline code. Within <inline function> refer to the
+% arguments via "##1" (<key>) and "##2" (<info>). 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" <plist> "{"<true code>"}{"<false code>"}"
+% "\prop_if_empty:NTF" <plist> "{"<true code>"}{"<false code>"}"
% \end{syntax}
% Set of conditionals that test whether or not a particular <plist>
% is empty.
% \end{function}
-%
+%
+% \begin{function}{\prop_if_eq:NNF |
+% \prop_if_eq:ccF
+% }
+% \begin{syntax}
+% "\prop_if_eq:NNF" <plist1> <plist2> "{"<false code>"}"
+% \end{syntax}
+% Execute <false code> if <plist1> doesn't hold the same token list as
+% <plist2>.
+% \end{function}
+%
+%
% \begin{function}{%
% \prop_if_in:NNTF |
% \prop_if_in:NOTF |
+% \prop_if_in:ccTF |
% }
% \begin{syntax}
% "\prop_if_in:NNTF" <plist><key>"{"<true code>"}{"<false code>"}"
@@ -176,16 +245,16 @@
% Tests if <key> is used in <plist> and then either executes <true code>
% or <false code>.
% \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" <plist> <key> <cmd>
@@ -223,20 +293,21 @@
% <key> in <plist>, then the 2 arg is "\q_no_value " and the 3rd arg is
% empty; otherwise the 3rd argument has the two extra tokens <prop>
% "\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}
-%<package>\RequirePackage{l3seq}\par
-%<*package>
+%<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}
-%</package>
+%</initex|package>
%<*showmemory>
%\showMemUsage
%</showmemory>
@@ -596,4 +829,22 @@
%</unused>
% \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.
+%%
+%% -----------------------------------------------------------------------
%
+%<package>\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
%</dtx>
-%<package>\NeedsTeXFormat{LaTeX2e}
-%<package>\ProvidesPackage{l3quark}
-%<driver> \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 <quark> 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" "{" <token list> "}"
+% "\quark_if_no_value:nTF" "{"<token list>"}"
% " {"<true code>"}{"<false code>"}"
% "\quark_if_no_value:NTF" <tlp>
% " {"<true code>"}{"<false code>"}"
% \end{syntax}
% This tests whether or not <token list> contains only the quark
% "\q_no_value".
-%
+%
% If <token list> 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" <token>
+% " {"<true code>"}{"<false code>"}"
+% \end{syntax}
+% This tests whether or not <token> 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" "{"<tokens>"}"
+% "{"<true code>"}{"<false code>"}"
+% \end{syntax}
+% This tests whether or not <tokens> 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}
%<package>\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
+%<package> {\token_to_string:N\q_no_value\space}
+%<initex> {\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
+%<package> {\token_to_string:N\q_nil\space}
+%<initex> {\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}
-%</package>
+%</initex|package>
%<*showmemory>
\showMemUsage
%</showmemory>
% \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.
+%%
+%% -----------------------------------------------------------------------
+%
+%<package>\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
%</dtx>
-%<package>\NeedsTeXFormat{LaTeX2e}
-%<package>\ProvidesPackage{l3seq}
-%<driver> \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 <tlp> assume
-% that the <tlp> 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 <sequence> 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 <sequence>.
% \end{function}
-%
+%
% \begin{function}{%
% \seq_put_left:Nn |
% \seq_put_left:No |
@@ -99,10 +133,11 @@
% or right of <sequence>. <token list> 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 <token list> as a single item to the left
% or right of <sequence>.
% \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" <seq1> <seq2>
+% \end{syntax}
+% Function that locally makes <seq1> identical to <seq2>.
+% \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" <seq1> <seq2>
+% \end{syntax}
+% Function that globally makes <seq1> identical to <seq2>.
+% \end{function}
+%
% \begin{function}{%
% \seq_gconcat:NNN |
% \seq_gconcat:ccc |
@@ -143,7 +201,19 @@
% Function that conatenates <seq2> and <seq3> and globally assigns the
% result to <seq1>.
% \end{function}
-%
+%
+% \begin{function}{\seq_map_variable:NNn |
+% \seq_map_variable:cNn
+% }
+% \begin{syntax}
+% "\seq_map_variable:NNn" <sequence> <tlp> "{" <code using tlp> "}"
+% \end{syntax}
+% Every element in <sequence> is assigned to <tlp> and then <code
+% using tlp> 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" <sequences> <function>
@@ -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" <sequence>
+% "\seq_if_empty_p:N" <sequence>
% \end{syntax}
% This predicate returns `true' if <sequence> 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" <sequence> "{" <true code> "}{" <false code> "}"
+% "\seq_if_empty:NTF" <sequence> "{" <true code> "}{" <false code> "}"
% \end{syntax}
% Set of conditionals that test whether or not a particular <sequence>
% is empty and if so executes either <true code> or <false code>.
% \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" <sequ> "{" <item> "}{" <true code> "}{" <false code> "}"
@@ -206,16 +279,16 @@
% Function that tests if <item> is in <sequ>. Depending on the result
% either <true code> or <false code> 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" <sequence>
+% "\seq_if_empty_err:N" <sequence>
% \end{syntax}
% Signals an \LaTeX3 error if <sequence> is empty.
% \end{function}
-%
+%
% \begin{function}{\seq_pop_aux:nnNN}
% \begin{syntax}
% "\seq_pop_aux:nnNN" <assign1> <assign2> <sequence> <tlp>
@@ -224,7 +297,7 @@
% <assign1> and assigns the tail to <sequence> using <assign2>. 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" <stack> "{" <token list> "}"
+% \end{syntax}
+% Locally or globally pushes <token list> as a single item onto the
+% <stack>. <token list> 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" <stack> <tlp>
+% \end{syntax}
+% Functions that assign the top item of <stack> to the token
+% list pointer <tlp> and removes it from <stack>!
+% \end{function}
+%
+% \begin{function}{%
+% \seq_top:NN |
+% \seq_top:cN |
+% }
+% \begin{syntax}
+% "\seq_top:NN" <stack> <tlp>
+% \end{syntax}
+% Functions that locally assign the top item of <stack> to the token
+% list pointer <tlp>. Item is not removed from <stack>!
+% \end{function}
+%
+% \subsection{Predicates and conditionals}
+%
+% Use "seq" functions.
+%
+% \StopEventually{}
+%
+% \subsection {Implementation}
+%
%
% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
-%<package&!check>\RequirePackage{l3toks}
%<package&!check>\RequirePackage{l3quark}
+%<package&!check>\RequirePackage{l3tlp}
%<package&check>\RequirePackage{l3chk}
%<package>\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>
-%<_check> \pref_global:D
+%<-check> \pref_global:D
\seq_put_left:Nn}
\def_new:Npn \seq_gput_right:Nn {
%<*check>
\pref_global_chk:
%</check>
-%<_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}
-%</package>
+%</initex|package>
%<*showmemory>
%\showMemUsage
%</showmemory>
% \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.
+%%
+%% -----------------------------------------------------------------------
+%
+%<package>\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
+%</dtx>
+%\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}
+%</driver>
+% \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" <skip>
+% \end{syntax}
+% Defines <skip> 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" <skip>
+% \end{syntax}
+% Locally or globally reset <skip> 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" <skip> "{" <skip value> "}"
+% \end{syntax}
+% These functions will set the <skip> register to the <length> value.
+% \end{function}
+%
+%
+% \begin{function}{%
+% \skip_add:Nn |
+% \skip_add:cn |
+% \skip_gadd:Nn |
+% }
+% \begin{syntax}
+% "\skip_add:Nn" <skip> "{" <length> "}"
+% \end{syntax}
+% These functions will add to the <skip> register the value <length>. If
+% the second argument is a <skip> register too, the surrounding braces
+% can be left out.
+% \end{function}
+%
+% \begin{function}{%
+% \skip_sub:Nn |
+% \skip_gsub:Nn |
+% }
+% \begin{syntax}
+% "\skip_gsub:Nn" <skip> "{" <length> "}"
+% \end{syntax}
+% These functions will subtract from the <skip> register the value
+% <length>. If the second argument is a <skip> register too, the
+% surrounding braces can be left out.
+% \end{function}
+%
+% \begin{function}{%
+% \skip_use:N |
+% \skip_use:c |
+% }
+% \begin{syntax}
+% "\skip_use:N" <skip>
+% \end{syntax}
+% This function returns the length value kept in <skip> 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> \\
+% "\skip_horizontal:n" "{" <length> "}"
+% \end{syntax}
+% The "hor" functions insert <skip> or <length> with the \TeX\
+% primitive \tn{hskip}. The "vertical" variants do the same with
+% \tn{vskip}. The "n" versions evaluate <length> with "\skip_eval:n".
+% \end{function}
+%
+%
+% \begin{function}{%
+% \skip_infinite_glue:nTF |
+% }
+% \begin{syntax}
+% "\skip_infinite_glue:nTF" "{"<skip>"}" "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Checks if <skip> contains infinite stretch or shrink components
+% and executes either <true> or <false>. 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" "{"<skip>"}" "{"<action>"}"
+% <dimen1> <dimen2>
+% \end{syntax}
+% Checks if <skip> contains finite glue. If it does then it assigns
+% <dimen1> the stretch component and <dimen2> the shrink component. If
+% it contains infinite glue set <dimen1> and <dimen2> 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" "{"<skip expr>"}"
+% \end{syntax}
+% Evaluates the value of <skip expr> 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 <skip>
+% 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" <dim>
+% \end{syntax}
+% Defines <dim> 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" <dim>
+% \end{syntax}
+% Locally or globally reset <dim> 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" <dim> "{" <dim value> "}"
+% \end{syntax}
+% These functions will set the <dim> register to the <dim value> value.
+% \end{function}
+%
+%
+% \begin{function}{%
+% \dim_add:Nn |
+% \dim_add:cn |
+% \dim_gadd:Nn |
+% }
+% \begin{syntax}
+% "\dim_add:Nn" <dim> "{" <length> "}"
+% \end{syntax}
+% These functions will add to the <dim> register the value <length>. If
+% the second argument is a <dim> register too, the surrounding braces
+% can be left out.
+% \end{function}
+%
+% \begin{function}{%
+% \dim_sub:Nn |
+% \dim_gsub:Nn |
+% }
+% \begin{syntax}
+% "\dim_gsub:Nn" <dim> "{" <length> "}"
+% \end{syntax}
+% These functions will subtract from the <dim> register the value
+% <length>. If the second argument is a <dim> register too, the
+% surrounding braces can be left out.
+% \end{function}
+%
+% \begin{function}{%
+% \dim_use:N |
+% \dim_use:c |
+% }
+% \begin{syntax}
+% "\dim_use:N" <dim>
+% \end{syntax}
+% This function returns the length value kept in <dim> 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" "{"<dim expr>"}"
+% \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" <dimen1> <rel> <dimen2> <true> "\else:" <false> "\fi:"
+% \end{syntax}
+% Compare two dimensions. It is recommended to use "\dim_eval:n" to
+% correctly evaluate and terminate these numbers. <rel> 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" "{"<dim~expr>"}" <rel> "{"<dim~expr>"}"
+% "{"<true>"}" "{"<false>"}"
+% \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" "{"<dim~expr>"}" <rel> "{"<dim~expr>"}"
+% \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" <dim expr> <rel> <dim~expr> <true>
+% \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 <dim>
+% 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" <muskip>
+% \end{syntax}
+% Defines <muskip> 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" <muskip> "{" <muskip value> "}"
+% \end{syntax}
+% These functions will set the <muskip> register to the <length>
+% value.
+% \end{function}
+%
+%
+% \begin{function}{%
+% \muskip_add:Nn |
+% \muskip_gadd:Nn |
+% }
+% \begin{syntax}
+% "\muskip_add:Nn" <muskip> "{" <length> "}"
+% \end{syntax}
+% These functions will add to the <muskip> register the value
+% <length>. If the second argument is a <muskip> register too, the
+% surrounding braces can be left out.
+% \end{function}
+%
+% \begin{function}{%
+% \muskip_sub:Nn |
+% \muskip_gsub:Nn |
+% }
+% \begin{syntax}
+% "\muskip_gsub:Nn" <muskip> "{" <length> "}"
+% \end{syntax}
+% These functions will subtract from the <muskip> register the value
+% <length>. If the second argument is a <muskip> 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}
+%<package&!check>\RequirePackage{l3int}
+%<package&!check>\RequirePackage{l3prg}
+%<package&check>\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 }
+%</initex>
+%<package>\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
+%</check>
+}
+\def_new:Npn \skip_gset:Nn {
+%<*check>
+ \pref_global_chk:
+%</check>
+%<-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
+%</check>
+}
+\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>
+%<-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 <skip>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
+%</check>
+}
+\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
+%</check>
+}
+\def_new:Npn \skip_gadd:Nn {
+%<*check>
+ \pref_global_chk:
+%</check>
+%<-check> \pref_global:D
+ \skip_add:Nn }
+\def_new:Npn \skip_gsub:Nn {
+%<*check>
+ \pref_global_chk:
+%</check>
+%<-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}
+%</!package>
+%<*!initex>
+\let:NN \c_zero_skip \z@
+\let:NN \c_max_skip \maxdimen
+%</!initex>
+% \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 }
+%</initex>
+%<package>\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}
+%</initex>
+%<package>\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}
+%</initex|package>
+% \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.
+%%
+%% -----------------------------------------------------------------------
%
+%<package>\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
%</dtx>
-%<package>\NeedsTeXFormat{LaTeX2e}
-%<package>\ProvidesPackage{l3tlp}
-%<driver> \ProvidesFile{l3tlp.drv}
-% \fi
-% \ProvidesFile{l3tlp.dtx}
- [1998/04/20 v1.0d L3 Experimental Token List Pointers]
+%\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" <tlp> "{" <initial token list> "}"
% \end{syntax}
-% Defines <varible> to be a new variable (or constant) of type token
-% list pointer. <initial token list> is the initial value of
-% <tlp>. This makes it possible to assign values to a constant
-% token list pointer.
+% Defines <tlp> to be a new variable (or constant) of type token list
+% pointer. <initial token list> is the initial value of <tlp>. This
+% makes it possible to assign values to a constant token list pointer.
% \end{function}
-%
+%
+% \begin{function}{%
+% \tlp_use:N |
+% \tlp_use:c
+% }
+% \begin{syntax}
+% "\tlp_use:N" <tlp>
+% \end{syntax}
+% Function that inserts the <tlp> into the processing stream.
+% \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" <tlp> "{" <token list> "}"
% \end{syntax}
% Defines <tlp> to hold the token list <token list>. Global
% variants of this command assign the value globally the other variants
% expand the <token list> up to a certain level before the assignment
-% or interpret the <tokenlist> as a character list and form a control
+% or interpret the <token list> as a character list and form a control
% sequence out of it.
% \end{function}
-%
+%
% \begin{function}{%
% \tlp_clear:N |
% \tlp_clear:c |
@@ -84,10 +139,12 @@
% generate a control sequence name which is then interpreted as
% <tlp> before clearing.
% \end{function}
-%
+%
% \begin{function}{%
% \tlp_clear_new:N |
% \tlp_clear_new:c |
+% \tlp_gclear_new:N |
+% \tlp_gclear_new:c |
% }
% \begin{syntax}
% "\tlp_clear_new:N" <tlp>
@@ -95,28 +152,37 @@
% These functions check if <tlp> exists. If it does it will be cleared;
% if it doesn't it will be allocated.
% \end{function}
-%
+%
% \begin{function}{%
% \tlp_put_left:Nn |
% \tlp_put_left:No |
% \tlp_gput_left:Nn |
% \tlp_gput_left:No |
+% \tlp_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" <tlp> "{" <token list> "}"
% \end{syntax}
% These functions will append <token list> to the left or right of
-% <tlp>. Assigment is done either locally or globally and <token
-% list> might be subject to expansion before assigment.
+% <tlp>. Assignment is done either locally or globally and <token
+% list> 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" <tlp1> <tlp2>
@@ -127,7 +193,7 @@
% \end{syntax}
% when <tlp2> is known to be a variable of type token list pointer.
% \end{function}
-%
+%
% \begin{function}{\tlp_to_str:N |
% \tlp_to_str:c
% }
@@ -137,36 +203,240 @@
% This function returns the token list kept in <tlp> as a string list
% with all characters catcoded to `other'.
% \end{function}
-%
+%
% \subsection{Predicates and conditionals}
-%
-% \begin{function}{\tlp_empty_p:N}
+%
+% \begin{function}{\tlp_if_empty_p:N|
+% \tlp_if_empty_p:c
+% }
% \begin{syntax}
-% "\tlp_empty_p:N" <tlp>
+% "\tlp_if_empty_p:N" <tlp>
% \end{syntax}
% This predicate returns `true' if <tlp> is `empty' i.e., doesn't
% contain any tokens.
% \end{function}
-%
-% \begin{function}{\tlp_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> "{"<false code>"}"
+% "\tlp_if_empty:NTF" <tlp> "{"<true code>"}""{"<false code>"}"
% \end{syntax}
-% Execute <false code> if <tlp> is empty.
-% contain any tokens.
+% Execute <true code> if <tlp> is empty and <false code> 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" <tlp1> <tlp2> "{"<false code>"}"
+% "\tlp_if_eq_p:NN" <tlp1> <tlp2>
% \end{syntax}
-% Execute <false code> if <tlp1> doesn't hold the same token list as
-% <tlp2>.
+% 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" <tlp1> <tlp2> "{"<true code>"}""{"<false code>"}"
+% \end{syntax}
+% Execute <true code> if <tlp1> holds the same token list as <tlp2>
+% and <false code> otherwise.
+% \end{function}
+%
+%
+% \subsection{Token lists}
+%
+% \begin{function}{\tlist_if_eq:nnTF |
+% \tlist_if_eq:nnT |
+% \tlist_if_eq:nnF |
+% \tlist_if_eq:noTF |
+% \tlist_if_eq:noT |
+% \tlist_if_eq:noF |
+% }
+% \begin{syntax}
+% "\tlist_if_eq:nnTF" "{"<tlist1>"}" "{"<tlist2>"}" "{"<true
+% code>"}" "{"<false code>"}"
+% \end{syntax}
+% Execute <true code> if the two token lists <tlist1> and <tlist2> are
+% identical.
+% \end{function}
+%
+%
+% \begin{function}{\tlist_if_empty_p:n |
+% \tlist_if_empty_p:o |
+% \tlist_if_empty:nTF |
+% \tlist_if_empty:nT |
+% \tlist_if_empty:nF |
+% \tlist_if_empty:oTF |
+% \tlist_if_empty:oT |
+% \tlist_if_empty:oF |
+% }
+% \begin{syntax}
+% "\tlist_if_empty:nTF" "{"<tlist>"}" "{"<true code>"}" "{"<false code>"}"
+% \end{syntax}
+% Execute <true code> if <tlist> doesn't contain any tokens and <false
+% code> otherwise.
+% \end{function}
+%
+% \begin{function}{\tlist_if_blank_p:n |
+% \tlist_if_blank:nTF |
+% \tlist_if_blank:nT |
+% \tlist_if_blank:nF |
+% \tlist_if_blank_p:o |
+% \tlist_if_blank:oTF |
+% \tlist_if_blank:oT |
+% \tlist_if_blank:oF |
+% }
+% \begin{syntax}
+% "\tlist_if_blank:nTF" "{"<tlist>"}" "{"<true code>"}" "{"<false code>"}"
+% \end{syntax}
+% Execute <true code> if <tlist> is blank meaning that it is either
+% empty or contains only blank spaces.
+% \end{function}
+%
+% \begin{function}{\tlist_to_lowercase:n |
+% \tlist_to_uppercase:n
+% }
+% \begin{syntax}
+% "\tlist_to_lowercase:n" "{"<tlist>"}"
+% \end{syntax}
+% "\tlist_to_lowercase:n" converts all tokens in <tlist> to their
+% lower case representation. Similar for "\tlist_to_uppercase:n".
+% \begin{texnote}
+% These are the \TeX\ primitives \tn{lowercase} and \tn{uppercase}
+% renamed.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{\tlist_to_str:n
+% }
+% \begin{syntax}
+% "\tlist_to_str:n" "{"<tlist>"}"
+% \end{syntax}
+% This function turns its argument into a string where all characters
+% have catcode `other'.
+% \begin{texnote}
+% This is the \eTeX\ primitive \tn{detokenize}.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+% \tlist_map_function:nN |
+% \tlp_map_function:NN |
+% \tlp_map_function:cN |
+% }
+% \begin{syntax}
+% "\tlist_map_function:nN" "{"<tlist>"}" <function> \\
+% "\tlp_map_function:NN" <tlp> <function>
+% \end{syntax}
+% Runs through all elements in a |tlist| from left to right and places
+% <function> in front of each element. As this function will also pick
+% up elements in brace groups, the element is returned with braces and
+% hence <function> should be a function with a |:n| suffix even though
+% it may very well only deal with a single token. This function uses a
+% purely expandable loop function and will stay so as long as
+% <function> is expandable too.
+% \end{function}
+%
+% \begin{function}{%
+% \tlist_map_inline:nn |
+% \tlp_map_inline:Nn |
+% \tlp_map_inline:cn |
+% }
+% \begin{syntax}
+% "\tlist_map_inline:nn" "{"<tlist>"}" "{"<inline~function>"}" \\
+% "\tlp_map_inline:Nn" <tlp> "{"<inline~function>"}"
+% \end{syntax}
+% Allows a syntax like "\tlist_map_inline:nn" "{"<tlist>"}"
+% "{\token_to_string:N ##1}". This renders it non-expandable though.
+% Remember to double the "#"s for each level.
+% \end{function}
+%
+%
+% \begin{function}{%
+% \tlist_map_variable:nNn |
+% \tlp_map_variable:NNn |
+% \tlp_map_variable:cNn |
+% }
+% \begin{syntax}
+% "\tlist_map_variable:nNn" "{"<tlist>"}" <temp> "{"<action>"}" \\
+% "\tlp_map_variable:NNn" <tlp> <temp> "{"<action>"}"
+% \end{syntax}
+% Assigns <temp> to each element on <tlist> and executes <action>.
+% As there is an assignment in this process it is not expandable.
+% \begin{texnote}
+% This is the \LaTeX2{} function \tn{@tfor} but with a more sane syntax.
+% Also it works by tail recursion and so is faster as lists grow longer.
+% \end{texnote}
+% \end{function}
+%
+% \begin{function}{%
+% \tlist_map_break:w |
+% \tlp_map_break:w |
+% }
+% \begin{syntax}
+% "\tlist_map_break:w"
+% \end{syntax}
+% For breaking out of a loop. You should take note of the ":w" as
+% its usage must be precise!
+% \end{function}
+%
+%
+% \begin{function}{%
+% \tlist_reverse:n |
+% }
+% \begin{syntax}
+% "\tlist_reverse:n" "{"<token$\sb1$><token$\sb2$>...<token$\sb n$>"}"
+% \end{syntax}
+% Reverse the token list to result in
+% <token$\sb n$>\dots<token$\sb2$><token$\sb1$>. Note that spaces in this
+% token list are gobbled in the process.
+% \end{function}
+%
+%
+%
+% \subsubsection{Internal functions}
+%
+%
+% \begin{function}{%
+% \tlist_map_function_aux:Nn |
+% \tlist_map_inline_aux:Nn |
+% \tlist_map_variable_aux:Nnn |
+% }
+% \begin{syntax}\end{syntax}
+% Internal helper functions for the <tlist> loops.
+% \end{function}
+%
+%
+%
+% \begin{function}{\tlist_if_blank_p_aux:w
+% }
+% \end{function}
+%
+%
+%
+% \subsection{Variables and constants}
+%
% \begin{variable}{\C_job_name_tlp}
% Constant that gets the `job name' assigned when \TeX{} starts.
% \begin{texnote}
@@ -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" <tlp> "{" <item> "}{" <true code> "}{"
+% <false code> "}"
+% \end{syntax}
+% Function that tests if <item> is in <tlp>. Depending on the result
+% either <true code> or <false code> is executed. Note that <item>
+% cannot contain brace groups.
+% \end{function}
+%
+% \begin{function}{
+% \tlp_replace_in:Nnn |
+% \tlp_replace_in:cnn |
+% \tlp_greplace_in:Nnn |
+% \tlp_greplace_in:cnn |
+% }
+% \begin{syntax}
+% "\tlp_replace_in:Nnn" <tlp> "{" <item1> "}{" <item2> "}"
+% \end{syntax}
+% Replaces the leftmost occurrence of <item1> in <tlp> with
+% <item2> if present, otherwise the <tlp> is left untouched.
+% \end{function}
+%
+% \begin{function}{
+% \tlp_replace_all_in:Nnn |
+% \tlp_replace_all_in:cnn |
+% \tlp_greplace_all_in:Nnn |
+% \tlp_greplace_all_in:cnn |
+% }
+% \begin{syntax}
+% "\tlp_replace_all_in:Nnn" <tlp> "{" <item1> "}{" <item2> "}"
+% \end{syntax}
+% Replaces \emph{all} occurrences of <item1> in <tlp> with
+% <item2>.
+% \end{function}
+%
+%
+% \begin{function}{
+% \tlp_remove_in:Nn |
+% \tlp_remove_in:cn |
+% \tlp_gremove_in:Nn |
+% \tlp_gremove_in:cn |
+% }
+% \begin{syntax}
+% "\tlp_remove_in:Nn" <tlp> "{" <item> "}"
+% \end{syntax}
+% Removes the leftmost occurrence of <item> from <tlp> if present.
+% \end{function}
+%
+%
+% \begin{function}{
+% \tlp_remove_all_in:Nn |
+% \tlp_remove_all_in:cn |
+% \tlp_gremove_all_in:Nn |
+% \tlp_gremove_all_in:cn |
+% }
+% \begin{syntax}
+% "\tlp_remove_all_in:Nn" <tlp> "{" <item> "}"
+% \end{syntax}
+% Removes \emph{all} occurrences of <item> from <tlp>.
+% \end{function}
+%
+%
+% \subsection{Heads or tails?}
+%
+% Here are some functions for grabbing either the head or tail of a
+% list and perform some tests on it.
%
+% \begin{function}{%
+% \tlist_head:n |
+% \tlist_tail:n |
+% \tlist_head_iii:n |
+% \tlist_head_iii:f |
+% \tlist_head:w |
+% \tlist_tail:w |
+% \tlist_head_iii:w
+% }
+% \begin{syntax}
+% "\tlist_head:n" "{" <token1><token2>...<token-n> "}" \\
+% "\tlist_tail:n" "{" <token1><token2>...<token-n> "}"
+% \end{syntax}
+% These functions return either the head or the tail of a list, thus in
+% the above example "\tlist_head:n" would return <token1> and "\tlist_tail:n"
+% would return <token2>\dots<token-n>. "\tlist_head_iii:n" returns the first
+% three tokens. The ":w" versions require some care as they use a
+% delimited argument internally.
+% \begin{texnote}
+% These are the Lisp functions "car" and "cdr" but with \LaTeX3 names.
+% \end{texnote}
+% \end{function}
+%
+%
+%
+%
+% \begin{function}{%
+% \tlist_if_head_eq_meaning_p:nN |
+% \tlist_if_head_eq_meaning:nNTF |
+% \tlist_if_head_eq_meaning:nNTF |
+% \tlist_if_head_eq_meaning:nNTF |
+% }
+% \begin{syntax}
+% "\tlist_if_head_eq_meaning:nNTF" "{" <token list> "}" <token>
+% "{"<true>"}""{"<false>"}"
+% \end{syntax}
+% Returns <true> if the first token in <token list> is equal to
+% <token> and <false> otherwise. The |meaning| version compares the
+% two tokens with |\if_meaning:NN|.
+% \end{function}
+%
+% \begin{function}{%
+% \tlist_if_head_eq_charcode_p:nN |
+% \tlist_if_head_eq_charcode:nNTF |
+% \tlist_if_head_eq_charcode:nNTF |
+% \tlist_if_head_eq_charcode:nNTF |
+% }
+% \begin{syntax}
+% "\tlist_if_head_eq_charcode:nNTF" "{" <token list> "}" <token>
+% "{"<true>"}""{"<false>"}"
+% \end{syntax}
+% Returns <true> if the first token in <token list> is equal to
+% <token> and <false> otherwise. The |meaning| version compares the
+% two tokens with |\if_charcode:w| but it prevents expansion of
+% them. If you want them to expand, you can use an |f| type expansion
+% first (define |\tlist_if_head_eq_charcode:fNTF| or similar).
+% \end{function}
+%
+% \begin{function}{%
+% \tlist_if_head_eq_catcode_p:nN |
+% \tlist_if_head_eq_catcode:nNTF |
+% \tlist_if_head_eq_catcode:nNTF |
+% \tlist_if_head_eq_catcode:nNTF |
+% }
+% \begin{syntax}
+% "\tlist_if_head_eq_catcode:nNTF" "{" <token list> "}" <token>
+% "{"<true>"}""{"<false>"}"
+% \end{syntax}
+% Returns <true> if the first token in <token list> is equal to
+% <token> and <false> otherwise. This version uses |\if_catcode:w| for
+% the test but is otherwise identical to the |charcode| version.
+% \end{function}
+%
+%
% \StopEventually{}
%
-% \section{The code}
-%
+% \subsection{The Implementation}
+%
% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
-%<package&!check>\RequirePackage{l3basics}\par
-%<package&check>\RequirePackage{l3chk}\par
-%<*package>
+%<package&!check>\RequirePackage{l3basics}
+%<package&check>\RequirePackage{l3chk}
+% \end{macrocode}
+% \begin{macrocode}
+%<*initex|package>
% \end{macrocode}
%
% A token list pointer is a control sequence that holds tokens. The
@@ -224,48 +668,211 @@
% 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}
+% If checking we don't allow constants to be defined.
+% \begin{macrocode}
+%<*check>
+ \chk_var_or_const:N #1
+%</check>
+% \end{macrocode}
+% Otherwise any variable type is allowed.
+% \begin{macrocode}
+ \gdef:Npn #1{#2}
+}
+\def_new:Npn \tlp_new:cn {\exp_args:Nc \tlp_new:Nn }
+\def_long_new:Npn \tlp_new:Nx #1#2{
+ \chk_new_cs:N #1
+%<check> \chk_var_or_const:N #1
+ \gdef:Npx #1{#2}
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\tlp_use:N}
+% \begin{macro}{\tlp_use:c}
+% Perhaps this should just be enabled when checking?
+% \begin{macrocode}
+\def_new:Npn \tlp_use:N #1 {
+ \if_meaning:NN #1 \scan_stop:
+% \end{macrocode}
+% If \m{tlp} equals |\scan_stop:| it is probably stemming from a
+% |\cs:w ... \cd_end:| that was created by mistake somewhere.
+% \begin{macrocode}
+ \err_latex_bug:x {Token~list~pointer~ `\token_to_string:N #1'~
+ has~ an~ erroneous~ structure!}
+ \else:
+ \exp_after:NN #1
+ \fi:
+}
+\def_new:Npn \tlp_use:c {\exp_args:Nc \tlp_use:N}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\tlp_set:Nn}
+% \begin{macro}{\tlp_set:No}
+% \begin{macro}{\tlp_set: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_set:Nn #1#2{
+ \chk_exist_cs:N #1 \def:Npn #1{#2}
+% \end{macrocode}
+% We use |\chk_local_or_pref_global:N| after the assignment to
+% allow constructs with |\pref_global_chk:|. But one should note
+% that this is less efficient then using the real global variant
+% since they are built-in.
+% \begin{macrocode}
+ \chk_local_or_pref_global:N #1
+}
+\def_long_new:Npn \tlp_set:Nx #1#2{
+ \chk_exist_cs:N #1 \def:Npx #1{#2} \chk_local:N #1
+}
% \end{macrocode}
-% The next line contains the token list assignments without any
-% checking for variable types etc.\ since we want to allow to
-% update constants here.
+% The the global versions.
% \begin{macrocode}
- \gdef:Npn #1{#2}}
+\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>
-%<-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}
+% For some functions like |\tlp_set:Nn| we need to define the
+% `non-check' version with arguments since we want to allow
+% constructions like |\tlp_set:Nn\l_tmpa_tlp\foo| and so we can't
+% use the primitive \TeX{} command.
+% \begin{macrocode}
+%<*!check>
+\def_long_new:Npn\tlp_set:Nn#1#2{\def:Npn#1{#2}}
+\def_long_new:Npn\tlp_set:Nx#1#2{\def:Npx#1{#2}}
+\def_long_new:Npn\tlp_gset:Nn#1#2{\gdef:Npn#1{#2}}
+\def_long_new:Npn\tlp_gset:Nx#1#2{\gdef:Npx#1{#2}}
+%</!check>
+% \end{macrocode}
+% The remaining functions can just be defined with help from the
+% expansion module.
+% \begin{macrocode}
+\def_new:Npn \tlp_set:No {\exp_args:NNo \tlp_set:Nn}
+\def_new:Npn \tlp_set: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}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\tlp_set_eq:NN}
+% \begin{macro}{\tlp_set_eq:Nc}
+% \begin{macro}{\tlp_set_eq:cN}
+% \begin{macro}{\tlp_set_eq:cc}
+% \begin{macro}{\tlp_gset_eq:NN}
+% \begin{macro}{\tlp_gset_eq:Nc}
+% \begin{macro}{\tlp_gset_eq:cN}
+% \begin{macro}{\tlp_gset_eq:cc}
+% For setting token list pointers equal to each other. First checking:
+% \begin{macrocode}
+%<*check>
+\def_new:Npn \tlp_set_eq:NN #1#2{
+ \chk_exist_cs:N #1 \let:NN #1#2
+ \chk_local_or_pref_global:N #1 \chk_var_or_const:N #2
+}
+\def_new:Npn \tlp_gset_eq:NN #1#2{
+ \chk_exist_cs:N #1 \glet:NN #1#2
+ \chk_global:N #1 \chk_var_or_const:N #2
+}
+%</check>
+% \end{macrocode}
+% Non-checking versions are easy.
+% \begin{macrocode}
+%<*!check>
+\let_new:NN \tlp_set_eq:NN \let:NN
+\let_new:NN \tlp_gset_eq:NN \glet:NN
+%</!check>
+% \end{macrocode}
+% The rest again with the expansion module.
+% \begin{macrocode}
+\def_new:Npn \tlp_set_eq:Nc {\exp_args:NNc \tlp_set_eq:NN}
+\def_new:Npn \tlp_set_eq:cN {\exp_args:Nc \tlp_set_eq:NN}
+\def_new:Npn \tlp_set_eq:cc {\exp_args:Ncc \tlp_set_eq:NN}
+\def_new:Npn \tlp_gset_eq:Nc {\exp_args:NNc \tlp_gset_eq:NN}
+\def_new:Npn \tlp_gset_eq:cN {\exp_args:Nc \tlp_gset_eq:NN}
+\def_new:Npn \tlp_gset_eq:cc {\exp_args:Ncc \tlp_gset_eq:NN}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\tlp_clear:N}
% \begin{macro}{\tlp_clear:c}
+% \begin{macro}{\tlp_gclear:N}
% \begin{macro}{\tlp_gclear:c}
-% We also define the variants that construct the token list name
-% from a string.
+% 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}
@@ -273,16 +880,17 @@
% is cleared, if it doesn't it is allocated.
% \begin{macrocode}
%<*check>
-\def_long_new:Npn \tlp_clear_new:N #1{
- \chk_var_or_const:N #1
- \if:w \cs_exist_p:N #1
- \tlp_clear:N #1
- \else:
- \tlp_new:Nn #1{}
- \fi:}
+\def_new:Npn \tlp_clear_new:N #1{
+ \chk_var_or_const:N #1
+ \if:w \cs_exist_p:N #1
+ \tlp_clear:N #1
+ \else:
+ \tlp_new:Nn #1{}
+ \fi:
+}
%</check>
%<-check>\let_new:NN \tlp_clear_new:N \tlp_clear:N
-\def_long_new:Npn \tlp_clear_new:c {\exp_args:Nc \tlp_clear_new:N}
+\def_new:Npn \tlp_clear_new:c {\exp_args:Nc \tlp_clear_new:N}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -292,16 +900,16 @@
% These are the global versions of the above.
% \begin{macrocode}
%<*check>
-\def_long_new:Npn \tlp_gclear_new:N #1{
- \chk_var_or_const:N #1
- \if:w \cs_exist_p:N #1
- \tlp_gclear:N #1
- \else:
- \tlp_new:Nn #1{}
- \fi:}
+\def_new:Npn \tlp_gclear_new:N #1{
+ \chk_var_or_const:N #1
+ \if:w \cs_exist_p:N #1
+ \tlp_gclear:N #1
+ \else:
+ \tlp_new:Nn #1{}
+ \fi:}
%</check>
%<-check>\let_new:NN \tlp_gclear_new:N \tlp_gclear:N
-\def_long_new:Npn \tlp_gclear_new:c {\exp_args:Nc \tlp_gclear_new:N}
+\def_new:Npn \tlp_gclear_new:c {\exp_args:Nc \tlp_gclear_new:N}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -310,30 +918,33 @@
% \begin{macro}{\tlp_put_left:No}
% \begin{macro}{\tlp_gput_left:Nn}
% \begin{macro}{\tlp_gput_left:No}
-% \begin{macro}{\tlp_put_left:aux}
+% \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}
-\def_long_new:Npn \tlp_put_left:Nn #1{\exp_after: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}
- \tlp_put_left:aux\exp_after:NN{#1}#1}
+ \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_long_new:Npn \tlp_gput_left:Nn {
+\def_new:Npn \tlp_gput_left:Nn {
%<*check>
\pref_global_chk:
%</check>
%<-check> \pref_global:D
- \tlp_put_left:Nn}
+ \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}
+\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
+ \chk_local_or_pref_global:N #2
%</check>
}
% \end{macrocode}
@@ -342,6 +953,7 @@
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
%
% \begin{macro}{\tlp_put_right:Nn}
% \begin{macro}{\tlp_put_right:No}
@@ -349,6 +961,8 @@
% \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.
@@ -357,6 +971,8 @@
\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}
@@ -368,85 +984,11 @@
% \end{macro}
% \end{macro}
% \end{macro}
-%
-%
-% \begin{macro}{\tlp_set:Nn}
-% \begin{macro}{\tlp_set:No}
-% \begin{macro}{\tlp_set:Nx}
-% \begin{macro}{\tlp_gset:Nn}
-% \begin{macro}{\tlp_gset:No}
-% \begin{macro}{\tlp_gset:Nx}
-% \begin{macro}{\tlp_set_eq:NN}
-% \begin{macro}{\tlp_gset_eq:NN}
-% To set token lists to a specific value to type of functions are
-% available: |\tlp_set_eq:NN| takes two token-lists as its
-% arguments assign the first the contents of the second;
-% |\tlp_set:Nn| has as its second argument a `real' list of tokens.
-% One can view |\tlp_set_eq:NN| as a special form of |\tlp_set:No|
-% (which is not implemented). Both functions have global
-% counterparts.
-%
-% During development we check if the token list that is being
-% assigned to exists. If not, a warning will be issued.
-% \begin{macrocode}
-%<*check>
-\def_long_new:Npn \tlp_set:Nn #1#2{
- \chk_exist_cs:N #1
- \def:Npn #1{#2}
-% \end{macrocode}
-% We use |\chk_local_or_pref_global:N| after the assignment to
-% allow constructs with |\pref_global_chk:|. But one should note
-% that this is less efficient then using the real global variant
-% since they are builtin.
-% \begin{macrocode}
- \chk_local_or_pref_global:N #1}
-\def_long_new:Npn \tlp_set:No {
- \exp_args:NNo \tlp_set:Nn}
-\def_long_new:Npn \tlp_set:Nx #1#2{
- \chk_exist_cs:N #1
- \def:Npx #1{#2}\chk_local:N #1}
-\def_long_new:Npn \tlp_gset:Nn #1#2{
- \chk_exist_cs:N #1
- \gdef:Npn #1{#2}\chk_global:N #1}
-\def_long_new:Npn \tlp_gset:No {
- \exp_args:NNo \tlp_gset:Nn}
-\def_long_new:Npn \tlp_gset:Nx #1#2{
- \chk_exist_cs:N #1
- \gdef:Npx #1{#2}\chk_global:N #1}
-\def_long_new:Npn \tlp_set_eq:NN #1#2{
- \chk_exist_cs:N #1
- \let:NwN #1#2
- \chk_local_or_pref_global:N #1\chk_var_or_const:N #2}
-\def_long_new:Npn \tlp_gset_eq:NN #1#2{
- \chk_exist_cs:N #1
- \glet:NN #1#2
- \chk_global:N #1\chk_var_or_const:N #2}
-%</check>
-% \end{macrocode}
-% For some functions like |\tlp_set:Nn| we need to define the
-% `non-check' version with arguments since we want to allow
-% constructions like |\tlp_set:Nn\l_tmpa_tlp\foo| and so we can't
-% use the primitive \TeX{} command.
-% \begin{macrocode}
-%<-check> \def_new:Npn\tlp_set:Nn#1#2{\def:Npn#1{#2}}
-%<-check> \def_new:Npn\tlp_set:Nx#1#2{\def:Npx#1{#2}}
-%<-check> \def_new:Npn\tlp_gset:Nn#1#2{\gdef:Npn#1{#2}}
-%<-check> \def_new:Npn\tlp_gset:Nx#1#2{\gdef:Npx#1{#2}}
-%<-check> \let_new:NN\tlp_set:No\def:No
-%<-check> \let_new:NN\tlp_gset:No\gdef:No
-%<-check> \let_new:NN\tlp_set_eq:NN\let:NwN
-%<-check> \let_new:NN\tlp_gset_eq:NN\glet:NN
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
% \end{macro}
% \end{macro}
%
%
+%
% \begin{macro}{\tlp_gset:Nc}
% \begin{macro}{\tlp_set:Nc}
% These two functions are included because they are necessary in
@@ -459,10 +1001,10 @@
% \begin{macrocode}
\def_new:Npn \tlp_gset:Nc {
%<*check>
- \pref_global_chk:
+ \pref_global_chk:
%</check>
%<-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}
+%<package>\RequirePackage{l3expan}
+%<package>\RequirePackage{l3num}\par
+% \end{macrocode}
% Show token usage:
% \begin{macrocode}
-%</package>
+%</initex|package>
%<*showmemory>
\showMemUsage
%</showmemory>
% \end{macrocode}
%
+% \endinput
+%
+% $Log$
+% Revision 1.28 2006/07/30 15:51:53 morten
+% Made \tlist_map_inline:nn and variants nestable. Reimplemented
+% \tlp_if_in:..., \tlp_replace_in:..., \tlp_replace_all_in:...
+%
+% Revision 1.27 2006/07/25 15:32:48 morten
+% More \tlist_if_blank functions
+%
+% Revision 1.26 2006/07/06 14:58:50 morten
+% Documentation touch-ups. Added more functions plus some new comparison
+% functions which are dependent on a reasonably new pdfTeX.
+%
+% Revision 1.25 2006/06/05 14:55:14 morten
+% Function for reversing a list of tokens.
+%
+% Revision 1.24 2006/06/03 16:31:19 morten
+% Another version of \tlist_head...
+%
+% Revision 1.23 2006/03/20 18:26:41 braams
+% Updated the copyright notice (2006) and demoted all implementation
+% sections to subsections and so on to clean up the toc for source3.tex
+%
+% Revision 1.22 2006/01/26 14:00:42 morten
+% Added a few missing functions (that were documented to be there!)
+%
+% Revision 1.21 2006/01/19 22:27:08 morten
+% Added \tlp_replace_ and \tlp_remove_if_in functions.
+%
+% Revision 1.20 2006/01/17 23:07:06 morten
+% Added "if_in" functions.
+%
+% Revision 1.19 2005/12/27 10:09:07 morten
+% Changed RCS information retrieval, imported all tlist functions since
+% half of them dealt with token list pointers anyway
+%
+% Revision 1.18 2005/07/25 19:50:40 morten
+% Fixed the \long-ness aspects.
+%
+% Revision 1.17 2005/04/12 16:43:03 morten
+% Minor updates
+%
+% Revision 1.16 2005/04/12 12:10:28 morten
+% Rearranged and cleaned up code to avoid much doubling.
+%
+% Revision 1.15 2005/04/06 21:34:07 morten
+% Fixed all tlp_set:XX so that they're \long. Added \tlp_set:Nf
+%
+% Revision 1.14 2005/03/22 23:20:43 morten
+% Fixed \long versions according to Benjamin's suggestions. Slightly reorganized.
+%
+% Revision 1.13 2005/03/16 22:35:41 braams
+% Added the tweaks necessary to be able to load with initex
+%
+% Revision 1.12 2005/03/11 21:43:58 braams
+% Fixed the use of RCS information;
+% Fixed a documentation typo
+%
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.
+%%
+%% -----------------------------------------------------------------------
+%<package>\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
+%</dtx>
+%\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}
+%</driver>
+% \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>"}" "{"<number>"}"\\
+% "\char_set_catcode:w" <char> = <number> \\
+% "\char_value_catcode:n" "{"<char>"}" \\
+% "\char_show_value_catcode:n" "{"<char>"}"
+% \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>"}" "{"<number>"}" \\
+% "\char_set_lccode:w" <char> = <number> \\
+% "\char_value_lccode:n" "{"<char>"}"\\
+% "\char_show_value_lccode:n" "{"<char>"}"
+% \end{syntax}
+% Set the lower caser representation of <char> for when <char> 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>"}" "{"<number>"}"\\
+% "\char_set_uccode:w" <char> = <number> \\
+% "\char_value_uccode:n" "{"<char>"}"\\
+% "\char_show_value_uccode:n" "{"<char>"}"
+% \end{syntax}
+% Set the uppercase representation of <char> for when <char> 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>"}" "{"<number>"}"\\
+% "\char_set_sfcode:w" <char> = <number> \\
+% "\char_value_sfcode:n" "{"<char>"}"\\
+% "\char_show_value_sfcode:n" "{"<char>"}"
+% \end{syntax}
+% Set the space factor for <char>.
+% \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" <token 1> "{"<token 2>"}"
+% \end{syntax}
+% Defines <token 1> to globally be a snapshot of <token 2>. This will
+% be an implicit representation of <token 2>.
+% \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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token1> <token2>"{"<true>"}""{"<false>"}"
+% \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" <token1> <token2>"{"<true>"}""{"<false>"}"
+% \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" <token1> <token2>"{"<true>"}""{"<false>"}"
+% \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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> is expandable or not. Note that <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> is a ``protected'' macro. This test does \emph{not}
+% return <true> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <token>
+% \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 <token>
+% 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" <token> "{"<true>"}" "{"<false>"}"
+% \end{syntax}
+% Check if <token> 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" <function><token>
+% \end{syntax}
+% Assign <token> to "\l_peek_token" and then run <function> which
+% should perform some sort of test on this token. Leaves <token> 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" <token> "{"<true>"}""{"<false>"}"
+% \end{syntax}
+% "\peek_meaning:NTF" checks (by using "\if_meaning:NN") if <token>
+% equals the next token in the input stream and executes either <true
+% code> or <false code> 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" <token> "{"<true>"}""{"<false>"}"
+% \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" <token> "{"<true>"}""{"<false>"}"
+% \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" <token><function> "{"<true>"}""{"<false>"}"
+% \end{syntax}
+% "\peek_token_generic:NNTF" looks ahead and checks if the next token
+% in the input stream is equal to <token>. It uses <function> to make
+% that decision. "\peek_token_remove_generic:NNTF" does the same
+% thing but additionally removes <token> from the input stream if it
+% is found. This also works if <token> 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}
+%<package>\RequirePackage{l3prg}
+%<package>\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}
+%</initex|package>
+%<*showmemory>
+\showMemUsage
+%</showmemory>
+% \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.
+%%
+%% -----------------------------------------------------------------------
%
+%<package>\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
%</dtx>
-%<package>\NeedsTeXFormat{LaTeX2e}
-%<package>\ProvidesPackage{l3toks}
-%<driver> \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 <toks> (token registers) and <tlp> (token
-% list pointers) is their behavior regarding expansion. While <tlp>'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|)
-% <toks>'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" <toks>
% \end{syntax}
% Defines <toks> 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 <toks> 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 @@
% <toks>. 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" <toks>
@@ -130,7 +175,7 @@
% Something like \tn{the} <toks>.
% \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>
% "\toks_clear:N" <toks> 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> "{"<true code>"}{"<false code>"}"
+% "\toks_if_empty:NTF" <toks> "{"<true code>"}{"<false code>"}"
% \end{syntax}
% Tests if <toks> 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 <cs> 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}
%<package&check>\RequirePackage{l3chk}\par
%<package>\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}
+%</initex>
+%<package>\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>
%<-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
%</check>
@@ -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}
+%<check>\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}}
+%<check>\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}
+%<check>\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}
%</check>
% \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}}
+%<check> \def_new:Npn \toks_set:No {\exp_args:NNo \toks_set:Nn}
+%<check> \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}
+%<check>\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>
%<-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
+%<initex>\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}
-%</package>
+%</initex|package>
%<*showmemory>
\showMemUsage
%</showmemory>
% \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.
+%%
+%% -----------------------------------------------------------------------
+%<package>\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
+%</dtx>
+%\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}
+%</driver>
+% \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~<return>~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>}
+%</initex>
+% \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.
+%%
+%% -----------------------------------------------------------------------
+%
+%<package>\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
+%<dtx> \ProvidesFile{#1.dtx}[#3/#4/#5 v#2 #8]%
+%<-dtx> \ProvidesFile{\jobname.tex}[#3/#4/#5 v#2 #8]%
+%\fi
+}
+%\iffalse
+%</dtx|testfile>
+%\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}
+%</driver>
+% \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" "{"<name>"}"
+% \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" "{"<type>"}" "{"<value>"}"
+% \end{syntax}
+% Defines a new cross reference type <type>. This defines the token
+% list pointer |\l_xref_curr_|<type>|_tlp| with default value
+% <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" "{"<type>"}" "{"<value>"}"
+% \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" "{"<type>"}" "{"<name>"}"
+% \end{syntax}
+% Extracts the cross reference information of type <type> for the
+% label <name>. 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}
+%</package>
+%<*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}
+%</initex|package>
+%<*showmemory>
+\showMemUsage
+%</showmemory>
+% \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}
+%</testfile>
+% \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 <Your-First-Name> <Your-Second-Name>
-
-
-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: