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.dtx705
1 files changed, 705 insertions, 0 deletions
diff --git a/Master/texmf-dist/source/latex/expl3/l3expan.dtx b/Master/texmf-dist/source/latex/expl3/l3expan.dtx
new file mode 100644
index 00000000000..7f634d74f77
--- /dev/null
+++ b/Master/texmf-dist/source/latex/expl3/l3expan.dtx
@@ -0,0 +1,705 @@
+% \iffalse
+%% File: l3expan.dtx Copyright (C) 1990-1998 LaTeX3 project
+%
+%<*dtx>
+ \ProvidesFile{l3expan.dtx}
+%</dtx>
+%<package>\NeedsTeXFormat{LaTeX2e}
+%<package>\ProvidesPackage{l3expan}
+%<driver> \ProvidesFile{l3expan.drv}
+% \fi
+% \ProvidesFile{l3expan.dtx}
+ [1998/04/20 v1.0e L3 Experimental Argument Expansion module]
+%
+% \iffalse
+%<*driver>
+\documentclass{l3doc}
+
+\begin{document}
+\DocInput{l3expan.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+%
+% \GetFileInfo{l3expan.dtx}
+% \title{The \textsf{l3expan} package\thanks{This file
+% has version number \fileversion, last
+% revised \filedate.}\\
+% Controlling Expansion of Command Arguments}
+% \author{\Team}
+% \date{\filedate}
+% \maketitle
+%
+%
+% \section{\LaTeX3 functions}
+%
+% All \LaTeX3 functions contain a colon in their
+% name. Characters following the colon are used to denote the number and
+% the ``type'' of arguments that the function takes. An uppercase "N" is
+% 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.
+%
+% 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[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}
+%
+% Due to memory constraints not all possible variations are implemented
+% for every base function. Instead only those that are used within the
+% \LaTeX3 kernel or otherwise seem of general interest are implemented.
+% Consult the module description to find out which functions are
+% actually defined. The next section explains how to define missing
+% variants.
+%
+% \subsection{Defining new variants}
+%
+% The definition of variant forms for base functions may be necessary
+% when writing new functions or when applying a kernel function in a
+% situation that we haven't thought of before.
+%
+% Internally preprocessing of arguments is done with functions from the
+% "\exp_" module. They all look alike, an example would be
+% "\exp_args:NNo". This function has three arguments, the first and the
+% 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}
+% 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
+% function should be a single token which is left unchanged while the
+% second argument is expanded once. From this example we can also see
+% 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}"
+% \end{quote}
+% Providing variants in this way in style files is uncritical as the
+% "\def_new: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 available internal functions for argument expansion come in to
+% flavours, some of them are faster then others. Therefore it is usually
+% best to follow the following guidelines when defining new functions
+% 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.
+% \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.
+% \item
+% In general "n", "x", and "o" (if not in the last position) will
+% need special processing which is not fast and not expandable, i.e.,
+% functions of this type may not work correctly in arguments that are
+% itself subject to "x" expansion. Therefore it is best to use the
+% ``expandable'' functions (i.e., those that contain only "c", "N", "O"
+% or "o" in the last position) whenever possible.
+% \end{itemize}
+%
+% \subsection{Manipulating the first argument}
+%
+% \begin{function}{%
+% \exp_args:No
+% }
+% \begin{syntax}
+% " \exp_args:No" <funct> <arg1> <arg2> "..."
+% \end{syntax}
+% The first argument of <funct> (i.e., <arg1>) is expanded once, 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
+% }
+% \begin{syntax}
+% " \exp_args:Nc" <funct> <arg1> <arg2> "..."
+% \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 and passed to <funct> as the first argument. <funct> may have
+% more than one argument---all others are passed unchanged.
+% \end{function}
+%
+% \begin{function}{%
+% \exp_args:NC
+% }
+% \begin{syntax}
+% " \exp_args:Nc" <funct> <arg1> <arg2> "..."
+% \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.
+% \end{function}
+%
+% \begin{function}{%
+% \exp_args:Nx
+% }
+% \begin{syntax}
+% " \exp_args:Nx" <funct> <arg1> <arg2> "..."
+% \end{syntax}
+% The first argument of <funct> (i.e., <arg1>) is fully expanded until
+% only unexpandable tokens remain, the result is surrounded by braces
+% and passed to <funct>. <funct> may have more than one argument---all
+% others are passed unchanged.
+% As mentioned before, this type of function is relatively slow.
+% \end{function}
+%
+% \subsection{Manipulating two arguments}
+%
+% \begin{function}{%
+% \exp_args:Nno |
+% \exp_args:NNx |
+% \exp_args:Nnx |
+% \exp_args:Noo |
+% \exp_args:Nox |
+% \exp_args:Nxo |
+% \exp_args:Nxx |
+% }
+% \begin{syntax}
+% "\exp_args:Nno" <funct> <arg1> <arg2> "..."
+% \end{syntax}
+% The above functions all manipulate the first two arguments of <funct>.
+% They are all slow and non-expandable.
+% \end{function}
+%
+% \begin{function}{%
+% \exp_args:NNo |
+% \exp_args:NNc |
+% \exp_args:NOo |
+% \exp_args:NOc |
+% \exp_args:Nco |
+% \exp_args:Ncc |
+% }
+% \begin{syntax}
+% "\exp_args:NNo" <funct> <arg1> <arg2> "..."
+% \end{syntax}
+% These are the fast and expandable functions for the first two arguments.
+% \end{function}
+%
+% \subsection{Manipulating three arguments}
+%
+% So far not all possible functions are provided and even the selection
+% below may be reduced in the future as far as the non-expandable
+% functions are concerned.
+%
+% \begin{function}{%
+% \exp_args:Nnno |
+% \exp_args:Nnnx |
+% \exp_args:Noox |
+% \exp_args:Nnox |
+% \exp_args:Ncnx |
+% }
+% \begin{syntax}
+% "\exp_args:Nnno" <funct> <arg1> <arg2> <arg3> "..."
+% \end{syntax}
+% All the above functions are non-expandable.
+% \end{function}
+%
+% \begin{function}{%
+% \exp_args:NNOo |
+% \exp_args:NOOo |
+% \exp_args:Nccc |
+% }
+% \begin{syntax}
+% "\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}
+%
+% \begin{function}{\exp_not:N |
+% \exp_not:c }
+% \begin{syntax}
+% "\exp_not:N" <token>
+% \end{syntax}
+% This function will prohibit the expansion of <token> in situation
+% where <token> would otherwise be replaced by it definition, e.g.,
+% inside an argument that is handled by the "x" convention.
+% \begin{texnote}
+% "\exp_not:N" is the primitive \tn{noexpand} renamed.
+% \end{texnote}
+% \end{function}
+%
+%
+% \begin{function}{\exp_not:o}
+% \begin{syntax}
+% "\exp_not:o" <token>
+% \end{syntax}
+%
+% The name of this command is a lie. Perhaps it should be called
+% ``"exp_perhaps_once"''. What it actually does is, it expands <token> and
+% then issues an "\exp_not:N" to prohibit further expansion of the
+% first token in the replacement text of <token>. This means that if the
+% replacement text of <token> consists of more than one token all
+% further tokens are still subject to full expansion. The command is, for
+% example, useful when generating a new cs name inside a "x" situation
+% that shouldn't be expanded further, e.g., "\exp_not:o" "\cs:w" "foo"
+% "\cs_end:".
+% \begin{texnote}
+% This command has no equivalent.
+% \end{texnote}
+% \end{function}
+%
+% \begin{variable}{\l_exp_tlp | \l_exp_toks}
+% 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{}
+%
+% \section {Argument Expansion}
+%
+% We start by ensuring that the required packages are loaded.
+% \begin{macrocode}
+%<package>\RequirePackage{l3basics}
+%<package>\RequirePackage{l3tlp}
+%<*package>
+% \end{macrocode}
+%
+% \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 so is never
+% going to be expandable.)
+%
+% In a later section some common cases are coded by a more direct
+% method, typically using calls to |\exp_after:NN|.
+%
+% \begin{macro}{\l_exp_tlp}
+% We need a scratch token list pointer.
+% \begin{macrocode}
+\tlp_new:Nn\l_exp_tlp{}
+% \end{macrocode}
+% \end{macro}
+%
+% This code uses internal functions with names that start with |\::|
+% to perform the expansions.
+% \begin{macro}{\exp_arg_next:nnn}
+% This is basically the same function as |\Dexp_arg_next:nnn|.
+% \begin{macrocode}
+\def_new:Npn\exp_arg_next:nnn#1#2#3{%
+ #2\:::{#3#1}}
+% \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_new:Npn\::n#1\:::#2#3{%
+ #1\:::{#2{#3}}}
+% \end{macrocode}
+% \end{macro}
+%
+% \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_new:Npn\::N#1\:::#2#3{%
+ #1\:::{#2#3}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\::c}
+% This function is used to skip an argument that is turned into
+% as control sequence without expansion.
+% \begin{macrocode}
+\def_new:Npn\::c#1\:::#2#3{%
+ \exp_after:NN\exp_arg_next:nnn\cs:w #3\cs_end:{#1}{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\::o}
+% This function is used to expand an argument once.
+% \begin{macrocode}
+\def_new:Npn\::o#1\:::#2#3{%
+ \exp_after:NN\exp_arg_next:nnn\exp_after:NN{\exp_after:NN{#3}}{#1}{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\::x}
+% This function is used to expand an argument fully.
+%
+% \begin{macrocode}
+\def_new:Npn\::x#1\:::#2#3{%
+ \tlp_set:Nx\l_exp_tlp{{{#3}}}%
+ \exp_after:NN\exp_arg_next:nnn\l_exp_tlp{#1}{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\:::}
+% Just another name for the identity function.
+% \begin{macrocode}
+\def_new:Npn\:::#1{#1}
+% \end{macrocode}
+% \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{macrocode}
+\def_new:Npn\::C#1\:::#2#3{%
+ \exp_after:NN\exp_C_aux:nnn\cs:w #3\cs_end:{#1}{#2}}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\exp_C_aux:nnn}
+% A helper function for |\::C| wich expands its argument before
+% passing it on to |\exp_arg_next:nnn|.
+% \begin{macrocode}
+\def_new:Npn\exp_C_aux:nnn #1
+ {
+ \exp_after:NN
+ \exp_arg_next:nnn
+ \exp_after:NN
+ {
+ \exp_after:NN
+ {#1}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\exp_args:NC}
+% \begin{macro}{\exp_args:Nccx}
+% \begin{macro}{\exp_args:Ncnx}
+% \begin{macro}{\exp_args:NNno}
+% \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}
+% Here are the actual function definitions, using the helper functions
+% above.
+% \begin{macrocode}
+\def:Npn \exp_args:NC {\::C\:::}
+%\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:Nccx {\::c\::c\::x\:::}
+\def:Npn \exp_args:Ncnx {\::c\::n\::x\:::}
+%\def:Npn \exp_args:Nco {\::c\::o\:::}
+%\def:Npn \exp_args:NNc {\::N\::c\:::}
+%\def:Npn \exp_args:NNNo {\::N\::N\::o\:::}
+\def:Npn \exp_args:NNno {\::N\::n\::o\:::}
+\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:Nno {\::n\::o\:::}
+%\def:Npn \exp_args:NNOo {\::N\::O\::o\:::}
+\def:Npn \exp_args:Nnox {\::n\::o\::x\:::}
+\def:Npn \exp_args:NNx {\::N\::x\:::}
+\def:Npn \exp_args:Nnx {\::n\::x\:::}
+%\def:Npn \exp_args:No {\::o\:::}
+%\def:Npn \exp_args:NOc {\::O\::c\:::}
+%\def:Npn \exp_args:NOo {\::O\::o\:::}
+\def:Npn \exp_args:Noo {\::o\::o\:::}
+%\def:Npn \exp_args:NOOo {\::O\::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\:::}
+% \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}
+%
+%
+% \subsection{Preventing expansion}
+%
+% \begin{macro}{\exp_not:N}
+% This is the \TeX\ primitive that was defined earlier.
+% \end{macro}
+%
+% \begin{macro}{\exp_not:o}
+% \begin{macro}{\exp_not:c}
+% Two helper functions, which we can probably live without it.
+% \begin{macrocode}
+\def_new:Npn\exp_not:o{\exp_after:NN\exp_not:N}
+\def_new:Npn\exp_not:c#1{\exp_after:NN\exp_not:N\cs:w#1\cs_end:}
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{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: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.
+% \begin{macrocode}
+\def_new:Npn \exp_args:No #1#2{\exp_after:NN#1\exp_after:NN{#2}}
+\def_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_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_new:Npn \exp_args:NNo #1#2#3{\exp_after:NN#1\exp_after:NN#2
+ \exp_after:NN{#3}}
+\def_new:Npn \exp_args:NNOo #1#2#3#4{\exp_after:NN\exp_args:NNo
+ \exp_after:NN#1\exp_after:NN#2\exp_after:NN#3\exp_after:NN{#4}}
+\def_new:Npn \exp_args:NNNo #1#2#3#4{\exp_after:NN#1\exp_after:NN#2
+ \exp_after:NN#3\exp_after:NN{#4}}
+% \end{macrocode}
+% \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.
+% \begin{macrocode}
+\def_new:Npn \exp_args:Nc #1#2{\exp_after:NN#1\cs:w#2\cs_end:}
+\def_new:Npn \exp_args:NNc #1#2#3{\exp_after:NN#1\exp_after:NN#2
+ \cs:w#3\cs_end:}
+\def_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_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_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:}
+% \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_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{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:
+ }
+% \end{macrocode}
+% We also have to test if |exp_arg:N#3| is already defined
+% and if not define it via the
+% |\::| commands using the chars in |#3|
+% \begin{macrocode}
+ \cs_free:cT
+ {exp_args:N#3}
+ {\def:cpx {exp_args:N#3}
+ {\exp_args_form_x:w #3 :}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\exp_args_form_x:w}
+% This command graps char by char outputting |\::#1| (not expanded
+% further) until we see a |:|. That colon is in fact also turned into
+% |\:::| so that the required structure for |\exp_args...| commands
+% is correctly terminated.
+% \begin{macrocode}
+\def_new:Npn\exp_args_form_x:w #1 {
+ \exp_after:NN \exp_not:N \cs:w ::#1 \cs_end:
+ \if_meaning:NN #1 :
+ \else:
+ \exp_after:NN\exp_args_form_x:w
+ \fi:}
+% \end{macrocode}
+% \end{macro}
+
+% Show token usage:
+% \begin{macrocode}
+%</package>
+%<*showmemory>
+\showMemUsage
+%</showmemory>
+% \end{macrocode}
+%
+%
+
+
+