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.dtx3950
1 files changed, 2204 insertions, 1746 deletions
diff --git a/Master/texmf-dist/source/latex/expl3/l3basics.dtx b/Master/texmf-dist/source/latex/expl3/l3basics.dtx
index e34e42f2732..ecbafc5d6b9 100644
--- a/Master/texmf-dist/source/latex/expl3/l3basics.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3basics.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3basics.dtx Copyright (C) 1990-2006 LaTeX3 project
+%% File: l3basics.dtx Copyright (C) 1990-2008 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
@@ -17,7 +17,7 @@
%%
%% The development version of the bundle can be found at
%%
-%% http://www.latex-project.org/cgi-bin/cvsweb.cgi/
+%% http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
@@ -35,7 +35,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3basics.dtx 702 2007-11-27 14:21:49Z morten $
+\GetIdInfo$Id: l3basics.dtx 1365 2009-05-31 17:26:17Z mittelba $
{L3 Experimental basic definitions}
%\iffalse
%<*driver>
@@ -43,9 +43,9 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
-\DocInput{\filename.\filenameext}
+\DocInput{l3basics.dtx}
\end{document}
%</driver>
% \fi
@@ -59,41 +59,116 @@
% \date{\filedate}
% \maketitle
%
+% \begin{documentation}
%
% 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. With
+% Here we describe those functions that are 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}
+% \section{Predicates and conditionals}
+% \label{sec:predicates}
+%
+% \LaTeX3 has three concepts for conditional flow processing:
+% \begin{description}
+%
+% \item[Branching conditionals]
+% Functions that carry out a test and then execute, depending on its
+% 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_if_free:cTF{abc}" \Arg{true code} \Arg{false code}
+% \end{quote}
+% a function that will turn the first argument into a control sequence
+% (since it's marked as "c") then checks whether this control sequence
+% is still free and then depending on the result carry out the code in
+% the second argument (true case) or in the third argument (false
+% case).
+%
+% These type of functions are known as `conditionals'; whenever a "TF"
+% function is defined it will usually be accompanied by "T" and "F"
+% functions as well. These are provided for convenience when the
+% branch only needs to go a single way. Package writers are free to
+% choose which types to define but the kernel definitions will always
+% provide all three versions.
+%
+% Important to note is that these branching 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.
+%
+% These conditional functions may or may not be fully expandable, but if they
+% are expandable they will be accompanied by a `predicate' for the same test
+% as described below.
+%
+% \item[Predicates]
+% `Predicates' are functions that return a special type of boolean
+% value which can be tested by the function "\if_predicate:w"
+% or in the boolean expression parser. All functions of this type
+% are expandable and have names that end with "_p" in the
+% description part. For example,
+% \begin{quote}
+% "\cs_if_free_p:N"
+% \end{quote}
+% would be a predicate function for the same type of test as the
+% conditional described above. It would return `true' if its argument (a
+% single token denoted by "N") is still free for definition. It would be used
+% in constructions like
+% \begin{quote}
+% "\if_predicate:w \cs_if_free_p:N \l_tmpz_tl" \m{true code} "\else:"
+% \m{false code} "\fi:"
+% \end{quote}
+% or in expressions utilizing the boolean logic parser:
+% \begin{quote}
+% "\bool_if:nTF {" \\
+% " \cs_if_free_p:N \l_tmpz_tl || \cs_if_free_p:N \g_tmpz_tl " \\
+% "}"
+% \Arg{true code} \Arg{false code}
+% \end{quote}
%
-% \subsubsection{Primitive conditionals}
+% Like their branching cousins, predicate functions ensure that all
+% underlying primitive "\else:" or "\fi:" have been removed before
+% returning the boolean true or false values.\footnote{If defined
+% using the interface provided.}
+%
+% For each predicate defined, a `predicate conditional' will also exist that
+% behaves like a conditional described above.
+%
+% \item[Primitive conditionals]
+% There is a third variety of conditional, which is the original concept used in
+% plain \TeX{} and \LaTeX. Their use is discouraged in \pkg{expl3} (although
+% still used in low-level definitions) because they are more fragile and
+% in many cases require more expansion control (hence more code) than the two
+% types of conditionals described above.
+% \end{description}
+%
+%
+% \subsection{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|.
+% |\intexpr_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}{%
-% \if_true: |
-% \if_false: |
-% \else: |
-% \fi: |
-% \reverse_if:N |
-% }
+% \begin{function}{ \if_true: / (EXP) |
+% \if_false: / (EXP) |
+% \or: / (EXP) |
+% \else: / (EXP) |
+% \fi: / (EXP) |
+% \reverse_if:N / (EXP) }
% \begin{syntax}
% "\if_true:" <true code> "\else:" <false code> "\fi:" \\
% "\if_false:" <true code> "\else:" <false code> "\fi:" \\
@@ -101,37 +176,31 @@
% \end{syntax}
% "\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.
+% conditional. "\else:" and "\fi:" delimit the branches of the
+% conditional. "\or:" is used in case switches, see \pkg{l3intexpr}
+% for more.
+% \begin{texnote}
+% These are equivalent to their corresponding \TeX\ primitive
+% conditionals; |\reverse_if:N| is \eTeX's |\unless|.
+% \end{texnote}
% \end{function}
%
-% \begin{function}{%
-% \if_meaning:NN |
-% \if_cs_meaning_eq:NN |
-% \if_token_eq:NN |
-% }
+% \begin{function}{ \if_meaning:w / (EXP) }
% \begin{syntax}
-% "\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:"
+% "\if_meaning:w" <arg1> <arg2> <true code> "\else:" <false code> "\fi:"
% \end{syntax}
-% "\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.
+% "\if_meaning:w" executes <true code> when <arg1> and <arg2> are the same,
+% otherwise it executes <false code>.
+% <arg1> and <arg2> could be functions, variables, tokens; in all cases the
+% \emph{unexpanded} definitions are compared.
+% \begin{texnote}
+% This is \TeX's |\ifx|.
+% \end{texnote}
% \end{function}
%
-% \begin{function}{%
-% \if:w |
-% \if_charcode:w |
-% \if_catcode:w
-% }
+% \begin{function}{ \if:w / (EXP) |
+% \if_charcode:w / (EXP) |
+% \if_catcode:w / (EXP) }
% \begin{syntax}
% "\if:w" <token1> <token2> <true code> "\else:" <false code> "\fi:" \\
% "\if_catcode:w" <token1> <token2> <true code> "\else:" <false
@@ -145,10 +214,30 @@
% identical. "\if_charcode:w" is an alternative name for "\if:w".
% \end{function}
%
-% \begin{function}{%
-% \if_cs_exist:N |
-% \if_cs_exist:w
-% }
+%
+% \begin{function}{\if_predicate:w / (EXP)}
+% \begin{syntax}
+% "\if_predicate:w" <predicate> <true code> "\else:" <false code> "\fi:"
+% \end{syntax}
+% This function takes a predicate function and
+% branches according to the result. (In practice this function would also
+% accept a single boolean variable in place of the <predicate> but to make the
+% coding clearer this should be done through "\if_bool:N".)
+% \end{function}
+%
+%
+%
+% \begin{function}{\if_bool:N / (EXP)}
+% \begin{syntax}
+% "\if_bool:N" <boolean> <true code> "\else:" <false code> "\fi:"
+% \end{syntax}
+% This function takes a boolean variable and
+% branches according to the result.
+% \end{function}
+%
+%
+% \begin{function}{ \if_cs_exist:N / (EXP) |
+% \if_cs_exist:w / (EXP) }
% \begin{syntax}
% "\if_cs_exist:N" <cs> <true code> "\else:" <false code> "\fi:" \\
% "\if_cs_exist:w" <tokens> "\cs_end:" <true code> "\else:" <false
@@ -162,357 +251,388 @@
% \end{function}
%
% \begin{function}{
-% \if_mode_horizontal: |
-% \if_mode_vertical: |
-% \if_mode_math: |
-% \if_mode_inner:
-% }
+% \if_mode_horizontal: / (EXP) |
+% \if_mode_vertical: / (EXP) |
+% \if_mode_math: / (EXP) |
+% \if_mode_inner: / (EXP) }
% \begin{syntax}
-% "\if_horizontal_mode:" <true code> "\else:" <false code> "\fi:"
+% "\if_mode_horizontal:" <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}
+% \subsection{Non-primitive conditionals}
%
-% \begin{function}{%
-% \cs_if_eq_p:NN
-% }
+% \begin{function}{ \cs_if_eq_name_p:NN }
% \begin{syntax}
-% "\cs_if_eq_p:NN" <cs1> <cs2>
+% "\cs_if_eq_name_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_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{function}{ \cs_if_eq_p:NN / (EXP) |
+% \cs_if_eq_p:cN / (EXP) |
+% \cs_if_eq_p:Nc / (EXP) |
+% \cs_if_eq_p:cc / (EXP) |
+% \cs_if_eq:NN / (TF)(EXP) |
+% \cs_if_eq:cN / (TF)(EXP) |
+% \cs_if_eq:Nc / (TF)(EXP) |
+% \cs_if_eq:cc / (TF)(EXP) }
% \begin{syntax}
-% "\cs_if_eq:NNTF" <cs1> <cs2> "{"<true code>"}{"<false code>"}"
+% "\cs_if_eq_p:NNTF" <cs1> <cs2>
+% "\cs_if_eq:NNTF" <cs1> <cs2> \Arg{true code} \Arg{false code}
% \end{syntax}
-% These functions check if <cs1> and <cs2> have same meaning and then
-% execute either <true code> or <false code>.
+% These functions check if <cs1> and <cs2> have same meaning.
% \end{function}
%
%
-% \begin{function}{%
-% \cs_if_free_p:N
-% }
+% \begin{function}{ \cs_if_free_p:N / (EXP) |
+% \cs_if_free_p:c / (EXP) |
+% \cs_if_free:N / (TF)(EXP) |
+% \cs_if_free:c / (TF)(EXP) }
% \begin{syntax}
% "\cs_if_free_p:N" <cs>
+% "\cs_if_free:NTF" <cs> \Arg{true code} \Arg{false code}
% \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:".
+% Returns `true' if <cs> is either undefined or equal to
+% "\tex_relax:D" (the function that is assigned to newly created
+% control sequences by \TeX{} when "\cs:w" "..." "\cs_end:" is
+% used). In addition to this, `true' is only returned if <cs> does not
+% have a signature equal to "D", i.e., `do not use' functions are not
+% free to be redefined.
% \end{function}
%
-% \begin{function}{%
-% \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{function}{ \cs_if_exist_p:N / (EXP) |
+% \cs_if_exist_p:c / (EXP) |
+% \cs_if_exist:N / (TF)(EXP) |
+% \cs_if_exist:c / (TF)(EXP) }
% \begin{syntax}
-% "\cs_if_free:NTF" <cs> "{"<true code>"}{"<false code>"}"
+% "\cs_if_exist_p:N" <cs>
+% "\cs_if_exist:NTF" <cs> \Arg{true code} \Arg{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_if_free:cTF" is the \LaTeX3 implementation of
-% the \LaTeX2 function \tn{@ifundefined}. The other functions
-% haven't been around before.
-% \end{texnote}
+% These functions check if <cs> exists, i.e., if <cs> is present in
+% the hash table and is not the primitive "\tex_relax:D".
% \end{function}
%
-% \begin{function}{%
-% \cs_if_really_free:cTF |
-% \cs_if_really_free:cF |
-% \cs_if_really_free:cT
-% }
+% \begin{function}{ \cs_if_do_not_use_p:N / (EXP) }
% \begin{syntax}
-% "\cs_if_really_free:cTF" "{"<tokens>"}" "{"<true code>"} {"<false
-% code>"}"
+% "\cs_if_do_not_use_p:N" <cs>
% \end{syntax}
-% 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.
+% These functions check if <cs> has the arg spec "D" for `\emph{do not use}'.
+% There are no "TF"-type conditionals for this function as it is only used
+% internally and not expected to be widely used. (For now, anyway.)
% \end{function}
%
-% \begin{function}{%
-% \cs_if_exist_p:N
-% }
+% \begin{function}{ \chk_if_free_cs:N }
% \begin{syntax}
-% "\cs_if_exist_p:N" <cs>
+% "\chk_if_free_cs:N" <cs>
% \end{syntax}
-% This function does the opposite of "\cs_if_free_p:N".
+% This function checks that <cs> is \m{free} according to the criteria
+% for "\cs_if_free_p:N" above. If not, an error is generated.
% \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{function}{ \chk_if_exist_cs:N |
+% \chk_if_exist_cs:c }
% \begin{syntax}
-% "\cs_if_exist:NTF" <cs> "{"<true code>"}{"<false code>"}"
+% "\chk_if_exist_cs:N" <cs>
% \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".
+% This function checks that <cs> is defined. If it is not an error
+% is generated.
% \end{function}
%
-% \begin{function}{%
-% \cs_if_really_exist:cTF |
-% \cs_if_really_exist:cF |
-% \cs_if_really_exist:cT
-% }
+% \begin{variable}{ \c_true_bool | \c_false_bool }
% \begin{syntax}
-% "\cs_if_really_exist:cTF" "{"<tokens>"}" "{"<true code>"} {"<false
-% code>"}"
% \end{syntax}
-% The opposite of "\cs_if_really_free:cTF".
-% \end{function}
+% Constants that represent `true' or `false', respectively. Used to
+% implement predicates.
+% \end{variable}
%
+% \subsection{Applications}
%
-% \begin{function}{%
-% \chk_new_cs:N |
-% }
+% \begin{function}{ \str_if_eq_p:nn / (EXP) }
% \begin{syntax}
-% "\chk_new_cs:N" <cs>
+% "\str_if_eq_p:nn" \Arg{string1} \Arg{string2}
% \end{syntax}
-% This function checks that <cs> is so far either undefined or equals
-% "\scan_stop:" (the function that is assigned to newly created
-% control sequences by \TeX{} when "\cs:w" "..." "\cs_end:" is
-% used).
+% Expands to `true' if <string1> is the same as <string2>,
+% otherwise `false'. Ignores spaces within the strings.
% \end{function}
%
-% \begin{function}{%
-% \chk_exist_cs:N |
-% \chk_exist_cs:c
-% }
+% \begin{function}{ \str_if_eq_var_p:nf / (EXP) }
% \begin{syntax}
-% "\chk_exist_cs:N" <cs>
+% "\str_if_eq_var_p:nf" \Arg{string1} \Arg{string2}
% \end{syntax}
-% This function checks that <cs> is defined. If it is not an error
-% is generated.
+% A variant of "\str_if_eq_p:nn" which has the advantage of
+% obeying spaces in at least the second argument.
% \end{function}
%
%
-% \begin{variable}{%
-% \c_true |
-% \c_false
-% }
+% \section{Control sequences}
+%
+% \begin{function}{ \cs:w / (EXP) | \cs_end: / (EXP) }
% \begin{syntax}
+% "\cs:w" <tokens> "\cs_end:"
% \end{syntax}
-% Constants that represent `true' or `false', respectively. Used to
-% implement predicates.
-% \end{variable}
+% This is the \TeX{} internal way of generating a control sequence from
+% some token list. <tokens> get expanded and must ultimately result in a
+% sequence of characters.
+% \begin{texnote}
+% These functions are the primitives \tn{csname} and \tn{endcsname}.
+% "\cs:w" is considered weird because it expands tokens until it reaches
+% "\cs_end:".
+% \end{texnote}
+% \end{function}
%
+% \begin{function}{ \cs_show:N |
+% \cs_show:c }
+% \begin{syntax}
+% "\cs_show:N" <cs>
+% "\cs_show:c" \Arg{arg}
+% \end{syntax}
+% This function shows in the console output the \emph{meaning} of the control
+% sequence <cs> or that created by <arg>.
+% \begin{texnote}
+% This is \TeX's |\show| and associated csname version of it.
+% \end{texnote}
+% \end{function}
%
+% \begin{function}{ \cs_meaning:N / (EXP) |
+% \cs_meaning:c / (EXP) }
+% \begin{syntax}
+% "\cs_meaning:N" <cs>
+% "\cs_meaning:c" \Arg{arg}
+% \end{syntax}
+% This function expands to the \emph{meaning} of the control sequence <cs> or
+% that created by <arg>.
+% \begin{texnote}
+% This is \TeX's |\meaning| and associated csname version of it.
+% \end{texnote}
+% \end{function}
%
-% \subsection{Selecting and discarding tokens from the input stream}
+% \section{Selecting and discarding tokens from the input stream}
%
-% The conditional processing could not have been implemented without
+% The conditional processing cannot be 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{function}{ \use:n / (EXP) |
+% \use:nn / (EXP) |
+% \use:nnn / (EXP) |
+% \use:nnnn / (EXP) }
% \begin{syntax}
-% "\use_none:n" "{"<arg1>"}"\\
-% "\use_none:nn" "{"<arg1>"}{"<arg2>"}"
+% "\use:n" \Arg{arg}
% \end{syntax}
-% These functions gobble the tokens or brace groups from the input
-% stream.
+% Functions that returns all of their arguments to the input stream after
+% removing the surrounding braces around each argument.
+% \begin{texnote}
+% "\use:n" is \LaTeXe's "\@firstofone"/"\@iden".
+% \end{texnote}
% \end{function}
%
+% \begin{function}{ \use:c / (EXP) }
+% \begin{syntax}
+% "\use:c" \Arg{cs}
+% \end{syntax}
+% Function that returns to the input stream the control sequence created from
+% its argument. Requires two expansions before a control sequence is returned.
+% \begin{texnote}
+% "\use:c" is \LaTeXe's "\@nameuse".
+% \end{texnote}
+% \end{function}
%
-% \begin{function}{\use_arg_i:n}
+% \begin{function}{ \use_none:n / (EXP) |
+% \use_none:nn / (EXP) |
+% \use_none:nnn / (EXP) |
+% \use_none:nnnn / (EXP) |
+% \use_none:nnnnn / (EXP) |
+% \use_none:nnnnnn / (EXP) |
+% \use_none:nnnnnnn / (EXP) |
+% \use_none:nnnnnnnn / (EXP) |
+% \use_none:nnnnnnnnn / (EXP) }
% \begin{syntax}
-% "\use_arg_i:n" "{" <code1> "}"
+% "\use_none:n" \Arg{arg1}\\
+% "\use_none:nn" \Arg{arg1} \Arg{arg2}
% \end{syntax}
-% Function that executes the next argument after removing the
-% surrounding braces. Used to implement conditionals.
+% These functions gobble the tokens or brace groups from the input
+% stream.
+% \begin{texnote}
+% "\use_none:n", "\use_none:nn", "\use_none:nnnn" are \LaTeXe's
+% "\@gobble", "\@gobbletwo", and "\@gobblefour".
+% \end{texnote}
% \end{function}
%
-% \begin{function}{%
-% \use_arg_i:nn |
-% \use_arg_ii:nn |
-% }
+% \begin{function}{ \use_i:nn / (EXP) |
+% \use_ii:nn / (EXP) }
% \begin{syntax}
-% "\use_arg_i:nn" "{" <code1> "}{" <code2> "}"
+% "\use_i:nn" \Arg{code1} \Arg{code2}
% \end{syntax}
% Functions that execute the first or second argument respectively,
% after removing the surrounding braces. Primarily used to implement
% conditionals.
+% \begin{texnote}
+% These are \LaTeXe's "\@firstoftwo" and "\@secondoftwo", respectively.
+% \end{texnote}
% \end{function}
%
-% \begin{function}{%
-% \use_arg_i:nnn |
-% \use_arg_ii:nnn |
-% \use_arg_iii:nnn |
-% }
+% \begin{function}{ \use_i:nnn / (EXP) |
+% \use_ii:nnn / (EXP) |
+% \use_iii:nnn / (EXP) }
% \begin{syntax}
-% "\use_arg_i:nnn" "{" <arg1> "}{" <arg2> "}{" <arg3> "}"
+% "\use_i:nnn" \Arg{arg1} \Arg{arg2} \Arg{arg3}
% \end{syntax}
% Functions that pick up one of three arguments and execute them after
-% removing the surrounding braces. Should be described somewhere else.
+% removing the surrounding braces.
+% \begin{texnote}
+% \LaTeXe\ has only "\@thirdofthree".
+% \end{texnote}
% \end{function}
%
-% \begin{function}{%
-% \use_arg_i:nnnn |
-% \use_arg_ii:nnnn |
-% \use_arg_iii:nnnn |
-% \use_arg_iv:nnnn |
-% }
+% \begin{function}{ \use_i:nnnn / (EXP) |
+% \use_ii:nnnn / (EXP) |
+% \use_iii:nnnn / (EXP) |
+% \use_iv:nnnn / (EXP) }
% \begin{syntax}
-% "\use_arg_i:nnnn" "{" <arg1> "}{" <arg2> "}{" <arg3> "}{" <arg4> "}"
+% "\use_i:nnnn" \Arg{arg1} \Arg{arg2} \Arg{arg3} \Arg{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.
+% \subsection{Extending the interface}
%
-% \begin{function}{%
-% \use_none_delimit_by_q_nil:w |
-% \use_none_delimit_by_q_stop:w |
-% }
+% \begin{function}{ \use_i_ii:nnn / (EXP) }
+% \begin{syntax}
+% "\use_i_ii:nnn" \Arg{arg1} \Arg{arg2} \Arg{arg3}
+% \end{syntax}
+% This function used in the expansion module reads three arguments and
+% returns (without braces) the first and second argument while
+% discarding the third argument.
+%
+% If you wish to select multiple arguments while discarding others,
+% use a syntax like this. Its definition is
+% \begin{verbatim}
+% \cs_set:Npn \use_i_ii:nnn #1#2#3 {#1#2}
+% \end{verbatim}
+% \end{function}
+%
+% \subsection{Selecting tokens from delimited arguments}
+%
+% A different kind of function for selecting tokens from the token
+% stream are those that use delimited arguments.
+%
+% \begin{function}{ \use_none_delimit_by_q_nil:w / (EXP) |
+% \use_none_delimit_by_q_stop:w / (EXP) |
+% \use_none_delimit_by_q_recursion_stop:w / (EXP) }
% \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.
+% structure or terminating recursion.
% \end{function}
%
-% \begin{function}{%
-% \use_arg_i_delimit_by_q_nil:nw |
-% \use_arg_i_delimit_by_q_stop:nw |
-% }
+% \begin{function}{ \use_i_delimit_by_q_nil:nw / (EXP) |
+% \use_i_delimit_by_q_stop:nw / (EXP) |
+% \use_i_delimit_by_q_recursion_stop:nw / (EXP) }
% \begin{syntax}
-% "\use_arg_i_delimit_by_q_nil:nw" "{"<arg>"}" <balanced text> "\q_nil"
+% "\use_i_delimit_by_q_nil:nw" \Arg{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 |
-% \use_arg_i_after_orelse:nw
-% }
+% \begin{function}{ \use_i_after_fi:nw / (EXP) |
+% \use_i_after_else:nw / (EXP) |
+% \use_i_after_or:nw / (EXP) |
+% \use_i_after_orelse:nw / (EXP) }
% \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:"
-% "\use_arg_i_after_orelse:nw" "{"<arg>"}" "\or:/\else:" <balanced text> "\fi:"
+% "\use_i_after_fi:nw" \Arg{arg} "\fi:"
+% "\use_i_after_else:nw" \Arg{arg} "\else:" <balanced text> "\fi:"
+% "\use_i_after_or:nw" \Arg{arg} "\or:" <balanced text> "\fi:"
+% "\use_i_after_orelse:nw" \Arg{arg} "\or:/\else:" <balanced text> "\fi:"
% \end{syntax}
% Executes <arg> after executing closing out
-% "\fi:". "\use_arg_i_after_orelse:nw" can be used anywhere where
-% "\use_arg_i_after_else:nw" or "\use_arg_i_after_or:nw" are used.
+% "\fi:". "\use_i_after_orelse:nw" can be used anywhere where
+% "\use_i_after_else:nw" or "\use_i_after_or:nw" are used.
% \end{function}
%
-% \subsection{Internal functions}
%
-% \begin{function}{%
-% \cs:w |
-% \cs_end:
-% }
+% \section{That which belongs in other modules but needs to be defined earlier}
+%
+% \begin{function}{ \exp_after:wN / (EXP) }
% \begin{syntax}
-% "\cs:w" <tokens> "\cs_end:"
+% "\exp_after:wN" <token1> <token2>
% \end{syntax}
-% This is the \TeX{} internal way of generating a control sequence from
-% some token list. <tokens> get expanded and must ultimately result in a
-% sequence of characters.
+% Expands <token2> once and then continues processing from <token1>.
% \begin{texnote}
-% These functions are the primitives \tn{csname} and \tn{endcsname}.
-% "\cs:w" is considered weird because it expands tokens until it reaches
-% "\cs_end:".
-% \end{texnote}
+% This is \TeX's \tn{expandafter}.
+% \end{texnote}
% \end{function}
%
-% \begin{function}{\pref_global:D |
-% \pref_long:D |
-% \pref_protected:D |
-% }
+% \begin{function}{ \exp_not:N / (EXP) | \exp_not:n / (EXP) }
% \begin{syntax}
-% "\pref_global:D" "\def:Npn"
+% "\exp_not:N" <token>
+% "\exp_not:n" \Arg{tokens}
% \end{syntax}
-% Prefix functions that can be used in front of some definition
-% 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,
-% 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:Npn".
+% In an expanding context, this function prevents <token> or <tokens> from
+% expanding.
% \begin{texnote}
-% These prefixes are the primitives \tn{global}, \tn{long}, and
-% \tn{protected}. The \tn{outer} isn't used at all within \LaTeX3
-% because \ldots
+% These are \TeX's \tn{noexpand} and \eTeX's \tn{unexpanded}, respectively.
% \end{texnote}
% \end{function}
%
+% \begin{function}{ \prg_do_nothing: / (EXP) }
+% This is as close as we get to a null operation or no-op.
+% \begin{texnote}
+% Definition as in \LaTeX's \tn{\@empty} but not used for the same thing.
+% \end{texnote}
+% \end{function}
%
-%
-% \begin{function}{\io_put_log:x |
-% \io_put_term:x |
-% \io_put_deferred:Nx |
-% }
+% \begin{function}{ \iow_log:x |
+% \iow_term:x |
+% \iow_shipout_x:Nn }
% \begin{syntax}
-% "\io_put_log:x" "{"<message>"}"
-% "\io_put_deferred:Nx" <write_stream> "{"<message>"}"
+% "\iow_log:x" \Arg{message}
+% "\iow_shipout_x:Nn" <write_stream> \Arg{message}
% \end{syntax}
% Writes <message> to either to log or the terminal.
% \end{function}
%
-% \subsection{Defining functions}
+% \begin{function}{ \msg_kernel_bug:x }
+% \begin{syntax}
+% "\msg_kernel_bug:x" \Arg{message}
+% \end{syntax}
+% Internal function for calling errors in our code.
+% \end{function}
+%
+% \begin{function}{ \cs_record_meaning:N }
+% Placeholder for a function to be defined by \file{l3chk}.
+% \end{function}
+%
+% \begin{variable}{ \c_minus_one | \c_zero | \c_sixteen }
+% Numeric constants.
+% \end{variable}
+%
+%
+%
+% \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
+% simply make the definition. The latter are used for internal scratch
% functions that get new meanings all over the place.
%
% 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.
+% 99\% of the cases is no. For this type the programmer will know the
+% number of arguments and in most cases use the argument signature to
+% signal this, e.g., "\foo_bar:nnn" presumably takes three
+% arguments. We therefore also provide functions that automatically
+% detect how many arguments are required and construct the parameter
+% text on the fly.
%
% A definition of a new function can be done locally and globally. Currently
% nearly all function definitions are done locally on top level, in
@@ -528,104 +648,126 @@
% as individual functions.
% \end{texnote}
%
-%
-% \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
+% A slew of functions are defined in the following sections for defining
+% new functions. Here's a quick summary to get an idea of what's available:
+% {\centering
+% "\cs_"("g")("new"/"set")("_protected")("_nopar")":"("N"/"c")("p")("n"/"x")
+% \par}
+% That stands for, respectively, the following variations:
+% \begin{description}
+% \item[\texttt g] Global or local;
+% \item[\texttt{new}/\texttt{set}]
+% Define a new function or re-define an existing one;
+% \item[\texttt{protected}]
+% Prevent expansion of the function in "x" arguments;
+% \item[\texttt{nopar}] Restrict the argument(s) from containing "\par";
+% \item[\texttt N/\texttt c] Either a control sequence or a `csname';
+% \item[\texttt p]
+% Either the a primitive \TeX\ argument or the number of arguments
+% is detected from the argument signature, i.e., |\foo:nnn| is
+% assumed to have three arguments |#1#2#3|;
+% \item[\texttt n/\texttt x] Either an unexpanded or an expanded definition.
+% \end{description}
+% That adds up to 128 variations (!). However, the system is very
+% logical and only a handful will usually be required often.
+%
+%
+%
+% \subsection{Defining new functions using primitive parameter text}
+%
+%
+% \begin{function}{\cs_new:Npn |
+% \cs_new:Npx |
+% \cs_new:cpn |
+% \cs_new:cpx
% }
% \begin{syntax}
-% "\def_new:NNn" <cs> <num> "{" <code> "}"
+% "\cs_new:Npn" <cs> <parms> \Arg{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).
+% 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_new:NNn |
-% \gdef_new:cNn |
-% \gdef_new:NNx |
-% \gdef_new:cNx
+% \begin{function}{\cs_gnew:Npn |
+% \cs_gnew:Npx |
+% \cs_gnew:cpn |
+% \cs_gnew:cpx
% }
% \begin{syntax}
-% "\gdef_new:NNn" <cs> <num> "{" <code> "}"
+% "\cs_gnew:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Like "\def_new:NNn" but defines the new function globally.
+% Global versions of the above functions.
% \end{function}
%
-% \begin{function}{\def_long_new:NNn |
-% \def_long_new:NNx |
-% \def_long_new:cNn |
-% \def_long_new:cNx
+% \begin{function}{\cs_new_nopar:Npn |
+% \cs_new_nopar:Npx |
+% \cs_new_nopar:cpn |
+% \cs_new_nopar:cpx
% }
% \begin{syntax}
-% "\def_long_new:NNn" <cs> <num> "{" <code> "}"
+% "\cs_new_nopar:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Defines a function that may contain "\par" tokens in the argument(s)
-% when called. This is not allowed for normal functions.
+% Defines a new function, making sure that <cs> is unused so far.
+% <parms> may consist of arbitrary parameter specification in \TeX{}
+% syntax. It is under the responsibility of the programmer to name the
+% new function according to the rules laid out in the previous section.
+% <code> is either passed literally or may be subject to expansion
+% (under the "x" variants).
% \end{function}
%
-% \begin{function}{\gdef_long_new:NNn |
-% \gdef_long_new:NNx |
-% \gdef_long_new:cNn |
-% \gdef_long_new:cNx
+% \begin{function}{\cs_gnew_nopar:Npn |
+% \cs_gnew_nopar:Npx |
+% \cs_gnew_nopar:cpn |
+% \cs_gnew_nopar:cpx
% }
% \begin{syntax}
-% "\gdef_long_new:NNn" <cs> <num> "{" <code> "}"
+% "\cs_gnew_nopar:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Global versions of the above functions.
+% Like "\cs_new_nopar:Npn" but defines the new function globally. See
+% comments above.
% \end{function}
%
-% \begin{function}{\def_protected_new:NNn |
-% \def_protected_new:NNx |
-% \def_protected_new:cNn |
-% \def_protected_new:cNx
+% \begin{function}{\cs_new_protected:Npn |
+% \cs_new_protected:Npx |
+% \cs_new_protected:cpn |
+% \cs_new_protected:cpx
% }
% \begin{syntax}
-% "\def_protected_new:NNn" <cs> <num> "{" <code> "}"
+% "\cs_new_protected:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Defines a function that does not expand when inside an |x| type
-% expansion.
+% Defines a function that is both robust and may contain "\par" tokens
+% in the argument(s) when called.
% \end{function}
%
-% \begin{function}{\gdef_protected_new:NNn |
-% \gdef_protected_new:NNx |
-% \gdef_protected_new:cNn |
-% \gdef_protected_new:cNx
-% }
+% \begin{function}{ \cs_gnew_protected:Npn |
+% \cs_gnew_protected:Npx |
+% \cs_gnew_protected:cpn |
+% \cs_gnew_protected:cpx }
% \begin{syntax}
-% "\gdef_protected_new:NNn" <cs> <num> "{" <code> "}"
+% "\cs_gnew_protected:Npn" <cs> <parms> \Arg{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{function}{\cs_new_protected_nopar:Npn |
+% \cs_new_protected_nopar:Npx |
+% \cs_new_protected_nopar:cpn |
+% \cs_new_protected_nopar:cpx
% }
% \begin{syntax}
-% "\def_protected_long_new:NNn" <cs> <num> "{" <code> "}"
+% "\cs_new_protected_nopar:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Defines a function that is both robust and may contain "\par" tokens
-% in the argument(s) when called.
+% Defines a function that does not expand when inside an |x| type
+% expansion.
% \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{function}{\cs_gnew_protected_nopar:Npn |
+% \cs_gnew_protected_nopar:Npx |
+% \cs_gnew_protected_nopar:cpn |
+% \cs_gnew_protected_nopar:cpx
% }
% \begin{syntax}
-% "\gdef_protected_long_new:NNn" <cs> <num> "{" <code> "}"
+% "\cs_gnew_protected_nopar:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
% Global versions of the above functions.
% \end{function}
@@ -634,367 +776,385 @@
%
%
%
-% Secondly comes the ones where the programmer can use delimited
-% arguments. Rarely needed outside the kernel.
%
%
-% \begin{function}{\def_new:Npn |
-% \def_new:Npx |
-% \def_new:cpn |
-% \def_new:cpx
-% }
-% \begin{syntax}
-% "\def_new:Npn" <cs> <parms> "{" <code> "}"
-% \end{syntax}
-% Defines a new function, making sure that <cs> is unused so far.
-% <parms> may consist of arbitrary parameter specification in \TeX{}
-% syntax. It is under the responsibility of the programmer to name the
-% new function according to the rules laid out in the previous section.
-% <code> is either passed literally or may be subject to expansion
-% (under the "x" variants).
-% \end{function}
%
-% \begin{function}{\gdef_new:Npn |
-% \gdef_new:cpn |
-% \gdef_new:Npx |
-% \gdef_new:cpx
-% }
-% \begin{syntax}
-% "\gdef_new:Npn" <cs> <parms> "{" <code> "}"
-% \end{syntax}
-% Like "\def_new:Npn" but defines the new function globally. See
-% comments above.
-% \end{function}
%
-% \begin{function}{\def_long_new:Npn |
-% \def_long_new:Npx |
-% \def_long_new:cpn |
-% \def_long_new:cpx
+% \subsection{Defining new functions using the signature}
+%
+%
+% \begin{function}{\cs_new:Nn |
+% \cs_new:Nx |
+% \cs_new:cn |
+% \cs_new:cx
% }
% \begin{syntax}
-% "\def_long_new:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_new:Nn" <cs> \Arg{code}
% \end{syntax}
-% Defines a function that may contain "\par" tokens in the argument(s)
-% when called. This is not allowed for normal functions.
+% Defines a new function, making sure that <cs> is unused so far. The
+% parameter text is automatically detected from the length of the
+% function signature. If <cs> is missing a colon in its name, 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).
+% \begin{texnote}
+% Internally, these use \TeX's "\long". These forms are
+% recommended for low-level definitions as experience has shown that "\par"
+% tokens often turn up in programming situations that wouldn't have been
+% expected.
+% \end{texnote}
% \end{function}
%
-% \begin{function}{\gdef_long_new:Npn |
-% \gdef_long_new:Npx |
-% \gdef_long_new:cpn |
-% \gdef_long_new:cpx
+% \begin{function}{\cs_gnew:Nn |
+% \cs_gnew:Nx |
+% \cs_gnew:cn |
+% \cs_gnew:cx
% }
% \begin{syntax}
-% "\gdef_long_new:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_gnew:Nn" <cs> \Arg{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{function}{\cs_new_nopar:Nn |
+% \cs_new_nopar:Nx |
+% \cs_new_nopar:cn |
+% \cs_new_nopar:cx
% }
% \begin{syntax}
-% "\def_protected_new:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_new_nopar:Nn" <cs> \Arg{code}
% \end{syntax}
-% Defines a function that does not expand when inside an |x| type
-% expansion.
+% Version of the above in which "\par" is not allowed to appear within the
+% argument(s) of the defined functions.
% \end{function}
%
-% \begin{function}{\gdef_protected_new:Npn |
-% \gdef_protected_new:Npx |
-% \gdef_protected_new:cpn |
-% \gdef_protected_new:cpx
+% \begin{function}{\cs_gnew_nopar:Nn |
+% \cs_gnew_nopar:Nx |
+% \cs_gnew_nopar:cn |
+% \cs_gnew_nopar:cx
% }
% \begin{syntax}
-% "\gdef_protected_new:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_gnew_nopar:Nn" <cs> \Arg{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{function}{\cs_new_protected:Nn |
+% \cs_new_protected:Nx |
+% \cs_new_protected:cn |
+% \cs_new_protected:cx
% }
% \begin{syntax}
-% "\def_protected_long_new:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_new_protected:Nn" <cs> \Arg{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{function}{\cs_gnew_protected:Nn |
+% \cs_gnew_protected:Nx |
+% \cs_gnew_protected:cn |
+% \cs_gnew_protected:cx
% }
% \begin{syntax}
-% "\gdef_protected_long_new:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_gnew_protected:Nn" <cs> \Arg{code}
% \end{syntax}
% Global versions of the above functions.
% \end{function}
%
-% \begin{function}{\let_new:NN |
-% \let_new:cN |
-% \let_new:Nc |
-% \let_new:cc |
-% \glet_new:NN|
-% \glet_new:cN|
-% \glet_new:Nc|
-% \glet_new:cc }
+% \begin{function}{\cs_new_protected_nopar:Nn |
+% \cs_new_protected_nopar:Nx |
+% \cs_new_protected_nopar:cn |
+% \cs_new_protected_nopar:cx
+% }
% \begin{syntax}
-% "\let_new:NN" <cs1> <cs2>
+% "\cs_new_protected_nopar:Nn" <cs> \Arg{code}
% \end{syntax}
-% Gives the function <cs1> the current meaning of <cs2>. Again, we may
-% do this always globally.
+% Defines a function that does not expand when inside an |x| type
+% expansion. "\par" is not allowed in the argument(s) of the defined function.
% \end{function}
%
-%
-%
-% \subsubsection{Undefining functions}
-%
-% \begin{function}{ \cs_gundefine:N
+% \begin{function}{\cs_gnew_protected_nopar:Nn |
+% \cs_gnew_protected_nopar:Nx |
+% \cs_gnew_protected_nopar:cn |
+% \cs_gnew_protected_nopar:cx
% }
% \begin{syntax}
-% "\cs_gundefine:N" <cs>
+% "\cs_gnew_protected_nopar:Nn" <cs> \Arg{code}
% \end{syntax}
-% Undefines the control sequence.
+% Global versions of the above functions.
% \end{function}
%
-% \subsubsection{Defining internal functions (no checks)}
+%
+%
+% \subsection{Defining functions using primitive parameter text}
+%
%
% 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{function}{\cs_set:Npn |
+% \cs_set:Npx |
+% \cs_set:cpn |
+% \cs_set:cpx |
% }
% \begin{syntax}
-% "\def:NNn" <cs> <num> "{" <code> "}"
+% "\cs_set:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Like "\def_new:NNn" etc.\ but does not check the <cs> name.
+% Like "\cs_set_nopar:Npn" but allows "\par" tokens in the arguments of the
+% function being defined.
+% \begin{texnote}
+% These are equivalent to \TeX's "\long\def" and so on. These forms are
+% recommended for low-level definitions as experience has shown that "\par"
+% tokens often turn up in programming situations that wouldn't have been
+% expected.
+% \end{texnote}
% \end{function}
%
-% \begin{function}{\gdef:NNn |
-% \gdef:NNx |
-% \gdef:cNn |
-% \gdef:cNx |
+% \begin{function}{\cs_gset:Npn |
+% \cs_gset:Npx |
+% \cs_gset:cpn |
+% \cs_gset:cpx |
% }
% \begin{syntax}
-% "\gdef:NNn" <cs> <num> "{" <code> "}"
+% "\cs_gset:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Like "\def:NNn" but defines the <cs> globally.
+% Global variant of "\cs_set:Npn".
% \end{function}
%
-%
-% \begin{function}{\def_long:NNn |
-% \def_long:NNx |
-% \def_long:cNn |
-% \def_long:cNx |
+% \begin{function}{\cs_set_nopar:Npn |
+% \cs_set_nopar:Npx |
+% \cs_set_nopar:cpn |
+% \cs_set_nopar:cpx |
% }
% \begin{syntax}
-% "\def_long:NNn" <cs> <num> "{" <code> "}"
+% "\cs_set_nopar:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Like "\def:NNn" but allows "\par" tokens in the arguments of the
-% function being defined.
+% Like "\cs_new_nopar:Npn" etc.\ but does not check the <cs> name.
+% \begin{texnote}
+% "\cs_set_nopar:Npn" is the \LaTeX3 name for \TeX{}'s \tn{def} and
+% "\cs_set_nopar:Npx" corresponds to the primitive \tn{edef}. The
+% "\cs_set_nopar:cpn" function was known in \LaTeX2 as \tn{@namedef}.
+% "\cs_set_nopar:cpx" has no equivalent.
+% \end{texnote}
% \end{function}
%
-% \begin{function}{\gdef_long:NNn |
-% \gdef_long:NNx |
-% \gdef_long:cNn |
-% \gdef_long:cNx |
+% \begin{function}{\cs_gset_nopar:Npn |
+% \cs_gset_nopar:Npx |
+% \cs_gset_nopar:cpn |
+% \cs_gset_nopar:cpx |
% }
% \begin{syntax}
-% "\gdef_long:NNn" <cs> <num> "{" <code> "}"
+% "\cs_gset_nopar:Npn" <cs> <parms> \Arg{code}
% \end{syntax}
-% Global variant of "\def_long:NNn".
+% Like "\cs_set_nopar:Npn" but defines the <cs> globally.
+% \begin{texnote}
+% "\cs_gset_nopar:Npn" and "\cs_gset_nopar:Npx"
+% are \TeX's \tn{gdef} and \tn{xdef}.
+% \end{texnote}
% \end{function}
%
-% \begin{function}{\def_protected:NNn |
-% \def_protected:cNn |
-% \def_protected:NNx |
-% \def_protected:cNx |
+%
+% \begin{function}{\cs_set_protected:Npn |
+% \cs_set_protected:Npx |
+% \cs_set_protected:cpn |
+% \cs_set_protected:cpx |
% }
% \begin{syntax}
-% "\def_protected:NNn" <cs> <num> "{" <code> "}"
+% "\cs_set_protected:Npn" <cs> <parms> \Arg{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:|.
+% These varieties allow |\par| tokens in the arguments of the
+% function being defined.
% \end{function}
%
-% \begin{function}{\gdef_protected:NNn |
-% \gdef_protected:cNn |
-% \gdef_protected:NNx |
-% \gdef_protected:cNx |
+% \begin{function}{\cs_gset_protected:Npn |
+% \cs_gset_protected:Npx |
+% \cs_gset_protected:cpn |
+% \cs_gset_protected:cpx |
% }
% \begin{syntax}
-% "\gdef_protected:NNn" <cs> <num> "{" <code> "}"
+% "\cs_gset_protected:Npn" <cs> <parms> \Arg{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{function}{\cs_set_protected_nopar:Npn |
+% \cs_set_protected_nopar:Npx |
+% \cs_set_protected_nopar:cpn |
+% \cs_set_protected_nopar:cpx |
% }
% \begin{syntax}
-% "\def_protected_long:NNn" <cs> <num> "{" <code> "}"
+% "\cs_set_protected_nopar:Npn" <cs> <parms> \Arg{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.
+% If you want for some reason to expand it inside an |x| type expansion,
+% prefix it with |\exp_after:wN \prg_do_nothing:|.
% \end{function}
%
-% \begin{function}{\gdef_protected_long:NNn |
-% \gdef_protected_long:cNn |
-% \gdef_protected_long:NNx |
-% \gdef_protected_long:cNx |
+% \begin{function}{\cs_gset_protected_nopar:Npn |
+% \cs_gset_protected_nopar:Npx |
+% \cs_gset_protected_nopar:cpn |
+% \cs_gset_protected_nopar:cpx |
% }
% \begin{syntax}
-% "\gdef_protected_long:NNn" <cs> <num> "{" <code> "}"
+% "\cs_gset_protected_nopar:Npn" <cs> <parms> \Arg{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 |
-% \def:cpx |
+% \subsection{Defining functions using the signature (no checks)}
+%
+% As above but now detecting the parameter text from inspecting the
+% signature.
+%
+% \begin{function}{\cs_set:Nn |
+% \cs_set:Nx |
+% \cs_set:cn |
+% \cs_set:cx |
% }
% \begin{syntax}
-% "\def:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_set:Nn" <cs> \Arg{code}
% \end{syntax}
-% Like "\def_new:Npn" etc.\ but does not check the <cs> name.
-% \begin{texnote}
-% "\def:Npn" is the \LaTeX3 name for \TeX{}'s \tn{def} and "\def:Npx"
-% corresponds to the primitive \tn{edef}. The "\def:cpn" function was
-% known in \LaTeX2 as \tn{@namedef}. "\def:cpx" has no equivalent.
-% \end{texnote}
+% Like "\cs_set_nopar:Nn" but allows "\par" tokens in the arguments of the
+% function being defined.
% \end{function}
%
-% \begin{function}{\gdef:Npn |
-% \gdef:Npx |
-% \gdef:cpn |
-% \gdef:cpx |
+% \begin{function}{\cs_gset:Nn |
+% \cs_gset:Nx |
+% \cs_gset:cn |
+% \cs_gset:cx |
% }
% \begin{syntax}
-% "\gdef:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_gset:Nn" <cs> \Arg{code}
% \end{syntax}
-% Like "\def:Npn" but defines the <cs> globally.
-% \begin{texnote}
-% "\gdef:Npn" and "\gdef:Npx" are known to \TeX{}hackers as \tn{gdef}
-% and \tn{xdef}.
-% \end{texnote}
+% Global variant of "\cs_set:Nn".
% \end{function}
%
-%
-% \begin{function}{\def_long:Npn |
-% \def_long:Npx |
-% \def_long:cpn |
-% \def_long:cpx |
+% \begin{function}{\cs_set_nopar:Nn |
+% \cs_set_nopar:Nx |
+% \cs_set_nopar:cn |
+% \cs_set_nopar:cx |
% }
% \begin{syntax}
-% "\def_long:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_set_nopar:Nn" <cs> \Arg{code}
% \end{syntax}
-% Like "\def:Npn" but allows "\par" tokens in the arguments of the
-% function being defined.
+% Like "\cs_new_nopar:Nn" etc.\ but does not check the <cs> name.
% \end{function}
%
-% \begin{function}{\gdef_long:Npn |
-% \gdef_long:Npx |
-% \gdef_long:cpn |
-% \gdef_long:cpx |
+% \begin{function}{\cs_gset_nopar:Nn |
+% \cs_gset_nopar:Nx |
+% \cs_gset_nopar:cn |
+% \cs_gset_nopar:cx |
% }
% \begin{syntax}
-% "\gdef_long:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_gset_nopar:Nn" <cs> \Arg{code}
% \end{syntax}
-% Global variant of "\def_long:Npn".
+% Like "\cs_set_nopar:Nn" but defines the <cs> globally.
% \end{function}
%
-% \begin{function}{\def_protected:Npn |
-% \def_protected:cpn |
-% \def_protected:Npx |
-% \def_protected:cpx |
+% \begin{function}{\cs_set_protected:Nn |
+% \cs_set_protected:cn |
+% \cs_set_protected:Nx |
+% \cs_set_protected:cx |
% }
% \begin{syntax}
-% "\def_protected:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_set_protected:Nn" <cs> \Arg{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:|.
+% These varieties also allow |\par| tokens in the arguments of the
+% function being defined.
% \end{function}
%
-% \begin{function}{\gdef_protected:Npn |
-% \gdef_protected:cpn |
-% \gdef_protected:Npx |
-% \gdef_protected:cpx |
+% \begin{function}{\cs_gset_protected:Nn |
+% \cs_gset_protected:cn |
+% \cs_gset_protected:Nx |
+% \cs_gset_protected:cx |
% }
% \begin{syntax}
-% "\gdef_protected:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_gset_protected:Nn" <cs> \Arg{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{function}{\cs_set_protected_nopar:Nn |
+% \cs_set_protected_nopar:cn |
+% \cs_set_protected_nopar:Nx |
+% \cs_set_protected_nopar:cx |
% }
% \begin{syntax}
-% "\def_protected_long:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_set_protected_nopar:Nn" <cs> \Arg{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.
+% 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:wN \prg_do_nothing:|.
% \end{function}
%
-% \begin{function}{\gdef_protected_long:Npn |
-% \gdef_protected_long:cpn |
-% \gdef_protected_long:Npx |
-% \gdef_protected_long:cpx |
+% \begin{function}{\cs_gset_protected_nopar:Nn |
+% \cs_gset_protected_nopar:cn |
+% \cs_gset_protected_nopar:Nx |
+% \cs_gset_protected_nopar:cx |
% }
% \begin{syntax}
-% "\gdef_protected_long:Npn" <cs> <parms> "{" <code> "}"
+% "\cs_gset_protected_nopar:Nn" <cs> \Arg{code}
% \end{syntax}
% Global versions of the above functions.
% \end{function}
%
%
%
-% \begin{function}{\let:NN |
-% \let:cN |
-% \let:Nc |
-% \let:cc |
-% \glet:NN |
-% \glet:cN |
-% \glet:Nc |
-% \glet:cc
-% }
+% \subsection{Undefining functions}
+%
+% \begin{function}{ \cs_gundefine:N }
+% \begin{syntax}
+% "\cs_gundefine:N" <cs>
+% \end{syntax}
+% Undefines the control sequence globally.
+% \end{function}
+%
+%
+% \subsection{Copying function definitions}
+%
+% \begin{function}{ \cs_new_eq:NN |
+% \cs_new_eq:cN |
+% \cs_new_eq:Nc |
+% \cs_new_eq:cc |
+% \cs_gnew_eq:NN |
+% \cs_gnew_eq:cN |
+% \cs_gnew_eq:Nc |
+% \cs_gnew_eq:cc }
+% \begin{syntax}
+% "\cs_new_eq:NN" <cs1> <cs2>
+% \end{syntax}
+% Gives the function <cs1> locally or globally the current meaning of <cs2>.
+% If <cs1> already exists then an error is called.
+% \end{function}
+%
+%
+% \begin{function}{\cs_set_eq:NN |
+% \cs_set_eq:cN |
+% \cs_set_eq:Nc |
+% \cs_set_eq:cc |
+% \cs_gset_eq:NN |
+% \cs_gset_eq:cN |
+% \cs_gset_eq:Nc |
+% \cs_gset_eq:cc }
% \begin{syntax}
-% "\let:cN" <cs1> <cs2>
+% "\cs_set_eq:cN" <cs1> <cs2>
% \end{syntax}
% Gives the function <cs1> the current meaning of <cs2>. Again, we may
% always do this globally.
% \end{function}
%
-% \begin{function}{\let:NwN}
+% \begin{function}{\cs_set_eq:NwN}
% \begin{syntax}
-% "\let:NwN" <cs1> <cs2>
-% "\let:NwN" <cs1> "=" <cs2>
+% "\cs_set_eq:NwN" <cs1> <cs2>
+% "\cs_set_eq:NwN" <cs1> "=" <cs2>
% \end{syntax}
% These functions assign the meaning of <cs2> locally or globally to the
% function <cs1>. Because the \TeX{} primitive operation is being used
@@ -1002,67 +1162,109 @@
% <cs1> and <cs2> the name contains a "w". (Not happy about this
% convention!).
% \begin{texnote}
-% "\let:NwN" is the \LaTeX3 name for \TeX{}'s \tn{let}.
+% "\cs_set_eq:NwN" is the \LaTeX3 name for \TeX{}'s \tn{let}.
% \end{texnote}
% \end{function}
%
+% \subsection{Internal functions}
%
-% \subsection{Defining test functions}
%
+% \begin{function}{ \pref_global:D |
+% \pref_long:D |
+% \pref_protected:D }
+% \begin{syntax}
+% "\pref_global:D" "\cs_set_nopar:Npn"
+% \end{syntax}
+% Prefix functions that can be used in front of some definition
+% 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,
+% and "\pref_protected:D" makes the definition robust in "\write"s etc.
%
-% \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.
+% None of these internal functions should be used by a programmer since
+% the necessary combinations are all available as separate function,
+% e.g., "\cs_set:Npn" is internally implemented as "\pref_long:D"
+% "\cs_set_nopar:Npn".
+% \begin{texnote}
+% These prefixes are the primitives \tn{global}, \tn{long}, and
+% \tn{protected}. The \tn{outer} prefix isn't used at all within \LaTeX3
+% because \ldots (it causes more hassle than it's worth? It's nevery proved
+% useful in any meaningful way?)
+% \end{texnote}
% \end{function}
%
+% \section{The innards of a function}
%
-% \subsection{The innards of a function}
-%
-% \begin{function}{\cs_to_str:N}
+% \begin{function}{\cs_to_str:N / (EXP)}
% \begin{syntax}
% "\cs_to_str:N" <cs>
% \end{syntax}
-% This function return the name of <cs> as a sequence of letters with
+% This function returns the name of <cs> as a sequence of letters with
% the escape character removed.
% \end{function}
%
-% \begin{function}{\token_to_string:N}
+% \begin{function}{\token_to_str:N / (EXP) | \token_to_str:c / (EXP)}
% \begin{syntax}
-% "\token_to_string:N" <arg>
+% "\token_to_str:N" <arg>
% \end{syntax}
% This function return the name of <arg> as a sequence of letters
% including the escape character.
+% \begin{texnote}
+% This is \TeX's \tn{string}.
+% \end{texnote}
% \end{function}
%
-% \begin{function}{\token_to_meaning:N}
+% \begin{function}{\token_to_meaning:N / (EXP)}
% \begin{syntax}
% "\token_to_meaning:N" <arg>
% \end{syntax}
% This function returns the type and definition of <arg> as a sequence
% of letters.
+% \begin{texnote}
+% This is \TeX's \tn{meaning}.
+% \end{texnote}
+% \end{function}
+%
+%
+% \begin{function}{\cs_get_function_name:N / (EXP) |
+% \cs_get_function_signature:N / (EXP)}
+% \begin{syntax}
+% "\cs_get_function_name:N" "\"<fn>":"<args>
+% \end{syntax}
+% The "name" variant strips off the leading escape character and the
+% trailing argument specification (including the colon) to return
+% <fn>. The "signature" variants does the same but returns the
+% signature <args> instead.
% \end{function}
%
+%
+% \begin{function}{\cs_split_function:NN / (EXP)}
+% \begin{syntax}
+% "\cs_split_function:NN" "\"<fn>":"<args> <post process>
+% \end{syntax}
+% Strips off the leading escape character, splits off the signature
+% without the colon, informs whether or not a colon was present and
+% then prefixes these results with <post process>, i.e., <post
+% process>\Arg{name}\Arg{signature}\meta{true}/\meta{false}. For
+% example, "\cs_get_function_name:N" is nothing more than
+% "\cs_split_function:NN" "\"<fn>":"<args> "\use_i:nnn".
+% \end{function}
+%
+%
+% \begin{function}{\cs_get_arg_count_from_signature:N / (EXP)}
+% \begin{syntax}
+% "\cs_get_arg_count_from_signature:N" "\"<fn>":"<args>
+% \end{syntax}
+% Returns the number of chars in <args>, signifying the number of arguments
+% that the function uses.
+% \end{function}
+%
+%
% Other functions regarding arbitrary tokens can be found in the
% \textsf{l3token} module.
%
-% \subsection{Grouping and scanning}
+% \section{Grouping and scanning}
%
% \begin{function}{\scan_stop:}
% \begin{syntax}
@@ -1087,32 +1289,52 @@
% \end{texnote}
% \end{function}
%
+% \begin{function}{\group_execute_after:N}
+% \begin{syntax}
+% "\group_execute_after:N" <token>
+% \end{syntax}
+% Adds <token> to the list of tokens to be inserted after the
+% current group ends (through an explicit or implicit "\group_end:").
+% \begin{texnote}
+% This is \TeX's \tn{aftergroup}.
+% \end{texnote}
+% \end{function}
+%
%
-% \subsection{Engine specific definitions}
+% \section{Checking the engine}
+%
+% \begin{function}{\xetex_if_engine: / (TF)(EXP)}
+% \begin{syntax}
+% "\xetex_if_engine:TF" \Arg{true code} \Arg{false code}
+% \end{syntax}
+% This function detects if we're running a Xe\TeX-based format.
+% \end{function}
%
-% \begin{function}{\engine_if_aleph:TF}
+% \begin{function}{\luatex_if_engine: / (TF)(EXP)}
% \begin{syntax}
-% "\engine_if_aleph:TF" "{"<true code>"}" "{"<false code>"}"
+% "\luatex_if_engine:TF" \Arg{true code} \Arg{false code}
% \end{syntax}
-% This function detects if we're running an Aleph based format. This
-% is particularly useful when allocating registers.
+% This function detects if we're running a Lua\TeX-based format.
% \end{function}
%
+% \begin{variable}{\c_xetex_is_engine_bool|\c_luatex_is_engine_bool}
+% Boolean variables used for the above functions.
+% \end{variable}
%
+% \end{documentation}
%
-% \StopEventually{}
+% \begin{implementation}
%
+% \section{\pkg{l3basics} implementation}
%
-% \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
+% 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 the file \file{l3basics.dtx}.
+% Also, most of the code below won't run until \textsf{l3expan} has been
% loaded.
%
-% \subsubsection{Renaming some \TeX{} primitives (again)}
+% \subsection{Renaming some \TeX{} primitives (again)}
%
-% \begin{macro}{\let:NwN}
+% \begin{macro}{\cs_set_eq: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 appropriate modules, but
@@ -1120,30 +1342,39 @@
% 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>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
%<*initex|package>
-\tex_let:D \let:NwN \tex_let:D
+\tex_let:D \cs_set_eq:NwN \tex_let:D
% \end{macrocode}
% \end{macro}
% \begin{macro}{\if_true:}
% \begin{macro}{\if_false:}
+% \begin{macro}{\or:}
% \begin{macro}{\else:}
% \begin{macro}{\fi:}
% \begin{macro}{\reverse_if:N}
% \begin{macro}{\if:w}
+% \begin{macro}{\if_bool:N}
+% \begin{macro}{\if_predicate: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
+\cs_set_eq:NwN \if_true: \tex_iftrue:D
+\cs_set_eq:NwN \if_false: \tex_iffalse:D
+\cs_set_eq:NwN \or: \tex_or:D
+\cs_set_eq:NwN \else: \tex_else:D
+\cs_set_eq:NwN \fi: \tex_fi:D
+\cs_set_eq:NwN \reverse_if:N \etex_unless:D
+\cs_set_eq:NwN \if:w \tex_if:D
+\cs_set_eq:NwN \if_bool:N \tex_ifodd:D
+\cs_set_eq:NwN \if_predicate:w \tex_ifodd:D
+\cs_set_eq:NwN \if_charcode:w \tex_if:D
+\cs_set_eq:NwN \if_catcode:w \tex_ifcat:D
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1153,28 +1384,26 @@
% \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_meaning:w}
+% \begin{macrocode}
+\cs_set_eq:NwN \if_meaning:w \tex_ifx:D
+% \end{macrocode}
+% \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
+\cs_set_eq:NwN \if_mode_math: \tex_ifmmode:D
+\cs_set_eq:NwN \if_mode_horizontal: \tex_ifhmode:D
+\cs_set_eq:NwN \if_mode_vertical: \tex_ifvmode:D
+\cs_set_eq:NwN \if_mode_inner: \tex_ifinner:D
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1183,29 +1412,30 @@
% \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
+\cs_set_eq:NwN \if_cs_exist:N \etex_ifdefined:D
+\cs_set_eq:NwN \if_cs_exist:w \etex_ifcsname:D
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\exp_after:NN}
+% \begin{macro}{\exp_after:wN}
% \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
+\cs_set_eq:NwN \exp_after:wN \tex_expandafter:D
+\cs_set_eq:NwN \exp_not:N \tex_noexpand:D
+\cs_set_eq:NwN \exp_not:n \etex_unexpanded:D
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\io_put_deferred:Nx}
+% \begin{macro}{\iow_shipout_x:Nn}
% \begin{macro}{\token_to_meaning:N}
-% \begin{macro}{\token_to_string:N}
+% \begin{macro}{\token_to_str:N}
+% \begin{macro}{\token_to_str:c}
% \begin{macro}{\cs:w}
% \begin{macro}{\cs_end:}
% \begin{macro}{\cs_meaning:N}
@@ -1213,15 +1443,16 @@
% \begin{macro}{\cs_show:N}
% \begin{macro}{\cs_show:c}
% \begin{macrocode}
-\let:NwN \io_put_deferred:Nx \tex_write:D
-\let:NwN \token_to_meaning:N \tex_meaning:D
-\let:NwN \token_to_string:N \tex_string:D
-\let:NwN \cs:w \tex_csname:D
-\let:NwN \cs_end: \tex_endcsname:D
-\let:NwN \cs_meaning:N \tex_meaning:D
-\tex_def:D \cs_meaning:c #1{\exp_after:NN\cs_meaning:N\cs:w #1\cs_end:}
-\let:NwN \cs_show:N \tex_show:D
-\tex_def:D \cs_show:c #1{\exp_after:NN\cs_show:N\cs:w #1\cs_end:}
+\cs_set_eq:NwN \iow_shipout_x:Nn \tex_write:D
+\cs_set_eq:NwN \token_to_meaning:N \tex_meaning:D
+\cs_set_eq:NwN \token_to_str:N \tex_string:D
+\cs_set_eq:NwN \cs:w \tex_csname:D
+\cs_set_eq:NwN \cs_end: \tex_endcsname:D
+\cs_set_eq:NwN \cs_meaning:N \tex_meaning:D
+\tex_def:D \cs_meaning:c {\exp_args:Nc\cs_meaning:N}
+\cs_set_eq:NwN \cs_show:N \tex_show:D
+\tex_def:D \cs_show:c {\exp_args:Nc\cs_show:N}
+\tex_def:D \token_to_str:c {\exp_args:Nc\token_to_str:N}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1232,6 +1463,8 @@
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+%
% \begin{macro}{\scan_stop:}
% \begin{macro}{\group_begin:}
% \begin{macro}{\group_end:}
@@ -1239,70 +1472,69 @@
% versions that are safe inside alignments. These safe versions are
% defined in the \textsf{l3prg} module.
% \begin{macrocode}
-\let:NwN \scan_stop: \tex_relax:D
-\let:NwN \group_begin: \tex_begingroup:D
-\let:NwN \group_end: \tex_endgroup:D
+\cs_set_eq:NwN \scan_stop: \tex_relax:D
+\cs_set_eq:NwN \group_begin: \tex_begingroup:D
+\cs_set_eq: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
+\cs_set_eq: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
+\cs_set_eq:NwN \pref_global:D \tex_global:D
+\cs_set_eq:NwN \pref_long:D \tex_long:D
+\cs_set_eq:NwN \pref_protected:D \etex_protected:D
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
%
%
%
-% \subsubsection {Defining functions}
+% \subsection {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}
+% \begin{macro}{\cs_set_nopar:Npn}
+% \begin{macro}{\cs_set_nopar:Npx}
+% \begin{macro}{\cs_set:Npn}
+% \begin{macro}{\cs_set:Npx}
+% \begin{macro}{\cs_set_protected_nopar:Npn}
+% \begin{macro}{\cs_set_protected_nopar:Npx}
+% \begin{macro}{\cs_set_protected:Npn}
+% \begin{macro}{\cs_set_protected: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
+\cs_set_eq:NwN \cs_set_nopar:Npn \tex_def:D
+\cs_set_eq:NwN \cs_set_nopar:Npx \tex_edef:D
+\pref_protected:D \cs_set_nopar:Npn \cs_set:Npn {
+ \pref_long:D \cs_set_nopar:Npn
+}
+\pref_protected:D \cs_set_nopar:Npn \cs_set:Npx {
+ \pref_long:D \cs_set_nopar:Npx
+}
+\pref_protected:D \cs_set_nopar:Npn \cs_set_protected_nopar:Npn {
+ \pref_protected:D \cs_set_nopar:Npn
+}
+\pref_protected:D \cs_set_nopar:Npn \cs_set_protected_nopar:Npx {
+ \pref_protected:D \cs_set_nopar:Npx
+}
+\cs_set_protected_nopar:Npn \cs_set_protected:Npn {
+ \pref_protected:D \pref_long:D \cs_set_nopar:Npn
}
-\def_protected:Npn \def_protected_long:Npx {
- \pref_protected:D \pref_long:D \def:Npx
+\cs_set_protected_nopar:Npn \cs_set_protected:Npx {
+ \pref_protected:D \pref_long:D \cs_set_nopar:Npx
}
% \end{macrocode}
% \end{macro}
@@ -1314,27 +1546,35 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\gdef:Npn}
-% \begin{macro}{\gdef:Npx}
-% \begin{macro}{\gdef_long:Npn}
-% \begin{macro}{\gdef_long:Npx}
-% \begin{macro}{\gdef_protected:Npn}
-% \begin{macro}{\gdef_protected:Npx}
-% \begin{macro}{\gdef_protected_long:Npn}
-% \begin{macro}{\gdef_protected_long:Npx}
+% \begin{macro}{\cs_gset_nopar:Npn}
+% \begin{macro}{\cs_gset_nopar:Npx}
+% \begin{macro}{\cs_gset:Npn}
+% \begin{macro}{\cs_gset:Npx}
+% \begin{macro}{\cs_gset_protected_nopar:Npn}
+% \begin{macro}{\cs_gset_protected_nopar:Npx}
+% \begin{macro}{\cs_gset_protected:Npn}
+% \begin{macro}{\cs_gset_protected: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
+\cs_set_eq:NwN \cs_gset_nopar:Npn \tex_gdef:D
+\cs_set_eq:NwN \cs_gset_nopar:Npx \tex_xdef:D
+\cs_set_protected_nopar:Npn \cs_gset:Npn {
+ \pref_long:D \cs_gset_nopar:Npn
}
-\def_protected:Npn \gdef_protected_long:Npx {
- \pref_protected:D \pref_long:D \gdef:Npx
+\cs_set_protected_nopar:Npn \cs_gset:Npx {
+ \pref_long:D \cs_gset_nopar:Npx
+}
+\cs_set_protected_nopar:Npn \cs_gset_protected_nopar:Npn {
+ \pref_protected:D \cs_gset_nopar:Npn
+}
+\cs_set_protected_nopar:Npn \cs_gset_protected_nopar:Npx {
+ \pref_protected:D \cs_gset_nopar:Npx
+}
+\cs_set_protected_nopar:Npn \cs_gset_protected:Npn {
+ \pref_protected:D \pref_long:D \cs_gset_nopar:Npn
+}
+\cs_set_protected_nopar:Npn \cs_gset_protected:Npx {
+ \pref_protected:D \pref_long:D \cs_gset_nopar:Npx
}
% \end{macrocode}
% \end{macro}
@@ -1346,34 +1586,666 @@
% \end{macro}
% \end{macro}
%
-% \subsubsection{Predicate implementation}
%
+%
+% \subsection{Selecting tokens}
+%
+% \begin{macro}{\use:c}
+% This macro grabs its argument and returns a csname from it.
+% \begin{macrocode}
+\cs_set:Npn \use:c #1 { \cs:w#1\cs_end: }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\use:n}
+% \begin{macro}{\use:nn}
+% \begin{macro}{\use:nnn}
+% \begin{macro}{\use:nnnn}
+% These macro grabs its arguments and returns it back to the input
+% (with outer braces removed). "\use:n" is defined earlier for bootstrapping.
+% \begin{macrocode}
+\cs_set:Npn \use:n #1 {#1}
+\cs_set:Npn \use:nn #1#2 {#1#2}
+\cs_set:Npn \use:nnn #1#2#3 {#1#2#3}
+\cs_set:Npn \use:nnnn #1#2#3#4 {#1#2#3#4}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\use_i:nn}
+% \begin{macro}{\use_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:wN| |\use_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_bool| syntax is used.
+% \begin{macrocode}
+\cs_set:Npn \use_i:nn #1#2 {#1}
+\cs_set:Npn \use_ii:nn #1#2 {#2}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\use_i:nnn}
+% \begin{macro}{\use_ii:nnn}
+% \begin{macro}{\use_iii:nnn}
+% \begin{macro}{\use_i:nnnn}
+% \begin{macro}{\use_ii:nnnn}
+% \begin{macro}{\use_iii:nnnn}
+% \begin{macro}{\use_iv:nnnn}
+% \begin{macro}{\use_i_ii:nnn}
+% We also need something for picking up arguments from a longer
+% list.
+% \begin{macrocode}
+\cs_set:Npn \use_i:nnn #1#2#3{#1}
+\cs_set:Npn \use_ii:nnn #1#2#3{#2}
+\cs_set:Npn \use_iii:nnn #1#2#3{#3}
+\cs_set:Npn \use_i:nnnn #1#2#3#4{#1}
+\cs_set:Npn \use_ii:nnnn #1#2#3#4{#2}
+\cs_set:Npn \use_iii:nnnn #1#2#3#4{#3}
+\cs_set:Npn \use_iv:nnnn #1#2#3#4{#4}
+\cs_set:Npn \use_i_ii:nnn #1#2#3{#1#2}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\use_none_delimit_by_q_nil:w}
+% \begin{macro}{\use_none_delimit_by_q_stop:w}
+% \begin{macro}{\use_none_delimit_by_q_recursion_stop:w}
+% Functions that gobble everything until they see either |\q_nil| or
+% |\q_stop| resp.
+% \begin{macrocode}
+\cs_set:Npn \use_none_delimit_by_q_nil:w #1\q_nil{}
+\cs_set:Npn \use_none_delimit_by_q_stop:w #1\q_stop{}
+\cs_set:Npn \use_none_delimit_by_q_recursion_stop:w #1 \q_recursion_stop {}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\use_i_delimit_by_q_nil:nw}
+% \begin{macro}{\use_i_delimit_by_q_stop:nw}
+% \begin{macro}{\use_i_delimit_by_q_recursion_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}
+\cs_set:Npn \use_i_delimit_by_q_nil:nw #1#2\q_nil{#1}
+\cs_set:Npn \use_i_delimit_by_q_stop:nw #1#2\q_stop{#1}
+\cs_set:Npn \use_i_delimit_by_q_recursion_stop:nw #1#2 \q_recursion_stop {#1}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\use_i_after_fi:nw}
+% \begin{macro}{\use_i_after_else:nw}
+% \begin{macro}{\use_i_after_or:nw}
+% \begin{macro}{\use_i_after_orelse:nw}
+% Returns the first argument after ending the conditional.
+% \begin{macrocode}
+\cs_set:Npn \use_i_after_fi:nw #1\fi:{\fi: #1}
+\cs_set:Npn \use_i_after_else:nw #1\else:#2\fi:{\fi: #1}
+\cs_set:Npn \use_i_after_or:nw #1\or: #2\fi: {\fi:#1}
+\cs_set:Npn \use_i_after_orelse:nw #1 #2#3\fi: {\fi:#1}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \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}
+% \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}
+\cs_set:Npn \use_none:n #1{}
+\cs_set:Npn \use_none:nn #1#2{}
+\cs_set:Npn \use_none:nnn #1#2#3{}
+\cs_set:Npn \use_none:nnnn #1#2#3#4{}
+\cs_set:Npn \use_none:nnnnn #1#2#3#4#5{}
+\cs_set:Npn \use_none:nnnnnn #1#2#3#4#5#6{}
+\cs_set:Npn \use_none:nnnnnnn #1#2#3#4#5#6#7{}
+\cs_set:Npn \use_none:nnnnnnnn #1#2#3#4#5#6#7#8{}
+\cs_set:Npn \use_none:nnnnnnnnn #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}
+%
+% \subsection{Expansion control from l3expan}
+%
+% \begin{macro}{\exp_args:Nc}
+% Moved here for now as it is going to be used right away.
+% \begin{macrocode}
+\cs_set:Npn \exp_args:Nc #1#2{\exp_after:wN#1\cs:w#2\cs_end:}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Conditional processing and definitions}
+%
+% Underneath any predicate function (|_p|) or other conditional forms
+% (|TF|, etc.) is a built-in logic saying that it after all of the
+% testing and processing must return the \meta{state} this leaves
+% \TeX\ in. Therefore, a simple user interface could be something like
+% \begin{verbatim}
+% \if_meaning:w #1#2 \prg_return_true: \else:
+% \if_meaning:w #1#3 \prg_return_true: \else:
+% \prg_return_false:
+% \fi: \fi:
+% \end{verbatim}
+% Usually, a \TeX\ programmer would have to insert a number of
+% |\exp_after:wN|s to ensure the state value is returned at exactly
+% the point where the last conditional is finished. However, that
+% obscures the code and forces the \TeX\ programmer to prove that
+% he/she knows the $2^{n}-1$ table. We therefore provide the simpler
+% interface.
+%
+% \begin{macro}{\prg_return_true:}
+% \begin{macro}{\prg_return_false:}
+% These break statements put \TeX\ in a \m{true} or \m{false} state.
+% The idea is that the expansion of |\tex_romannumeral:D \c_zero| is
+% \m{null} so we set off a |\tex_romannumeral:D|. It will on its
+% way expand any |\else:| or |\fi:| that are waiting to be discarded
+% anyway before finally arriving at the |\c_zero| we will place
+% right after the conditional. After this expansion has terminated,
+% we issue either |\if_true:| or |\if_false:| to put \TeX\ in the
+% correct state.
+% \begin{macrocode}
+\cs_set:Npn \prg_return_true: { \exp_after:wN\if_true:\tex_romannumeral:D }
+\cs_set:Npn \prg_return_false: {\exp_after:wN\if_false:\tex_romannumeral:D }
+% \end{macrocode}
+% An extended state space could instead utilize |\tex_ifcase:D|:
+% \begin{verbatim}
+% \cs_set:Npn \prg_return_true: {
+% \exp_after:wN\tex_ifcase:D \exp_after:wN \c_zero \tex_romannumeral:D
+% }
+% \cs_set:Npn \prg_return_false: {
+% \exp_after:wN\tex_ifcase:D \exp_after:wN \c_one \tex_romannumeral:D
+% }
+% \cs_set:Npn \prg_return_error: {
+% \exp_after:wN\tex_ifcase:D \exp_after:wN \c_two \tex_romannumeral:D
+% }
+% \end{verbatim}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\prg_set_conditional:Npnn,\prg_new_conditional:Npnn,
+% \prg_set_protected_conditional:Npnn,\prg_new_protected_conditional:Npnn}
+% The user functions for the types using parameter text from the
+% programmer. Call aux function to grab parameters, split the base
+% function into name and signature and then use, e.g., |\cs_set:Npn|
+% to define it with.
+% \begin{macrocode}
+\cs_set:Npn \prg_set_conditional:Npnn #1{
+ \prg_get_parm_aux:nw{
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_set:Npn {parm}
+ }
+}
+\cs_set:Npn \prg_new_conditional:Npnn #1{
+ \prg_get_parm_aux:nw{
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_new:Npn {parm}
+ }
+}
+\cs_set:Npn \prg_set_protected_conditional:Npnn #1{
+ \prg_get_parm_aux:nw{
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_set_protected:Npn {parm}
+ }
+}
+\cs_set:Npn \prg_new_protected_conditional:Npnn #1{
+ \prg_get_parm_aux:nw{
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_new_protected:Npn {parm}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\prg_set_conditional:Nnn,\prg_new_conditional:Nnn,
+% \prg_set_protected_conditional:Nnn,\prg_new_protected_conditional:Nnn}
+% The user functions for the types automatically inserting the
+% correct parameter text based on the signature. Call aux function
+% after calculating number of arguments, split the base function
+% into name and signature and then use, e.g., |\cs_set:Npn| to
+% define it with.
+% \begin{macrocode}
+\cs_set:Npn \prg_set_conditional:Nnn #1{
+ \exp_args:Nnf \prg_get_count_aux:nn{
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_set:Npn {count}
+ }{\cs_get_arg_count_from_signature:N #1}
+}
+\cs_set:Npn \prg_new_conditional:Nnn #1{
+ \exp_args:Nnf \prg_get_count_aux:nn{
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_new:Npn {count}
+ }{\cs_get_arg_count_from_signature:N #1}
+}
+
+\cs_set:Npn \prg_set_protected_conditional:Nnn #1{
+ \exp_args:Nnf \prg_get_count_aux:nn{
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_set_protected:Npn {count}
+ }{\cs_get_arg_count_from_signature:N #1}
+}
+
+\cs_set:Npn \prg_new_protected_conditional:Nnn #1{
+ \exp_args:Nnf \prg_get_count_aux:nn{
+ \cs_split_function:NN #1 \prg_generate_conditional_aux:nnNNnnnn
+ \cs_new_protected:Npn {count}
+ }{\cs_get_arg_count_from_signature:N #1}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\prg_get_parm_aux:nw,\prg_get_count_aux:nn}
+% For the "Npnn" type we must grab the parameter text before
+% continuing. We make this a very generic function that takes one
+% argument before reading everything up to a left brace. Something
+% similar for the "Nnn" type.
+% \begin{macrocode}
+\cs_set:Npn \prg_get_count_aux:nn #1#2 {#1{#2}}
+\cs_set:Npn \prg_get_parm_aux:nw #1#2#{#1{#2}}
+% \end{macrocode}
+% \end{macro}
+% \begin{macro}[aux]{\prg_generate_conditional_parm_aux:nnNNnnnn,
+% \prg_generate_conditional_parm_aux:nw}
+%
+% The workhorse here is going through a list of desired forms, i.e.,
+% p, TF, T and F. The first three arguments come from splitting up
+% the base form of the conditional, which gives the name, signature
+% and a boolean to signal whether or not there was a colon in the
+% name. For the time being, we do not use this piece of information
+% but could well throw an error. The fourth argument is how to
+% define this function, the fifth is the text "parm" or "count" for
+% which version to use to define the functions, the sixth is the
+% parameters to use (possibly empty) or number of arguments, the
+% seventh is the list of forms to define, the eight is the
+% replacement text which we will augment when defining the forms.
+% \begin{macrocode}
+\cs_set:Npn \prg_generate_conditional_aux:nnNNnnnn #1#2#3#4#5#6#7#8{
+ \prg_generate_conditional_aux:nnw{#5}{
+ #4{#1}{#2}{#6}{#8}
+ }#7,?, \q_recursion_stop
+}
+% \end{macrocode}
+% Looping through the list of desired forms. First is the text "parm"
+% or "count", second is five arguments packed together and third is
+% the form. Use text and form to call the correct type.
+% \begin{macrocode}
+\cs_set:Npn \prg_generate_conditional_aux:nnw #1#2#3,{
+ \if:w ?#3
+ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ \use:c{prg_generate_#3_form_#1:Nnnnn} #2
+ \prg_generate_conditional_aux:nnw{#1}{#2}
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\prg_generate_p_form_parm:Nnnnn,
+% \prg_generate_TF_form_parm:Nnnnn,
+% \prg_generate_T_form_parm:Nnnnn,
+% \prg_generate_F_form_parm:Nnnnn
+% }
+% How to generate the various forms. The "parm" types here takes the
+% following arguments: 1: how to define (an N-type), 2: name, 3:
+% signature, 4: parameter text (or empty), 5: replacement.
+% \begin{macrocode}
+\cs_set:Npn \prg_generate_p_form_parm:Nnnnn #1#2#3#4#5{
+ \exp_args:Nc #1 {#2_p:#3}#4{#5 \c_zero
+ \exp_after:wN\c_true_bool\else:\exp_after:wN\c_false_bool\fi:
+ }
+}
+\cs_set:Npn \prg_generate_TF_form_parm:Nnnnn #1#2#3#4#5{
+ \exp_args:Nc#1 {#2:#3TF}#4{#5 \c_zero
+ \exp_after:wN \use_i:nn \else: \exp_after:wN \use_ii:nn \fi:
+ }
+}
+\cs_set:Npn \prg_generate_T_form_parm:Nnnnn #1#2#3#4#5{
+ \exp_args:Nc#1 {#2:#3T}#4{#5 \c_zero
+ \else:\exp_after:wN\use_none:nn\fi:\use:n
+ }
+}
+\cs_set:Npn \prg_generate_F_form_parm:Nnnnn #1#2#3#4#5{
+ \exp_args:Nc#1 {#2:#3F}#4{#5 \c_zero
+ \exp_after:wN\use_none:nn\fi:\use:n
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[aux]{\prg_generate_p_form_count:Nnnnn,
+% \prg_generate_TF_form_count:Nnnnn,
+% \prg_generate_T_form_count:Nnnnn,
+% \prg_generate_F_form_count:Nnnnn
+% }
+% How to generate the various forms. The "count" types here use a
+% number to insert the correct parameter text, otherwise like the
+% "parm" functions above.
+% \begin{macrocode}
+\cs_set:Npn \prg_generate_p_form_count:Nnnnn #1#2#3#4#5{
+ \cs_generate_from_arg_count:cNnn {#2_p:#3} #1 {#4}{#5 \c_zero
+ \exp_after:wN\c_true_bool\else:\exp_after:wN\c_false_bool\fi:
+ }
+}
+\cs_set:Npn \prg_generate_TF_form_count:Nnnnn #1#2#3#4#5{
+ \cs_generate_from_arg_count:cNnn {#2:#3TF} #1 {#4}{#5 \c_zero
+ \exp_after:wN\use_i:nn\else:\exp_after:wN\use_ii:nn\fi:
+ }
+}
+\cs_set:Npn \prg_generate_T_form_count:Nnnnn #1#2#3#4#5{
+ \cs_generate_from_arg_count:cNnn {#2:#3T} #1 {#4}{#5 \c_zero
+ \else:\exp_after:wN\use_none:nn\fi:\use:n
+ }
+}
+\cs_set:Npn \prg_generate_F_form_count:Nnnnn #1#2#3#4#5{
+ \cs_generate_from_arg_count:cNnn {#2:#3F} #1 {#4}{#5 \c_zero
+ \exp_after:wN\use_none:nn\fi:\use:n
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+% All that is left is to define the canonical boolean true and false.
% 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.
+% \texttt{00} and \texttt{01}, so they could be used in logical
+% operations. Later again they were changed to being numerical
+% constants with values of $1$ for true and $0$ for false. We need
+% this from the get-go.
%
-% \begin{macro}{\c_true}
-% \begin{macro}{\c_false}
+% \begin{macro}{\c_true_bool}
+% \begin{macro}{\c_false_bool}
% Here are the canonical boolean values.
% \begin{macrocode}
-\def:Npn \c_true {00}
-\def:Npn \c_false {01}
+\tex_chardef:D \c_true_bool = 1~
+\tex_chardef:D \c_false_bool = 0~
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \subsubsection {Defining and checking (new) functions}
+%
+% \subsection{Dissecting a control sequence}
+%
+% \begin{macro}{\cs_to_str:N}
+% \begin{macro}[aux]{\cs_to_str_aux:w}
+% This converts a control sequence into the character string of its
+% name, removing the leading escape character. This turns out to be
+% a non-trivial matter as there a different cases:
+% \begin{itemize}
+% \item The usual case of a printable escape character;
+% \item the case of a non-printable escape characters, e.g., when
+% the value of |\tex_escapechar:D| is negative;
+% \item when the escape character is a space.
+% \end{itemize}
+% The route chosen is this: If |\token_to_str:N \a| produces a
+% non-space escape char, then this will produce two tokens. If the
+% escape char is non-printable, only one token is produced. If the
+% escape char is a space, then a space token plus one token
+% character token is produced. If we augment the result of this
+% expansion with the letters |ax| we get the following three
+% scenarios (with \meta{X} being a printable non-space escape
+% character):
+% \begin{itemize}
+% \item \meta{X}"aax"
+% \item "aax"
+% \item " aax"
+% \end{itemize}
+% In the second and third case, putting an auxiliary function in front
+% reading undelimited arguments will treat them the same, removing the
+% space token for us automatically. Therefore, if we test the second
+% and third argument of what such a function reads, in case 1 we will
+% get true and in cases 2 and 3 we will get false. If we choose to
+% optimize for the usual case of a printable escape char, we can do it
+% like this (again getting TeX to remove the leading space for us):
+% \begin{macrocode}
+\cs_set_nopar:Npn \cs_to_str:N {
+ \if:w \exp_after:wN \cs_str_aux:w\token_to_str:N \a ax\q_nil
+ \else:
+ \exp_after:wN \exp_after:wN\exp_after:wN \use_ii:nn
+ \fi:
+ \exp_after:wN \use_none:n \token_to_str:N
+}
+\cs_set:Npn \cs_str_aux:w #1#2#3#4\q_nil{#2#3}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \begin{macro}{\cs_split_function:NN}
+% \begin{macro}[aux]{\cs_split_function_aux:w}
+% \begin{macro}[aux]{\cs_split_function_auxii:w}
+% This function takes a function name and splits it into name with
+% the escape char removed and argument specification. In addition to
+% this, a third argument, a boolean \m{true} or \m{false} is
+% returned with \m{true} for when there is a colon in the function
+% and \m{false} if there is not. Lastly, the second argument of
+% |\cs_split_function:NN| is supposed to be a function
+% taking three variables, one for name, one for signature, and one
+% for the boolean. For example,
+% "\cs_split_function:NN\foo_bar:cnx\use_i:nnn" as input
+% becomes "\use_i:nnn {foo_bar}{cnx}\c_true_bool".
+%
+% Can't use a literal ":" because it has the wrong catcode here, so
+% it's transformed from "@" with "\tex_lowercase:D".
+% \begin{macrocode}
+\group_begin:
+ \tex_lccode:D `\@ = `\: \scan_stop:
+ \tex_catcode:D `\@ = 12~
+\tex_lowercase:D {
+ \group_end:
+% \end{macrocode}
+% First ensure that we actually get a properly evaluated str as we
+% don't know how many expansions |\cs_to_str:N| requires. Insert
+% extra colon to catch the error cases.
+% \begin{macrocode}
+\cs_set:Npn \cs_split_function:NN #1#2{
+ \exp_after:wN \cs_split_function_aux:w
+ \tex_romannumeral:D -`\q \cs_to_str:N #1 @a \q_nil #2
+}
+% \end{macrocode}
+% If no colon in the name, |#2| is |a| with catcode 11 and |#3| is
+% empty. If colon in the name, then either |#2| is a colon or the
+% first letter of the signature. The letters here have catcode 12.
+% If a colon was given we need to a) split off the colon and quark at
+% the end and b) ensure we return the name, signature and boolean true
+% We can't use |\quark_if_no_value:NTF| yet but this is very safe
+% anyway as all tokens have catcode~12.
+% \begin{macrocode}
+\cs_set:Npn \cs_split_function_aux:w #1@#2#3\q_nil#4{
+ \if_meaning:w a#2
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN\use_ii:nn
+ \fi:
+ {#4{#1}{}\c_false_bool}
+ {\cs_split_function_auxii:w#2#3\q_nil #4{#1}}
+}
+\cs_set:Npn \cs_split_function_auxii:w #1@a\q_nil#2#3{
+ #2{#3}{#1}\c_true_bool
+}
+% \end{macrocode}
+% End of lowercase
+% \begin{macrocode}
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cs_get_function_name:N, \cs_get_function_signature:N }
+% Now returning the name is trivial: just discard the last two
+% arguments. Similar for signature.
+% \begin{macrocode}
+\cs_set:Npn \cs_get_function_name:N #1 {
+ \cs_split_function:NN #1\use_i:nnn
+}
+\cs_set:Npn \cs_get_function_signature:N #1 {
+ \cs_split_function:NN #1\use_ii:nnn
+}
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Exist or free}
+%
+% A control sequence is said to \emph{exist} (to be used) if has an entry in
+% the hash table and its meaning is different from the primitive
+% "\tex_relax:D" token. A control sequence is said to be \emph{free}
+% (to be defined) if it does not already exist and also meets the
+% requirement that it does not contain a "D" signature. The reasoning
+% behind this is that most of the time, a check for a free control
+% sequence is when we wish to make a new control sequence and we do
+% not want to let the user define a new ``do not use'' control
+% sequence.
+%
+% \begin{macro}{\cs_if_exist_p:N,\cs_if_exist_p:c}
+% \begin{macro}[TF]{\cs_if_exist:N,\cs_if_exist:c}
+% Two versions for checking existence. For the "N" form we firstly
+% check for "\tex_relax:D" and then if it is in the hash
+% table. There is no problem when inputting something like "\else:"
+% or "\fi:" as \TeX\ will only ever skip input in case the token
+% tested against is "\tex_relax:D".
+% \begin{macrocode}
+\prg_set_conditional:Npnn \cs_if_exist:N #1 {p,TF,T,F}{
+ \if_meaning:w #1\tex_relax:D
+ \prg_return_false:
+ \else:
+ \if_cs_exist:N #1
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ \fi:
+}
+% \end{macrocode}
+% For the "c" form we firstly check if it is in the hash table and
+% then for "\tex_relax:D" so that we do not add it to the hash table
+% unless it was already there. Here we have to be careful as the text
+% to be skipped if the first test is false may contain tokens that
+% disturb the scanner. Therefore, we ensure that the second test is
+% performed after the first one has concluded completely.
+% \begin{macrocode}
+\prg_set_conditional:Npnn \cs_if_exist:c #1 {p,TF,T,F}{
+ \if_cs_exist:w #1 \cs_end:
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ {
+ \exp_after:wN \if_meaning:w \cs:w #1\cs_end: \tex_relax:D
+ \prg_return_false:
+ \else:
+ \prg_return_true:
+ \fi:
+ }
+ \prg_return_false:
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cs_if_do_not_use_p:N}
+% \begin{macro}[aux]{\cs_if_do_not_use_aux:nnN}
+% \begin{macrocode}
+\cs_set:Npn \cs_if_do_not_use_p:N #1{
+ \cs_split_function:NN #1 \cs_if_do_not_use_aux:nnN
+}
+\cs_set:Npn \cs_if_do_not_use_aux:nnN #1#2#3{
+ \exp_after:wN\str_if_eq_p:nn \token_to_str:N D {#2}
+}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\cs_if_free_p:N,\cs_if_free_p:c}
+% \begin{macro}[TF]{\cs_if_free:N,\cs_if_free:c}
+% The simple implementation is one using the boolean expression
+% parser: If it is exists or is do not use, then return false.
+% \begin{verbatim}
+% \prg_set_conditional:Npnn \cs_if_free:N #1{p,TF,T,F}{
+% \bool_if:nTF {\cs_if_exist_p:N #1 || \cs_if_do_not_use_p:N #1}
+% {\prg_return_false:}{\prg_return_true:}
+% }
+% \end{verbatim}
+% However, this functionality may not be available this early on. We
+% do something similar: The numerical values of true and false is one
+% and zero respectively, which we can use. The problem again here is
+% that the token we are checking may in fact be something that can
+% disturb the scanner, so we have to be careful. We would like to do
+% minimal evaluation so we ensure this.
+% \begin{macrocode}
+\prg_set_conditional:Npnn \cs_if_free:N #1{p,TF,T,F}{
+ \tex_ifnum:D \cs_if_exist_p:N #1 =\c_zero
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ {
+ \tex_ifnum:D \cs_if_do_not_use_p:N #1 =\c_zero
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+ \prg_return_false:
+}
+\cs_set_nopar:Npn \cs_if_free_p:c{\exp_args:Nc\cs_if_free_p:N}
+\cs_set_nopar:Npn \cs_if_free:cTF{\exp_args:Nc\cs_if_free:NTF}
+\cs_set_nopar:Npn \cs_if_free:cT{\exp_args:Nc\cs_if_free:NT}
+\cs_set_nopar:Npn \cs_if_free:cF{\exp_args:Nc\cs_if_free:NF}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{Defining and checking (new) functions}
%
% \begin{macro}{\c_minus_one}
+% \begin{macro}{\c_zero}
% \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
+% writing information to the log and the terminal and |\c_zero|
+% which is used by some functions in the \textsf{l3num}module. The
+% rest are defined in the \textsf{l3int} module -- at least for the
% ones that can be defined with |\tex_chardef:D| or
-% |\tex_mathchardef:D|. Otherwise the \textsf{l3int} module is
+% |\tex_mathchardef:D|. For other constants 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
@@ -1381,16 +2253,18 @@
% |\c_minus_one|.
% \begin{macrocode}
%<*!initex>
-\let:NwN \c_minus_one\m@ne
+\cs_set_eq:NwN \c_minus_one\m@ne
%</!initex>
%<*!package>
-\tex_countdef:D \c_minus_one = 10 \scan_stop:
-\c_minus_one = -1 \scan_stop:
+\tex_countdef:D \c_minus_one = 10 ~
+\c_minus_one = -1 ~
%</!package>
-\tex_chardef:D \c_sixteen = 16\scan_stop:
+\tex_chardef:D \c_sixteen = 16~
+\tex_chardef:D \c_zero = 0~
% \end{macrocode}
% \end{macro}
% \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
@@ -1402,25 +2276,29 @@
% 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}{\iow_log:x}
+% \begin{macro}{\iow_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.
%
% \begin{macrocode}
-\def:Npn \io_put_log:x{
- \tex_immediate:D\io_put_deferred:Nx \c_minus_one }
-\def:Npn \io_put_term:x{
- \tex_immediate:D\io_put_deferred:Nx \c_sixteen }
+\cs_set_nopar:Npn \iow_log:x {
+ \tex_immediate:D \iow_shipout_x:Nn \c_minus_one
+}
+\cs_set_nopar:Npn \iow_term:x {
+ \tex_immediate:D \iow_shipout_x:Nn \c_sixteen
+}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\err_latex_bug:x}
+% \begin{macro}{\msg_kernel_bug:x}
% This will show internal errors.
% \begin{macrocode}
-\def:Npn\err_latex_bug:x#1{
- \io_put_term:x{This~is~a~LaTeX~bug!~Check~coding!}\tex_errmessage:D{#1}}
+\cs_set_nopar:Npn \msg_kernel_bug:x #1 {
+ \iow_term:x { This~is~a~LaTeX~bug:~check~coding! }
+ \tex_errmessage:D {#1}
+}
% \end{macrocode}
% \end{macro}
%
@@ -1430,123 +2308,72 @@
% definition here.
% \begin{macrocode}
%<*trace>
-\def:Npn \cs_record_meaning:N#1{}
+\cs_set:Npn \cs_record_meaning:N #1{}
%</trace>
% \end{macrocode}
% \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.\
+% \begin{macro}{\chk_if_free_cs:N}
+% This command is called by |\cs_new_nopar:Npn| and |\cs_new_eq: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:w \cs_if_free_p:N #1
- \exp_after:NN \use_none:n
- \else:
- \exp_after:NN \use_arg_i:n
- \fi:
+\cs_set_nopar:Npn \chk_if_free_cs:N #1{
+ \cs_if_free:NF #1
{
- \err_latex_bug:x {Command~name~`\token_to_string:N #1'~
+ \msg_kernel_bug:x {Command~name~`\token_to_str: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~
+% \iow_term:x{Defining~\token_to_str:N #1~on~%}
+ \iow_log:x{Defining~\token_to_str:N #1~on~
line~\tex_the:D \tex_inputlineno:D}
%</trace>
}
% \end{macrocode}
% \end{macro}
%
-% 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_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_if_exist_cs:N }
% \begin{macro}{\chk_if_exist_cs:c }
% This function issues a warning message when the control sequence
% in its argument does not exist.
% \begin{macrocode}
-\def:Npn \chk_if_exist_cs:N #1 {
- \if:w \cs_if_exist_p:N #1
- \else:
- \err_latex_bug:x{Command~ `\token_to_string:N #1'~
+\cs_set_nopar:Npn \chk_if_exist_cs:N #1 {
+ \cs_if_exist:NF #1
+ {
+ \msg_kernel_bug:x {Command~ `\token_to_str:N #1'~
not~ yet~ defined!}
- \fi:}
-\def:Npn \chk_if_exist_cs:c #1 {
- \exp_after:NN \chk_if_exist_cs:N \cs:w #1\cs_end: }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\cs_if_free_p:N}
-% Expands into |\c_true| if the control sequence given as its
-% argument is not yet in use. Note that we make sure to expand
-% into |\c_false| if the control sequence is textually
-% |\c_undefined| or |\scan_stop:|, so that we don't end up
-% (re)defining them.
-% \begin{macrocode}
-\def:Npn \cs_if_free_p:N #1{
- \if_cs_exist:N #1
- \if_meaning:NN#1\scan_stop:
- \if:w\cs_if_eq_name_p:NN #1\scan_stop:
- \c_false \else: \c_true \fi:
- \else:
- \c_false
- \fi:
- \else:
- \if:w \cs_if_eq_name_p:NN #1\c_undefined
- \c_false \else: \c_true \fi:
- \fi:
+ }
}
-\let:NwN \cs_free_p:N \cs_if_free_p:N
+\cs_set_nopar:Npn \chk_if_exist_cs:c {\exp_args:Nc \chk_if_exist_cs:N }
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
%
% \begin{macro}{\str_if_eq_p:nn}
-% \begin{macro}{\str_if_eq_p_aux:w}
+% \begin{macro}[aux]{\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
+% |\c_true_bool| if they are equal, and |\c_false_bool| 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{
+\prg_set_conditional:Npnn \str_if_eq:nn #1#2{p}{
\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:
+\cs_set_nopar:Npn \str_if_eq_p_aux:w #1#2\\#3#4\\{
+ \if_meaning:w#1#3
+ \if_meaning:w#1\scan_stop:\prg_return_true: \else:
+ \if_meaning:w#3\scan_stop:\prg_return_false: \else:
\str_if_eq_p_aux:w #2\\#4\\\fi:\fi:
- \else:\c_false \fi:}
+ \else:\prg_return_false: \fi:}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1557,21 +2384,21 @@
% arguments and expands into true iff they have the same name.
% We make it long in case one of them is |\par|!
% \begin{macrocode}
-\def_long:Npn \cs_if_eq_name_p:NN #1#2{
- \exp_after:NN\exp_after:NN
- \exp_after:NN\str_if_eq_p_aux:w
- \exp_after:NN\token_to_string:N
- \exp_after:NN#1
- \exp_after:NN\scan_stop:
- \exp_after:NN\\
- \token_to_string:N#2\scan_stop:\\}
+\prg_set_conditional:Npnn \cs_if_eq_name:NN #1#2{p}{
+ \exp_after:wN\exp_after:wN
+ \exp_after:wN\str_if_eq_p_aux:w
+ \exp_after:wN\token_to_str:N
+ \exp_after:wN#1
+ \exp_after:wN\scan_stop:
+ \exp_after:wN\\
+ \token_to_str:N#2\scan_stop:\\}
% \end{macrocode}
% \end{macro}
%
%
% \begin{macro}{\str_if_eq_var_p:nf}
-% \begin{macro}{\str_if_eq_var_start:nnN}
-% \begin{macro}{\str_if_eq_var_stop:w}
+% \begin{macro}[aux]{\str_if_eq_var_start:nnN}
+% \begin{macro}[aux]{\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
@@ -1591,19 +2418,19 @@
% 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
+% return either |\c_true_bool| or |\c_false_bool| since some parts of
% \textsf{l3prg} expect a predicate to return one of these two
% tokens.
% \begin{macrocode}
-\def:Npn \str_if_eq_var_p:nf#1{
- \if:w \tex_number:D\str_if_eq_var_start:nnN{}{}#1\scan_stop:
+\prg_set_conditional:Npnn \str_if_eq_var:nf #1#2 {p} {
+ \if:w \tex_number:D\str_if_eq_var_start:nnN{}{}#1\scan_stop:{#2}
}
-\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:
+\cs_set_nopar:Npn\str_if_eq_var_start:nnN#1#2#3{
+ \if:w#3\scan_stop:\exp_after:wN\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:
+\cs_set:Npn\str_if_eq_var_stop:w\str_if_eq_var_start:nnN#1#2#3{
+ #1#3\scan_stop:'#213~\prg_return_true:\else:\prg_return_false:\fi:
}
% \end{macrocode}
% \end{macro}
@@ -1613,39 +2440,37 @@
%
%
%
-% \subsubsection{More new definitions}
+% \subsection{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
+% \begin{macro}{\cs_new_nopar:Npn}
+% \begin{macro}{\cs_new_nopar:Npx}
+% \begin{macro}{\cs_new:Npn}
+% \begin{macro}{\cs_new:Npx}
+% \begin{macro}{\cs_new_protected_nopar:Npn}
+% \begin{macro}{\cs_new_protected_nopar:Npx}
+% \begin{macro}{\cs_new_protected:Npn}
+% \begin{macro}{\cs_new_protected:Npx}
+% These are like |\cs_set_nopar:Npn| and |\cs_set_eq:NN|, but they
+% first check that the argument command is not already in use. You
+% may use |\pref_global:D|, |\pref_long:D|, |\pref_protected:D|, and
% |\tex_outer:D| as prefixes.
% \begin {macrocode}
-\def_protected:Npn \def_new:Npn #1{\chk_new_cs:N #1
- \def:Npn #1}
-\def_protected:Npn \def_new:Npx #1{\chk_new_cs:N #1
- \def:Npx #1}
-\def_protected:Npn \def_long_new:Npn #1{\chk_new_cs:N #1
- \def_long:Npn #1}
-\def_protected:Npn \def_long_new:Npx #1{\chk_new_cs:N #1
- \def_long:Npx #1}
-\def_protected:Npn \def_protected_new:Npn #1{\chk_new_cs:N #1
- \def_protected:Npn #1}
-\def_protected:Npn \def_protected_new:Npx #1{\chk_new_cs:N #1
- \def_protected:Npx #1}
-\def_protected:Npn \def_protected_long_new:Npn #1{\chk_new_cs:N #1
- \def_protected_long:Npn #1}
-\def_protected:Npn \def_protected_long_new:Npx #1{\chk_new_cs:N #1
- \def_protected_long:Npx #1}
+\cs_set:Npn \cs_tmp:w #1#2{
+ \cs_set_protected_nopar:Npn #1 ##1 {
+ \chk_if_free_cs:N ##1
+ #2 ##1
+ }
+}
+\cs_tmp:w \cs_new_nopar:Npn \cs_set_nopar:Npn
+\cs_tmp:w \cs_new_nopar:Npx\cs_set_nopar:Npx
+\cs_tmp:w \cs_new:Npn \cs_set:Npn
+\cs_tmp:w \cs_new:Npx\cs_set:Npx
+\cs_tmp:w \cs_new_protected_nopar:Npn \cs_set_protected_nopar:Npn
+\cs_tmp:w \cs_new_protected_nopar:Npx\cs_set_protected_nopar:Npx
+\cs_tmp:w \cs_new_protected:Npn \cs_set_protected:Npn
+\cs_tmp:w \cs_new_protected:Npx\cs_set_protected:Npx
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1656,32 +2481,24 @@
% \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}
+% \begin{macro}{\cs_gnew_nopar:Npn}
+% \begin{macro}{\cs_gnew_nopar:Npx}
+% \begin{macro}{\cs_gnew:Npn}
+% \begin{macro}{\cs_gnew:Npx}
+% \begin{macro}{\cs_gnew_protected_nopar:Npn}
+% \begin{macro}{\cs_gnew_protected_nopar:Npx}
+% \begin{macro}{\cs_gnew_protected:Npn}
+% \begin{macro}{\cs_gnew_protected: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}
+\cs_tmp:w \cs_gnew_nopar:Npn \cs_gset_nopar:Npn
+\cs_tmp:w \cs_gnew_nopar:Npx \cs_gset_nopar:Npx
+\cs_tmp:w \cs_gnew:Npn \cs_gset:Npn
+\cs_tmp:w \cs_gnew:Npx \cs_gset:Npx
+\cs_tmp:w \cs_gnew_protected_nopar:Npn \cs_gset_protected_nopar:Npn
+\cs_tmp:w \cs_gnew_protected_nopar:Npx \cs_gset_protected_nopar:Npx
+\cs_tmp:w \cs_gnew_protected:Npn \cs_gset_protected:Npn
+\cs_tmp:w \cs_gnew_protected:Npx \cs_gset_protected:Npx
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1693,33 +2510,36 @@
% \end{macro}
%
%
-% \begin{macro}{\def:cpn}
-% \begin{macro}{\def:cpx}
-% \begin{macro}{\gdef:cpn}
-% \begin{macro}{\gdef:cpx}
-% \begin{macro}{\def_new:cpn}
-% \begin{macro}{\def_new:cpx}
-% \begin{macro}{\gdef_new:cpn}
-% \begin{macro}{\gdef_new:cpx}
-% Like |\def:Npn| and |\def_new:Npn|, except that the first argument
-% consists of the sequence of characters that should be used to form
-% the name of the desired control sequence (the |c| stands for
-% csname argument, see the expansion module.). Global versions are
-% also provided.
+% \begin{macro}{\cs_set_nopar:cpn}
+% \begin{macro}{\cs_set_nopar:cpx}
+% \begin{macro}{\cs_gset_nopar:cpn}
+% \begin{macro}{\cs_gset_nopar:cpx}
+% \begin{macro}{\cs_new_nopar:cpn}
+% \begin{macro}{\cs_new_nopar:cpx}
+% \begin{macro}{\cs_gnew_nopar:cpn}
+% \begin{macro}{\cs_gnew_nopar:cpx}
+% Like |\cs_set_nopar:Npn| and |\cs_new_nopar: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.
+% |\cs_set_nopar:cpn|\m{string}\m{rep-text} will turn \m{string}
+% into a csname and then assign \m {rep-text} to it by using
+% |\cs_set_nopar:Npn|. This means that there might be a parameter
+% string between the two arguments.
% \begin{macrocode}
-\def_new:Npn \def:cpn #1{\exp_after:NN \def:Npn \cs:w #1\cs_end:}
-\def_new:Npn \def:cpx #1{\exp_after:NN \def:Npx \cs:w #1\cs_end:}
-\def_new:Npn \gdef:cpn #1{\exp_after:NN \gdef:Npn \cs:w #1\cs_end:}
-\def_new:Npn \gdef:cpx #1{\exp_after:NN \gdef:Npx \cs:w #1\cs_end:}
-\def_new:Npn \def_new:cpn #1{\exp_after:NN \def_new:Npn \cs:w #1\cs_end:}
-\def_new:Npn \def_new:cpx #1{\exp_after:NN \def_new:Npx \cs:w #1\cs_end:}
-\def_new:Npn \gdef_new:cpn #1{\exp_after:NN \gdef_new:Npn \cs:w #1\cs_end:}
-\def_new:Npn \gdef_new:cpx #1{\exp_after:NN \gdef_new:Npx \cs:w #1\cs_end:}
+\cs_set:Npn \cs_tmp:w #1#2{
+ \cs_new_nopar:Npn #1 { \exp_args:Nc #2 }
+}
+\cs_tmp:w \cs_set_nopar:cpn \cs_set_nopar:Npn
+\cs_tmp:w \cs_set_nopar:cpx \cs_set_nopar:Npx
+\cs_tmp:w \cs_gset_nopar:cpn \cs_gset_nopar:Npn
+\cs_tmp:w \cs_gset_nopar:cpx \cs_gset_nopar:Npx
+\cs_tmp:w \cs_new_nopar:cpn \cs_new_nopar:Npn
+\cs_tmp:w \cs_new_nopar:cpx \cs_new_nopar:Npx
+\cs_tmp:w \cs_gnew_nopar:cpn \cs_gnew_nopar:Npn
+\cs_tmp:w \cs_gnew_nopar:cpx \cs_gnew_nopar:Npx
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1732,32 +2552,25 @@
%
%
%
-% \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
+% \begin{macro}{\cs_set:cpn}
+% \begin{macro}{\cs_set:cpx}
+% \begin{macro}{\cs_gset:cpn}
+% \begin{macro}{\cs_gset:cpx}
+% \begin{macro}{\cs_new:cpn}
+% \begin{macro}{\cs_new:cpx}
+% \begin{macro}{\cs_gnew:cpn}
+% \begin{macro}{\cs_gnew:cpx}
+% Variants of the |\cs_set: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:}
+\cs_tmp:w \cs_set:cpn \cs_set:Npn
+\cs_tmp:w \cs_set:cpx \cs_set:Npx
+\cs_tmp:w \cs_gset:cpn \cs_gset:Npn
+\cs_tmp:w \cs_gset:cpx \cs_gset:Npx
+\cs_tmp:w \cs_new:cpn \cs_new:Npn
+\cs_tmp:w \cs_new:cpx \cs_new:Npx
+\cs_tmp:w \cs_gnew:cpn \cs_gnew:Npn
+\cs_tmp:w \cs_gnew:cpx \cs_gnew:Npx
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1768,33 +2581,25 @@
% \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
+% \begin{macro}{\cs_set_protected_nopar:cpn}
+% \begin{macro}{\cs_set_protected_nopar:cpx}
+% \begin{macro}{\cs_gset_protected_nopar:cpn}
+% \begin{macro}{\cs_gset_protected_nopar:cpx}
+% \begin{macro}{\cs_new_protected_nopar:cpn}
+% \begin{macro}{\cs_new_protected_nopar:cpx}
+% \begin{macro}{\cs_gnew_protected_nopar:cpn}
+% \begin{macro}{\cs_gnew_protected_nopar:cpx}
+% Variants of the |\cs_set_protected_nopar: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:}
+\cs_tmp:w \cs_set_protected_nopar:cpn \cs_set_protected_nopar:Npn
+\cs_tmp:w \cs_set_protected_nopar:cpx \cs_set_protected_nopar:Npx
+\cs_tmp:w \cs_gset_protected_nopar:cpn \cs_gset_protected_nopar:Npn
+\cs_tmp:w \cs_gset_protected_nopar:cpx \cs_gset_protected_nopar:Npx
+\cs_tmp:w \cs_new_protected_nopar:cpn \cs_new_protected_nopar:Npn
+\cs_tmp:w \cs_new_protected_nopar:cpx \cs_new_protected_nopar:Npx
+\cs_tmp:w \cs_gnew_protected_nopar:cpn \cs_gnew_protected_nopar:Npn
+\cs_tmp:w \cs_gnew_protected_nopar:cpx \cs_gnew_protected_nopar:Npx
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1805,33 +2610,25 @@
% \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
+% \begin{macro}{\cs_set_protected:cpn}
+% \begin{macro}{\cs_set_protected:cpx}
+% \begin{macro}{\cs_gset_protected:cpn}
+% \begin{macro}{\cs_gset_protected:cpx}
+% \begin{macro}{\cs_new_protected:cpn}
+% \begin{macro}{\cs_new_protected:cpx}
+% \begin{macro}{\cs_gnew_protected:cpn}
+% \begin{macro}{\cs_gnew_protected:cpx}
+% Variants of the |\cs_set_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_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:}
+\cs_tmp:w \cs_set_protected:cpn \cs_set_protected:Npn
+\cs_tmp:w \cs_set_protected:cpx \cs_set_protected:Npx
+\cs_tmp:w \cs_gset_protected:cpn \cs_gset_protected:Npn
+\cs_tmp:w \cs_gset_protected:cpx \cs_gset_protected:Npx
+\cs_tmp:w \cs_new_protected:cpn \cs_new_protected:Npn
+\cs_tmp:w \cs_new_protected:cpx \cs_new_protected:Npx
+\cs_tmp:w \cs_gnew_protected:cpn \cs_gnew_protected:Npn
+\cs_tmp:w \cs_gnew_protected:cpx \cs_gnew_protected:Npx
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1843,56 +2640,31 @@
% \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{macro}[aux]{\use_0_parameter:}
+% \begin{macro}[aux]{\use_1_parameter:}
+% \begin{macro}[aux]{\use_2_parameter:}
+% \begin{macro}[aux]{\use_3_parameter:}
+% \begin{macro}[aux]{\use_4_parameter:}
+% \begin{macro}[aux]{\use_5_parameter:}
+% \begin{macro}[aux]{\use_6_parameter:}
+% \begin{macro}[aux]{\use_7_parameter:}
+% \begin{macro}[aux]{\use_8_parameter:}
+% \begin{macro}[aux]{\use_9_parameter:}
+% For using parameters, i.e., when you need to define a function to
+% process three parameters. See \textsf{xparse} for an application.
% \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
- }
-}
+\cs_set_nopar:cpn{use_0_parameter:}{}
+\cs_set_nopar:cpn{use_1_parameter:}{{##1}}
+\cs_set_nopar:cpn{use_2_parameter:}{{##1}{##2}}
+\cs_set_nopar:cpn{use_3_parameter:}{{##1}{##2}{##3}}
+\cs_set_nopar:cpn{use_4_parameter:}{{##1}{##2}{##3}{##4}}
+\cs_set_nopar:cpn{use_5_parameter:}{{##1}{##2}{##3}{##4}{##5}}
+\cs_set_nopar:cpn{use_6_parameter:}{{##1}{##2}{##3}{##4}{##5}{##6}}
+\cs_set_nopar:cpn{use_7_parameter:}{{##1}{##2}{##3}{##4}{##5}{##6}{##7}}
+\cs_set_nopar:cpn{use_8_parameter:}{
+ {##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}}
+\cs_set_nopar:cpn{use_9_parameter:}{
+ {##1}{##2}{##3}{##4}{##5}{##6}{##7}{##8}{##9}}
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1904,409 +2676,332 @@
% \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.
+% \subsection{Copying definitions}
+%
+% \begin{macro}{\cs_set_eq:NN}
+% \begin{macro}{\cs_set_eq:cN}
+% \begin{macro}{\cs_set_eq:Nc}
+% \begin{macro}{\cs_set_eq:cc}
+% These macros allow us to copy the definition of a control sequence
+% to another control sequence.
+%
+% 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 |=|.
+%
+% |\cs_set_eq:NN| is long to avoid problems with a literal argument
+% of |\par|. While |\cs_new_eq:NN| will probably never be correct
+% with a first argument of |\par|, define it long in order to throw
+% an `already defined' error rather than `runaway argument'.
+%
+% The |c| variants are not protected in order for their arguments to
+% be constructed in the correct context.
+%
% \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}}
+\cs_set_protected:Npn \cs_set_eq:NN #1 { \cs_set_eq:NwN #1=~ }
+\cs_set_nopar:Npn \cs_set_eq:cN { \exp_args:Nc \cs_set_eq:NN }
+\cs_set_nopar:Npn \cs_set_eq:Nc { \exp_args:NNc \cs_set_eq:NN }
+\cs_set_nopar:Npn \cs_set_eq:cc { \exp_args:Ncc \cs_set_eq:NN }
% \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{macro}{\cs_new_eq:NN}
+% \begin{macro}{\cs_new_eq:cN}
+% \begin{macro}{\cs_new_eq:Nc}
+% \begin{macro}{\cs_new_eq:cc}
% \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 }
+\cs_new_protected:Npn \cs_new_eq:NN #1 {
+ \chk_if_free_cs:N #1
+ \cs_set_eq:NN #1
+}
+\cs_new_nopar:Npn \cs_new_eq:cN { \exp_args:Nc \cs_new_eq:NN }
+\cs_new_nopar:Npn \cs_new_eq:Nc { \exp_args:NNc \cs_new_eq:NN }
+\cs_new_nopar:Npn \cs_new_eq:cc { \exp_args:Ncc \cs_new_eq:NN }
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \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{macro}{\cs_gset_eq:NN}
+% \begin{macro}{\cs_gset_eq:cN}
+% \begin{macro}{\cs_gset_eq:Nc}
+% \begin{macro}{\cs_gset_eq:cc}
% \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 }
+\cs_new_protected:Npn \cs_gset_eq:NN { \pref_global:D \cs_set_eq:NN }
+\cs_new_nopar:Npn \cs_gset_eq:Nc { \exp_args:NNc \cs_gset_eq:NN }
+\cs_new_nopar:Npn \cs_gset_eq:cN { \exp_args:Nc \cs_gset_eq:NN }
+\cs_new_nopar:Npn \cs_gset_eq:cc { \exp_args:Ncc \cs_gset_eq:NN }
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \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{macro}{\cs_gnew_eq:NN}
+% \begin{macro}{\cs_gnew_eq:cN}
+% \begin{macro}{\cs_gnew_eq:Nc}
+% \begin{macro}{\cs_gnew_eq:cc}
% \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 }
+\cs_new_protected:Npn \cs_gnew_eq:NN #1 {
+ \chk_if_free_cs:N #1
+ \pref_global:D \cs_set_eq:NN #1
+}
+\cs_new_nopar:Npn \cs_gnew_eq:cN { \exp_args:Nc \cs_gnew_eq:NN }
+\cs_new_nopar:Npn \cs_gnew_eq:Nc { \exp_args:NNc \cs_gnew_eq:NN }
+\cs_new_nopar:Npn \cs_gnew_eq:cc { \exp_args:Ncc \cs_gnew_eq:NN }
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \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.
+%
+% \subsection{Undefining functions}
+%
+% \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 \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 }
+\cs_new_nopar:Npn \cs_gundefine:N #1{\cs_gset_eq:NN #1\c_undefined:D}
% \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{
+% \subsection{Engine specific definitions}
+%
+% \begin{macro}{\c_xetex_is_engine_bool,\c_luatex_is_engine_bool}
+% \begin{macro}[TF]{\xetex_if_engine:,\luatex_if_engine:}
+% In some cases it will be useful to know which engine we're running.
+% Don't provide a "_p" predicate because the "_bool" is used for the
+% same thing.
+% \begin{macrocode}
+\if_cs_exist:N \xetex_version:D
+ \cs_new_eq:NN \c_xetex_is_engine_bool \c_true_bool
+\else:
+ \cs_new_eq:NN \c_xetex_is_engine_bool \c_false_bool
+\fi:
+\prg_new_conditional:Npnn \xetex_if_engine: {TF,T,F} {
+ \if_bool:N \c_xetex_is_engine_bool
+ \prg_return_true: \else: \prg_return_false: \fi:
+}
% \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}
+\if_cs_exist:N \luatex_directlua:D
+ \cs_new_eq:NN \c_luatex_is_engine_bool \c_true_bool
+\else:
+ \cs_new_eq:NN \c_luatex_is_engine_bool \c_false_bool
+\fi:
+\prg_set_conditional:Npnn \xetex_if_engine: {TF,T,F}{
+ \if_bool:N \c_xetex_is_engine_bool \prg_return_true:
+ \else: \prg_return_false: \fi:
+}
+\prg_set_conditional:Npnn \luatex_if_engine: {TF,T,F}{
+ \if_bool:N \c_luatex_is_engine_bool \prg_return_true:
+ \else: \prg_return_false: \fi:
+}
% \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.
+%
+%
+%
+% \subsection{Scratch functions}
+%
+% \begin{macro}{\prg_do_nothing:}
+% I don't think this function belongs here, but one place is as
+% good as any other. I want to use this function when I want to
+% express `no operation'. It is for example used in templates where
+% depending on the users settings we have to either select an function that
+% does something, or one that does nothing.
% \begin{macrocode}
-\def_protected_new:Npn \glet:NN {\pref_global:D \let:NN}
-\def_protected_new:Npn \glet:Nc {\exp_args:NNc \glet:NN}
-\def_protected_new:Npn \glet:cN {\exp_args:Nc \glet:NN}
-\def_new:Npn \glet:cc {\exp_args:Ncc \glet:NN}
-\def_new:Npn \glet_new:NN #1{\chk_new_cs:N #1
- \tex_global:D\let:NN #1}
-\def_new:Npn \glet_new:cN {\exp_args:Nc \glet_new:NN}
-\def_new:Npn \glet_new:Nc {\exp_args:NNc \glet_new:NN}
-\def_new:Npn \glet_new:cc {\exp_args:Ncc \glet_new:NN}
+\cs_new_nopar:Npn \prg_do_nothing: {}
% \end{macrocode}
% \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.
+% \subsection{Defining functions from a given number of arguments}
+%
+% \begin{macro}{\cs_get_arg_count_from_signature:N}
+% \begin{macro}[aux]{\cs_get_arg_count_from_signature_aux:nnN}
+% \begin{macro}[aux]{\cs_get_arg_count_from_signature_auxii:w}
+% Counting the number of tokens in the signature, i.e., the number
+% of arguments the function should take. If there is no signature,
+% we return that there is $-1$ arguments to signal an error.
+% Otherwise we insert the string |9876543210| after the signature.
+% If the signature is empty, the number we want is $0$ so we remove
+% the first nine tokens and return the tenth. Similarly, if the
+% signature is |nnn| we want to remove the nine tokens |nnn987654|
+% and return $3$. Therefore, we simply remove the first nine tokens
+% and then return the tenth.
+% \begin{macrocode}
+\cs_set:Npn \cs_get_arg_count_from_signature:N #1{
+ \cs_split_function:NN #1 \cs_get_arg_count_from_signature_aux:nnN
+}
+\cs_set:Npn \cs_get_arg_count_from_signature_aux:nnN #1#2#3{
+ \if_predicate:w #3 % \bool_if:NTF here
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN\use_ii:nn
+ \fi:
+ {
+ \exp_after:wN \cs_get_arg_count_from_signature_auxii:w
+ \use_none:nnnnnnnnn #2 9876543210\q_nil
+ }
+ {-1}
+}
+\cs_set:Npn \cs_get_arg_count_from_signature_auxii:w #1#2\q_nil{#1}
+% \end{macrocode}
+% A variant form we need right away.
% \begin{macrocode}
-\def_new:Npn \def:No{\exp_args:NNo\def:Npn}
-\def_new:Npn \gdef:No {\exp_args:NNo\gdef:Npn}
+\cs_set_nopar:Npn \cs_get_arg_count_from_signature:c {
+ \exp_args:Nc \cs_get_arg_count_from_signature:N
+}
% \end{macrocode}
% \end{macro}
% \end{macro}
+% \end{macro}
%
-% \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{macro}[aux]{\cs_generate_from_arg_count:NNnn}
+% \begin{macro}[aux]{\cs_generate_from_arg_count_error_msg:Nn}
+% We provide a constructor function for defining functions with a
+% given number of arguments. For this we need to choose the correct
+% parameter text and then use that when defining. Since \TeX\
+% supports from zero to nine arguments, we use a simple switch to
+% choose the correct parameter text, ensuring the result is returned
+% after finishing the conditional. If it is not between zero and
+% nine, we throw an error.
+%
+% 1: function to define, 2: with what to define it, 3: the number of
+% args it requires and 4: the replacement text
% \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 {#2FT} #3 {#4
- \exp_after:NN\use_arg_ii:nn\else:\exp_after:NN\use_arg_i: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 {#2FT} #3 {#4
- \exp_not:n{\exp_after:NN\use_arg_ii:nn\else:\exp_after:NN\use_arg_i: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}
+\cs_set:Npn \cs_generate_from_arg_count:NNnn #1#2#3#4{
+ \tex_ifcase:D \etex_numexpr:D #3\tex_relax:D
+ \use_i_after_orelse:nw{#2#1}
+ \or:
+ \use_i_after_orelse:nw{#2#1 ##1}
+ \or:
+ \use_i_after_orelse:nw{#2#1 ##1##2}
+ \or:
+ \use_i_after_orelse:nw{#2#1 ##1##2##3}
+ \or:
+ \use_i_after_orelse:nw{#2#1 ##1##2##3##4}
+ \or:
+ \use_i_after_orelse:nw{#2#1 ##1##2##3##4##5}
+ \or:
+ \use_i_after_orelse:nw{#2#1 ##1##2##3##4##5##6}
+ \or:
+ \use_i_after_orelse:nw{#2#1 ##1##2##3##4##5##6##7}
+ \or:
+ \use_i_after_orelse:nw{#2#1 ##1##2##3##4##5##6##7##8}
+ \or:
+ \use_i_after_orelse:nw{#2#1 ##1##2##3##4##5##6##7##8##9}
+ \else:
+ \use_i_after_fi:nw{
+ \cs_generate_from_arg_count_error_msg:Nn#1{#3}
+ \use_none:n % to remove replacement text
+ }
+ \fi:
+ {#4}
}
-\def_long_new:Npn \def_long_test_function_new:npn #1#2#{
- \def_test_function_aux:Nnnn \def_long_new:cpn {#1}{#2}
+% \end{macrocode}
+% A variant form we need right away.
+% \begin{macrocode}
+\cs_set_nopar:Npn \cs_generate_from_arg_count:cNnn {
+ \exp_args:Nc \cs_generate_from_arg_count:NNnn
}
-\def_long_new:Npn \def_test_function_new:npx #1#2#{
- \def_test_function_aux:Nnnx \def_new:cpx {#1}{#2}
+% \end{macrocode}
+% The error message. Elsewhere we use the value of $-1$ to signal a
+% missing colon in a function, so provide a hint for help on this.
+% \begin{macrocode}
+\cs_set:Npn \cs_generate_from_arg_count_error_msg:Nn #1#2 {
+ \msg_kernel_bug:x {
+ You're~ trying~ to~ define~ the~ command~ `\token_to_str:N #1'~
+ with~ \use:n{\tex_the:D\etex_numexpr:D #2\tex_relax:D} ~
+ arguments~ but~ I~ only~ allow~ 0-9~arguments.~Perhaps~you~
+ forgot~to~use~a~colon~in~the~function~name?~
+ I~ can~ probably~ not~ help~ you~ here
+ }
}
-\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}
+%
+%
+%
+%
+% \subsection{Using the signature to define functions}
+%
+% We can now combine some of the tools we have to provide a simple
+% interface for defining functions. We define some simpler functions
+% with user interface |\cs_set:Nn \foo_bar:nn {#1,#2}|, i.e., the
+% number of arguments is read from the signature.
+%
+%
+% \begin{macro}{\cs_set:Nn}
+% \begin{macro}{\cs_set:Nx}
+% \begin{macro}{\cs_set_nopar:Nn}
+% \begin{macro}{\cs_set_nopar:Nx}
+% \begin{macro}{\cs_set_protected:Nn}
+% \begin{macro}{\cs_set_protected:Nx}
+% \begin{macro}{\cs_set_protected_nopar:Nn}
+% \begin{macro}{\cs_set_protected_nopar:Nx}
+% \begin{macro}{\cs_gset:Nn}
+% \begin{macro}{\cs_gset:Nx}
+% \begin{macro}{\cs_gset_nopar:Nn}
+% \begin{macro}{\cs_gset_nopar:Nx}
+% \begin{macro}{\cs_gset_protected:Nn}
+% \begin{macro}{\cs_gset_protected:Nx}
+% \begin{macro}{\cs_gset_protected_nopar:Nn}
+% \begin{macro}{\cs_gset_protected_nopar:Nx}
+% We want to define |\cs_set:Nn| as
+% \begin{verbatim}
+% \cs_set_protected:Npn \cs_set:Nn #1#2{
+% \cs_generate_from_arg_count:NNnn #1\cs_set:Npn
+% {\cs_get_arg_count_from_signature:N #1}{#2}
+% }
+% \end{verbatim}
+% In short, to define |\cs_set:Nn| we need just use |\cs_set:Npn|,
+% everything else is the same for each variant. Therefore, we can
+% make it simpler by temporarily defining a function to do this for
+% us.
+% \begin{macrocode}
+\cs_set:Npn \cs_tmp:w #1#2#3{
+ \cs_set_protected:cpx {cs_#1:#2}##1##2{
+ \exp_not:N \cs_generate_from_arg_count:NNnn ##1
+ \exp_after:wN \exp_not:N \cs:w cs_#1:#3 \cs_end:
+ {\exp_not:N\cs_get_arg_count_from_signature:N ##1}{##2}
+ }
}
% \end{macrocode}
+% Then we define the 32 variants beginning with |N|.
+% \begin{macrocode}
+\cs_tmp:w {set}{Nn}{Npn}
+\cs_tmp:w {set}{Nx}{Npx}
+\cs_tmp:w {set_nopar}{Nn}{Npn}
+\cs_tmp:w {set_nopar}{Nx}{Npx}
+\cs_tmp:w {set_protected}{Nn}{Npn}
+\cs_tmp:w {set_protected}{Nx}{Npx}
+\cs_tmp:w {set_protected_nopar}{Nn}{Npn}
+\cs_tmp:w {set_protected_nopar}{Nx}{Npx}
+\cs_tmp:w {gset}{Nn}{Npn}
+\cs_tmp:w {gset}{Nx}{Npx}
+\cs_tmp:w {gset_nopar}{Nn}{Npn}
+\cs_tmp:w {gset_nopar}{Nx}{Npx}
+\cs_tmp:w {gset_protected}{Nn}{Npn}
+\cs_tmp:w {gset_protected}{Nx}{Npx}
+\cs_tmp:w {gset_protected_nopar}{Nn}{Npn}
+\cs_tmp:w {gset_protected_nopar}{Nx}{Npx}
+% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
@@ -2317,86 +3012,50 @@
% \end{macro}
% \end{macro}
% \end{macro}
-%
-%
-% \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
-% to read further input from outside the conditional. Actually,
-% the first part of the code below is more general, since it checks
-% \m{csnames} directly and therefore allows both |\scan_stop:| and
-% |\c_undefined|.
-% \begin{macrocode}
-\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_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_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{macro}{\cs_new:Nn}
+% \begin{macro}{\cs_new:Nx}
+% \begin{macro}{\cs_new_nopar:Nn}
+% \begin{macro}{\cs_new_nopar:Nx}
+% \begin{macro}{\cs_new_protected:Nn}
+% \begin{macro}{\cs_new_protected:Nx}
+% \begin{macro}{\cs_new_protected_nopar:Nn}
+% \begin{macro}{\cs_new_protected_nopar:Nx}
+% \begin{macro}{\cs_gnew:Nn}
+% \begin{macro}{\cs_gnew:Nx}
+% \begin{macro}{\cs_gnew_nopar:Nn}
+% \begin{macro}{\cs_gnew_nopar:Nx}
+% \begin{macro}{\cs_gnew_protected:Nn}
+% \begin{macro}{\cs_gnew_protected:Nx}
+% \begin{macro}{\cs_gnew_protected_nopar:Nn}
+% \begin{macro}{\cs_gnew_protected_nopar:Nx}
% \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
+\cs_tmp:w {new}{Nn}{Npn}
+\cs_tmp:w {new}{Nx}{Npx}
+\cs_tmp:w {new_nopar}{Nn}{Npn}
+\cs_tmp:w {new_nopar}{Nx}{Npx}
+\cs_tmp:w {new_protected}{Nn}{Npn}
+\cs_tmp:w {new_protected}{Nx}{Npx}
+\cs_tmp:w {new_protected_nopar}{Nn}{Npn}
+\cs_tmp:w {new_protected_nopar}{Nx}{Npx}
+\cs_tmp:w {gnew}{Nn}{Npn}
+\cs_tmp:w {gnew}{Nx}{Npx}
+\cs_tmp:w {gnew_nopar}{Nn}{Npn}
+\cs_tmp:w {gnew_nopar}{Nx}{Npx}
+\cs_tmp:w {gnew_protected}{Nn}{Npn}
+\cs_tmp:w {gnew_protected}{Nx}{Npx}
+\cs_tmp:w {gnew_protected_nopar}{Nn}{Npn}
+\cs_tmp:w {gnew_protected_nopar}{Nx}{Npx}
% \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}
@@ -2406,93 +3065,67 @@
% \end{macro}
% \end{macro}
% \end{macro}
-%
-%
-% \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 \cs_gundefine:N #1{\glet:NN #1\c_undefined}
-% \end{macrocode}
% \end{macro}
-%
-%
-% \subsubsection{Engine specific definitions}
-%
-% \begin{macro}{\engine_if_aleph:TF}
-% In some cases it will be useful to know which engine we're running.
-% \begin{macrocode}
-\def_test_function_new:npn {engine_if_aleph:}{\if_cs_exist:N \aleph_textdir:D}
-% \end{macrocode}
% \end{macro}
-%
-%
-%
-% \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_arg_i:n #1{#1}% moved earlier
-% \end{macrocode}
+% \end{macro}
% \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.
+% Then something similar for the |c| variants.
+% \begin{verbatim}
+% \cs_set_protected:Npn \cs_set:cn #1#2{
+% \cs_generate_from_arg_count:cNnn {#1}\cs_set:Npn
+% {\cs_get_arg_count_from_signature:c {#1}}{#2}
+% }
+% \end{verbatim}
% \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: }
+\cs_set:Npn \cs_tmp:w #1#2#3{
+ \cs_set_protected:cpx {cs_#1:#2}##1##2{
+ \exp_not:N\cs_generate_from_arg_count:cNnn {##1}
+ \exp_after:wN \exp_not:N \cs:w cs_#1:#3 \cs_end:
+ {\exp_not:N\cs_get_arg_count_from_signature:c {##1}}{##2}
+ }
+}
% \end{macrocode}
-% THE NAME IS COMPLETELY WRONG!!!!!
-% Morten says: Perhaps this is really |\exp_args:cc| instead?
+% \begin{macro}{\cs_set:cn}
+% \begin{macro}{\cs_set:cx}
+% \begin{macro}{\cs_set_nopar:cn}
+% \begin{macro}{\cs_set_nopar:cx}
+% \begin{macro}{\cs_set_protected:cn}
+% \begin{macro}{\cs_set_protected:cx}
+% \begin{macro}{\cs_set_protected_nopar:cn}
+% \begin{macro}{\cs_set_protected_nopar:cx}
+% \begin{macro}{\cs_gset:cn}
+% \begin{macro}{\cs_gset:cx}
+% \begin{macro}{\cs_gset_nopar:cn}
+% \begin{macro}{\cs_gset_nopar:cx}
+% \begin{macro}{\cs_gset_protected:cn}
+% \begin{macro}{\cs_gset_protected:cx}
+% \begin{macro}{\cs_gset_protected_nopar:cn}
+% \begin{macro}{\cs_gset_protected_nopar:cx}
+% The 32 |c| variants.
% \begin{macrocode}
-\def_new:Npn \use:cc #1#2
- {\cs:w #1\exp_after:NN\cs_end:\cs:w #2\cs_end:}
+\cs_tmp:w {set}{cn}{Npn}
+\cs_tmp:w {set}{cx}{Npx}
+\cs_tmp:w {set_nopar}{cn}{Npn}
+\cs_tmp:w {set_nopar}{cx}{Npx}
+\cs_tmp:w {set_protected}{cn}{Npn}
+\cs_tmp:w {set_protected}{cx}{Npx}
+\cs_tmp:w {set_protected_nopar}{cn}{Npn}
+\cs_tmp:w {set_protected_nopar}{cx}{Npx}
+\cs_tmp:w {gset}{cn}{Npn}
+\cs_tmp:w {gset}{cx}{Npx}
+\cs_tmp:w {gset_nopar}{cn}{Npn}
+\cs_tmp:w {gset_nopar}{cx}{Npx}
+\cs_tmp:w {gset_protected}{cn}{Npn}
+\cs_tmp:w {gset_protected}{cx}{Npx}
+\cs_tmp:w {gset_protected_nopar}{cn}{Npn}
+\cs_tmp:w {gset_protected_nopar}{cx}{Npx}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
-%
-% \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_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_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_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.
-% \begin{macrocode}
-\def_long_new:NNn \use_arg_i:nnn 3{#1}
-\def_long_new:NNn \use_arg_ii:nnn 3{#2}
-\def_long_new:NNn \use_arg_iii:nnn 3{#3}
-\def_long_new:NNn \use_arg_i:nnnn 4{#1}
-\def_long_new:NNn \use_arg_ii:nnnn 4{#2}
-\def_long_new:NNn \use_arg_iii:nnnn 4{#3}
-\def_long_new:NNn \use_arg_iv:nnnn 4{#4}
-% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
@@ -2500,84 +3133,49 @@
% \end{macro}
% \end{macro}
% \end{macro}
-%
-% \begin{macro}{\use_arg_i_ii:nn}
-% And a function for grabbing two arguments and returning them
-% again.
-% \begin{macrocode}
-\def_long_new:NNn\use_arg_i_ii:nn 2{#1#2}
-% \end{macrocode}
% \end{macro}
-%
-% \begin{macro}{\use_none_delimit_by_q_nil:w}
-% \begin{macro}{\use_none_delimit_by_q_stop:w}
-% Functions that gobble everything until they see either |\q_nil| or
-% |\q_stop| resp.
-% \begin{macrocode}
-\def_long_new:Npn \use_none_delimit_by_q_nil:w #1\q_nil{}
-\def_long_new:Npn \use_none_delimit_by_q_stop:w #1\q_stop{}
-% \end{macrocode}
% \end{macro}
% \end{macro}
-%
-% \begin{macro}{\use_arg_i_delimit_by_q_nil:nw}
-% \begin{macro}{\use_arg_i_delimit_by_q_stop:nw}
-% Same as above but execute first argument after gobbling. Very
-% useful when you need to skip the rest of a mapping sequence but
-% want an easy way to control what should be expanded next.
-% \begin{macrocode}
-\def_long_new:Npn \use_arg_i_delimit_by_q_nil:nw #1#2\q_nil{#1}
-\def_long_new:Npn \use_arg_i_delimit_by_q_stop:nw #1#2\q_stop{#1}
-% \end{macrocode}
-% \end{macro}
% \end{macro}
%
-%
-% \begin{macro}{\use_arg_i_after_fi:nw}
-% \begin{macro}{\use_arg_i_after_else:nw}
-% \begin{macro}{\use_arg_i_after_or:nw}
-% \begin{macro}{\use_arg_i_after_or:nw}
-% Returns the first argument after ending the conditional.
+% \begin{macro}{\cs_new:cn}
+% \begin{macro}{\cs_new:cx}
+% \begin{macro}{\cs_new_nopar:cn}
+% \begin{macro}{\cs_new_nopar:cx}
+% \begin{macro}{\cs_new_protected:cn}
+% \begin{macro}{\cs_new_protected:cx}
+% \begin{macro}{\cs_new_protected_nopar:cn}
+% \begin{macro}{\cs_new_protected_nopar:cx}
+% \begin{macro}{\cs_gnew:cn}
+% \begin{macro}{\cs_gnew:cx}
+% \begin{macro}{\cs_gnew_nopar:cn}
+% \begin{macro}{\cs_gnew_nopar:cx}
+% \begin{macro}{\cs_gnew_protected:cn}
+% \begin{macro}{\cs_gnew_protected:cx}
+% \begin{macro}{\cs_gnew_protected_nopar:cn}
+% \begin{macro}{\cs_gnew_protected_nopar:cx}
% \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: {\fi:#1}
-\def_long_new:Npn \use_arg_i_after_orelse:nw #1 #2#3\fi: {\fi:#1}
+\cs_tmp:w {new}{cn}{Npn}
+\cs_tmp:w {new}{cx}{Npx}
+\cs_tmp:w {new_nopar}{cn}{Npn}
+\cs_tmp:w {new_nopar}{cx}{Npx}
+\cs_tmp:w {new_protected}{cn}{Npn}
+\cs_tmp:w {new_protected}{cx}{Npx}
+\cs_tmp:w {new_protected_nopar}{cn}{Npn}
+\cs_tmp:w {new_protected_nopar}{cx}{Npx}
+\cs_tmp:w {gnew}{cn}{Npn}
+\cs_tmp:w {gnew}{cx}{Npx}
+\cs_tmp:w {gnew_nopar}{cn}{Npn}
+\cs_tmp:w {gnew_nopar}{cx}{Npx}
+\cs_tmp:w {gnew_protected}{cn}{Npn}
+\cs_tmp:w {gnew_protected}{cx}{Npx}
+\cs_tmp:w {gnew_protected_nopar}{cn}{Npn}
+\cs_tmp:w {gnew_protected_nopar}{cx}{Npx}
% \end{macrocode}
% \end{macro}
% \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}
@@ -2587,240 +3185,100 @@
% \end{macro}
% \end{macro}
% \end{macro}
-%
-%
-% \subsubsection{Scratch functions}
-%
-% \begin{macro}{\gtmp:w}
-% This function is for global scratch definitions that are used
-% immediately afterwards. It should be used when we need a function
-% that operates on input, i.e.\ has arguments. If we want to save
-% only some tokens for later use, token-list scratch variables
-% should be used.
-% \begin{macrocode}
-\def_new:Npn \gtmp:w {}
-% \end{macrocode}
% \end{macro}
-%
-% \begin{macro}{\tmp:w}
-% This is a local version of the previous function.
-% \begin{macrocode}
-\def_new:Npn \tmp:w {}
-% \end{macrocode}
% \end{macro}
-%
-% \begin{macro}{\use_noop:}
-% I don't think this function belongs here, but one place is as
-% good as any other. I want to use this function when I want to
-% express `no operation'.
-% \begin{macrocode}
-\def_new:Npn \use_noop: {}
-% \end{macrocode}
% \end{macro}
%
-% \subsubsection{Strings and input stream token lists}
-%
-% \begin{macro}{\cs_to_str:N}
-% 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}{\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}
+% \begin{macro}{\cs_if_eq_p:NN,\cs_if_eq_p:cN,\cs_if_eq_p:Nc,\cs_if_eq_p:cc}
+% \begin{macro}[TF]{\cs_if_eq:NN,\cs_if_eq:cN,\cs_if_eq:Nc,\cs_if_eq:cc}
% Check if two control sequences are identical.
% \begin{macrocode}
-\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}
+\prg_set_conditional:Npnn \cs_if_eq:NN #1#2{p,TF,T,F}{
+ \if_meaning:w #1#2
+ \prg_return_true: \else: \prg_return_false: \fi:
+}
+\cs_new_nopar:Npn \cs_if_eq_p:cN {\exp_args:Nc \cs_if_eq_p:NN}
+\cs_new_nopar:Npn \cs_if_eq:cNTF {\exp_args:Nc \cs_if_eq:NNTF}
+\cs_new_nopar:Npn \cs_if_eq:cNT {\exp_args:Nc \cs_if_eq:NNT}
+\cs_new_nopar:Npn \cs_if_eq:cNF {\exp_args:Nc \cs_if_eq:NNF}
+\cs_new_nopar:Npn \cs_if_eq_p:Nc {\exp_args:NNc \cs_if_eq_p:NN}
+\cs_new_nopar:Npn \cs_if_eq:NcTF {\exp_args:NNc \cs_if_eq:NNTF}
+\cs_new_nopar:Npn \cs_if_eq:NcT {\exp_args:NNc \cs_if_eq:NNT}
+\cs_new_nopar:Npn \cs_if_eq:NcF {\exp_args:NNc \cs_if_eq:NNF}
+\cs_new_nopar:Npn \cs_if_eq_p:cc {\exp_args:Ncc \cs_if_eq_p:NN}
+\cs_new_nopar:Npn \cs_if_eq:ccTF {\exp_args:Ncc \cs_if_eq:NNTF}
+\cs_new_nopar:Npn \cs_if_eq:ccT {\exp_args:Ncc \cs_if_eq:NNT}
+\cs_new_nopar:Npn \cs_if_eq:ccF {\exp_args:Ncc \cs_if_eq:NNF}
% \end{macrocode}
% \end{macro}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
% 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}}
+\cs_new_nopar:Npn\file_not_found:nTF #1#2#3{\IfFileExists{#1}{#3}{#2}}
% \end{macrocode}
%
%
-% \subsubsection{Predicates and conditionals}
-% \label{sec:predicates}
-%
-% \LaTeX3 has three concepts for conditional flow processing:
-% \begin{enumerate}
-%
-% \item
-% Functions that carry out a test an then execute, depending on its
-% 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}{...}{...}"
-% \end{quote}
-% a function that will turn the first argument into a control sequence
-% (since its marked as "c") then checks whether this control sequence is
-% still free and then depending on the result carry out the code in the
-% second argument (true case) or in the third argument (false case).
-%
-% \item
-% Functions that return a special type of boolean value which can be
-% tested by the function "\if:w". All functions of this type
-% have names that end with "_p" in the description part. For example
-% \begin{quote}
-% "\cs_free_p:N"
-% \end{quote}
-% would be a predicate function for the same type of test as the
-% function above. It would return `true' if its argument (a single token
-% denoted by "N") is still free for definition. It would be used in
-% constructions like
-% \begin{quote}
-% "\if:w \cs_free_p:N \l_foo_bar ... \else: ... \fi:"
-% \end{quote}
-%
-% \item
-% Actually there is a third one, namely the original concept used in
-% plain \TeX{}. This belongs to the second form but needs further
-% thoughts.
-% \end{enumerate}
-%
-% 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.
%
+% \begin{macro}{\prg_set_eq_conditional:NNn,\prg_new_eq_conditional:NNn}
+% \begin{macrocode}
+\cs_set:Npn \prg_set_eq_conditional:NNn #1#2#3 {
+ \prg_set_eq_conditional_aux:NNNn \cs_set_eq:cc #1#2 {#3}
+}
+\cs_set:Npn \prg_new_eq_conditional:NNn #1#2#3 {
+ \prg_set_eq_conditional_aux:NNNn \cs_new_eq:cc #1#2 {#3}
+}
+% \end{macrocode}
+% \begin{macro}[aux]{\prg_set_eq_conditional_aux:NNNn,
+% \prg_set_eq_conditional_aux:NNNw}
+% \begin{macrocode}
+\cs_set:Npn \prg_set_eq_conditional_aux:NNNn #1#2#3#4 {
+ \prg_set_eq_conditional_aux:NNNw #1#2#3#4,?,\q_recursion_stop
+}
+% \end{macrocode}
+% Manual clist loop over argument "#4".
+% \begin{macrocode}
+\cs_set:Npn \prg_set_eq_conditional_aux:NNNw #1#2#3#4, {
+ \if:w ? #4 \scan_stop:
+ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ #1 {
+ \exp_args:NNc \cs_split_function:NN #2 {prg_conditional_form_#4:nnn}
+ }{
+ \exp_args:NNc \cs_split_function:NN #3 {prg_conditional_form_#4:nnn}
+ }
+ \prg_set_eq_conditional_aux:NNNw #1{#2}{#3}
+}
+% \end{macrocode}
+% \begin{macrocode}
+\cs_set:Npn \prg_conditional_form_p:nnn #1#2#3 {#1_p:#2}
+\cs_set:Npn \prg_conditional_form_TF:nnn #1#2#3 {#1:#2TF}
+\cs_set:Npn \prg_conditional_form_T:nnn #1#2#3 {#1:#2T}
+\cs_set:Npn \prg_conditional_form_F:nnn #1#2#3 {#1:#2F}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
%
% \begin{macrocode}
%</initex|package>
+% \end{macrocode}
+%
+% \begin{macrocode}
%<*showmemory>
\showMemUsage
%</showmemory>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.38 2006/08/06 17:05:25 morten
-% Make \chk_new_cs:N bulletproof
-%
-% 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
-%
-% 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".
+% \end{implementation}
%
-% 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
+% \PrintIndex
%
+% \endinput