diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/expl3/l3expan.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/expl3/l3expan.dtx | 705 |
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} +% +% + + + |