summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/expl3/l3basics.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/expl3/l3basics.dtx')
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3basics.dtx2792
1 files changed, 2265 insertions, 527 deletions
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}
-%
-