summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/l3kernel/l3basics.dtx')
-rw-r--r--Master/texmf-dist/source/latex/l3kernel/l3basics.dtx1343
1 files changed, 764 insertions, 579 deletions
diff --git a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
index f6be95ab725..549ec6de6f8 100644
--- a/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
+++ b/Master/texmf-dist/source/latex/l3kernel/l3basics.dtx
@@ -35,8 +35,8 @@
%
%<*driver|package>
\RequirePackage{l3names}
-\GetIdInfo$Id: l3basics.dtx 3491 2012-03-04 06:13:18Z bruno $
- {L3 Experimental basic definitions}
+\GetIdInfo$Id: l3basics.dtx 3987 2012-07-15 21:57:39Z joseph $
+ {L3 Basic definitions}
%</driver|package>
%<*driver>
\documentclass[full]{l3doc}
@@ -155,36 +155,36 @@
% for the formal parameters (|#1|, |#2|, \ldots).
% \begin{description}
% \item[\texttt{new}]
-% Create a new function with the \texttt{new} primitives,
+% Create a new function with the \texttt{new} scope,
% such as \cs{cs_new:Npn}. The definition is global and will result in
% an error if it is already defined.
% \item[\texttt{set}]
-% Create a new function with the \texttt{set} primitives,
+% Create a new function with the \texttt{set} scope,
% such as \cs{cs_set:Npn}. The definition is restricted to the current
% \TeX{} group and will not result in an error if the function is already
% defined.
% \item[\texttt{gset}]
-% Create a new function with the \texttt{gset} primitives,
+% Create a new function with the \texttt{gset} scope,
% such as \cs{cs_gset:Npn}. The definition is global and
% will not result in an error if the function is already defined.
% \end{description}
%
-% Within each set of primitives there are different ways to define a function.
+% Within each set of scope there are different ways to define a function.
% The differences depend on restrictions on the actual parameters and
% the expandability of the resulting function.
% \begin{description}
% \item[\texttt{nopar}]
-% Create a new function with the \texttt{nopar} primitives,
+% Create a new function with the \texttt{nopar} restriction,
% such as \cs{cs_set_nopar:Npn}. The parameter may not contain
% \cs{par} tokens.
% \item[\texttt{protected}]
-% Create a new function with the \texttt{protected} primitives,
+% Create a new function with the \texttt{protected} restriction,
% such as \cs{cs_set_protected:Npn}. The parameter may contain
% \cs{par} tokens but the function will not expand within an
% \texttt{x}-type expansion.
% \end{description}
%
-% \subsection{Defining new functions using primitive parameter text}
+% \subsection{Defining new functions using parameter text}
%
% \begin{function}{\cs_new:Npn, \cs_new:cpn, \cs_new:Npx, \cs_new:cpx}
% \begin{syntax}
@@ -613,11 +613,11 @@
% \begin{function}
% {\cs_new_eq:NN, \cs_new_eq:Nc, \cs_new_eq:cN, \cs_new_eq:cc}
% \begin{syntax}
-% \cs{cs_new_eq:NN} \meta{cs 1} \meta{cs 2}
-% \cs{cs_new_eq:NN} \meta{cs 1} \meta{token}
+% \cs{cs_new_eq:NN} \meta{cs_1} \meta{cs_2}
+% \cs{cs_new_eq:NN} \meta{cs_1} \meta{token}
% \end{syntax}
-% Globally creates \meta{control sequence 1} and sets it to have the same
-% meaning as \meta{control sequence 2} or <token>.
+% Globally creates \meta{control sequence_1} and sets it to have the same
+% meaning as \meta{control sequence_2} or <token>.
% The second control sequence may
% subsequently be altered without affecting the copy.
% \end{function}
@@ -625,28 +625,28 @@
% \begin{function}
% {\cs_set_eq:NN, \cs_set_eq:Nc, \cs_set_eq:cN, \cs_set_eq:cc}
% \begin{syntax}
-% \cs{cs_set_eq:NN} \meta{cs 1} \meta{cs 2}
-% \cs{cs_set_eq:NN} \meta{cs 1} \meta{token}
+% \cs{cs_set_eq:NN} \meta{cs_1} \meta{cs_2}
+% \cs{cs_set_eq:NN} \meta{cs_1} \meta{token}
% \end{syntax}
-% Sets \meta{control sequence 1} to have the same meaning as
-% \meta{control sequence 2} (or <token>).
+% Sets \meta{control sequence_1} to have the same meaning as
+% \meta{control sequence_2} (or <token>).
% The second control sequence may subsequently be
% altered without affecting the copy. The assignment of a meaning
-% to the \meta{control sequence 1} is restricted to the current
+% to the \meta{control sequence_1} is restricted to the current
% \TeX{} group level.
% \end{function}
%
% \begin{function}
% {\cs_gset_eq:NN, \cs_gset_eq:Nc, \cs_gset_eq:cN, \cs_gset_eq:cc}
% \begin{syntax}
-% \cs{cs_gset_eq:NN} \meta{cs 1} \meta{cs 2}
-% \cs{cs_gset_eq:NN} \meta{cs 1} \meta{token}
+% \cs{cs_gset_eq:NN} \meta{cs_1} \meta{cs_2}
+% \cs{cs_gset_eq:NN} \meta{cs_1} \meta{token}
% \end{syntax}
-% Globally sets \meta{control sequence 1} to have the same meaning as
-% \meta{control sequence 2} (or <token>).
+% Globally sets \meta{control sequence_1} to have the same meaning as
+% \meta{control sequence_2} (or <token>).
% The second control sequence may subsequently be
% altered without affecting the copy. The assignment of a meaning to
-% the \meta{control sequence 1} is \emph{not} restricted to the current
+% the \meta{control sequence_1} is \emph{not} restricted to the current
% \TeX{} group level: the assignment is global.
% \end{function}
%
@@ -938,56 +938,6 @@
% in the input stream for further processing.
% \end{function}
%
-% \subsection{Decomposing control sequences}
-%
-% \begin{function}[EXP]{\cs_get_arg_count_from_signature:N}
-% \begin{syntax}
-% \cs{cs_get_arg_count_from_signature:N} \meta{function}
-% \end{syntax}
-% Splits the \meta{function} into the \meta{name} (\emph{i.e.}~the part
-% before the colon) and the \meta{signature} (\emph{i.e.}~after the colon).
-% The \meta{number} of tokens in the \meta{signature} is then left in
-% the input stream. If there was no \meta{signature} then the result is
-% the marker value $-1$.
-% \end{function}
-%
-% \begin{function}[EXP]{\cs_get_function_name:N}
-% \begin{syntax}
-% \cs{cs_get_function_name:N} \meta{function}
-% \end{syntax}
-% Splits the \meta{function} into the \meta{name} (\emph{i.e.}~the part
-% before the colon) and the \meta{signature} (\emph{i.e.}~after the colon).
-% The \meta{name} is then left in the input stream without the escape
-% character present made up of tokens with category code $12$
-% (other).
-% \end{function}
-%
-% \begin{function}[EXP]{\cs_get_function_signature:N}
-% \begin{syntax}
-% \cs{cs_get_function_signature:N} \meta{function}
-% \end{syntax}
-% Splits the \meta{function} into the \meta{name} (\emph{i.e.}~the part
-% before the colon) and the \meta{signature} (\emph{i.e.}~after the colon).
-% The \meta{signature} is then left in the input stream made up of
-% tokens with category code $12$ (other).
-% \end{function}
-%
-% \begin{function}[EXP]{\cs_split_function:NN}
-% \begin{syntax}
-% \cs{cs_split_function:NN} \meta{function} \meta{processor}
-% \end{syntax}
-% Splits the \meta{function} into the \meta{name} (\emph{i.e.}~the part
-% before the colon) and the \meta{signature} (\emph{i.e.}~after the colon).
-% This information is then placed in the input stream after the
-% \meta{processor} function in three parts: the \meta{name}, the
-% \meta{signature} and a logic token indicating if a colon was found
-% (to differentiate variables from function names). The \meta{name}
-% will not include the escape character, and both the \meta{name} and
-% \meta{signature} are made up of tokens with category code $12$
-% (other). The \meta{processor} should be a function with argument
-% specification \texttt{:nnN} (plus any trailing arguments needed).
-% \end{function}
-%
% \section{Predicates and conditionals}
% \label{sec:predicates}
%
@@ -1031,7 +981,7 @@
% are expandable and have names that end with |_p| in the
% description part. For example,
% \begin{quote}
-% |\cs_if_free_p:N|
+% \cs{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 \enquote{true} if its
@@ -1100,7 +1050,7 @@
% \begin{function}[EXP,pTF]
% {
% \str_if_eq:nn, \str_if_eq:Vn, \str_if_eq:on, \str_if_eq:no,
-% \str_if_eq:nV, \str_if_eq:VV, \str_if_eq:xx
+% \str_if_eq:nV, \str_if_eq:VV
% }
% \begin{syntax}
% \cs{str_if_eq_p:nn} \Arg{tl_1} \Arg{tl_2}
@@ -1110,11 +1060,63 @@
% basis, and is \texttt{true} if the two lists contain the same
% characters in the same order. Thus for example
% \begin{verbatim}
-% \str_if_eq_p:xx { abc } { \tl_to_str:n { abc } }
+% \str_if_eq_p:no { abc } { \tl_to_str:n { abc } }
+% \end{verbatim}
+% is logically \texttt{true}.
+% \end{function}
+%
+% \begin{function}[EXP,pTF, added = 2012-06-05]{\str_if_eq_x:nn}
+% \begin{syntax}
+% \cs{str_if_eq_x_p:nn} \Arg{tl_1} \Arg{tl_2}
+% \cs{str_if_eq_x:nnTF} \Arg{tl_1} \Arg{tl_2} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Compares the full expansion of two \meta{token lists} on a character by
+% character basis, and is \texttt{true} if the two lists contain the same
+% characters in the same order. Thus for example
+% \begin{verbatim}
+% \str_if_eq_x_p:nn { abc } { \tl_to_str:n { abc } }
% \end{verbatim}
-% is logically \texttt{true}. All versions of these functions are fully
-% expandable (including those involving an \texttt{x}-type
-% expansion).
+% is logically \texttt{true}.
+% \end{function}
+%
+% \begin{function}[added = 2012-06-03, EXP]{\str_case:nnn, \str_case:onn}
+% \begin{syntax}
+% \cs{str_case:nnn} \Arg{test string} \\
+% ~~|{| \\
+% ~~~~\Arg{string case_1} \Arg{code case_1} \\
+% ~~~~\Arg{string case_2} \Arg{code case_2} \\
+% ~~~~\ldots \\
+% ~~~~\Arg{string case_n} \Arg{code case_n} \\
+% ~~|}| \\
+% ~~\Arg{else code}
+% \end{syntax}
+% This function compares the \meta{test string} in turn with each
+% of the \meta{string cases}. If the two are equal (as described for
+% \cs{str_if_eq:nnTF} then the
+% associated \meta{code} is left in the input stream. If none of
+% the tests are \texttt{true} then the \texttt{else code} will be
+% left in the input stream.
+% \end{function}
+%
+% \begin{function}[added = 2012-06-05, EXP]{\str_case_x:nnn}
+% \begin{syntax}
+% \cs{str_case_x:nnn} \Arg{test string} \\
+% ~~|{| \\
+% ~~~~\Arg{string case_1} \Arg{code case_1} \\
+% ~~~~\Arg{string case_2} \Arg{code case_2} \\
+% ~~~~\ldots \\
+% ~~~~\Arg{string case_n} \Arg{code case_n} \\
+% ~~|}| \\
+% ~~\Arg{else code}
+% \end{syntax}
+% This function comapres the full expansion of the \meta{test string}
+% in turn with the full expansion of the \meta{string cases}. If the two
+% full expansions are equal (as described for \cs{str_if_eq:nnTF} then the
+% associated \meta{code} is left in the input stream. If none of the tests
+% are \texttt{true} then the \texttt{else code} will be left in the input
+% stream. The \meta{test string} is expanded in each comparison, and must
+% always yield the same result: for example, random numbers should
+% not be used within this string.
% \end{function}
%
% \subsection{Engine-specific conditionals}
@@ -1146,7 +1148,7 @@
% 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|.
+% \cs{int_compare_p:nNn} which is a wrapper for \cs{if_int_compare:w}.
%
% Certain conditionals deal with specific data types like boxes and
% fonts and are described there. The ones described below are either
@@ -1167,7 +1169,7 @@
% for more.
% \begin{texnote}
% These are equivalent to their corresponding \TeX\ primitive
-% conditionals; |\reverse_if:N| is \eTeX's |\unless|.
+% conditionals; \cs{reverse_if:N} is \eTeX's \tn{unless}.
% \end{texnote}
% \end{function}
%
@@ -1180,7 +1182,7 @@
% <arg_1> and <arg_2> could be functions, variables, tokens; in all cases the
% \emph{unexpanded} definitions are compared.
% \begin{texnote}
-% This is \TeX{}'s |\ifx|.
+% This is \TeX{}'s \tn{ifx}.
% \end{texnote}
% \end{function}
%
@@ -1223,45 +1225,105 @@
%
% \section{Internal kernel functions}
%
-% \begin{function}{\chk_if_exist_cs:N, \chk_if_exist_cs:c}
+% \begin{function}{\__chk_if_exist_cs:N, \__chk_if_exist_cs:c}
% \begin{syntax}
-% \cs{chk_if_exist_cs:N} \meta{cs}
+% \cs{__chk_if_exist_cs:N} \meta{cs}
% \end{syntax}
% This function checks that \meta{cs} exists according to the
% criteria for \cs{cs_if_exist_p:N}, and if not raises a kernel-level
% error.
% \end{function}
%
-% \begin{function}{\chk_if_free_cs:N, \chk_if_free_cs:c}
+% \begin{function}{\__chk_if_free_cs:N, \__chk_if_free_cs:c}
% \begin{syntax}
-% \cs{chk_if_free_cs:N} \meta{cs}
+% \cs{__chk_if_free_cs:N} \meta{cs}
% \end{syntax}
% This function checks that \meta{cs} is free according to the
% criteria for \cs{cs_if_free_p:N}, and if not raises a kernel-level
% error.
% \end{function}
%
-% \section{Experimental functions}
+% \begin{function}[EXP]{\__cs_count_signature:N, \__cs_count_signature:c}
+% \begin{syntax}
+% \cs{__cs_count_signature:N} \meta{function}
+% \end{syntax}
+% Splits the \meta{function} into the \meta{name} (\emph{i.e.}~the part
+% before the colon) and the \meta{signature} (\emph{i.e.}~after the colon).
+% The \meta{number} of tokens in the \meta{signature} is then left in
+% the input stream. If there was no \meta{signature} then the result is
+% the marker value $-1$.
+% \end{function}
%
-% \begin{function}[EXP,TF,added=2011-10-10]
-% {\cs_if_exist_use:N, \cs_if_exist_use:c}
+% \begin{function}[EXP]{\__cs_split_function:NN}
% \begin{syntax}
-% \cs{cs_if_exist_use:NTF} \meta{control sequence} \Arg{true code} \Arg{false code}
+% \cs{__cs_split_function:NN} \meta{function} \meta{processor}
% \end{syntax}
-% If the \meta{control sequence} exists, leave it in the input stream,
-% followed by the \meta{true code} (unbraced). Otherwise, leave the
-% \meta{false} code in the input stream. For example,
-% \begin{verbatim}
-% \cs_set:Npn \mypkg_use_character:N #1
-% { \cs_if_exist_use:cF { mypkg_#1:n } { \mypkg_default:N #1 } }
-% \end{verbatim}
-% calls the function |\mypkg_#1:n| if it exists, and falls back to
-% a default action otherwise. This could also be done (more slowly)
-% using \cs{prg_case_str:xxn}.
-% \begin{texnote}
-% The \texttt{c} variants do not introduce the \meta{control sequence}
-% in the hash table if it is not there.
-% \end{texnote}
+% Splits the \meta{function} into the \meta{name} (\emph{i.e.}~the part
+% before the colon) and the \meta{signature} (\emph{i.e.}~after the colon).
+% This information is then placed in the input stream after the
+% \meta{processor} function in three parts: the \meta{name}, the
+% \meta{signature} and a logic token indicating if a colon was found
+% (to differentiate variables from function names). The \meta{name}
+% will not include the escape character, and both the \meta{name} and
+% \meta{signature} are made up of tokens with category code $12$
+% (other). The \meta{processor} should be a function with argument
+% specification \texttt{:nnN} (plus any trailing arguments needed).
+% \end{function}
+%
+% \begin{function}[EXP]{\__cs_get_function_name:N}
+% \begin{syntax}
+% \cs{__cs_get_function_name:N} \meta{function}
+% \end{syntax}
+% Splits the \meta{function} into the \meta{name} (\emph{i.e.}~the part
+% before the colon) and the \meta{signature} (\emph{i.e.}~after the colon).
+% The \meta{name} is then left in the input stream without the escape
+% character present made up of tokens with category code $12$
+% (other).
+% \end{function}
+%
+% \begin{function}[EXP]{\__cs_get_function_signature:N}
+% \begin{syntax}
+% \cs{__cs_get_function_signature:N} \meta{function}
+% \end{syntax}
+% Splits the \meta{function} into the \meta{name} (\emph{i.e.}~the part
+% before the colon) and the \meta{signature} (\emph{i.e.}~after the colon).
+% The \meta{signature} is then left in the input stream made up of
+% tokens with category code $12$ (other).
+% \end{function}
+%
+% \begin{function}{\__cs_tmp:w}
+% Function used for various short-term usages, for instance defining
+% functions whose definition involves tokens which are hard to insert
+% normally (spaces, charactes with category other).
+% \end{function}
+%
+% \begin{function}{\__kernel_register_show:N, \__kernel_register_show:c}
+% \begin{syntax}
+% \cs{\__kernel_register_show:N} \meta{register}
+% \end{syntax}
+% Used to show the contents of a \TeX{} register at the terminal, formatted
+% such that internal parts of the mechanism are not visible.
+% \end{function}
+%
+% \begin{function}{\__prg_case_end:nw}
+% \begin{syntax}
+% \cs{__prg_case_end:nw} \Arg{code} \meta{tokens} \cs{q_recursion_stop}
+% \end{syntax}
+% Used to terminate case statements (\cs{int_case:nnn}, \emph{etc.})
+% by removing trailing \meta{tokens} and the end marker
+% \cs{q_recursion_stop}, and inserting the \meta{code} for the successful
+% case.
+% \end{function}
+%
+% \begin{function}{\__str_if_eq_x_return:nn}
+% \begin{syntax}
+% \cs{__str_if_eq_x_return:nn} \Arg{tl_1} \Arg{tl_2}
+% \end{syntax}
+% Compares the full expansion of two \meta{token lists} on a character by
+% character basis, and is \texttt{true} if the two lists contain the same
+% characters in the same order. Either \cs{prg_return_true:} or
+% \cs{prg_return_false:} is then left in the input stream. This is a version
+% of \cs{str_if_eq_x:nn(TF)} coded for speed.
% \end{function}
%
% \end{documentation}
@@ -1278,7 +1340,7 @@
%<*package>
\ProvidesExplPackage
{\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
-\package_check_loaded_expl:
+\__expl_package_check:
%</package>
% \end{macrocode}
%
@@ -1370,11 +1432,11 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[EXP]{\if_int_compare:w, \int_to_roman:w}
+% \begin{macro}[EXP]{\if_int_compare:w, \__int_to_roman:w}
% For integers.
% \begin{macrocode}
\tex_let:D \if_int_compare:w \tex_ifnum:D
-\tex_let:D \int_to_roman:w \tex_romannumeral:D
+\tex_let:D \__int_to_roman:w \tex_romannumeral:D
% \end{macrocode}
% \end{macro}
%
@@ -1385,15 +1447,6 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\tex_global:D, \tex_long:D, \etex_protected:D}
-% Three prefixes for assignments.
-% \begin{macrocode}
-\tex_let:D \tex_global:D \tex_global:D
-\tex_let:D \tex_long:D \tex_long:D
-\tex_let:D \tex_protected:D \etex_protected:D
-% \end{macrocode}
-% \end{macro}
-%
% \begin{macro}[EXP]{\exp_args:Nc}
% Discussed in \pkg{l3expan}, but needed much earlier.
% \begin{macrocode}
@@ -1403,15 +1456,16 @@
%
% \begin{macro}[EXP]{\token_to_str:c, \cs_meaning:c}
% \begin{macro}{\cs_show:c}
-% A small number of variants by hand. Some of the necessary functions
+% A small number of variants defined by hand.
+% Some of the necessary functions
% (\cs{use_i:nn}, \cs{use_ii:nn}, and \cs{exp_args:NNc}) are not
% defined at that point yet, but will be defined before those variants
% are used. The \cs{cs_meaning:c} command must check for an undefined
% control sequence to avoid defining it mistakenly. The
% \cs{cs_show:c} command is \enquote{protected} because its action is
% not expandable. Also, the conversion of its argument to a control
-% sequence is done within a group to avoid converting it to
-% \tn{relax}.
+% sequence is done within a group to avoid showing \tn{relax} for
+% undefined control sequences.
% \begin{macrocode}
\tex_def:D \token_to_str:c { \exp_args:Nc \token_to_str:N }
\tex_long:D \tex_def:D \cs_meaning:c #1
@@ -1424,7 +1478,7 @@
{ \exp_args:Nc \cs_meaning:N {#1} }
{ \tl_to_str:n {undefined} }
}
-\tex_protected:D \tex_def:D \cs_show:c
+\etex_protected:D \tex_def:D \cs_show:c
{ \group_begin: \exp_args:NNc \group_end: \cs_show:N }
% \end{macrocode}
% \end{macro}
@@ -1434,17 +1488,17 @@
%
% \begin{variable}{\c_minus_one, \c_zero, \c_sixteen}
% \begin{variable}{\c_six, \c_seven, \c_twelve}
-% We need the constants |\c_minus_one| and |\c_sixteen| now for
-% writing information to the log and the terminal and |\c_zero|
+% We need the constants \cs{c_minus_one} and \cs{c_sixteen} now for
+% writing information to the log and the terminal and \cs{c_zero}
% which is used by some functions in the \textsf{l3alloc} 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|. For other constants the \textsf{l3int} module is
+% ones that can be defined with \cs{tex_chardef:D} or
+% \cs{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
% 0--9, the first available one is~10 so we use that for
-% |\c_minus_one|.
+% \cs{c_minus_one}.
% \begin{macrocode}
%<*package>
\tex_let:D \c_minus_one \m@ne
@@ -1453,18 +1507,18 @@
\tex_countdef:D \c_minus_one = 10 ~
\c_minus_one = -1 ~
%</initex>
-\tex_chardef:D \c_sixteen = 16~
-\tex_chardef:D \c_zero = 0~
-\tex_chardef:D \c_six = 6~
-\tex_chardef:D \c_seven = 7~
-\tex_chardef:D \c_twelve = 12~
+\tex_chardef:D \c_sixteen = 16 ~
+\tex_chardef:D \c_zero = 0 ~
+\tex_chardef:D \c_six = 6 ~
+\tex_chardef:D \c_seven = 7 ~
+\tex_chardef:D \c_twelve = 12 ~
% \end{macrocode}
% \end{variable}
% \end{variable}
%
% \begin{variable}{\c_max_register_int}
% This is here as this particular integer is needed both in package
-% mode and to bootstrap \pkg{l3alloc}.
+% mode and to bootstrap \pkg{l3alloc}, and is documented in \pkg{l3int}.
% \begin{macrocode}
\etex_ifdefined:D \luatex_luatexversion:D
\tex_chardef:D \c_max_register_int = 65 535 ~
@@ -1486,24 +1540,24 @@
% \cs_set_protected_nopar:Npn , \cs_set_protected_nopar:Npx ,
% \cs_set_protected:Npn , \cs_set_protected:Npx
% }
-% All assignment functions in \LaTeX3 should be naturally robust;
+% All assignment functions in \LaTeX3 should be naturally protected;
% after all, the \TeX{} primitives for assignments are and it can be
% a cause of problems if others aren't.
% \begin{macrocode}
\tex_let:D \cs_set_nopar:Npn \tex_def:D
\tex_let:D \cs_set_nopar:Npx \tex_edef:D
-\tex_protected:D \cs_set_nopar:Npn \cs_set:Npn
+\etex_protected:D \cs_set_nopar:Npn \cs_set:Npn
{ \tex_long:D \cs_set_nopar:Npn }
-\tex_protected:D \cs_set_nopar:Npn \cs_set:Npx
+\etex_protected:D \cs_set_nopar:Npn \cs_set:Npx
{ \tex_long:D \cs_set_nopar:Npx }
-\tex_protected:D \cs_set_nopar:Npn \cs_set_protected_nopar:Npn
- { \tex_protected:D \cs_set_nopar:Npn }
-\tex_protected:D \cs_set_nopar:Npn \cs_set_protected_nopar:Npx
- { \tex_protected:D \cs_set_nopar:Npx }
+\etex_protected:D \cs_set_nopar:Npn \cs_set_protected_nopar:Npn
+ { \etex_protected:D \cs_set_nopar:Npn }
+\etex_protected:D \cs_set_nopar:Npn \cs_set_protected_nopar:Npx
+ { \etex_protected:D \cs_set_nopar:Npx }
\cs_set_protected_nopar:Npn \cs_set_protected:Npn
- { \tex_protected:D \tex_long:D \cs_set_nopar:Npn }
+ { \etex_protected:D \tex_long:D \cs_set_nopar:Npn }
\cs_set_protected_nopar:Npn \cs_set_protected:Npx
- { \tex_protected:D \tex_long:D \cs_set_nopar:Npx }
+ { \etex_protected:D \tex_long:D \cs_set_nopar:Npx }
% \end{macrocode}
% \end{macro}
%
@@ -1523,13 +1577,13 @@
\cs_set_protected_nopar:Npn \cs_gset:Npx
{ \tex_long:D \cs_gset_nopar:Npx }
\cs_set_protected_nopar:Npn \cs_gset_protected_nopar:Npn
- { \tex_protected:D \cs_gset_nopar:Npn }
+ { \etex_protected:D \cs_gset_nopar:Npn }
\cs_set_protected_nopar:Npn \cs_gset_protected_nopar:Npx
- { \tex_protected:D \cs_gset_nopar:Npx }
+ { \etex_protected:D \cs_gset_nopar:Npx }
\cs_set_protected_nopar:Npn \cs_gset_protected:Npn
- { \tex_protected:D \tex_long:D \cs_gset_nopar:Npn }
+ { \etex_protected:D \tex_long:D \cs_gset_nopar:Npn }
\cs_set_protected_nopar:Npn \cs_gset_protected:Npx
- { \tex_protected:D \tex_long:D \cs_gset_nopar:Npx }
+ { \etex_protected:D \tex_long:D \cs_gset_nopar:Npx }
% \end{macrocode}
% \end{macro}
%
@@ -1544,18 +1598,18 @@
%
% \begin{macro}{\use:x}
% Fully expands its argument and passes it to the input stream. Uses
-% the reserved \cs{l_exp_internal_tl} which will be set up in \pkg{l3expan}.
+% the reserved \cs{l__exp_internal_tl} which will be set up in \pkg{l3expan}.
% \begin{macrocode}
\cs_set_protected:Npn \use:x #1
{
- \cs_set_nopar:Npx \l_exp_internal_tl {#1}
- \l_exp_internal_tl
+ \cs_set_nopar:Npx \l__exp_internal_tl {#1}
+ \l__exp_internal_tl
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[EXP]{\use:n, \use:nn, \use:nnn, \use:nnnn}
-% These macro grabs its arguments and returns it back to the input
+% These macros grab their arguments and returns them back to the input
% (with outer braces removed).
% \begin{macrocode}
\cs_set:Npn \use:n #1 {#1}
@@ -1663,20 +1717,25 @@
% 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:
+% \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
+% \cs{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}[EXP]{\prg_return_true:, \prg_return_false:}
-% The idea here is that \cs{int_to_roman:w} will expand fully any
+% The idea here is that \cs{__int_to_roman:w} will expand fully any
% \cs{else:} and the \cs{fi:} that are waiting to be discarded,
% before reaching the \cs{c_zero} which will leave the expansion null.
% The code can then leave either the first or second argument in the
@@ -1685,9 +1744,9 @@
% to see this.
% \begin{macrocode}
\cs_set_nopar:Npn \prg_return_true:
- { \exp_after:wN \use_i:nn \int_to_roman:w }
+ { \exp_after:wN \use_i:nn \__int_to_roman:w }
\cs_set_nopar:Npn \prg_return_false:
- { \exp_after:wN \use_ii:nn \int_to_roman:w}
+ { \exp_after:wN \use_ii:nn \__int_to_roman:w}
% \end{macrocode}
% An extended state space could be implemented by including a more
% elaborate function in place of \cs{use_i:nn}/\cs{use_ii:nn}. Provided
@@ -1701,29 +1760,29 @@
% \prg_set_protected_conditional:Npnn ,
% \prg_new_protected_conditional:Npnn ,
% }
-% \begin{macro}[aux]{\prg_generate_conditional_parm_aux:NNpnn}
+% \begin{macro}[aux]{\__prg_generate_conditional_parm:nnNpnn}
% The user functions for the types using parameter text from the
% programmer. The various functions only differ by which function is
% used for the assignment. For those |Npnn| type functions, we must
% grab the parameter text, reading everything up to a left brace
% before continuing. Then split the base function into name and
% signature, and feed \Arg{name} \Arg{signature} \meta{boolean}
-% \meta{defining~function} |{parm}| \Arg{parameters} |{TF,...}|
+% \Arg{set~or~new} \Arg{maybe~protected} \Arg{parameters} |{TF,...}|
% \Arg{code} to the auxiliary function responsible for defining all
% conditionals.
% \begin{macrocode}
\cs_set_protected_nopar:Npn \prg_set_conditional:Npnn
- { \prg_generate_conditional_parm_aux:NNpnn \cs_set:Npn }
+ { \__prg_generate_conditional_parm:nnNpnn { set } { } }
\cs_set_protected_nopar:Npn \prg_new_conditional:Npnn
- { \prg_generate_conditional_parm_aux:NNpnn \cs_new:Npn }
+ { \__prg_generate_conditional_parm:nnNpnn { new } { } }
\cs_set_protected_nopar:Npn \prg_set_protected_conditional:Npnn
- { \prg_generate_conditional_parm_aux:NNpnn \cs_set_protected:Npn }
+ { \__prg_generate_conditional_parm:nnNpnn { set } { _protected } }
\cs_set_protected_nopar:Npn \prg_new_protected_conditional:Npnn
- { \prg_generate_conditional_parm_aux:NNpnn \cs_new_protected:Npn }
-\cs_set_protected:Npn \prg_generate_conditional_parm_aux:NNpnn #1#2#3#
+ { \__prg_generate_conditional_parm:nnNpnn { new } { _protected } }
+\cs_set_protected:Npn \__prg_generate_conditional_parm:nnNpnn #1#2#3#4#
{
- \cs_split_function:NN #2 \prg_generate_conditional_aux:nnNNnnnn
- #1 { parm } {#3}
+ \__cs_split_function:NN #3 \__prg_generate_conditional:nnNnnnnn
+ {#1} {#2} {#4}
}
% \end{macrocode}
% \end{macro}
@@ -1736,204 +1795,248 @@
% \prg_set_protected_conditional:Nnn ,
% \prg_new_protected_conditional:Nnn ,
% }
-% \begin{macro}[aux]{\prg_generate_conditional_count_aux:NNnn}
+% \begin{macro}[aux]
+% {
+% \__prg_generate_conditional_count:nnNnn ,
+% \__prg_generate_conditional_count:nnNnnnn
+% }
% The user functions for the types automatically inserting the correct
% parameter text based on the signature. The various functions only
-% differ by which function is used for the assignment. For those |Nnn|
-% type functions, we calculate the number of arguments. Then split the
-% base function into name and signature, and feed \Arg{name}
-% \Arg{signature} \meta{boolean} \meta{defining~function} |{count}|
-% \Arg{arg~count} |{TF,...}| \Arg{code} to the auxiliary function
-% responsible for defining all conditionals.
+% differ by which function is used for the assignment. Split the base
+% function into name and signature. The second auxiliary generates
+% the parameter text from the number of letters in the signature.
+% Then feed \Arg{name} \Arg{signature} \meta{boolean} \Arg{set~or~new}
+% \Arg{maybe~protected} \Arg{parameters} |{TF,...}| \Arg{code} to the
+% auxiliary function responsible for defining all conditionals. If
+% the \meta{signature} has more than $9$ letters, the definition is
+% aborted since \TeX{} macros have at most $9$ arguments. The
+% erroneous case where the function name contains no colon is captured
+% later.
% \begin{macrocode}
\cs_set_protected_nopar:Npn \prg_set_conditional:Nnn
- { \prg_generate_conditional_count_aux:NNnn \cs_set:Npn }
+ { \__prg_generate_conditional_count:nnNnn { set } { } }
\cs_set_protected_nopar:Npn \prg_new_conditional:Nnn
- { \prg_generate_conditional_count_aux:NNnn \cs_new:Npn }
+ { \__prg_generate_conditional_count:nnNnn { new } { } }
\cs_set_protected_nopar:Npn \prg_set_protected_conditional:Nnn
- { \prg_generate_conditional_count_aux:NNnn \cs_set_protected:Npn }
+ { \__prg_generate_conditional_count:nnNnn { set } { _protected } }
\cs_set_protected_nopar:Npn \prg_new_protected_conditional:Nnn
- { \prg_generate_conditional_count_aux:NNnn \cs_new_protected:Npn }
-\cs_set_protected:Npn \prg_generate_conditional_count_aux:NNnn #1#2
+ { \__prg_generate_conditional_count:nnNnn { new } { _protected } }
+\cs_set_protected:Npn \__prg_generate_conditional_count:nnNnn #1#2#3
+ {
+ \__cs_split_function:NN #3 \__prg_generate_conditional_count:nnNnnnn
+ {#1} {#2}
+ }
+\cs_set_protected:Npn \__prg_generate_conditional_count:nnNnnnn #1#2#3#4#5
{
- \exp_args:Nnf \use:n
+ \__cs_parm_from_arg_count:nnF
+ { \__prg_generate_conditional:nnNnnnnn {#1} {#2} #3 {#4} {#5} }
+ { \tl_count:n {#2} }
{
- \cs_split_function:NN #2 \prg_generate_conditional_aux:nnNNnnnn
- #1 { count }
+ \__msg_kernel_error:nnxx { kernel } { bad-number-of-arguments }
+ { \token_to_str:c { #1 : #2 } }
+ { \tl_count:n {#2} }
+ \use_none:nn
}
- { \cs_get_arg_count_from_signature:N #2 }
}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\prg_set_eq_conditional:NNn,\prg_new_eq_conditional:NNn}
-% The obvious setting-equal functions.
-% \begin{macrocode}
-\cs_set_protected:Npn \prg_set_eq_conditional:NNn #1#2#3
- { \prg_set_eq_conditional_aux:NNNn \cs_set_eq:cc #1#2 {#3} }
-\cs_set_protected:Npn \prg_new_eq_conditional:NNn #1#2#3
- { \prg_set_eq_conditional_aux:NNNn \cs_new_eq:cc #1#2 {#3} }
-% \end{macrocode}
-% \end{macro}
-%
% \begin{macro}[aux]
% {
-% \prg_generate_conditional_aux:nnNNnnnn,
-% \prg_generate_conditional_aux:nnw
+% \__prg_generate_conditional:nnNnnnnn,
+% \__prg_generate_conditional:nnnnnnw
% }
% The workhorse here is going through a list of desired forms, \emph{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
+% name. In the absence of a colon, we throw an error and don't define
+% any conditional. The fourth and fifth arguments build up the
+% defining function. The sixth is the parameters to use (possibly
+% empty), the seventh is the list of forms to define, the eigth is the
% replacement text which we will augment when defining the forms.
% \begin{macrocode}
-\cs_set_protected:Npn \prg_generate_conditional_aux:nnNNnnnn #1#2#3#4#5#6#7#8
+\cs_set_protected:Npn \__prg_generate_conditional:nnNnnnnn #1#2#3#4#5#6#7#8
{
- \prg_generate_conditional_aux:nnw {#5}
- {
- #4 {#1} {#2} {#6} {#8}
- }
- #7 , ? , \q_recursion_stop
+ \if_meaning:w \c_true_bool #3
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
+ {
+ \__prg_generate_conditional:nnnnnnw
+ {#4} {#5} {#1} {#2} {#6} {#8}
+ #7 , , \q_recursion_stop
+ }
+ {
+ \__msg_kernel_error:nnx { kernel } { missing-colon }
+ { \token_to_str:c {#1} }
+ }
}
% \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.
+% Looping through the list of desired forms. First are six arguments
+% and seventh is the form. Use the form to call the
+% correct type. If the form does not exist, the \cs{use:c}
+% construction results in \tn{relax}, and the error message is
+% displayed, then \cs{use_none:nnnnnnn} cleans up. Otherwise, the
+% error message is removed by the variant form.
% \begin{macrocode}
-\cs_set_protected:Npn \prg_generate_conditional_aux:nnw #1#2#3 ,
+\cs_set_protected:Npn \__prg_generate_conditional:nnnnnnw #1#2#3#4#5#6#7 ,
{
- \if:w ?#3
+ \if_catcode:w \scan_stop: \etex_detokenize:D {#7} \scan_stop:
\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}
+ \use:c { __prg_generate_ \etex_detokenize:D {#7} _form:wnnnnnn }
+ \__msg_kernel_error:nnxx
+ { kernel } { conditional-form-unknown }
+ { \tl_to_str:n {#7} } { \token_to_str:c { #3 : #4 } }
+ \use_none:nnnnnnn
+ \q_stop
+ {#1} {#2} {#3} {#4} {#5} {#6}
+ \__prg_generate_conditional:nnnnnnw {#1} {#2} {#3} {#4} {#5} {#6}
}
% \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
+% \__prg_generate_p_form:wnnnnnn,
+% \__prg_generate_TF_form:wnnnnnn,
+% \__prg_generate_T_form:wnnnnnn,
+% \__prg_generate_F_form:wnnnnnn
% }
-% 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. Remember that
-% the logic-returning functions expect two arguments to be present after
-% \cs{c_zero}: notice the construction of the different variants
-% relies on this, and that the |TF| variant will be slightly faster
-% than the |T| version.
-% \begin{macrocode}
-\cs_set_protected:Npn \prg_generate_p_form_parm:Nnnnn #1#2#3#4#5
+% How to generate the various forms. Those functions take the
+% following arguments: 1: \texttt{set} or \texttt{new}, 2: empty or
+% \texttt{\_protected}, 3: function name 4: signature, 5: parameter
+% text (or empty), 6: replacement. Remember that the logic-returning
+% functions expect two arguments to be present after \cs{c_zero}:
+% notice the construction of the different variants relies on this,
+% and that the |TF| variant will be slightly faster than the |T|
+% version. The |p| form is only valid for expandable tests, we check
+% for that by making sure that the second argument is empty.
+% \begin{macrocode}
+\cs_set_protected:Npn \__prg_generate_p_form:wnnnnnn #1 \q_stop #2#3#4#5#6#7
{
- \exp_args:Nc #1 { #2 _p: #3 } #4
+ \if_meaning:w \scan_stop: #3 \scan_stop:
+ \exp_after:wN \use_i:nn
+ \else:
+ \exp_after:wN \use_ii:nn
+ \fi:
{
- #5 \c_zero
- \c_true_bool \c_false_bool
+ \exp_args:Nc \exp_args:Nc { cs_ #2 #3 :Npn } { #4 _p: #5 } #6
+ { #7 \c_zero \c_true_bool \c_false_bool }
}
- }
-\cs_set_protected:Npn \prg_generate_T_form_parm:Nnnnn #1#2#3#4#5
- {
- \exp_args:Nc #1 { #2 : #3 T } #4
{
- #5 \c_zero
- \use:n \use_none:n
+ \__msg_kernel_error:nnx { kernel } { protected-predicate }
+ { \token_to_str:c { #4 _p: #5 } }
}
}
-\cs_set_protected:Npn \prg_generate_F_form_parm:Nnnnn #1#2#3#4#5
+\cs_set_protected:Npn \__prg_generate_T_form:wnnnnnn #1 \q_stop #2#3#4#5#6#7
{
- \exp_args:Nc #1 { #2 : #3 F } #4
- {
- #5 \c_zero
- { }
- }
+ \exp_args:Nc \exp_args:Nc { cs_ #2 #3 :Npn } { #4 : #5 T } #6
+ { #7 \c_zero \use:n \use_none:n }
}
-\cs_set_protected:Npn \prg_generate_TF_form_parm:Nnnnn #1#2#3#4#5
+\cs_set_protected:Npn \__prg_generate_F_form:wnnnnnn #1 \q_stop #2#3#4#5#6#7
{
- \exp_args:Nc #1 { #2 : #3 TF } #4
- { #5 \c_zero }
+ \exp_args:Nc \exp_args:Nc { cs_ #2 #3 :Npn } { #4 : #5 F } #6
+ { #7 \c_zero { } }
+ }
+\cs_set_protected:Npn \__prg_generate_TF_form:wnnnnnn #1 \q_stop #2#3#4#5#6#7
+ {
+ \exp_args:Nc \exp_args:Nc { cs_ #2 #3 :Npn } { #4 : #5 TF } #6
+ { #7 \c_zero }
}
% \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
-% }
-% The |count| form is similar, but of course requires a number rather
-% than a primitive argument specification.
+% \begin{macro}{\prg_set_eq_conditional:NNn,\prg_new_eq_conditional:NNn}
+% The setting-equal functions. Split the base function to be copied,
+% and feed a first auxiliary \Arg{name} \Arg{signature} \meta{boolean}
+% \meta{copying~function} \meta{new~function} \Arg{conditions}.
% \begin{macrocode}
-\cs_set_protected:Npn \prg_generate_p_form_count:Nnnnn #1#2#3#4#5
+\cs_set_protected:Npn \prg_set_eq_conditional:NNn #1#2
{
- \cs_generate_from_arg_count:cNnn { #2 _p: #3 } #1 {#4}
- {
- #5 \c_zero
- \c_true_bool \c_false_bool
- }
+ \__cs_split_function:NN #2 \__prg_set_eq_conditional:nnNNNn
+ \cs_set_eq:cc #1
}
-\cs_set_protected:Npn \prg_generate_T_form_count:Nnnnn #1#2#3#4#5
+\cs_set_protected:Npn \prg_new_eq_conditional:NNn #1#2
{
- \cs_generate_from_arg_count:cNnn { #2 : #3 T } #1 {#4}
- {
- #5 \c_zero
- \use:n \use_none:n
- }
- }
-\cs_set_protected:Npn \prg_generate_F_form_count:Nnnnn #1#2#3#4#5
- {
- \cs_generate_from_arg_count:cNnn { #2 : #3 F } #1 {#4}
- {
- #5 \c_zero
- { }
- }
- }
-\cs_set_protected:Npn \prg_generate_TF_form_count:Nnnnn #1#2#3#4#5
- {
- \cs_generate_from_arg_count:cNnn { #2 : #3 TF } #1 {#4}
- { #5 \c_zero }
+ \__cs_split_function:NN #2 \__prg_set_eq_conditional:nnNNNn
+ \cs_new_eq:cc #1
}
% \end{macrocode}
% \end{macro}
%
% \begin{macro}[aux]
-% {\prg_set_eq_conditional_aux:NNNn, \prg_set_eq_conditional_aux:NNNw}
+% {
+% \__prg_set_eq_conditional:nnNNNn ,
+% \__prg_set_eq_conditional:nnNnnNNw ,
+% \__prg_set_eq_conditional_loop:nnnnNw
+% }
% \begin{macro}[aux, EXP]
% {
-% \prg_conditional_form_p:nnn ,
-% \prg_conditional_form_TF:nnn ,
-% \prg_conditional_form_T:nnn ,
-% \prg_conditional_form_F:nnn ,
+% \__prg_conditional_p_form:nnn ,
+% \__prg_conditional_TF_form:nnn ,
+% \__prg_conditional_T_form:nnn ,
+% \__prg_conditional_F_form:nnn ,
% }
-% Manual clist loop over argument |#4|.
-% \begin{macrocode}
-\cs_set_protected:Npn \prg_set_eq_conditional_aux:NNNn #1#2#3#4
- { \prg_set_eq_conditional_aux:NNNw #1#2#3#4 , ? , \q_recursion_stop }
-\cs_set_protected:Npn \prg_set_eq_conditional_aux:NNNw #1#2#3#4 ,
+% Split the function to be defined, and setup a manual clist loop over
+% argument |#6| of the first auxiliary. The second auxiliary receives
+% twice three arguments coming from splitting the function to be
+% defined and the function to copy. Make sure that both functions
+% contained a colon, otherwise we don't know how to build
+% conditionals, hence abort. Call the looping macro, with arguments
+% \Arg{name_1} \Arg{signature_1} \Arg{name_2} \Arg{signature_2}
+% \meta{copying~function} and followed by the comma list. At each
+% step in the loop, make sure that the conditional form we copy is
+% defined, and copy it, otherwise abort.
+% \begin{macrocode}
+\cs_set_protected:Npn \__prg_set_eq_conditional:nnNNNn #1#2#3#4#5#6
{
- \if:w ? #4 \scan_stop:
+ \__cs_split_function:NN #5 \__prg_set_eq_conditional:nnNnnNNw
+ {#1} {#2} #3 #4
+ #6 , \scan_stop: , \q_recursion_stop
+ }
+\cs_set_protected:Npn \__prg_set_eq_conditional:nnNnnNNw #1#2#3#4#5#6
+ {
+ \if_meaning:w \c_false_bool #3
+ \__msg_kernel_error:nnx { kernel } { missing-colon }
+ { \token_to_str:c {#1} }
+ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ \if_meaning:w \c_false_bool #6
+ \__msg_kernel_error:nnx { kernel } { missing-colon }
+ { \token_to_str:c {#4} }
\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}
+ \__prg_set_eq_conditional_loop:nnnnNw {#1} {#2} {#4} {#5}
+ }
+\cs_set_protected:Npn \__prg_set_eq_conditional_loop:nnnnNw #1#2#3#4#5#6 ,
+ {
+ \if_meaning:w \scan_stop: #6 \scan_stop:
+ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
+ \fi:
+ \cs_if_exist:cTF
+ { \use:c { __prg_conditional_ #6 _form:nn } {#3} {#4} }
+ {
+ #5
+ { \use:c { __prg_conditional_ #6 _form:nn } {#1} {#2} }
+ { \use:c { __prg_conditional_ #6 _form:nn } {#3} {#4} }
+ }
+ {
+ \__msg_kernel_error:nnx { kernel } { command-not-defined }
+ {
+ \token_to_str:c
+ { \use:c { __prg_conditional_ #6 _form:nn } {#3} {#4} }
+ }
+ }
+ \__prg_set_eq_conditional_loop:nnnnNw {#1} {#2} {#3} {#4} #5
}
-\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 : #2 TF }
-\cs_set:Npn \prg_conditional_form_T:nnn #1#2#3 { #1 : #2 T }
-\cs_set:Npn \prg_conditional_form_F:nnn #1#2#3 { #1 : #2 F }
+\cs_set:Npn \__prg_conditional_p_form:nn #1#2 { #1 _p : #2 }
+\cs_set:Npn \__prg_conditional_TF_form:nn #1#2 { #1 : #2 TF }
+\cs_set:Npn \__prg_conditional_T_form:nn #1#2 { #1 : #2 T }
+\cs_set:Npn \__prg_conditional_F_form:nn #1#2 { #1 : #2 F }
% \end{macrocode}
% \end{macro}
% \end{macro}
@@ -1941,7 +2044,7 @@
% 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{TF} to be tested using \cs{if:w} but this was later changed to
% |00| and |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
@@ -1950,22 +2053,22 @@
% \begin{variable}{\c_true_bool, \c_false_bool}
% Here are the canonical boolean values.
% \begin{macrocode}
-\tex_chardef:D \c_true_bool = 1~
-\tex_chardef:D \c_false_bool = 0~
+\tex_chardef:D \c_true_bool = 1 ~
+\tex_chardef:D \c_false_bool = 0 ~
% \end{macrocode}
% \end{variable}
%
% \subsection{Dissecting a control sequence}
%
% \begin{macro}[EXP]{\cs_to_str:N}
-% \begin{macro}[aux, EXP]{\cs_to_str_aux:N, \cs_to_str_aux:w}
+% \begin{macro}[aux, EXP]{\__cs_to_str:N, \__cs_to_str: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;
+% the value of the \tn{escapechar} is negative;
% \item when the escape character is a space.
% \end{itemize}
% One approach to solve this is to test how many tokens result from
@@ -1979,109 +2082,97 @@
% a little more intricate still. When the escape character is printable,
% \verb*|\token_to_str:N \ | yields the escape character itself and a space.
% The character codes are different, thus the \cs{if:w} test is false,
-% and \TeX{} reads \cs{cs_to_str_aux:N} after turning the following
+% and \TeX{} reads \cs{__cs_to_str:N} after turning the following
% control sequence into a string; this auxiliary removes the escape
-% character, and stops the expansion of the initial \cs{int_to_roman:w}.
+% character, and stops the expansion of the initial \cs{__int_to_roman:w}.
% The second case is that the escape character is not printable. Then
% the \cs{if:w} test is unfinished after reading a the space from
-% \verb*|\token_to_str:N \ |, and the auxiliary \cs{cs_to_str_aux:w}
+% \verb*|\token_to_str:N \ |, and the auxiliary \cs{__cs_to_str:w}
% is expanded, feeding |-| as a second character for the test;
% the test is false, and \TeX{} skips to \cs{fi:}, then performs
-% \cs{token_to_str:N}, and stops the \cs{int_to_roman:w} with \cs{c_zero}.
+% \cs{token_to_str:N}, and stops the \cs{__int_to_roman:w} with \cs{c_zero}.
% The last case is that the escape character is itself a space. In this
-% case, the \cs{if:w} test is true, and the auxiliary \cs{cs_to_str_aux:w}
-% comes into play, inserting |-\int_value:w|, which expands \cs{c_zero}
-% to the character |0|. The initial \cs{int_to_roman:w} then sees
+% case, the \cs{if:w} test is true, and the auxiliary \cs{__cs_to_str:w}
+% comes into play, inserting |-\__int_value:w|, which expands \cs{c_zero}
+% to the character |0|. The initial \cs{__int_to_roman:w} then sees
% |0|, which is not a terminated number, followed by the escape character,
% a space, which is removed, terminating the argument of
-% \cs{int_to_roman:w}.
+% \cs{__int_to_roman:w}.
% In all three cases, \cs{cs_to_str:N} takes two expansion steps
% to be fully expanded.
% \begin{macrocode}
\cs_set_nopar:Npn \cs_to_str:N
{
- \int_to_roman:w
- \if:w \token_to_str:N \ \cs_to_str_aux:w \fi:
- \exp_after:wN \cs_to_str_aux:N \token_to_str:N
+ \__int_to_roman:w
+ \if:w \token_to_str:N \ \__cs_to_str:w \fi:
+ \exp_after:wN \__cs_to_str:N \token_to_str:N
}
-\cs_set:Npn \cs_to_str_aux:N #1 { \c_zero }
-\cs_set:Npn \cs_to_str_aux:w #1 \cs_to_str_aux:N
- { - \int_value:w \fi: \exp_after:wN \c_zero }
+\cs_set:Npn \__cs_to_str:N #1 { \c_zero }
+\cs_set:Npn \__cs_to_str:w #1 \__cs_to_str:N
+ { - \__int_value:w \fi: \exp_after:wN \c_zero }
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \begin{macro}[EXP]{\cs_split_function:NN}
+% \begin{macro}[EXP, int]{\__cs_split_function:NN}
% \begin{macro}[aux, EXP]
-% {\cs_split_function_aux:w, \cs_split_function_auxii:w}
+% {\__cs_split_function_i:w, \__cs_split_function_ii: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 \meta{true} or \meta{false} is
% returned with \meta{true} for when there is a colon in the function
% and \meta{false} if there is not. Lastly, the second argument of
-% \cs{cs_split_function:NN} is supposed to be a function
+% \cs{__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|.
+% |\__cs_split_function:NN \foo_bar:cnx \use_i:nnn| as input
+% becomes |\use_i:nnn {foo_bar} {cnx} \c_true_bool|.
+%
+% We can't use a literal |:| because it has the wrong catcode here, so
+% it's transformed from |@| with \cs{tex_lowercase:D}.
+%
+% First ensure that we actually get a properly evaluated string by
+% expanding \cs{cs_to_str:N} twice. If the function contained a
+% colon, the auxiliary takes as |#1| the function name, delimited by
+% the first colon, then the signature |#2|, delimited by \cs{q_mark},
+% then \cs{c_true_bool} as |#3|, and |#4| cleans up until \cs{q_stop}.
+% Otherwise, the |#1| contains the function name and \cs{q_mark}
+% \cs{c_true_bool}, |#2| is empty, |#3| is \cs{c_false_bool}, and |#4|
+% cleans up. In both cases, |#5| is the \meta{processor}. The second
+% auxiliary trims the trailing \cs{q_mark} from the function name if
+% present (that is, if the original function had no colon).
% \begin{macrocode}
\group_begin:
- \tex_lccode:D `\@ = `\: \scan_stop:
- \tex_catcode:D `\@ = 12~
+\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
-% by expanding \cs{cs_to_str:N} twice. Insert
-% extra colon to catch the error cases.
-% \begin{macrocode}
- \cs_set:Npn \cs_split_function:NN #1#2
+ \cs_set:Npn \__cs_split_function:NN #1
{
\exp_after:wN \exp_after:wN
- \exp_after:wN \cs_split_function_aux:w
- \cs_to_str:N #1 @ a \q_stop #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 \cs{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_stop #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_stop #4 {#1} }
+ \exp_after:wN \__cs_split_function_i:w
+ \cs_to_str:N #1 \q_mark \c_true_bool
+ @ \q_mark \c_false_bool
+ \q_stop
}
- \cs_set:Npn \cs_split_function_auxii:w #1 @a \q_stop #2#3
- { #2{#3}{#1}\c_true_bool }
-% \end{macrocode}
-% End of lowercase
-% \begin{macrocode}
+ \cs_set:Npn \__cs_split_function_i:w #1 @ #2 \q_mark #3#4 \q_stop #5
+ { \__cs_split_function_ii:w #5 #1 \q_mark \q_stop {#2} #3 }
+ \cs_set:Npn \__cs_split_function_ii:w #1#2 \q_mark #3 \q_stop
+ { #1 {#2} }
}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \begin{macro}[EXP]{\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{macro}[EXP, int]
+% {\__cs_get_function_name:N, \__cs_get_function_signature:N}
+% Simple wrappers.
% \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 }
+\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}
%
@@ -2089,15 +2180,15 @@
%
% 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}
+% \tn{relax} token. A control sequence is said to be \emph{free}
% (to be defined) if it does not already exist.
%
% \begin{macro}[pTF, EXP]{\cs_if_exist:N,\cs_if_exist:c}
% Two versions for checking existence. For the |N| form we firstly
-% check for |\scan_stop:| 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 |\scan_stop:|.
+% check for \cs{scan_stop:} and then if it is in the hash
+% table. There is no problem when inputting something like \cs{else:}
+% or \cs{fi:} as \TeX{} will only ever skip input in case the token
+% tested against is \cs{scan_stop:}.
% \begin{macrocode}
\prg_set_conditional:Npnn \cs_if_exist:N #1 { p , T , F , TF }
{
@@ -2113,7 +2204,7 @@
}
% \end{macrocode}
% For the |c| form we firstly check if it is in the hash table and
-% then for |\scan_stop:| so that we do not add it to the hash table
+% then for \cs{scan_stop:} 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
@@ -2226,14 +2317,14 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}
-% {\msg_kernel_error:nnxx, \msg_kernel_error:nnx, \msg_kernel_error:nn}
+% \begin{macro}[int]
+% {\__msg_kernel_error:nnxx, \__msg_kernel_error:nnx, \__msg_kernel_error:nn}
% If an internal error occurs before \LaTeX3 has loaded \pkg{l3msg} then
% the code should issue a usable if terse error message and halt. This
% can only happen if a coding error is made by the team, so this is
% a reasonable response.
% \begin{macrocode}
-\cs_set_protected:Npn \msg_kernel_error:nnxx #1#2#3#4
+\cs_set_protected:Npn \__msg_kernel_error:nnxx #1#2#3#4
{
\tex_errmessage:D
{
@@ -2245,10 +2336,10 @@
}
\tex_end:D
}
-\cs_set_protected:Npn \msg_kernel_error:nnx #1#2#3
- { \msg_kernel_error:nnxx {#1} {#2} {#3} { } }
-\cs_set_protected:Npn \msg_kernel_error:nn #1#2
- { \msg_kernel_error:nnxx {#1} {#2} { } { } }
+\cs_set_protected:Npn \__msg_kernel_error:nnx #1#2#3
+ { \__msg_kernel_error:nnxx {#1} {#2} {#3} { } }
+\cs_set_protected:Npn \__msg_kernel_error:nn #1#2
+ { \__msg_kernel_error:nnxx {#1} {#2} { } { } }
% \end{macrocode}
% \end{macro}
%
@@ -2256,11 +2347,11 @@
% Another one from \pkg{l3msg} which will be altered later.
% \begin{macrocode}
\cs_set_nopar:Npn \msg_line_context:
- { on~line~\tex_the:D \tex_inputlineno:D }
+ { on~line~ \tex_the:D \tex_inputlineno:D }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[int]{\chk_if_free_cs:N, \chk_if_free_cs:c}
+% \begin{macro}[int]{\__chk_if_free_cs:N, \__chk_if_free_cs:c}
% This command is called by \cs{cs_new_nopar:Npn} and \cs{cs_new_eq:NN}
% \emph{etc.}\
% to make sure that the argument sequence is not already in use. If
@@ -2269,46 +2360,46 @@
% 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}
-\cs_set_protected:Npn \chk_if_free_cs:N #1
+\cs_set_protected:Npn \__chk_if_free_cs:N #1
{
\cs_if_free:NF #1
{
- \msg_kernel_error:nnxx { kernel } { command-already-defined }
+ \__msg_kernel_error:nnxx { kernel } { command-already-defined }
{ \token_to_str:N #1 } { \token_to_meaning:N #1 }
}
}
%<*package>
\tex_ifodd:D \l@expl@log@functions@bool
- \cs_set_protected:Npn \chk_if_free_cs:N #1
+ \cs_set_protected:Npn \__chk_if_free_cs:N #1
{
\cs_if_free:NF #1
{
- \msg_kernel_error:nnxx { kernel } { command-already-defined }
+ \__msg_kernel_error:nnxx { kernel } { command-already-defined }
{ \token_to_str:N #1 } { \token_to_meaning:N #1 }
}
\iow_log:x { Defining~\token_to_str:N #1~ \msg_line_context: }
}
\fi:
%</package>
-\cs_set_protected_nopar:Npn \chk_if_free_cs:c
- { \exp_args:Nc \chk_if_free_cs:N }
+\cs_set_protected_nopar:Npn \__chk_if_free_cs:c
+ { \exp_args:Nc \__chk_if_free_cs:N }
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[int]{\chk_if_exist_cs:N, \chk_if_exist_cs:c}
-% This function issues a warning message when the control sequence
+% \begin{macro}[int]{\__chk_if_exist_cs:N, \__chk_if_exist_cs:c}
+% This function issues an error message when the control sequence
% in its argument does not exist.
% \begin{macrocode}
-\cs_set_protected:Npn \chk_if_exist_cs:N #1
+\cs_set_protected:Npn \__chk_if_exist_cs:N #1
{
\cs_if_exist:NF #1
{
- \msg_kernel_error:nnxx { kernel } { command-not-defined }
- { \token_to_str:N #1 } { \token_to_meaning:N #1 }
+ \__msg_kernel_error:nnx { kernel } { command-not-defined }
+ { \token_to_str:N #1 }
}
}
-\cs_set_protected_nopar:Npn \chk_if_exist_cs:c
- { \exp_args:Nc \chk_if_exist_cs:N }
+\cs_set_protected_nopar:Npn \__chk_if_exist_cs:c
+ { \exp_args:Nc \__chk_if_exist_cs:N }
% \end{macrocode}
% \end{macro}
%
@@ -2324,22 +2415,22 @@
% Function which check that the control sequence is free before
% defining it.
% \begin{macrocode}
-\cs_set:Npn \cs_tmp:w #1#2
+\cs_set:Npn \__cs_tmp:w #1#2
{
\cs_set_protected:Npn #1 ##1
{
- \chk_if_free_cs:N ##1
+ \__chk_if_free_cs:N ##1
#2 ##1
}
}
-\cs_tmp:w \cs_new_nopar:Npn \cs_gset_nopar:Npn
-\cs_tmp:w \cs_new_nopar:Npx \cs_gset_nopar:Npx
-\cs_tmp:w \cs_new:Npn \cs_gset:Npn
-\cs_tmp:w \cs_new:Npx \cs_gset:Npx
-\cs_tmp:w \cs_new_protected_nopar:Npn \cs_gset_protected_nopar:Npn
-\cs_tmp:w \cs_new_protected_nopar:Npx \cs_gset_protected_nopar:Npx
-\cs_tmp:w \cs_new_protected:Npn \cs_gset_protected:Npn
-\cs_tmp:w \cs_new_protected:Npx \cs_gset_protected:Npx
+\__cs_tmp:w \cs_new_nopar:Npn \cs_gset_nopar:Npn
+\__cs_tmp:w \cs_new_nopar:Npx \cs_gset_nopar:Npx
+\__cs_tmp:w \cs_new:Npn \cs_gset:Npn
+\__cs_tmp:w \cs_new:Npx \cs_gset:Npx
+\__cs_tmp:w \cs_new_protected_nopar:Npn \cs_gset_protected_nopar:Npn
+\__cs_tmp:w \cs_new_protected_nopar:Npx \cs_gset_protected_nopar:Npx
+\__cs_tmp:w \cs_new_protected:Npn \cs_gset_protected:Npn
+\__cs_tmp:w \cs_new_protected:Npx \cs_gset_protected:Npx
% \end{macrocode}
% \end{macro}
%
@@ -2360,14 +2451,14 @@
% \cs{cs_set_nopar:Npn}. This means that there might be a parameter
% string between the two arguments.
% \begin{macrocode}
-\cs_set:Npn \cs_tmp:w #1#2
+\cs_set:Npn \__cs_tmp:w #1#2
{ \cs_new_protected_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_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
% \end{macrocode}
% \end{macro}
%
@@ -2380,12 +2471,12 @@
% Variants of the \cs{cs_set:Npn} versions which make a csname out
% of the first arguments. We may also do this globally.
% \begin{macrocode}
-\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_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
% \end{macrocode}
% \end{macro}
%
@@ -2398,12 +2489,12 @@
% Variants of the \cs{cs_set_protected_nopar:Npn} versions which make
% a csname out of the first arguments. We may also do this globally.
% \begin{macrocode}
-\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_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
% \end{macrocode}
% \end{macro}
%
@@ -2416,12 +2507,12 @@
% Variants of the \cs{cs_set_protected:Npn} versions which make a csname
% out of the first arguments. We may also do this globally.
% \begin{macrocode}
-\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_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
% \end{macrocode}
% \end{macro}
%
@@ -2456,7 +2547,7 @@
\cs_new_protected_nopar:Npn \cs_gset_eq:cc { \exp_args:Ncc \cs_gset_eq:NN }
\cs_new_protected:Npn \cs_new_eq:NN #1
{
- \chk_if_free_cs:N #1
+ \__chk_if_free_cs:N #1
\tex_global:D \cs_set_eq:NN #1
}
\cs_new_protected_nopar:Npn \cs_new_eq:cN { \exp_args:Nc \cs_new_eq:NN }
@@ -2488,57 +2579,88 @@
% \end{macrocode}
% \end{macro}
%
+% \subsection{Generating parameter text from argument count}
+%
+% \begin{macro}[int]{\__cs_parm_from_arg_count:nnF}
+% \begin{macro}[aux]{\__cs_parm_from_arg_count_test:nnF}
+% \LaTeX3 provides shorthands to define control sequences and
+% conditionals with a simple parameter text, derived directly from the
+% signature, or more generally from knowing the number of arguments,
+% between~$0$ and~$9$. This function expands to its first argument,
+% untouched, followed by a brace group containing the parameter text
+% |{#|$1$\ldots{}|#|$n$|}|, where $n$ is the result of evaluating the
+% second argument (as described in \cs{int_eval:n}). If the second
+% argument gives a result outside the range $[0,9]$, the third
+% argument is returned instead, normally an error message. Some of
+% the functions use here are not defined yet, but will be defined
+% before this function is called.
+% \begin{macrocode}
+\cs_set_protected:Npn \__cs_parm_from_arg_count:nnF #1#2
+ {
+ \exp_args:Nx \__cs_parm_from_arg_count_test:nnF
+ {
+ \exp_after:wN \exp_not:n
+ \if_case:w \__int_eval:w #2 \__int_eval_end:
+ { }
+ \or: { ##1 }
+ \or: { ##1##2 }
+ \or: { ##1##2##3 }
+ \or: { ##1##2##3##4 }
+ \or: { ##1##2##3##4##5 }
+ \or: { ##1##2##3##4##5##6 }
+ \or: { ##1##2##3##4##5##6##7 }
+ \or: { ##1##2##3##4##5##6##7##8 }
+ \or: { ##1##2##3##4##5##6##7##8##9 }
+ \else: { \c_false_bool }
+ \fi:
+ }
+ {#1}
+ }
+\cs_set_protected:Npn \__cs_parm_from_arg_count_test:nnF #1#2
+ {
+ \if_meaning:w \c_false_bool #1
+ \exp_after:wN \use_ii:nn
+ \else:
+ \exp_after:wN \use_i:nn
+ \fi:
+ { #2 {#1} }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
% \subsection{Defining functions from a given number of arguments}
%
-% \begin{macro}[EXP]{\cs_get_arg_count_from_signature:N}
-% \begin{macro}[aux, EXP]
-% {
-% \cs_get_arg_count_from_signature_aux:nnN,
-% \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_new:Npn \cs_get_arg_count_from_signature:N #1
- { \cs_split_function:NN #1 \cs_get_arg_count_from_signature_aux:nnN }
-\cs_new:Npn \cs_get_arg_count_from_signature_aux:nnN #1#2#3
+% \begin{macro}[EXP, int]{\__cs_count_signature:N, \__cs_count_signature:c}
+% \begin{macro}[aux, EXP]{\__cs_count_signature:nnN}
+% Counting the number of tokens in the signature, \emph{i.e.}, the
+% number of arguments the function should take. Since this is not
+% used in any time-critical function, we simply use \cs{tl_count:n} if
+% there is a signature, otherwise $-1$ arguments to signal an error.
+% We need a variant form right away.
+% \begin{macrocode}
+\cs_new:Npn \__cs_count_signature:N #1
+ { \int_eval:n { \__cs_split_function:NN #1 \__cs_count_signature:nnN } }
+\cs_new:Npn \__cs_count_signature:nnN #1#2#3
{
\if_meaning:w \c_true_bool #3
- \exp_after:wN \use_i:nn
+ \tl_count:n {#2}
\else:
- \exp_after:wN\use_ii:nn
+ \c_minus_one
\fi:
- {
- \exp_after:wN \cs_get_arg_count_from_signature_auxii:w
- \use_none:nnnnnnnnn #2 9876543210 \q_stop
- }
- { -1 }
-}
-\cs_new:Npn \cs_get_arg_count_from_signature_auxii:w #1#2 \q_stop {#1}
-% \end{macrocode}
-% A variant form we need right away.
-% \begin{macrocode}
-\cs_new_nopar:Npn \cs_get_arg_count_from_signature:c
- { \exp_args:Nc \cs_get_arg_count_from_signature:N }
+ }
+\cs_new_nopar:Npn \__cs_count_signature:c
+ { \exp_args:Nc \__cs_count_signature:N }
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \begin{macro}[aux]
+% \begin{macro}
% {
% \cs_generate_from_arg_count:NNnn,
% \cs_generate_from_arg_count:cNnn,
% \cs_generate_from_arg_count:Ncnn
% }
-% \begin{macro}[aux]{\cs_generate_from_arg_count_error_msg:Nn}
-% \begin{macro}[aux]{\cs_generate_from_arg_count_aux:nwn}
% 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{}
@@ -2552,27 +2674,13 @@
% \begin{macrocode}
\cs_new_protected:Npn \cs_generate_from_arg_count:NNnn #1#2#3#4
{
- \if_case:w \int_eval:w #3 \int_eval_end:
- \cs_generate_from_arg_count_aux:nwn {}
- \or: \cs_generate_from_arg_count_aux:nwn {##1}
- \or: \cs_generate_from_arg_count_aux:nwn {##1##2}
- \or: \cs_generate_from_arg_count_aux:nwn {##1##2##3}
- \or: \cs_generate_from_arg_count_aux:nwn {##1##2##3##4}
- \or: \cs_generate_from_arg_count_aux:nwn {##1##2##3##4##5}
- \or: \cs_generate_from_arg_count_aux:nwn {##1##2##3##4##5##6}
- \or: \cs_generate_from_arg_count_aux:nwn {##1##2##3##4##5##6##7}
- \or: \cs_generate_from_arg_count_aux:nwn {##1##2##3##4##5##6##7##8}
- \or: \cs_generate_from_arg_count_aux:nwn {##1##2##3##4##5##6##7##8##9}
- \else:
- \cs_generate_from_arg_count_error_msg:Nn #1 {#3}
- \use_i:nnn
- \fi:
- {#2#1}
- {#4}
+ \__cs_parm_from_arg_count:nnF { \use:nnn #2 #1 } {#3}
+ {
+ \__msg_kernel_error:nnxx { kernel } { bad-number-of-arguments }
+ { \token_to_str:N #1 } { \int_eval:n {#3} }
+ }
+ {#4}
}
-\cs_new_protected:Npn
- \cs_generate_from_arg_count_aux:nwn #1 #2 \fi: #3
- { \fi: #3 #1 }
% \end{macrocode}
% A variant form we need right away, plus one which is used elsewhere but
% which is most logically created here.
@@ -2582,17 +2690,6 @@
\cs_new_protected_nopar:Npn \cs_generate_from_arg_count:Ncnn
{ \exp_args:NNc \cs_generate_from_arg_count:NNnn }
% \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_new_protected:Npn \cs_generate_from_arg_count_error_msg:Nn #1#2
- {
- \msg_kernel_error:nnxx { kernel } { bad-number-of-arguments }
- { \token_to_str:N #1 } { \int_eval:n {#2} }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
% \end{macro}
%
% \subsection{Using the signature to define functions}
@@ -2622,7 +2719,7 @@
% \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}
+% { \__cs_count_signature:N #1 } {#2}
% }
% \end{verbatim}
% In short, to define \cs{cs_set:Nn} we need just use \cs{cs_set:Npn},
@@ -2630,42 +2727,58 @@
% 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:Npn \__cs_tmp:w #1#2#3
{
- \cs_new_protected:cpx { cs_ #1 : #2 } ##1##2
+ \cs_new_protected_nopar:cpx { cs_ #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}
+ \exp_not:N \__cs_generate_from_signature:NNn
+ \exp_after:wN \exp_not:N \cs:w cs_ #1 : #3 \cs_end:
+ }
+ }
+\cs_new_protected:Npn \__cs_generate_from_signature:NNn #1#2
+ {
+ \__cs_split_function:NN #2 \__cs_generate_from_signature:nnNNNn
+ #1 #2
+ }
+\cs_new_protected:Npn \__cs_generate_from_signature:nnNNNn #1#2#3#4#5#6
+ {
+ \bool_if:NTF #3
+ {
+ \cs_generate_from_arg_count:NNnn
+ #5 #4 { \tl_count:n {#2} } {#6}
+ }
+ {
+ \__msg_kernel_error:nnx { kernel } { missing-colon }
+ { \token_to_str:N #5 }
}
}
% \end{macrocode}
% Then we define the 24 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 }
-\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 { 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 }
+\__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 }
% \end{macrocode}
% \end{macro}
%
@@ -2684,49 +2797,40 @@
% \cs_new_protected:cn , \cs_new_protected:cx ,
% \cs_new_protected_nopar:cn , \cs_new_protected_nopar:cx ,
% }
-% 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}
-% The 24 |c| variants.
+% The 24 |c| variants simply use \cs{exp_args:Nc}.
% \begin{macrocode}
-\cs_set:Npn \cs_tmp:w #1#2#3
+\cs_set:Npn \__cs_tmp:w #1#2
{
- \cs_new_protected:cpx {cs_#1:#2} ##1##2
+ \cs_new_protected_nopar:cpx { cs_ #1 : c #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}
+ \exp_not:N \exp_args:Nc
+ \exp_after:wN \exp_not:N \cs:w cs_ #1 : N #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 }
-\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 { set } { n }
+\__cs_tmp:w { set } { x }
+\__cs_tmp:w { set_nopar } { n }
+\__cs_tmp:w { set_nopar } { x }
+\__cs_tmp:w { set_protected } { n }
+\__cs_tmp:w { set_protected } { x }
+\__cs_tmp:w { set_protected_nopar } { n }
+\__cs_tmp:w { set_protected_nopar } { x }
+\__cs_tmp:w { gset } { n }
+\__cs_tmp:w { gset } { x }
+\__cs_tmp:w { gset_nopar } { n }
+\__cs_tmp:w { gset_nopar } { x }
+\__cs_tmp:w { gset_protected } { n }
+\__cs_tmp:w { gset_protected } { x }
+\__cs_tmp:w { gset_protected_nopar } { n }
+\__cs_tmp:w { gset_protected_nopar } { x }
+\__cs_tmp:w { new } { n }
+\__cs_tmp:w { new } { x }
+\__cs_tmp:w { new_nopar } { n }
+\__cs_tmp:w { new_nopar } { x }
+\__cs_tmp:w { new_protected } { n }
+\__cs_tmp:w { new_protected } { x }
+\__cs_tmp:w { new_protected_nopar } { n }
+\__cs_tmp:w { new_protected_nopar } { x }
% \end{macrocode}
% \end{macro}
%
@@ -2758,25 +2862,25 @@
%
% \subsection{Diagnostic wrapper functions}
%
-% \begin{macro}{\kernel_register_show:N, \kernel_register_show:c}
-% Check that the variable, then apply the \tn{showthe} primitive to
+% \begin{macro}[int]{\__kernel_register_show:N, \__kernel_register_show:c}
+% Check that the variable exists, then apply the \tn{showthe} primitive to
% the variable. The odd-looking \cs{use:n} gives a nicer output.
% \begin{macrocode}
-\cs_new:Npn \kernel_register_show:N #1
+\cs_new_protected:Npn \__kernel_register_show:N #1
{
\cs_if_exist:NTF #1
{ \tex_showthe:D \use:n {#1} }
{
- \msg_kernel_error:nnx { kernel } { variable-not-defined }
+ \__msg_kernel_error:nnx { kernel } { variable-not-defined }
{ \token_to_str:N #1 }
}
}
-\cs_new_nopar:Npn \kernel_register_show:c
- { \exp_args:Nc \kernel_register_show:N }
+\cs_new_protected_nopar:Npn \__kernel_register_show:c
+ { \exp_args:Nc \__kernel_register_show:N }
% \end{macrocode}
% \end{macro}
%
-% \subsection{Engine specific definitions}
+% \subsection{Engine specific definitions}
%
% \begin{macro}[pTF, EXP]
% {\xetex_if_engine:, \luatex_if_engine:, \pdftex_if_engine:}
@@ -2831,7 +2935,7 @@
%
% \subsection{String comparisons}
%
-% \begin{macro}[pTF, EXP]{\str_if_eq:nn, \str_if_eq:xx}
+% \begin{macro}[pTF, EXP]{\str_if_eq:nn, \str_if_eq_x:nn}
% Modern engines provide a direct way of comparing two token lists,
% but returning a number. This set of conditionals therefore make life
% a bit clearer. The \texttt{nn} and \texttt{xx} versions are created
@@ -2844,7 +2948,7 @@
= \c_zero
\prg_return_true: \else: \prg_return_false: \fi:
}
-\prg_new_conditional:Npnn \str_if_eq:xx #1#2 { p , T , F , TF }
+\prg_new_conditional:Npnn \str_if_eq_x:nn #1#2 { p , T , F , TF }
{
\if_int_compare:w \pdftex_strcmp:D {#1} {#2} = \c_zero
\prg_return_true: \else: \prg_return_false: \fi:
@@ -2852,20 +2956,83 @@
% \end{macrocode}
% \end{macro}
%
+% \begin{macro}[int, EXP]{\__str_if_eq_x_return:nn}
+% It turns out that we often need to compare a token list
+% with the result of applying some function to it, and
+% return with \cs{prg_return_true/false:}. This test is
+% similar to \cs{str_if_eq:nnTF}, but hard-coded for speed.
+% \begin{macrocode}
+\cs_new:Npn \__str_if_eq_x_return:nn #1 #2
+ {
+ \if_int_compare:w \pdftex_strcmp:D {#1} {#2} = \c_zero
+ \prg_return_true:
+ \else:
+ \prg_return_false:
+ \fi:
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\str_case:nnn, \str_case_x:nnn}
+% \begin{macro}[int, EXP]{\__prg_case_end:nw}
+% \begin{macro}[aux, EXP]
+% {\__str_case:nw, \__str_case_x:nw, \__str_case_end:nw}
+% No calculations for strings, otherwise no surprises.
+% \begin{macrocode}
+\cs_new:Npn \str_case:nnn #1#2#3
+ {
+ \tex_romannumeral:D
+ \__str_case:nw {#1} #2 {#1} {#3} \q_recursion_stop
+ }
+\cs_new:Npn \__str_case:nw #1#2#3
+ {
+ \str_if_eq:nnTF {#1} {#2}
+ { \__str_case_end:nw {#3} }
+ { \__str_case:nw {#1} }
+ }
+\cs_new:Npn \str_case_x:nnn #1#2#3
+ {
+ \tex_romannumeral:D
+ \__str_case_x:nw {#1} #2 {#1} {#3} \q_recursion_stop
+ }
+\cs_new:Npn \__str_case_x:nw #1#2#3
+ {
+ \str_if_eq_x:nnTF {#1} {#2}
+ { \__str_case_end:nw {#3} }
+ { \__str_case_x:nw {#1} }
+ }
+% \end{macrocode}
+% Here, |#1| will be the code needed, |#2| will be any remaining case
+% or cases, and the \cs{c_zero} stops the \tn{romannumeral}.
+% \begin{macrocode}
+\cs_new:Npn \__prg_case_end:nw #1#2 \q_recursion_stop { \c_zero #1 }
+\cs_new_eq:NN \__str_case_end:nw \__prg_case_end:nw
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
% \subsection{Breaking out of mapping functions}
%
-% \begin{macro}[EXP]{\prg_break_point:n, \prg_map_break:, \prg_map_break:n}
+% \begin{macro}[EXP]{\__prg_break_point:Nn, \__prg_map_break:Nn}
% In inline mappings, the nesting level must be reset
% at the end of the mapping, even when the user decides
% to break out. This is done by putting the code that
-% must be performed as an argument of \cs{prg_break_point:n}.
+% must be performed as an argument of \cs{__prg_break_point:Nn}.
% The breaking functions are then defined to jump to
-% that point and perform the argument of \cs{prg_break_point:n},
-% before the user's code (if any).
+% that point and perform the argument of \cs{__prg_break_point:Nn},
+% before the user's code (if any). There is a check that we close the
+% correct loop, otherwise we continue breaking.
% \begin{macrocode}
-\cs_new_eq:NN \prg_break_point:n \use:n
-\cs_new:Npn \prg_map_break: #1 \prg_break_point:n #2 { #2 }
-\cs_new:Npn \prg_map_break:n #1 #2 \prg_break_point:n #3 { #3 #1 }
+\cs_new_eq:NN \__prg_break_point:Nn \use_ii:nn
+\cs_new:Npn \__prg_map_break:Nn #1#2#3 \__prg_break_point:Nn #4#5
+ {
+ #5
+ \if_meaning:w #1 #4
+ \exp_after:wN \use_iii:nnn
+ \fi:
+ \__prg_map_break:Nn #1 {#2}
+ }
% \end{macrocode}
% \end{macro}
%
@@ -2963,6 +3130,24 @@
% \end{macrocode}
% \end{macro}
%
+% Deprecated 2012-06-05 for removal after 2012-12-31.
+%
+% \begin{macro}[pTF, EXP]{\str_if_eq:xx}
+% Not really true \texttt{x}-type expansion
+% \begin{macrocode}
+\cs_new_eq:NN \str_if_eq_p:xx \str_if_eq_x_p:nn
+\cs_new_eq:NN \str_if_eq:xxT \str_if_eq_x:nnT
+\cs_new_eq:NN \str_if_eq:xxF \str_if_eq_x:nnF
+\cs_new_eq:NN \str_if_eq:xxTF \str_if_eq_x:nnTF
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\chk_if_free_cs:N}
+% \begin{macrocode}
+\cs_new_eq:NN \chk_if_free_cs:N \__chk_if_free_cs:N
+% \end{macrocode}
+% \end{macro}
+%
% \begin{macrocode}
%</initex|package>
% \end{macrocode}