summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/expl3/l3expan.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'Master/texmf-dist/source/latex/expl3/l3expan.dtx')
-rw-r--r--Master/texmf-dist/source/latex/expl3/l3expan.dtx1378
1 files changed, 748 insertions, 630 deletions
diff --git a/Master/texmf-dist/source/latex/expl3/l3expan.dtx b/Master/texmf-dist/source/latex/expl3/l3expan.dtx
index 1efadb1dab3..7f2323b2e0c 100644
--- a/Master/texmf-dist/source/latex/expl3/l3expan.dtx
+++ b/Master/texmf-dist/source/latex/expl3/l3expan.dtx
@@ -1,5 +1,5 @@
% \iffalse
-%% File: l3expan.dtx Copyright (C) 1990-2006 LaTeX3 project
+%% File: l3expan.dtx Copyright (C) 1990-2009 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.
%%
@@ -36,7 +36,7 @@
\RequirePackage{l3names}
%</driver|package>
%\fi
-\GetIdInfo$Id: l3expan.dtx 735 2008-01-14 22:31:02Z morten $
+\GetIdInfo$Id: l3expan.dtx 1376 2009-06-01 17:01:30Z morten $
{L3 Experimental Argument Expansion module}
%\iffalse
%<*driver>
@@ -44,153 +44,37 @@
\ProvidesFile{\filename.\filenameext}
[\filedate\space v\fileversion\space\filedescription]
%\iffalse
-\documentclass{l3doc}
+\documentclass[full]{l3doc}
\begin{document}
-\DocInput{\filename.\filenameext}
+\DocInput{l3expan.dtx}
\end{document}
%</driver>
% \fi
%
%
-% \title{The \textsf{l3expan} package\thanks{This file
+% \title{The \pkg{l3expan} package\thanks{This file
% has version number \fileversion, last
% revised \filedate.}\\
-% Controlling Expansion of Command Arguments}
+% Controlling Expansion of Function Arguments}
% \author{\Team}
% \date{\filedate}
% \maketitle
%
+% \begin{documentation}
%
-% \section{\LaTeX3 functions}
+% \section{Brief overview}
%
-% All \LaTeX3 functions contain a colon in their
-% name. Characters following the colon are used to denote the number and
-% the ``type'' of arguments that the function takes. An uppercase "N" is
-% used to denote an argument that consists of a single token and a
-% lowercase "n" is used when the argument can consist of several tokens
-% surrounded by braces. In case of "n" arguments that consist of a
-% single token the surrounding braces can be omitted in nearly all
-% situations---functions that force the use of braces even for single
-% token arguments are explicitly mentioned. For example, "\seq_gpush:Nn"
-% is a function that takes two arguments, the first is a single token
-% (the sequence) and the second may consist of several tokens surrounded
-% by braces.
+% The functions in this module all have prefix |exp|.
%
-% This concept of argument specification makes it easy to read the code
-% and should be followed when defining new functions.
-%
-% \subsection{Expanding arguments of functions}
-%
-% Within code it is often necessary to expand or partially expand
-% arguments before passing it on to some function. For example, if the
-% token list pointer "\l_tmpa_tlp" contains the current file
-% that should be pushed onto some stack, we can not write
-% \begin{quote}
-% "\seq_gpush:Nn" \\
-% " \g_file_name_stack" \\
-% " \l_tmpa_tlp"
-% \end{quote}
-% since this would put the token "\l_tmpa_tlp" and not its
-% contents on the stack. Instead a suitable number of "\exp_after:NN"
-% would be necessary (together with extra braces) to change the order of
-% execution, i.e.
-% \begin{quote}
-% "\exp_after:NN" \\
-% " \seq_gpush:Nn" \\
-% "\exp_after:NN" \\
-% " \g_file_name_stack" \\
-% "\exp_after:NN" \\
-% " {\l_tmpa_tlp}"
-% \end{quote}
-%
-% The above example is probably the simplest case but is already shows
-% how the code changes to something difficult to understand. Therefore
-% \LaTeX3 provides the programmer with a general scheme that keeps the
-% code compact and easy to understand.
-% To denote that some argument to a function needs special treatment one
-% just uses different letters in the argument part of the function to
-% mark the desired behavior. In the above example one would write
-% \begin{quote}
-% "\seq_gpush:No" \\
-% " \g_file_name_stack" \\
-% " \l_tmpa_tlp"
-% \end{quote}
-% to achieve the desired effect. Here the "o" stands for expand this
-% (the second) argument once before passing it to the function.
-%
-% The following letters can be used to denote special treatment of
-% arguments before passing it to the basic function:
-% \begin{description}
-% \item[o] One time expanded token or token-list. In the latter case,
-% effectively only the first token in the list gets expanded. Since
-% the expansion might result in more than one token, the result is
-% surrounded for further processing with braces.
-%
-% \item[x] Fully expanded token or token-list. Like "o" but the
-% argument is expanded using "\def:Npx" before it is passed on. This means
-% that expansion takes place until only unexpandable tokens are left.
-%
-% \item[f] Almost the same as the |x| type except here the token list
-% is expanded fully until the first unexpandable token is found and
-% the rest is left unchanged. Note that if this function finds a
-% space at the beginning of the argument it will gobble it and not
-% expand the next argument.
-%
-% \item[N,O,X] Like "n", "o", "x" but the argument must be a single
-% token without any braces around it.
-%
-% \item[c] A character string or a token-list that ultimately expands
-% to characters. This string (after expansion) is used to construct a
-% command name that is eventually passed on.
-%
-% \item[C] A character string or a token-list that ultimately expands
-% to characters. From this string (after expansion) a command name is
-% constructed and then this command name is expanded once (like "o").
-% The result of this is eventually passed on. In other words
-% \begin{quote}
-% "\seq_gpush:NC" \\
-% " \g_file_name_stack" \\
-% " {l_tmpa_tlp}"
-% \end{quote}
-% Has the same effect as the example above.
-%
-%
-% \end{description}
-%
-% Here are three new expansion types that may be useful but I'm not
-% sure yet. Only time will tell\dots{} Proper documentation of these
-% functions is postponed until later.
-% \begin{description}
-% \item[d] This is pretty much like the |o| type except the token list
-% get's expanded twice before being passed on. (|d| is for double.)
-% It is often useful in conjunction with a forced expansion.
-%
-% \item[E] Sometimes you need to unpack a token list or something else
-% but you don't want it to add the braces that the |o| type
-% does. This is where you usually wind up with a lot of
-% |\exp_after:NN|s and we would like to avoid that. This type works
-% quite well with the other syntax but it won't work in certain
-% circumstances: Since the generic expansion functions read their
-% arguments when the expanded code is shuffled around, this type
-% will have a problem if the last token you want to expand once is
-% |\token_to_str:N| \emph{and} you're in an argument expansion
-% process involving arguments in braces such as the |n| and |o| type
-% arguments. If you stick to functions invloving only |N| and |E|
-% everything will work just fine. (|E| is for expanded, single
-% token.)
-%
-% \item[e] Same as above but the argument must be given in braces.
-% \end{description}
-%
-% Due to memory constraints not all possible variations are implemented
-% for every base function. Instead only those that are used within the
-% \LaTeX3 kernel or otherwise seem to be of general interest are
-% implemented.
+% Not all possible variations are implemented for every base
+% function. Instead only those that are used within the \LaTeX3 kernel
+% or otherwise seem to be of general interest are implemented.
% Consult the module description to find out which functions are
% actually defined. The next section explains how to define missing
% variants.
+%
%
-% \subsection{Defining new variants}
+% \section{Defining new variants}
%
% The definition of variant forms for base functions may be necessary
% when writing new functions or when applying a kernel function in a
@@ -202,11 +86,11 @@
% second are a single tokens the third argument gets
% expanded once. If "\seq_gpush:No" wouldn't be defined the example
% above could be coded in the following way:
-% \begin{quote}
-% "\exp_args:NNo\seq_gpush:Nn" \\
-% " \g_file_name_stack" \\
-% " \l_tmpa_tlp"
-% \end{quote}
+% \begin{verbatim}
+% \exp_args:NNo\seq_gpush:Nn
+% \g_file_name_stack
+% \l_tmpa_tl
+% \end{verbatim}
% In other words, the first argument to "\exp_args:NNo" is the base
% function and the other arguments are preprocessed and then passed to
% this base function. In the example the first argument to the base
@@ -215,85 +99,132 @@
% how the variants are defined. They just expand into the appropriate
% "\exp_" function followed by the desired base function, e.g.
% \begin{quote}
-% "\def_new:Npn\seq_gpush:No{\exp_args:NNo\seq_gpush:Nn}"
+% "\cs_new_nopar:Npn\seq_gpush:No{\exp_args:NNo\seq_gpush:Nn}"
% \end{quote}
% Providing variants in this way in style files is uncritical as the
-% "\def_new:Npn" function will silently accept definitions whenever the
+% "\cs_new_nopar:Npn" function will silently accept definitions whenever the
% new definition is identical to an already given one. Therefore adding
% such definition to later releases of the kernel will not make such
% style files obsolete.
%
-% The |f| type is so special that it deserves an example.
-% Let's pretend we want to set "\aaa" equal to the control sequence
-% stemming from turning "b \l_tmpa_tlp b" into a control
-% sequence. Furthermore we want to store the execution of it in a
-% \m{toks} register. In this example we assume "\l_tmpa_tlp" contains
-% the text string "lur". The straight forward approach is
-% \begin{quote}
-% "\toks_set:No \l_tmpa_toks {\let:Nc \aaa {b \l_tmpa_tlp b}}"
-% \end{quote}
-% Unfortunately this only puts
-% "\exp_args:NNc \let:NN \aaa {b \l_tmpa_tlp b}" into "\l_tmpa_toks"
-% and not "\let:NwN \aaa = \blurb" as we probably wanted. Using
-% "\toks_set:Nx" is not an option as that will die horribly. Instead
-% we can do a
-% \begin{quote}
-% "\toks_set:Nf \l_tmpa_toks {\let:Nc \aaa {b \l_tmpa_tlp b}}"
-% \end{quote}
-% which puts the desired result in "\l_tmpa_toks". It requires
-% "\toks_set:Nf" to be defined as
-% \begin{quote}
-% "\def:Npn \toks_set:Nf {\exp_args:NNf \toks_set:Nn}"
-% \end{quote}
-% If you use this type of expansion in conditional processing then
-% you should stick to using "TF" type functions only as it does not
-% try to finish any "\if... \fi:" itself!
-%
-%
-%
-%
-%
-% The available internal functions for argument expansion come in to
+% The steps above may be automated by using the function
+% "\cs_generate_variant:Nn", described next.
+%
+% \subsection{Methods for defining variants}
+%
+% \begin{function}{\cs_generate_variant:Nn}
+% \begin{syntax}
+% "\cs_generate_variant:Nn" <function> <variant argument>
+% "\cs_generate_variant:Nn " "\foo:Nn" "{c}"
+% "\cs_generate_variant:Nn" "\foo:Nn" "{c,Nx,cx}"
+% \end{syntax}
+% This function greatly simplify the task of defining
+% variantions on a base function with differing expansion control.
+% The first example is equivalent to writing
+% \begin{verbatim}
+% \cs_set_nopar:Npn \foo:cn { \exp_args:Nc \foo:Nn }
+% \end{verbatim}
+% If used with a comma-separated list of variants, it does so for each
+% variant form, i.e., the second example is equivalent to
+% \begin{verbatim}
+% \cs_set_nopar:Npn \foo:cn { \exp_args:Nc \foo:Nn }
+% \cs_set_nopar:Npn \foo:Nx { \exp_args:NNx \foo:Nn }
+% \cs_set_nopar:Npn \foo:cx { \exp_args:Ncx \foo:Nn }
+% \end{verbatim}
+% \end{function}
+%
+% \paragraph{Internal functions} \mbox{}
+%
+% \begin{function}{\cs_generate_internal_variant:n}
+% \begin{syntax}
+% "\cs_generate_internal_variant:n" \Arg{args}
+% \end{syntax}
+% Defines the appropriate "\exp_args:N"<args> function, if necessary,
+% to perform the expansion control specified by <args>.
+% \end{function}
+%
+% \section{Introducing the variants}
+%
+% The available internal functions for argument expansion come in two
% flavours, some of them are faster then others. Therefore it is usually
% best to follow the following guidelines when defining new functions
% that are supposed to come with variant forms:
% \begin{itemize}
% \item
% Arguments that might need expansion should come first in the list of
-% arguments to make processing faster.
+% arguments to make processing faster.
% \item
% Arguments that should consist of single tokens should come first.
% \item
% Arguments that need full expansion (i.e., are denoted with "x")
-% should be avoided if possible as they can not be processed very fast.
+% should be avoided if possible as they can not be processed very fast.
% \item
% In general "n", "x", and "o" (if not in the last position) will
% need special processing which is not fast and not expandable,
% i.e., functions of this type may not work correctly in arguments
% that are itself subject to "x" expansion. Therefore it is best to
% use the ``expandable'' functions (i.e., those that contain only
-% "c", "N", "O", "o" or "f" in the last position) whenever possible.
+% "c", "N", "o" or "f" in the last position) whenever possible.
% \end{itemize}
%
+% The |V| type returns the value of a register, which can be one of
+% |tl|, |num|, |int|, |skip|, |dim|, |toks|, or built-in \TeX\
+% registers. The |v| type is the same except it first creates a
+% control sequence out of its argument before returning the
+% value. This recent addition to the argument specifiers may shake
+% things up a bit as most places where |o| is used will be replaced by
+% |V|. The documentation you are currently reading will therefore
+% require a fair bit of re-writing.
+%
+% In general, the programmer should not need to be concerned with
+% expansion control. When simply using the content of a variable,
+% functions with a "V" specifier should be used. For those referred to by
+% (cs)name, the "v" specifier is available for the same purpose. Only when
+% specific expansion steps are needed, such as when using delimited
+% arguments, should the lower-level functions with "o" specifiers be employed.
+%
+% The |f| type is so special that it deserves an example.
+% Let's pretend we want to set "\aaa" equal to the control sequence
+% stemming from turning "b \l_tmpa_tl b" into a control
+% sequence. Furthermore we want to store the execution of it in a
+% \m{toks} register. In this example we assume "\l_tmpa_tl" contains
+% the text string "lur". The straight forward approach is
+% \begin{quote}
+% "\toks_set:No \l_tmpa_toks {\cs_set_eq:Nc \aaa {b \l_tmpa_tl b}}"
+% \end{quote}
+% Unfortunately this only puts
+% "\exp_args:NNc \cs_set_eq:NN \aaa {b \l_tmpa_tl b}" into "\l_tmpa_toks"
+% and not "\cs_set_eq:NwN \aaa = \blurb" as we probably wanted. Using
+% "\toks_set:Nx" is not an option as that will die horribly. Instead
+% we can do a
+% \begin{quote}
+% "\toks_set:Nf \l_tmpa_toks {\cs_set_eq:Nc \aaa {b \l_tmpa_tl b}}"
+% \end{quote}
+% which puts the desired result in "\l_tmpa_toks". It requires
+% "\toks_set:Nf" to be defined as
+% \begin{quote}
+% "\cs_set_nopar:Npn \toks_set:Nf {\exp_args:NNf \toks_set:Nn}"
+% \end{quote}
+% If you use this type of expansion in conditional processing then
+% you should stick to using "TF" type functions only as it does not
+% try to finish any "\if... \fi:" itself!
+%
%
% When pdf\TeX\ 1.50 arrives, it will contain a primitive for
% performing the equivalent of an "x" expansion after only one
% expansion and most importantly: as an expandable operation.
-% \begin{function}{%
-% \exp_arg:x
-% }
+% \begin{function}{\exp_arg:x}
% \begin{syntax}
-% " \exp_arg:x" "{" <arg> "}"
+% "\exp_arg:x" \Arg{arg}
% \end{syntax}
% <arg> is expanded fully using an "x" expansion.
% \end{function}
%
%
-% \subsection{Manipulating the first argument}
%
-% \begin{function}{%
-% \exp_args:No
-% }
+% \section{Manipulating the first argument}
+%
+% \begin{function}{ \exp_args:No / (EXP) }
% \begin{syntax}
% " \exp_args:No" <funct> <arg1> <arg2> "..."
% \end{syntax}
@@ -302,9 +233,16 @@
% more than one argument---all others are passed unchanged.
% \end{function}
%
-% \begin{function}{%
-% \exp_args:Nc
-% }
+% \begin{function}{ \exp_args:Nd / (EXP) }
+% \begin{syntax}
+% " \exp_args:Nd" <funct> <arg1> <arg2> "..."
+% \end{syntax}
+% The first argument of <funct> (i.e., <arg1>) is expanded twice, the
+% result is surrounded by braces and passed to <funct>. <funct> may have
+% more than one argument---all others are passed unchanged.
+% \end{function}
+%
+% \begin{function}{ \exp_args:Nc / (EXP) | \exp_args:cc / (EXP) }
% \begin{syntax}
% " \exp_args:Nc" <funct> <arg1> <arg2> "..."
% \end{syntax}
@@ -313,25 +251,32 @@
% result of this expansion.) Then the result is turned into a control
% sequence and passed to <funct> as the first argument. <funct> may have
% more than one argument---all others are passed unchanged.
+%
+% In the ":cc" variant, the <funct> control sequence itself is constructed
+% (with the same process as described above) before <arg1> is turned into a
+% control sequence and passed as its argument.
% \end{function}
%
-% \begin{function}{%
-% \exp_args:NC
-% }
+% \begin{function}{ \exp_args:NV / (EXP) }
% \begin{syntax}
-% " \exp_args:Nc" <funct> <arg1> <arg2> "..."
+% " \exp_args:NV" <funct> <register>
% \end{syntax}
-% The first argument of <funct> (i.e., <arg1>) is expanded until only
-% characters remain. (An internal error occurs if something else is the
-% result of this expansion.) Then the result is turned into a control
-% sequence which is then expanded once more. The result of this is then
-% passed to <funct> as the first argument. <funct> may have more than
-% one argument---all others are passed unchanged.
+% The first argument of <funct> (i.e., <register>) is expanded to its
+% value. By value we mean a number stored in an |int| or |num|
+% register, the length value of a |dim|, |skip| or |muskip| register, the
+% contents of a |toks| register or the unexpanded contents of a |tl var.|
+% register. The value is passed onto <funct> in braces.
% \end{function}
%
-% \begin{function}{%
-% \exp_args:Nx
-% }
+% \begin{function}{ \exp_args:Nv / (EXP) }
+% \begin{syntax}
+% " \exp_args:Nv" <funct> \Arg{register}
+% \end{syntax}
+% Like the |V| type except the register is given by a list of
+% characters from which a control sequence name is generated.
+% \end{function}
+%
+% \begin{function}{ \exp_args:Nx }
% \begin{syntax}
% " \exp_args:Nx" <funct> <arg1> <arg2> "..."
% \end{syntax}
@@ -342,9 +287,7 @@
% As mentioned before, this type of function is relatively slow.
% \end{function}
%
-% \begin{function}{%
-% \exp_args:Nf
-% }
+% \begin{function}{ \exp_args:Nf / (EXP) }
% \begin{syntax}
% " \exp_args:Nf" <funct> <arg1> <arg2> "..."
% \end{syntax}
@@ -355,8 +298,7 @@
% Beware of its special behavior as explained above.
% \end{function}
%
-%
-% \subsection{Manipulating two arguments}
+% \section{Manipulating two arguments}
%
% \begin{function}{%
% \exp_args:NNx |
@@ -374,16 +316,22 @@
% \end{function}
%
% \begin{function}{%
-% \exp_args:NNo |
-% \exp_args:NNf |
-% \exp_args:Nno |
-% \exp_args:NNc |
-% \exp_args:Noo |
-% \exp_args:NOo |
-% \exp_args:NOc |
-% \exp_args:Nco |
-% \exp_args:Ncc |
-% \exp_args:NNC |
+% \exp_args:NNo / (EXP) |
+% \exp_args:NNc / (EXP) |
+% \exp_args:NNv / (EXP) |
+% \exp_args:NNV / (EXP) |
+% \exp_args:NNd / (EXP) |
+% \exp_args:NNf / (EXP) |
+% \exp_args:Nno / (EXP) |
+% \exp_args:Nnf / (EXP) |
+% \exp_args:Noo / (EXP) |
+% \exp_args:Noc / (EXP) |
+% \exp_args:Nco / (EXP) |
+% \exp_args:Ncf / (EXP) |
+% \exp_args:Ncc / (EXP) |
+% \exp_args:Nff / (EXP) |
+% \exp_args:Nfo / (EXP) |
+% \exp_args:NVV / (EXP) |
% }
% \begin{syntax}
% "\exp_args:NNo" <funct> <arg1> <arg2> "..."
@@ -391,17 +339,20 @@
% These are the fast and expandable functions for the first two arguments.
% \end{function}
%
-% \subsection{Manipulating three arguments}
+% \section{Manipulating three arguments}
%
% So far not all possible functions are provided and even the selection
% below may be reduced in the future as far as the non-expandable
% functions are concerned.
%
% \begin{function}{%
+% \exp_args:NNnx |
+% \exp_args:NNox |
% \exp_args:Nnnx |
-% \exp_args:Noox |
% \exp_args:Nnox |
+% \exp_args:Noox |
% \exp_args:Ncnx |
+% \exp_args:Nccx |
% }
% \begin{syntax}
% "\exp_args:Nnnx" <funct> <arg1> <arg2> <arg3> "..."
@@ -410,44 +361,32 @@
% \end{function}
%
% \begin{function}{%
-% \exp_args:NnnN |
-% \exp_args:Nnno |
-% \exp_args:NNOo |
-% \exp_args:NOOo |
-% \exp_args:Nccc |
-% \exp_args:NcNc |
-% \exp_args:Nnnc |
-% \exp_args:NcNo |
-% \exp_args:Ncco |
+% \exp_args:NNNo / (EXP) |
+% \exp_args:NNoo / (EXP) |
+% \exp_args:NNno / (EXP) |
+% \exp_args:Nnno / (EXP) |
+% \exp_args:Nnnc / (EXP) |
+% \exp_args:Nooo / (EXP) |
+% \exp_args:Nccc / (EXP) |
+% \exp_args:NcNc / (EXP) |
+% \exp_args:NcNo / (EXP) |
+% \exp_args:Ncco / (EXP) |
% }
% \begin{syntax}
-% "\exp_args:NNOo" <funct> <arg1> <arg2> <arg3> "..."
+% "\exp_args:NNoo" <funct> <arg1> <arg2> <arg3> "..."
% \end{syntax}
% These are the fast and expandable functions for the first three
% arguments.
% \end{function}
%
-% \subsection{Internal functions and variables}
-%
-% \begin{function}{\exp_after:NN}
-% \begin{syntax}
-% "\exp_after:NN" <token1> <token2>
-% \end{syntax}
-% This will expand <token2> once before processing <token1>. This is
-% similar to "\exp_args:No" except that no braces are put around the
-% result of expanding <token2>.
-% \begin{texnote}
-% This is the primitive \tn{expandafter} which was renamed to fit into
-% the naming conventions of \LaTeX3.
-% \end{texnote}
-% \end{function}
+% \section{Preventing expansion}
%
% \begin{function}{\exp_not:N |
% \exp_not:c |
% \exp_not:n }
% \begin{syntax}
% "\exp_not:N" <token>
-% "\exp_not:n" "{" <token list> "}"
+% "\exp_not:n" \Arg{token list}
% \end{syntax}
% This function will prohibit the expansion of <token> in situation
% where <token> would otherwise be replaced by it definition, e.g.,
@@ -458,45 +397,40 @@
% \end{texnote}
% \end{function}
%
-%
% \begin{function}{\exp_not:o |
% \exp_not:d |
-% \exp_not:f}
+% \exp_not:f }
% \begin{syntax}
-% "\exp_not:o" "{"<token list>"}"
+% "\exp_not:o" \Arg{token list}
% \end{syntax}
% Same as "\exp_not:n" except <token list> is expanded once for the
% "o" type and twice for the "d" type and the result of this expansion
-% is then prohibited from being expanded further.
+% is then prohibited from being expanded further.
% \end{function}
-%
-% \begin{function}{\exp_not:E}
+%
+% \begin{function}{\exp_not:V |
+% \exp_not:v }
% \begin{syntax}
-% "\exp_not:E" <token>
+% "\exp_not:V" <register>
+% "\exp_not:v" \Arg{token list}
% \end{syntax}
-% The name of this command is a lie. Perhaps it should be called
-% ``"exp_perhaps_once"''. What it actually does is, it expands <token>
-% and then issues an "\exp_not:N" to prohibit further expansion of the
-% first token in the replacement text of <token>. This means that if
-% the replacement text of <token> consists of more than one token all
-% further tokens are still subject to full expansion.
-% \begin{texnote}
-% This command has no equivalent.
-% \end{texnote}
+% The value of <register> is retrieved and then passed on to
+% "\exp_not:n" which will prohibit further expansion. The |v| type
+% first creates a control sequence from <token list> but is otherwise
+% identical to |V|.
% \end{function}
-%
%
-% \begin{function}{\exp_stop_f: }
+% \begin{function}{\exp_stop_f:}
% \begin{syntax}
% <f expansion> ... "\exp_stop_f:"
% \end{syntax}
% This function stops an "f" type expansion. An example use is one such as
% \begin{verbatim}
-% \tlp_set:Nf \l_tmpa_tlp {
+% \tl_set:Nf \l_tmpa_tl {
% \if_case:w \l_tmpa_int
-% \or: \use_arg_i_after_orelse:nw{\exp_stop_f: \textbullet}
-% \or: \use_arg_i_after_orelse:nw{\exp_stop_f: \textendash}
-% \else: \use_arg_i_after_orelse:nw{\exp_stop_f: else-item}
+% \or: \use_i_after_orelse:nw {\exp_stop_f: \textbullet}
+% \or: \use_i_after_orelse:nw {\exp_stop_f: \textendash}
+% \else: \use_i_after_fi:nw {\exp_stop_f: else-item}
% \fi:
% }
% \end{verbatim}
@@ -508,46 +442,122 @@
% writing code.
% \end{texnote}
% \end{function}
+%
+% \section{Unbraced expansion}
+%
+% \begin{function}{
+% \exp_last_unbraced:Nf|
+% \exp_last_unbraced:NV|
+% \exp_last_unbraced:Nv|
+% \exp_last_unbraced:NcV|
+% \exp_last_unbraced:NNo|
+% \exp_last_unbraced:NNV|
+% \exp_last_unbraced:NNNo|
+% }
+% \begin{syntax}
+% "\exp_last_unbraced:NV" <token> <variable name>
+% \end{syntax}
+% There are a small number of occasions where the last argument
+% in an expansion run must be expanded unbraced. These functions
+% should only be used inside functions, \emph{not} for creating
+% variants.
+% \end{function}
+%
+% \end{documentation}
+%
+% \begin{implementation}
%
+% \section{\pkg{l3expan} implementation}
%
-% \begin{variable}{\l_exp_tlp | }
+% \subsection{Internal functions and variables}
+%
+% \begin{function}{\exp_after:wN}
+% \begin{syntax}
+% "\exp_after:wN" <token1> <token2>
+% \end{syntax}
+% This will expand <token2> once before processing <token1>. This is
+% similar to "\exp_args:No" except that no braces are put around the
+% result of expanding <token2>.
+% \begin{texnote}
+% This is the primitive \tn{expandafter} which was renamed to fit into
+% the naming conventions of \LaTeX3.
+% \end{texnote}
+% \end{function}
+%
+% \begin{variable}{\l_exp_tl}
% \begin{syntax}\end{syntax}
% The "\exp_" module has its private variables to temporarily store
% results of the argument expansion. This is done to avoid interference
% with other functions using temporary variables.
% \end{variable}
%
-% \StopEventually{}
+% \begin{function}{ \exp_eval_register:N / (EXP) |
+% \exp_eval_register:c / (EXP) }
+% \begin{syntax}
+% "\exp_eval_register:N" <register>
+% \end{syntax}
+% These functions evaluates a register as part of a "V" or "v" expansion
+% (respectively). A register might exist as
+% one of two things: A parameter-less non-long, non-protected macro
+% or a built-in \TeX\ register such as |\count|.
+% \end{function}
+%
+% \begin{function}{\::n|\::N|\::c|\::o|\::f|\::x|\::v|\::V|\::d|\:::}
+% \begin{syntax}
+% "\cs_set_nopar:Npn \exp_args:Ncof {\::c\::o\::f\:::}"
+% \end{syntax}
+% Internal forms for the base expansion types.
+% \end{function}
%
-% \subsection {The Implementation}
+% \subsection{Module code}
%
% We start by ensuring that the required packages are loaded.
% \begin{macrocode}
-%<package>\ProvidesExplPackage
-%<package> {\filename}{\filedate}{\fileversion}{\filedescription}
-%<package>\RequirePackage{l3tlp}
+%<*package>
+\ProvidesExplPackage
+ {\filename}{\filedate}{\fileversion}{\filedescription}
+\package_check_loaded_expl:
+%</package>
%<*initex|package>
% \end{macrocode}
%
-% \subsubsection{General expansion}
+% \begin{macro}{\exp_after:wN}
+% \begin{macro}{\exp_not:N}
+% \begin{macro}{\exp_not:n}
+% These are defined in \pkg{l3basics}.
+% \begin{macrocode}
+%<*bootstrap>
+\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
+%</bootstrap>
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{General expansion}
%
% In this section a general mechanism for defining functions to handle
% argument handling is defined. These general expansion functions are
% expandable unless |x| is used. (Any version of |x| is going to have
-% to use one of the \LaTeX3\ names for |\def:Npx| at some point, and
+% to use one of the \LaTeX3\ names for |\cs_set_nopar:Npx| at some point, and
% so is never going to be expandable.\footnote{However, some
% primitives have certain characteristics that means that their
% arguments undergo an \texttt{x} type expansion but the primitive
% is in fact still expandable. We shall make it very clear when such
% a function is expandable.})
%
-% In a later section some common cases are coded by a more direct
-% method, typically using calls to |\exp_after:NN|.
+% The definition of expansion functions with this technique happens
+% in section~\ref{sec:gendef}.
+% In section~\ref{sec:handtune} some common cases are coded by a more direct
+% method for efficiency, typically using calls to |\exp_after:wN|.
%
-% \begin{macro}{\l_exp_tlp}
-% We need a scratch token list pointer.
+% \begin{macro}{\l_exp_tl}
+% We need a scratch token list variable.
+% We don't use "tl" methods so that \pkg{l3expan} can be loaded earlier.
% \begin{macrocode}
-\tlp_new:Nn\l_exp_tlp{}
+\cs_new_nopar:Npn \l_exp_tl {}
% \end{macrocode}
% \end{macro}
%
@@ -555,20 +565,47 @@
% to perform the expansions. All macros are |long| as this turned out
% to be desirable since the tokens undergoing expansion may be
% arbitrary user input.
-% \begin{macro}{\exp_arg_next:nnn}
-% This is basically the same function as |\Dexp_arg_next:nnn|.
+%
+% An argument manipulator |\::|\meta{Z} always has signature |#1\:::#2#3|
+% where |#1| holds the remaining argument manipulations to be performed,
+% |\:::| serves as an end marker for the list of manipulations, |#2|
+% is the carried over result of the previous expansion steps and |#3| is
+% the argument about to be processed.
+%
+% \begin{macro}[aux]{\exp_arg_next:nnn}
+% \begin{macro}[aux]{\exp_arg_next_nobrace:nnn}
+% |#1| is the result of an expansion step, |#2| is the remaining
+% argument manipulations and |#3| is the current result of the
+% expansion chain. This auxilliary function moves |#1| back after
+% |#3| in the input stream and checks if any expansion is left to
+% be done by calling |#2|. In by far the most cases we will require
+% to add a set of braces to the result of an argument manipulation
+% so it is more effective to do it directly here. Actually, so far
+% only the |c| of the final argument manipulation variants does not
+% require a set of braces.
% \begin{macrocode}
-\def_long_new:Npn\exp_arg_next:nnn#1#2#3{
+\cs_new:Npn\exp_arg_next:nnn#1#2#3{
+ #2\:::{#3{#1}}
+}
+\cs_new:Npn\exp_arg_next_nobrace:nnn#1#2#3{
#2\:::{#3#1}
}
% \end{macrocode}
% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\:::}
+% The end marker is just another name for the identity function.
+% \begin{macrocode}
+\cs_new:Npn\:::#1{#1}
+% \end{macrocode}
+% \end{macro}
%
% \begin{macro}{\::n}
% This function is used to skip an argument that doesn't need to
% be expanded.
% \begin{macrocode}
-\def_long_new:Npn\::n#1\:::#2#3{
+\cs_new:Npn\::n#1\:::#2#3{
#1\:::{#2{#3}}
}
% \end{macrocode}
@@ -577,9 +614,8 @@
% \begin{macro}{\::N}
% This function is used to skip an argument that consists of a
% single token and doesn't need to be expanded.
-%^^A was \let_new:NN\::N\::n (changed to match \;N above.
% \begin{macrocode}
-\def_long_new:Npn\::N#1\:::#2#3{
+\cs_new:Npn\::N#1\:::#2#3{
#1\:::{#2#3}
}
% \end{macrocode}
@@ -589,8 +625,8 @@
% This function is used to skip an argument that is turned into
% as control sequence without expansion.
% \begin{macrocode}
-\def_long_new:Npn\::c#1\:::#2#3{
- \exp_after:NN\exp_arg_next:nnn\cs:w #3\cs_end:{#1}{#2}
+\cs_new:Npn\::c#1\:::#2#3{
+ \exp_after:wN\exp_arg_next_nobrace:nnn\cs:w #3\cs_end:{#1}{#2}
}
% \end{macrocode}
% \end{macro}
@@ -598,8 +634,8 @@
% \begin{macro}{\::o}
% This function is used to expand an argument once.
% \begin{macrocode}
-\def_long_new:Npn\::o#1\:::#2#3{
- \exp_after:NN\exp_arg_next:nnn\exp_after:NN{\exp_after:NN{#3}}{#1}{#2}
+\cs_new:Npn\::o#1\:::#2#3{
+ \exp_after:wN\exp_arg_next:nnn\exp_after:wN{#3}{#1}{#2}
}
% \end{macrocode}
% \end{macro}
@@ -608,7 +644,7 @@
% \begin{macro}{\::f}
% \begin{macro}{\exp_stop_f:}
% This function is used to expand a token list until the first
-% unexpandable token is found. The underlying "\int_to_roman:w -`0"
+% unexpandable token is found. The underlying "\tex_romannumeral:D -`0"
% expands everything in its way to find something terminating the
% number and thereby expands the function in front of it. This
% scanning procedure is terminated once the expansion hits
@@ -616,459 +652,541 @@
% to mark such an end of expansion marker; in case the scanner hits
% a number, this number also terminates the scanning and is left
% untouched. In the example shown earlier the scanning was stopped
-% once \TeX{} had fully expanded "\let:Nc \aaa {b \l_tmpa_tlp b}"
-% into "\let:NwN \aaa = \blurb" which then turned out to contain
-% the non-expandable token "\let:NwN". Since the expansion of
-% "\int_to_roman:w -`0" is \m{null}, we wind up with a fully
+% once \TeX{} had fully expanded "\cs_set_eq:Nc \aaa {b \l_tmpa_tl b}"
+% into "\cs_set_eq:NwN \aaa = \blurb" which then turned out to contain
+% the non-expandable token "\cs_set_eq:NwN". Since the expansion of
+% "\tex_romannumeral:D -`0" is \m{null}, we wind up with a fully
% expanded list, only \TeX{} has not tried to execute any of the
% non-expandable tokens. This is what differentiates this function
% from the "x" argument type.
% \begin{macrocode}
-\def_long_new:Npn\::f#1\:::#2#3{
- \exp_after:NN\exp_arg_next:nnn
- \exp_after:NN{\exp_after:NN{\int_to_roman:w -`0 #3}}
+\cs_new:Npn\::f#1\:::#2#3{
+ \exp_after:wN\exp_arg_next:nnn
+ \exp_after:wN{\tex_romannumeral:D -`0 #3}
{#1}{#2}
}
-\def_new:Npn \exp_stop_f: {~}
+\cs_new_nopar:Npn \exp_stop_f: {~}
% \end{macrocode}
% \end{macro}
% \end{macro}
%
-% \begin{macro}{\::x}
+% \begin{macro}{\::x,\exp_arg:x}
% This function is used to expand an argument fully. If the
% pdf\TeX\ primitive "\expanded" is present, we use it.
% \begin{macrocode}
-\let_new:NN \exp_arg:x \expanded % Move eventually.
+\cs_new_eq:NN \exp_arg:x \expanded % Move eventually.
\cs_if_free:NTF\exp_arg:x{
- \def_long_new:Npn\::x#1\:::#2#3{
- % \tlp_set:Nx\l_exp_tlp{{{#3}}}
- \def:Npx \l_exp_tlp{{{#3}}}
- \exp_after:NN\exp_arg_next:nnn\l_exp_tlp{#1}{#2}}
+ \cs_new:Npn\::x#1\:::#2#3{
+ \cs_set_nopar:Npx \l_exp_tl{{#3}}
+ \exp_after:wN\exp_arg_next:nnn\l_exp_tl{#1}{#2}}
}
{
- \def_long_new:Npn\::x#1\:::#2#3{
- \exp_after:NN\exp_arg_next:nnn
- \exp_after:NN{\exp_arg:x{{#3}}}{#1}{#2}
+ \cs_new:Npn\::x#1\:::#2#3{
+ \exp_after:wN\exp_arg_next:nnn
+ \exp_after:wN{\exp_arg:x{{#3}}}{#1}{#2}
}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\:::}
-% Just another name for the identity function.
+%
+% \begin{macro}{\::v}
+% \begin{macro}{\::V}
+% These functions return the value of a register, i.e., one of
+% |tl|, |num|, |int|, |skip|, |dim| and |muskip|. The |V| version
+% expects a single token whereas |v| like |c| creates a csname from
+% its argument given in braces and then evaluates it as if it was a
+% |V|. The sequence |\tex_romannumeral:D -`0| sets off an |f| type
+% expansion. The argument is returned in braces.
% \begin{macrocode}
-\def_long_new:Npn\:::#1{#1}
+\cs_new:Npn \::V#1\:::#2#3{
+ \exp_after:wN\exp_arg_next:nnn
+ \exp_after:wN{
+ \tex_romannumeral:D -`0
+ \exp_eval_register:N #3
+ }
+ {#1}{#2}
+}
+\cs_new:Npn \::v#1\:::#2#3{
+ \exp_after:wN\exp_arg_next:nnn
+ \exp_after:wN{
+ \tex_romannumeral:D -`0
+ \exp_eval_register:c {#3}
+ }
+ {#1}{#2}
+}
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
-% \begin{macro}{\::C}
-% This function creates a control sequence out of |#3| and expands
-% that once before passing it on to |\exp_arg_next:nnn|.
+% \begin{macro}{\exp_eval_register:N,\exp_eval_register:c}
+% \begin{macro}{\exp_eval_error_msg:w}
+% This function evaluates a register. Now a register might exist as
+% one of two things: A parameter-less macro or a built-in \TeX\
+% register such as |\count|. For the \TeX\ registers we have to
+% utilize a |\tex_the:D| whereas for the macros we merely have to
+% expand them once. The trick is to find out when to use
+% |\tex_the:D| and when not to. What we do here is try to find out
+% whether the token will expand to something else when hit with
+% |\exp_after:wN|. The technique is to compare the meaning of the
+% register in question when it has been prefixed with |\exp_not:N|
+% and the register itself. If it is a macro, the prefixed
+% |\exp_not:N| will temporarily turn it into the primitive
+% |\tex_relax:D|.
% \begin{macrocode}
-\def_long_new:Npn\::C#1\:::#2#3{
- \exp_after:NN\exp_C_aux:nnn\cs:w #3\cs_end:{#1}{#2}}
+\cs_set_nopar:Npn \exp_eval_register:N #1{
+ \exp_after:wN \if_meaning:w \exp_not:N #1#1
% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\exp_C_aux:nnn}
-% A helper function for |\::C| wich expands its argument before
-% passing it on to |\exp_arg_next:nnn|.
+% If the token was not a macro it may be a malformed variable from a
+% |c| expansion in which case it is equal to the primitive
+% |\tex_relax:D|. In that case we throw an error. We could let \TeX\
+% do it for us but that would result in the rather obscure
+% \begin{quote}
+% |! You can't use `\relax' after \the.|
+% \end{quote}
+% which while quite true doesn't give many hints as to what actually
+% went wrong. We provide something more sensible.
+% \begin{macrocode}
+ \if_meaning:w \tex_relax:D #1
+ \exp_eval_error_msg:w
+ \fi:
+% \end{macrocode}
+% The next bit requires some explanation. The function must be
+% initiated by the sequence |\tex_romannumeral:D -`0| and we want to
+% terminate this expansion chain by inserting an |\exp_stop_f:|
+% token. However, we have to expand the register |#1| before we do
+% that. If it is a \TeX\ register, we need to execute the sequence
+% |\exp_after:wN\exp_stop_f:\tex_the:D #1| and if it is a macro we
+% need to execute |\exp_after:wN\exp_stop_f: #1|. We therefore issue
+% the longer of the two sequences and if the register is a macro, we
+% remove the |\tex_the:D|.
% \begin{macrocode}
-\def_long_new:Npn\exp_C_aux:nnn #1{
- \exp_after:NN
- \exp_arg_next:nnn
- \exp_after:NN
- {
- \exp_after:NN
- {#1}
- }
+ \else:
+ \exp_after:wN \use_i_ii:nnn
+ \fi:
+ \exp_after:wN \exp_stop_f: \tex_the:D #1
+}
+\cs_set_nopar:Npn \exp_eval_register:c #1{
+ \exp_after:wN\exp_eval_register:N\cs:w #1\cs_end:
}
% \end{macrocode}
-% \end{macro}
+% Clean up nicely, then call the undefined control sequence. The
+% result is an error message looking like this:
+% \begin{verbatim}
+% ! Undefined control sequence.
+% \exp_eval_error_msg:w ...erroneous variable used!
+%
+% l.55 \tl_set:Nv \l_tmpa_tl {undefined_tl}
+% \end{verbatim}
+% \begin{macrocode}
+\group_begin:%
+\tex_catcode:D`\!=11\tex_relax:D%
+\tex_catcode:D`\ =11\tex_relax:D%
+\cs_gset:Npn\exp_eval_error_msg:w#1\tex_the:D#2{%
+\fi:\fi:\erroneous variable used!}%
+\group_end:%
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
%
% Here are some that might not stay but let's see.
-% \begin{macro}{\::E}
-% This function is used to expand an argument once and return it
-% \emph{without} braces. Use this only when you feel pretty
-% comfortable about your input! Actually this is pretty much just
-% generic wrapper for |\exp_after:NN|.
+%
+% \begin{macro}{\::d}
+% This function is used to expand an argument twice. Mostly useful
+% for |toks| type things. This is likely to vanish with |V| around.
% \begin{macrocode}
-\def_long_new:Npn\::E#1\:::#2#3{
- \exp_after:NN\exp_arg_next:nnn \exp_after:NN{#3}{#1}{#2}
+\cs_new:Npn\::d#1\:::#2#3{
+ \exp_after:wN\exp_after:wN\exp_after:wN\exp_arg_next:nnn
+ \exp_after:wN\exp_after:wN\exp_after:wN{#3}{#1}{#2}
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\::e}
-% Same as |\::E| really but conceptually they are different.
+% \subsection{Hand-tuned definitions}
+% \label{sec:handtune}
+%
+% One of the most important features of these functions is that they
+% are fully expandable and therefore allow to prefix them with
+% |\pref_global:D| for example. This together with the fact that the
+% `general' concept above is slower means that we should convert
+% whenever possible and perhaps remove all remaining occurences by
+% hand-encoding in the end.
+%
+% \begin{macro}{\exp_args:No}
+% \begin{macro}{\exp_args:NNo}
+% \begin{macro}{\exp_args:NNNo}
% \begin{macrocode}
-\def_long_new:Npn\::e#1\:::#2#3{
- \exp_after:NN\exp_arg_next:nnn \exp_after:NN{#3}{#1}{#2}
-}
+\cs_new:Npn \exp_args:No #1#2{\exp_after:wN#1\exp_after:wN{#2}}
+\cs_new:Npn \exp_args:NNo #1#2#3{\exp_after:wN#1\exp_after:wN#2
+ \exp_after:wN{#3}}
+\cs_new:Npn \exp_args:NNNo #1#2#3#4{\exp_after:wN#1\exp_after:wN#2
+ \exp_after:wN#3\exp_after:wN{#4}}
% \end{macrocode}
% \end{macro}
+% \end{macro}
+% \end{macro}
%
-% \begin{macro}{\::d}
-% This function is used to expand an argument twice. Mostly useful
-% for |toks| type things.
+%
+% \begin{macro}{\exp_args:Nc,\exp_args:cc,\exp_args:NNc,\exp_args:Ncc,\exp_args:Nccc}
+% Here are the functions that turn their argument into csnames but
+% are expandable.
% \begin{macrocode}
-\def_long_new:Npn\::d#1\:::#2#3{
- \exp_after:NN\exp_after:NN\exp_after:NN\exp_arg_next:nnn
- \exp_after:NN\exp_after:NN\exp_after:NN{
- \exp_after:NN\exp_after:NN\exp_after:NN{#3}}{#1}{#2}
-}
+\cs_set:Npn \exp_args:Nc #1#2{\exp_after:wN#1\cs:w#2\cs_end:}
+\cs_new:Npn \exp_args:cc #1#2{\cs:w #1\exp_after:wN\cs_end:\cs:w #2\cs_end:}
+\cs_new:Npn \exp_args:NNc #1#2#3{\exp_after:wN#1\exp_after:wN#2
+ \cs:w#3\cs_end:}
+\cs_new:Npn \exp_args:Ncc #1#2#3{\exp_after:wN#1
+ \cs:w#2\exp_after:wN\cs_end:\cs:w#3\cs_end:}
+\cs_new:Npn \exp_args:Nccc #1#2#3#4{\exp_after:wN#1
+ \cs:w#2\exp_after:wN\cs_end:\cs:w#3\exp_after:wN
+ \cs_end:\cs:w #4\cs_end:}
% \end{macrocode}
% \end{macro}
%
-% We do most of them by hand here. This also means that we get a name
-% for |\exp_after:NN| that fits with the rest of the code.
+% \begin{macro}{\exp_args:Nco}
+% If we force that the third argument
+% always has braces, we could implement this function
+% with less tokens and only two arguments.
% \begin{macrocode}
-\let:NN \exp_args:NE \exp_after:NN
-\def:Npn \exp_args:NNE #1{\exp_args:NE#1\exp_args:NE}
-\def:Npn \exp_args:NNNE #1#2{\exp_args:NE#1\exp_args:NE#2\exp_args:NE}
-\def:Npn \exp_args:NEE #1{\exp_args:NE\exp_args:NE\exp_args:NE#1\exp_args:NE}
-\def:Npn \exp_args:NcE #1#2{\exp_after:NN #1\cs:w #2\exp_after:NN\cs_end:}
-\def:Npn \exp_args:Nd {\::d\:::}
-\def:Npn \exp_args:NNd {\::N\::d\:::}
+\cs_new:Npn \exp_args:Nco #1#2#3{\exp_after:wN#1\cs:w#2\exp_after:wN
+ \cs_end:\exp_after:wN{#3}}
% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Definitions with the `general' technique}
+% \label{sec:gendef}
+%
+% \begin{macro}{\exp_args:Nd,\exp_args:Nf,\exp_args:NV,\exp_args:Nv,\exp_args:Nx}
+% \begin{macrocode}
+\cs_set_nopar:Npn \exp_args:Nd {\::d\:::}
+\cs_set_nopar:Npn \exp_args:Nf {\::f\:::}
+\cs_set_nopar:Npn \exp_args:Nv {\::v\:::}
+\cs_set_nopar:Npn \exp_args:NV {\::V\:::}
+\cs_set_nopar:Npn \exp_args:Nx {\::x\:::}
+% \end{macrocode}
+% \end{macro}
%
-% \begin{macro}{\exp_args:NC}
-% \begin{macro}{\exp_args:Ncx}
-% \begin{macro}{\exp_args:Ncco}
-% \begin{macro}{\exp_args:Nccx}
-% \begin{macro}{\exp_args:Ncnx}
-% \begin{macro}{\exp_args:NcNc}
-% \begin{macro}{\exp_args:Nf}
-% \begin{macro}{\exp_args:NNf}
-% \begin{macro}{\exp_args:Nfo}
-% \begin{macro}{\exp_args:Nnf}
-% \begin{macro}{\exp_args:NNno}
-% \begin{macro}{\exp_args:NnnN}
-% \begin{macro}{\exp_args:Nnno}
-% \begin{macro}{\exp_args:Nnnx}
-% \begin{macro}{\exp_args:Nno}
-% \begin{macro}{\exp_args:Nnox}
-% \begin{macro}{\exp_args:NNx}
-% \begin{macro}{\exp_args:Nnx}
-% \begin{macro}{\exp_args:Noo}
-% \begin{macro}{\exp_args:Noox}
-% \begin{macro}{\exp_args:Nox}
-% \begin{macro}{\exp_args:Nx}
-% \begin{macro}{\exp_args:Nxx}
-% \begin{macro}{\exp_args:Nxx}
-% \begin{macro}{\exp_args:NNC}
-% \begin{macro}{\exp_args:Nnnc}
-% \begin{macro}{\exp_args:NNnx}
-% \begin{macro}{\exp_args:NNoo}
-% \begin{macro}{\exp_args:NNox}
+% \begin{macro}{\exp_args:NNV,\exp_args:NNv,\exp_args:NNd,\exp_args:NNf,\exp_args:NNx,
+% \exp_args:NVV,
+% \exp_args:Ncx,
+% \exp_args:Nfo,\exp_args:Nff,
+% \exp_args:Ncf,\exp_args:Nco,
+% \exp_args:Nnf,\exp_args:Nno,\exp_args:Nnx,
+% \exp_args:Noo,\exp_args:Noc,\exp_args:Nox,
+% \exp_args:Nxo,\exp_args:Nxx}
% Here are the actual function definitions, using the helper functions
% above.
% \begin{macrocode}
-%\def:Npn \exp_args:NNNo {\::N\::N\::o\:::}
-%\def:Npn \exp_args:NNOo {\::N\::O\::o\:::}
-%\def:Npn \exp_args:NNc {\::N\::c\:::}
-%\def:Npn \exp_args:NNo {\::N\::o\::\:::}
-%\def:Npn \exp_args:NOOo {\::O\::O\::o\:::}
-%\def:Npn \exp_args:NOc {\::O\::c\:::}
-%\def:Npn \exp_args:NOo {\::O\::o\:::}
-%\def:Npn \exp_args:Nc {\::c\:::}
-%\def:Npn \exp_args:Ncc {\::c\::c\:::}
-%\def:Npn \exp_args:Nccc {\::c\::c\::c\:::}
-%\def:Npn \exp_args:Nco {\::c\::o\:::}
-%\def:Npn \exp_args:No {\::o\:::}
+\cs_set_nopar:Npn \exp_args:NNd {\::N\::d\:::}
+\cs_set_nopar:Npn \exp_args:NNf {\::N\::f\:::}
+\cs_set_nopar:Npn \exp_args:NNv {\::N\::v\:::}
+\cs_set_nopar:Npn \exp_args:NNV {\::N\::V\:::}
+\cs_set_nopar:Npn \exp_args:NNx {\::N\::x\:::}
+
+\cs_set_nopar:Npn \exp_args:Ncx {\::c\::x\:::}
+\cs_set_nopar:Npn \exp_args:Nfo {\::f\::o\:::}
+\cs_set_nopar:Npn \exp_args:Nff {\::f\::f\:::}
+\cs_set_nopar:Npn \exp_args:Ncf {\::c\::f\:::}
+\cs_set_nopar:Npn \exp_args:Nnf {\::n\::f\:::}
+\cs_set_nopar:Npn \exp_args:Nno {\::n\::o\:::}
+\cs_set_nopar:Npn \exp_args:Nnx {\::n\::x\:::}
+
+\cs_set_nopar:Npn \exp_args:Noc {\::o\::c\:::}
+\cs_set_nopar:Npn \exp_args:Noo {\::o\::o\:::}
+\cs_set_nopar:Npn \exp_args:Nox {\::o\::x\:::}
-\def:Npn \exp_args:NC {\::C\:::}
-\def:Npn \exp_args:NNC {\::N\::C\:::}
-\def:Npn \exp_args:NNf {\::N\::f\:::}
-\def:Npn \exp_args:NNno {\::N\::n\::o\:::}
-\def:Npn \exp_args:NNnx {\::N\::n\::x\:::} % new
-\def:Npn \exp_args:NNoo {\::N\::o\::o\:::} % new
-\def:Npn \exp_args:NNox {\::N\::o\::x\:::} % new
-\def:Npn \exp_args:NNx {\::N\::x\:::}
-\def:Npn \exp_args:NcNc {\::c\::N\::c\:::}
-\def:Npn \exp_args:NcNo {\::c\::N\::o\:::}
-\def:Npn \exp_args:Ncco {\::c\::c\::o\:::}
-\def:Npn \exp_args:Ncco {\::c\::c\::o\:::}
-\def:Npn \exp_args:Nccx {\::c\::c\::x\:::}
-\def:Npn \exp_args:Ncnx {\::c\::n\::x\:::}
-\def:Npn \exp_args:Ncx {\::c\::x\:::}
-\def:Npn \exp_args:Nf {\::f\:::}
-\def:Npn \exp_args:Nfo{\::f\::o\:::}
-\def:Npn \exp_args:Nnf {\::n\::f\:::}
-\def:Npn \exp_args:NnnN {\::n\::n\::N\:::} %% Strange one this one...
-\def:Npn \exp_args:Nnnc {\::n\::n\::c\:::}
-\def:Npn \exp_args:Nnno {\::n\::n\::o\:::}
-\def:Npn \exp_args:Nnnx {\::n\::n\::x\:::}
-\def:Npn \exp_args:Nno {\::n\::o\:::}
-\def:Npn \exp_args:Nnox {\::n\::o\::x\:::}
-\def:Npn \exp_args:Nnx {\::n\::x\:::}
-\def:Npn \exp_args:Noo {\::o\::o\:::}
-\def:Npn \exp_args:Noox {\::o\::o\::x\:::}
-\def:Npn \exp_args:Nox {\::o\::x\:::}
-\def:Npn \exp_args:Nx {\::x\:::}
-\def:Npn \exp_args:Nxo {\::x\::o\:::}
-\def:Npn \exp_args:Nxx {\::x\::x\:::}
+\cs_set_nopar:Npn \exp_args:NVV {\::V\::V\:::}
+
+\cs_set_nopar:Npn \exp_args:Nxo {\::x\::o\:::}
+\cs_set_nopar:Npn \exp_args:Nxx {\::x\::x\:::}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
+%
+% \begin{macro}{\exp_args:Ncco,
+% \exp_args:Nccx,
+% \exp_args:Ncnx,
+% \exp_args:NcNc,
+% \exp_args:NcNo,
+% \exp_args:NNno,
+% \exp_args:Nnno,
+% \exp_args:Nnnx,
+% \exp_args:Nnox,
+% \exp_args:Nooo,
+% \exp_args:Noox,
+% \exp_args:Nnnc,
+% \exp_args:NNnx,
+% \exp_args:NNoo,
+% \exp_args:NNox}
+% \begin{macrocode}
+\cs_set_nopar:Npn \exp_args:NNno {\::N\::n\::o\:::}
+\cs_set_nopar:Npn \exp_args:NNnx {\::N\::n\::x\:::}
+\cs_set_nopar:Npn \exp_args:NNoo {\::N\::o\::o\:::}
+\cs_set_nopar:Npn \exp_args:NNox {\::N\::o\::x\:::}
+
+\cs_set_nopar:Npn \exp_args:Nnnc {\::n\::n\::c\:::}
+\cs_set_nopar:Npn \exp_args:Nnno {\::n\::n\::o\:::}
+\cs_set_nopar:Npn \exp_args:Nnnx {\::n\::n\::x\:::}
+\cs_set_nopar:Npn \exp_args:Nnox {\::n\::o\::x\:::}
+
+\cs_set_nopar:Npn \exp_args:NcNc {\::c\::N\::c\:::}
+\cs_set_nopar:Npn \exp_args:NcNo {\::c\::N\::o\:::}
+\cs_set_nopar:Npn \exp_args:Ncco {\::c\::c\::o\:::}
+\cs_set_nopar:Npn \exp_args:Ncco {\::c\::c\::o\:::}
+\cs_set_nopar:Npn \exp_args:Nccx {\::c\::c\::x\:::}
+\cs_set_nopar:Npn \exp_args:Ncnx {\::c\::n\::x\:::}
+
+\cs_set_nopar:Npn \exp_args:Noox {\::o\::o\::x\:::}
+\cs_set_nopar:Npn \exp_args:Nooo {\::o\::o\::o\:::}
+% \end{macrocode}
% \end{macro}
%
%
-% \subsubsection{Preventing expansion}
+% \subsection{Preventing expansion}
%
%
% \begin{macro}{\exp_not:o}
% \begin{macro}{\exp_not:d}
% \begin{macro}{\exp_not:f}
+% \begin{macro}{\exp_not:v}
+% \begin{macro}{\exp_not:V}
% \begin{macrocode}
-\def_long_new:Npn\exp_not:o#1{\exp_not:n\exp_after:NN{#1}}
-\def_long_new:Npn\exp_not:d#1{
- \exp_not:n\exp_after:NN\exp_after:NN\exp_after:NN{#1}
+\cs_new:Npn\exp_not:o#1{\exp_not:n\exp_after:wN{#1}}
+\cs_new:Npn\exp_not:d#1{
+ \exp_not:n\exp_after:wN\exp_after:wN\exp_after:wN{#1}
+}
+\cs_new:Npn\exp_not:f#1{
+ \exp_not:n\exp_after:wN{\tex_romannumeral:D -`0 #1}
+}
+\cs_new:Npn\exp_not:v#1{
+ \exp_not:n\exp_after:wN{\tex_romannumeral:D -`0 \exp_eval_register:c {#1}}
}
-\def_long_new:Npn\exp_not:f#1{
- \exp_not:n\exp_after:NN{\int_to_roman:w -`0 #1}
+\cs_new:Npn\exp_not:V#1{
+ \exp_not:n\exp_after:wN{\tex_romannumeral:D -`0 \exp_eval_register:N #1}
}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
+% \end{macro}
+% \end{macro}
%
-% \begin{macro}{\exp_not:E}
% \begin{macro}{\exp_not:c}
-% Two helper functions, which we can probably live without it.
+% A helper function.
% \begin{macrocode}
-\def_new:Npn\exp_not:E{\exp_after:NN\exp_not:N}
-\def_long_new:Npn\exp_not:c#1{\exp_after:NN\exp_not:N\cs:w#1\cs_end:}
+\cs_new:Npn\exp_not:c#1{\exp_after:wN\exp_not:N\cs:w#1\cs_end:}
% \end{macrocode}
% \end{macro}
-% \end{macro}
-%
-%
-% \subsubsection{Single token expansion}
%
-% Expansion for arguments that are single tokens is done with the
-% functions below. I first thought of using a different module name
-% but then I saw that this wouldn't do since I could then never
-% determine for, say, |\seq_put:no| whether this means single, or
-% general expansion. Therefore I decided to use uppercase `O' for
-% single expansion.
-%
-% One of the most important features of these functions is that they
-% are fully expandable and therefore allow to prefix them with
-% |\pref_global:D| for example. This together with the fact that the
-% above concept is much slower in general means that we should convert
-% whenever possible and perhaps remove all remaining occurences by
-% hand-encoding in the end.
%
-% \begin{macro}{\exp_args:No}
-% \begin{macro}{\exp_args:NOo}
-% \begin{macro}{\exp_args:NNo}
-% \begin{macro}{\exp_args:NNO}
-% \begin{macro}{\exp_args:NOOo}
-% \begin{macro}{\exp_args:NNOo}
-% \begin{macro}{\exp_args:NNNo}
-% This looks somewhat horrible but it runs well with the other
-% syntax. It is important to see that these functions really need
-% single tokens as arguments whenever capital letters are used.
+% \subsection{Defining function variants}
+%
+%
+% \begin{macro}{\cs_generate_variant:Nn}
+% \begin{macro}[aux]{\cs_generate_variant_aux:nnNn}
+% \begin{macro}[aux]{\cs_generate_variant_aux:nnw}
+% \begin{macro}[aux]{\cs_generate_variant_aux:N}
+% \begin{arguments}
+% \item Base form of a function; e.g., "\tl_set:Nn"
+% \item One or more variant argument specifiers; e.g., "{Nx,c,cx}"
+% \end{arguments}
+% Split up the original base function to grab its name and signature
+% consisting of $k$ letters. Then we wish to iterate through the list
+% of variant argument specifiers, and for each one construct a new
+% function name using the original base name, the variant signature
+% consisting of $l$ letters and the last $k-l$ letters of the base
+% signature. For example, for a base function "\tl_set:Nn" which
+% needs a "c" variant form, we want the new signature to be "cn".
% \begin{macrocode}
-\def_long_new:Npn \exp_args:No #1#2{\exp_after:NN#1\exp_after:NN{#2}}
-\def_long_new:Npn \exp_args:NOo #1#2#3{\exp_after:NN\exp_args:No \exp_after:NN#1
- \exp_after:NN#2\exp_after:NN{#3}}
-\def_long_new:Npn \exp_args:NOOo #1#2#3#4{\exp_after:NN\exp_args:NOo
- \exp_after:NN#1\exp_after:NN#2\exp_after:NN#3\exp_after:NN{#4}}
-\def_long_new:Npn \exp_args:NNo #1#2#3{\exp_after:NN#1\exp_after:NN#2
- \exp_after:NN{#3}}
-\def_long_new:Npn \exp_args:NNO #1#2#3 {\exp_after:NN#1
- \exp_after:NN#2 #3}
-\def_long_new:Npn \exp_args:NNOo #1#2#3#4{\exp_after:NN\exp_args:NNo
- \exp_after:NN#1\exp_after:NN#2\exp_after:NN#3\exp_after:NN{#4}}
-\def_long_new:Npn \exp_args:NNNo #1#2#3#4{\exp_after:NN#1\exp_after:NN#2
- \exp_after:NN#3\exp_after:NN{#4}}
+\cs_new:Npn \cs_generate_variant:Nn #1 {
+ \chk_if_exist_cs:N #1
+ \cs_split_function:NN #1 \cs_generate_variant_aux:nnNn
+}
% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-%
-% \begin{macro}{\exp_args:Nc}
-% \begin{macro}{\exp_args:NNc}
-% \begin{macro}{\exp_args:NOc}
-% \begin{macro}{\exp_args:Ncc}
-% \begin{macro}{\exp_args:Nccc}
-% Here are the functions that turn their argument into csnames but
-% are expandable.
+% We discard the boolean and then set off a loop through the desired
+% variant forms.
% \begin{macrocode}
-\def_long_new:Npn \exp_args:Nc #1#2{\exp_after:NN#1\cs:w#2\cs_end:}
-\def_long_new:Npn \exp_args:NNc #1#2#3{\exp_after:NN#1\exp_after:NN#2
- \cs:w#3\cs_end:}
-\def_long_new:Npn \exp_args:NOc#1#2#3{\exp_after:NN\exp_args:No\exp_after:NN
- #1\exp_after:NN#2\cs:w#3\cs_end:}
-\def_long_new:Npn \exp_args:Ncc #1#2#3{\exp_after:NN#1
- \cs:w#2\exp_after:NN\cs_end:\cs:w#3\cs_end:}
-\def_long_new:Npn \exp_args:Nccc #1#2#3#4{\exp_after:NN#1
- \cs:w#2\exp_after:NN\cs_end:\cs:w#3\exp_after:NN
- \cs_end:\cs:w #4\cs_end:}
+\cs_set:Npn \cs_generate_variant_aux:nnNn #1#2#3#4{
+ \cs_generate_variant_aux:nnw {#1}{#2} #4,?,\q_recursion_stop
+}
+% \end{macrocode}
+% Next is the real work to be done. We now have 1: base name, 2: base
+% signature, 3: beginning of variant signature. To construct the new
+% csname and the "\exp_args:Ncc" form, we need the variant signature.
+% In our example, we wanted to discard the first two letters of the
+% base signature because the variant form started with "cc". This is
+% the same as putting first "cc" in the signature and then
+% "\use_none:nn" followed by the base signature "NNn". We therefore
+% call a small loop that outputs an "n" for each letter in the variant
+% signature and use this to call the correct "\use_none:" variant.
+% Firstly though, we check whether to terminate the loop.
+% \begin{macrocode}
+\cs_set:Npn \cs_generate_variant_aux:nnw #1 #2 #3, {
+ \if:w ? #3
+ \exp_after:wN \use_none_delimit_by_q_recursion_stop:w
+ \fi:
+% \end{macrocode}
+% Then check if the variant form has already been defined.
+% \begin{macrocode}
+ \cs_if_free:cTF {
+ #1:#3\use:c {use_none:\cs_generate_variant_aux:N #3 ?}#2
+ }
+ {
+% \end{macrocode}
+% If not, then define it and then additionally check if
+% the |\exp_args:N| form needed is defined.
+% \begin{macrocode}
+ \cs_new_nopar:cpx {
+ #1:#3 \use:c{use_none:\cs_generate_variant_aux:N #3 ?}#2
+ }
+ {
+ \exp_not:c { exp_args:N #3} \exp_not:c {#1:#2}
+ }
+ \cs_generate_internal_variant:n {#3}
+ }
+% \end{macrocode}
+% Otherwise tell that it was already defined.
+% \begin{macrocode}
+ {
+ \iow_log:x{
+ Variant~\token_to_str:c {
+ #1:#3\use:c {use_none:\cs_generate_variant_aux:N #3 ?}#2
+ }~already~defined;~ not~ changing~ it~on~line~
+ \tex_the:D \tex_inputlineno:D
+ }
+ }
+% \end{macrocode}
+% Recurse.
+% \begin{macrocode}
+ \cs_generate_variant_aux:nnw{#1}{#2}
+}
+% \end{macrocode}
+% The small loop for defining the required number of "n"s. Break when
+% seeing a "?".
+% \begin{macrocode}
+\cs_set:Npn \cs_generate_variant_aux:N #1{
+ \if:w ?#1 \exp_after:wN\use_none:nn \fi: n \cs_generate_variant_aux:N
+}
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
% \end{macro}
-% \end{macro}
-%
-%
-% \begin{macro}{\exp_args:Nco}
-% If we force that the third argument
-% always has braces, we could implement this function
-% with less tokens and only two arguments.
-% \begin{macrocode}
-\def_long_new:Npn \exp_args:Nco #1#2#3{\exp_after:NN#1\cs:w#2\exp_after:NN
- \cs_end:\exp_after:NN{#3}}
-% \end{macrocode}
-% \end{macro}
%
%
-% \begin{macro}{\exp_def_form:nnn}
-% This command is a recent addition which was actually added
-% when we wrote the article for TUGboat (while most of the other
-% code goes way back to 1993).
+% \begin{macro}{\cs_generate_internal_variant:n}
+% Test if |exp_args:N #1| is already defined
+% and if not define it via the
+% |\::| commands using the chars in |#1|
% \begin{macrocode}
-\def:Npn\exp_def_form:nnn#1#2#3{
- \exp_after:NN
- \def:Npn
- \cs:w
- #1:#3
- \exp_after:NN
- \cs_end:
- \exp_after:NN
- {
- \cs:w
- exp_args:N#3
- \exp_after:NN
- \cs_end:
- \cs:w
- #1:#2
- \cs_end:
- }
+\cs_new:Npn \cs_generate_internal_variant:n #1 {
+ \cs_if_free:cT { exp_args:N #1 }{
% \end{macrocode}
-% We also have to test if |exp_args:N#3| is already defined
-% and if not define it via the
-% |\::| commands using the chars in |#3|
+% We use "new" to log the definition if we have to make one.
% \begin{macrocode}
- \cs_if_free:cT
- {exp_args:N#3}
- {\def:cpx {exp_args:N#3}
- {\exp_args_form_x:w #3 :}
- }
+ \cs_new:cpx { exp_args:N #1 }
+ { \cs_generate_internal_variant_aux:n #1 : }
+ }
}
% \end{macrocode}
% \end{macro}
%
-%
-% \begin{macro}{\exp_args_form_x:w}
+% \begin{macro}[aux]{\cs_generate_internal_variant_aux:n}
% This command grabs char by char outputting |\::#1| (not expanded
% further) until we see a |:|. That colon is in fact also turned into
% |\:::| so that the required structure for |\exp_args...| commands
% is correctly terminated.
% \begin{macrocode}
-\def_new:Npn\exp_args_form_x:w #1 {
+\cs_new:Npn \cs_generate_internal_variant_aux:n #1 {
\exp_not:c{::#1}
- \if_meaning:NN #1 :
- \else:
- \exp_after:NN\exp_args_form_x:w
- \fi:}
+ \if_meaning:w #1 :
+ \exp_after:wN \use_none:n
+ \fi:
+ \cs_generate_internal_variant_aux:n
+}
% \end{macrocode}
% \end{macro}
%
-% Show token usage:
+% \subsection{Last-unbraced versions}
+%
+%\begin{macro}[aux]{\exp_arg_last_unbraced:nn}
+%\begin{macro}[aux]{\::f_unbraced}
+%\begin{macro}[aux]{\::o_unbraced}
+%\begin{macro}[aux]{\::V_unbraced}
+%\begin{macro}[aux]{\::v_unbraced}
+% There are a few places where the last argument needs to be available
+% unbraced. First some helper macros.
+% \begin{macrocode}
+\cs_new:Npn \exp_arg_last_unbraced:nn #1#2 { #2#1 }
+\cs_new:Npn \::f_unbraced \:::#1#2 {
+ \exp_after:wN \exp_arg_last_unbraced:nn
+ \exp_after:wN { \tex_romannumeral:D -`0 #2 } {#1}
+}
+\cs_new:Npn \::o_unbraced \:::#1#2 {
+ \exp_after:wN \exp_arg_last_unbraced:nn \exp_after:wN {#2 }{#1}
+}
+\cs_new:Npn \::V_unbraced \:::#1#2 {
+ \exp_after:wN \exp_arg_last_unbraced:nn
+ \exp_after:wN { \tex_romannumeral:D -`0 \exp_eval_register:N #2 } {#1}
+}
+\cs_new:Npn \::v_unbraced \:::#1#2 {
+ \exp_after:wN \exp_arg_last_unbraced:nn
+ \exp_after:wN {
+ \tex_romannumeral:D -`0 \exp_eval_register:c {#2}
+ } {#1}
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
+%\begin{macro}{\exp_last_unbraced:NV}
+%\begin{macro}{\exp_last_unbraced:Nv}
+%\begin{macro}{\exp_last_unbraced:Nf}
+%\begin{macro}{\exp_last_unbraced:NcV}
+%\begin{macro}{\exp_last_unbraced:NNo}
+%\begin{macro}{\exp_last_unbraced:NNV}
+%\begin{macro}{\exp_last_unbraced:NNNo}
+% Now the business end.
+% \begin{macrocode}
+\cs_new_nopar:Npn \exp_last_unbraced:Nf { \::f_unbraced \::: }
+\cs_new_nopar:Npn \exp_last_unbraced:NV { \::V_unbraced \::: }
+\cs_new_nopar:Npn \exp_last_unbraced:Nv { \::v_unbraced \::: }
+\cs_new_nopar:Npn \exp_last_unbraced:NcV {
+ \::c \::V_unbraced \:::
+}
+\cs_new:Npn \exp_last_unbraced:NNo #1#2#3 {
+ \exp_after:wN #1 \exp_after:wN #2 #3
+}
+\cs_new_nopar:Npn \exp_last_unbraced:NNV {
+ \::N \::V_unbraced \:::
+}
+\cs_new:Npn \exp_last_unbraced:NNNo #1#2#3#4 {
+ \exp_after:wN #1 \exp_after:wN #2 \exp_after:wN #3 #4
+}
+% \end{macrocode}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%\end{macro}
+%
% \begin{macrocode}
%</initex|package>
+% \end{macrocode}
+%
+% Show token usage:
+% \begin{macrocode}
%<*showmemory>
\showMemUsage
%</showmemory>
% \end{macrocode}
%
-% \endinput
-%
-% $Log$
-% Revision 1.29 2006/07/30 15:43:38 morten
-% Minor touch-up plus added functions needed by clist module
-%
-% Revision 1.28 2006/06/03 18:56:31 morten
-% A few more functions
-%
-% Revision 1.27 2006/03/20 18:26:35 braams
-% Updated the copyright notice (2006) and demoted all implementation
-% sections to subsections and so on to clean up the toc for source3.tex
-%
-% Revision 1.26 2006/02/17 23:01:47 braams
-% Imported \exp_args:NNO from l3messages
-%
-% Revision 1.25 2005/12/27 10:00:45 morten
-% Changed RCS information retrieval
-%
-% Revision 1.24 2005/12/22 13:56:03 morten
-% Fixed error in \exp_args:NNd
-%
-% Revision 1.23 2005/12/21 20:44:30 morten
-% Corrected typo.
-%
-% Revision 1.22 2005/12/06 15:34:46 morten
-% Made \exp_not:o do what you'd expect
-%
-% Revision 1.21 2005/11/23 07:37:29 morten
-% A few new expansion types, we shall see if they will be useful.
-%
-% Revision 1.20 2005/04/12 16:44:06 morten
-% Fix to make it run as a package
-%
-% Revision 1.19 2005/04/12 13:24:07 morten
-% Minor updates
-%
-% Revision 1.18 2005/04/09 21:06:46 morten
-% Added yet another function.
-%
-% Revision 1.17 2005/04/06 21:38:10 morten
-% Added more functions.
-%
-% Revision 1.16 2005/03/26 21:09:44 morten
-% Added f argument type for "force expansion"
-%
-% Revision 1.15 2005/03/22 23:24:40 morten
-% Fixed documentation error.
-%
-% Revision 1.14 2005/03/16 22:36:37 braams
-% Added the tweaks necessary to be able to load with initex
-%
-% Revision 1.13 2005/03/11 21:37:37 braams
-% Fixed the use of RCS information
+% \end{implementation}
+% \PrintIndex
%
+% \endinput