[latex3-commits] [git/latex3] master: Documentation and code-documentation cleanup in l3expan (352fd7b)
Bruno Le Floch
bruno at le-floch.fr
Mon Nov 27 23:20:50 CET 2017
Repository : https://github.com/latex3/latex3
On branch : master
Link : https://github.com/latex3/latex3/commit/352fd7b5a2461475bf698ed1292d8943d38f6489
>---------------------------------------------------------------
commit 352fd7b5a2461475bf698ed1292d8943d38f6489
Author: Bruno Le Floch <bruno at le-floch.fr>
Date: Mon Nov 27 07:51:59 2017 -0500
Documentation and code-documentation cleanup in l3expan
>---------------------------------------------------------------
352fd7b5a2461475bf698ed1292d8943d38f6489
l3kernel/l3expan.dtx | 236 ++++++++++++++++++++++++++------------------------
1 file changed, 124 insertions(+), 112 deletions(-)
diff --git a/l3kernel/l3expan.dtx b/l3kernel/l3expan.dtx
index 249309a..064cb29 100644
--- a/l3kernel/l3expan.dtx
+++ b/l3kernel/l3expan.dtx
@@ -74,7 +74,7 @@
% \begin{verbatim}
% \exp_args:NNo \seq_gpush:Nn
% \g_file_name_stack
-% \l_tmpa_tl
+% { \l_tmpa_tl }
% \end{verbatim}
% In other words, the first argument to \cs{exp_args:NNo} is the base
% function and the other arguments are preprocessed and then passed to
@@ -90,7 +90,7 @@
% \begin{quote}
% |\cs_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
+% Providing variants in this way in style files is safe as the
% \cs{cs_generate_variant:Nn} function will only create new definitions if
% there is not already one available. Therefore adding
% such definition to later releases of the kernel will not make such
@@ -114,7 +114,8 @@
% once, |f|~expands fully the first token, |x|~expands fully all
% tokens at the price of being non-expandable.
% \item A few odd argument types remain: |T|~and |F|~for conditional
-% processing, otherwise identical to~|n|, |p|~for the parameter text
+% processing, otherwise identical to |n|-type arguments,
+% |p|~for the parameter text
% in definitions, |w|~for arguments with a specific syntax, and |D|~to
% denote primitives that should not be used directly.
% \end{itemize}
@@ -129,9 +130,9 @@
% \meta{base name} and \meta{original argument specifier}. The
% comma-separated list of \meta{variant argument specifiers} is
% then used to define variants of the
-% \meta{original argument specifier} where these are not already
+% \meta{original argument specifier} if these are not already
% defined. For each \meta{variant} given, a function is created
-% which expands its arguments as detailed and passes them
+% that expands its arguments as detailed and passes them
% to the \meta{parent control sequence}. So for example
% \begin{verbatim}
% \cs_set:Npn \foo:Nn #1#2 { code here }
@@ -146,50 +147,51 @@
% generates the functions |\foo:NV| and |\foo:cV| in the same
% way. The \cs{cs_generate_variant:Nn} function can only be applied if
% the \meta{parent control sequence} is already defined. Only |n|~and
-% |N| arguments can be changed to other types. If the \meta{parent
+% |N| arguments can be changed to other types, and |N|~can only be
+% changed to~|c| while |n|~can only be changed to |V|, |v|, |o|,
+% |f|, or~|x|, so that it is unambiguous what the \meta{parent} of
+% a \meta{variant} is. If the \meta{parent
% control sequence} is protected or if the \meta{variant} involves
% |x|~arguments, then the \meta{variant control sequence} is also
% protected. The \meta{variant} is created globally, as is any
% \cs[no-index]{exp_args:N\meta{variant}} function needed to carry out the
% expansion.
-%
-% While \cs{cs_generate_variant:Nn} |\foo:N { o }| is currently
-% allowed, one must know that it will break if the result of the
-% expansion is more than one token or if |\foo:N| requires its
-% argument not to be braced.
% \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
-% (when speed is important) it is usually
-% best to follow the following guidelines when defining new functions
-% that are supposed to come with variant forms:
+% 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 (\emph{i.e.}, are denoted
% with |x|) should be avoided if possible as they can not be
% processed expandably, \emph{i.e.}, functions of this type
% cannot work correctly in arguments that are themselves subject to |x|
% expansion.
+% \end{itemize}
+% When speed is essential (for functions that do very little work and
+% are used numerous times in a document) the following applies because
+% internal functions for argument expansion come in two flavours, some
+% faster than others.
+% \begin{itemize}
+% \item
+% Arguments that might need expansion should come first in the list of
+% arguments.
+% \item
+% Arguments that should consist of single tokens |N|, |c|, |V|, or
+% |v| should come first among these.
% \item
-% In general, unless in the last position, multi-token arguments
-% |n|, |f|, and |o| need special processing when more than
-% one argument is being expanded. This special processing is not fast.
-% Therefore it is best to use the optimized functions, namely
-% those that contain only |N|, |c|, |V|, and |v|, and, in the last
-% position, |o|, |f|, with possible trailing |N| or |n|, which are
-% not expanded.
+% Arguments that appear after the first multi-token argument |n|, |f|
+% or |o| require slightly slower special processing to be expanded.
+% Therefore it is best to use the optimized functions,
+% namely those that contain only |N|, |c|, |V|, and |v|, and, in the
+% last position, |o|, |f|, with possible trailing |N| or |n| or |T|
+% or |F|, which are not expanded.
% \end{itemize}
%
% The |V| type returns the value of a register, which can be one of
-% |tl|, |int|, |skip|, |dim|, |toks|, or built-in \TeX{}
+% |tl|, |clist|, |int|, |skip|, |dim|, |muskip|, 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.
@@ -228,10 +230,10 @@
% while using |\example:x| instead results in |\example:n { 3 , 7 }|
% at the cost of being protected.
% 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!
+% you should stick to using |TF| type functions only as the expansion
+% does not finish any |\if... \fi:| itself!
%
-% If is important to note that both \texttt{f}- and \texttt{o}-type
+% It is important to note that both \texttt{f}- and \texttt{o}-type
% expansion are concerned with the expansion of tokens from left to
% right in their arguments. In particular, \texttt{o}-type expansion
% applies to the first \emph{token} in the argument it receives: it
@@ -239,7 +241,7 @@
% \begin{verbatim}
% \exp_after:wN <base function> \exp_after:wN { <argument> }
% \end{verbatim}
-% At the same time, \texttt{f}-type expansion stops at the emph{first}
+% At the same time, \texttt{f}-type expansion stops at the \emph{first}
% non-expandable token. This means for example that both
% \begin{verbatim}
% \tl_set:No \l_tmpa_tl { { \g_tmpb_tl } }
@@ -274,8 +276,8 @@
% This function absorbs two arguments (the \meta{function} name and
% the \meta{tokens}). The \meta{tokens} are expanded until only characters
% remain, and are then turned into a control sequence. (An internal error
-% occurs if such a conversion is not possible). The result
-% is inserted into the input stream \emph{after} reinsertion
+% occurs if non-characters remain, as the conversion is not possible.)
+% The result is inserted into the input stream \emph{after} reinsertion
% of the \meta{function}. Thus the \meta{function} may take more than
% one argument: all others are left unchanged.
%
@@ -301,8 +303,8 @@
% This function absorbs two arguments (the \meta{function} name and
% the \meta{tokens}). The \meta{tokens} are expanded until only characters
% remain, and are then turned into a control sequence. (An internal error
-% occurs if such a conversion is not possible). This control sequence
-% should
+% occurs if non-characters remain, as the conversion is not possible.)
+% This control sequence should
% be the name of a \meta{variable}. The content of the \meta{variable} are
% recovered and placed inside braces into the input stream \emph{after}
% reinsertion of the \meta{function}. Thus the \meta{function} may take more
@@ -315,7 +317,8 @@
% \end{syntax}
% This function absorbs two arguments (the \meta{function} name and
% the \meta{tokens}). The \meta{tokens} are fully expanded until the
-% first non-expandable token or space is found, and the result
+% first non-expandable token is found (if that is a space it is
+% removed), and the result
% is inserted in braces into the input stream \emph{after} reinsertion
% of the \meta{function}. Thus the \meta{function} may take more than
% one argument: all others are left unchanged.
@@ -326,8 +329,8 @@
% \cs{exp_args:Nx} \meta{function} \Arg{tokens}
% \end{syntax}
% This function absorbs two arguments (the \meta{function} name and
-% the \meta{tokens}) and exhaustively expands the \meta{tokens}
-% second. The result is inserted in braces into the input stream
+% the \meta{tokens}) and exhaustively expands the \meta{tokens}.
+% The result is inserted in braces into the input stream
% \emph{after} reinsertion of the \meta{function}.
% Thus the \meta{function} may take more
% than one argument: all others are left unchanged.
@@ -375,7 +378,7 @@
% third as detailed by their argument specifier. The first argument
% of the function is then the next item on the input stream, followed
% by the expansion of the second and third arguments.
-% These functions need special (slower) processing.
+% These functions need slower processing.
% \end{function}
%
% \begin{function}
@@ -394,7 +397,7 @@
% third as detailed by their argument specifier. The first argument
% of the function is then the next item on the input stream, followed
% by the expansion of the second and third arguments. These functions
-% are not expandable.
+% are not expandable due to their |x|-type argument.
% \end{function}
%
% \section{Manipulating three arguments}
@@ -432,7 +435,7 @@
% and fourth as detailed by their argument specifier. The first
% argument of the function is then the next item on the input stream,
% followed by the expansion of the second argument, \emph{etc}.
-% These functions need special (slower) processing.
+% These functions need slower processing.
% \end{function}
%
% \begin{function}[added = 2015-08-12]
@@ -481,8 +484,8 @@
% specification, carry out the expansion
% indicated and leave the results in the input stream, with the
% last argument not surrounded by the usual braces.
-% Of these, the \texttt{:Nno}, \texttt{:Noo}, and \texttt{:Nfo}
-% variants need special (slower) processing.
+% Of these, the |:Nno|, |:Noo|, |:Nfo| and |:NnNo|
+% variants need slower processing.
% \begin{texnote}
% As an optimization, the last argument is unbraced by some
% of those functions before expansion. This can cause problems
@@ -496,8 +499,8 @@
% \begin{syntax}
% \cs{exp_last_unbraced:Nx} \meta{function} \Arg{tokens}
% \end{syntax}
-% This functions fully expands the \meta{tokens} and leaves
-% the result in the input stream after reinsertion of \meta{function}.
+% This function fully expands the \meta{tokens} and leaves the result
+% in the input stream after reinsertion of the \meta{function}.
% This function is not expandable.
% \end{function}
%
@@ -505,7 +508,7 @@
% \begin{syntax}
% \cs{exp_last_two_unbraced:Noo} \meta{token} \Arg{tokens_1} \Arg{tokens_2}
% \end{syntax}
-% This function absorbs three arguments and expand the second and third
+% This function absorbs three arguments and expands the second and third
% once. The first argument of the function is then the next item on the
% input stream, followed by the expansion of the second and third arguments,
% which are not wrapped in braces.
@@ -522,9 +525,9 @@
% unchanged. It is important to notice that \meta{token_1} may be
% \emph{any} single token, including group-opening and -closing
% tokens (|{| or |}| assuming normal \TeX{} category codes). Unless
-% specifically required, expansion should be carried out using an
+% specifically required this should be avoided: expansion should be carried out using an
% appropriate argument specifier variant or the appropriate
-% \cs{exp_arg:N} function.
+% \cs[no-index]{exp_arg:N} function.
% \begin{texnote}
% This is the \TeX{} primitive \tn{expandafter} renamed.
% \end{texnote}
@@ -542,10 +545,16 @@
% \begin{syntax}
% \cs{exp_not:N} \meta{token}
% \end{syntax}
-% Prevents expansion of the \meta{token} in a context where it would otherwise
-% be expanded, for example an |x|-type argument.
+% Prevents expansion of the \meta{token} in a context where it would
+% otherwise be expanded, for example an |x|-type argument or the first
+% token in an |o| or |f| argument.
% \begin{texnote}
-% This is the \TeX{} \tn{noexpand} primitive.
+% This is the \TeX{} \tn{noexpand} primitive. It only prevents
+% expansion. At the beginning of an |f|-type argument, a space
+% \meta{token} is removed despite \cs{exp_not:N}. In an
+% |x|-expanding definition (\cs{cs_new:Npx}) a macro parameter
+% \meta{token} (normally~|#|) denotes an argument despite
+% \cs{exp_not:N} (see \cs{exp_not:n}).
% \end{texnote}
% \end{function}
%
@@ -553,20 +562,25 @@
% \begin{syntax}
% \cs{exp_not:c} \Arg{tokens}
% \end{syntax}
-% Expands the \meta{tokens} until only unexpandable content remains, and then
-% converts this into a control sequence. Further expansion of this control
-% sequence is then inhibited.
+% Expands the \meta{tokens} until only characters remain, and then
+% converts this into a control sequence. (An internal error occurs if
+% non-characters remain, as the conversion is not possible.)
+% Further expansion of this control sequence is then inhibited using
+% \cs{exp_not:N}.
% \end{function}
%
% \begin{function}[EXP]{\exp_not:n}
% \begin{syntax}
% \cs{exp_not:n} \Arg{tokens}
% \end{syntax}
-% Prevents expansion of the \meta{tokens} in a context where they
-% would otherwise be expanded, for example an |x|-type argument.
+% Prevents expansion of the \meta{tokens} in an |x|-type argument. In
+% other cases (input stream or |o| or |f| arguments) the \meta{tokens}
+% continue being expanded.
% \begin{texnote}
% This is the \eTeX{} \tn{unexpanded} primitive. Hence its argument
-% \emph{must} be surrounded by braces.
+% \emph{must} be surrounded by braces. In an |x|-expanding
+% definition (\cs{cs_new:Npx}), \cs{exp_not:n}~|{#}| inserts a macro
+% parameter character in the replacement text.
% \end{texnote}
% \end{function}
%
@@ -575,38 +589,38 @@
% \cs{exp_not:V} \meta{variable}
% \end{syntax}
% Recovers the content of the \meta{variable}, then prevents expansion
-% of this material in a context where it would otherwise
-% be expanded, for example an |x|-type argument.
+% of this material in |x|-type arguments using \cs{exp_not:n}.
% \end{function}
%
% \begin{function}[EXP]{\exp_not:v}
% \begin{syntax}
% \cs{exp_not:v} \Arg{tokens}
% \end{syntax}
-% Expands the \meta{tokens} until only unexpandable content remains, and then
-% converts this into a control sequence (which should be a \meta{variable}
-% name). The content of the \meta{variable} is recovered, and further
-% expansion is prevented in a context where it would otherwise
-% be expanded, for example an |x|-type argument.
+% Expands the \meta{tokens} until only characters remains, and then
+% converts this into a control sequence which should be a \meta{variable}
+% name. (An internal error occurs if
+% non-characters remain, as the conversion is not possible.)
+% The content of the \meta{variable} is recovered, and further
+% expansion in |x|-type arguments is prevented using \cs{exp_not:n}.
% \end{function}
%
% \begin{function}[EXP]{\exp_not:o}
% \begin{syntax}
% \cs{exp_not:o} \Arg{tokens}
% \end{syntax}
-% Expands the \meta{tokens} once, then prevents any further expansion in a
-% context where they would otherwise
-% be expanded, for example an |x|-type argument.
+% Expands the \meta{tokens} once, then prevents any further expansion
+% in |x|-type arguments using \cs{exp_not:n}.
% \end{function}
%
% \begin{function}[EXP]{\exp_not:f}
% \begin{syntax}
% \cs{exp_not:f} \Arg{tokens}
% \end{syntax}
-% Expands \meta{tokens} fully until the first unexpandable token
-% is found. Expansion then stops, and the result of the expansion
-% (including any tokens which were not expanded) is protected from
-% further expansion.
+% Expands \meta{tokens} fully until the first unexpandable token is
+% found (if it is a space it is removed). Expansion then stops, and
+% the result of the expansion (including any tokens which were not
+% expanded) is protected from further expansion in |x|-type arguments
+% using \cs{exp_not:n}.
% \end{function}
%
% \begin{function}[updated = 2011-06-03, EXP]{\exp_stop_f:}
@@ -710,7 +724,7 @@
% in |#2|. For technical reasons this has to happen using two tokens
% (if they would be hidden inside another command \cs{exp_after:wN}
% would only expand the command but not trigger any additional
-% f-expansion).
+% |f|-expansion).
%
% You might wonder why there are two different approaches available,
% after all the effect of
@@ -740,18 +754,18 @@
% \cs{exp:w} \meta{expandable-tokens} \cs{exp_end_continue_f:nw} \meta{further-tokens}
% \end{syntax}
% The difference to \cs{exp_end_continue_f:w} is that we first we pick
-% up an argument which is then returned to the input stream. If
-% \meta{further-tokens} starts with a brace group then the braces
-% are removed. If on the other hand it starts with space tokens then
-% these space tokens are removed while searching for the
-% argument. Thus such space tokens will not terminate the \texttt{f}-type expansion.
+% up an argument which is then returned to the input stream. If
+% \meta{further-tokens} starts with space tokens then these space
+% tokens are removed while searching for the argument. If it starts
+% with a brace group then the braces are removed. Thus such spaces or
+% braces will not terminate the \texttt{f}-type expansion.
% \end{function}
%
% \section{Internal functions and variables}
%
% \begin{variable}{\l__exp_internal_tl}
-% The |\exp_| module has its private variables to temporarily store
-% results of the argument expansion. This is done to avoid interference
+% The |\exp_| module has its private variable to temporarily store the
+% result of |x|-type argument expansion. This is done to avoid interference
% with other functions using temporary variables.
% \end{variable}
%
@@ -781,15 +795,16 @@
% \begin{macro}{\exp_after:wN}
% \begin{macro}{\exp_not:N}
% \begin{macro}{\exp_not:n}
-% These are defined in \pkg{l3basics}.
+% These are defined in \pkg{l3basics}, as they are needed
+% \enquote{early}. This is just a reminder of that fact!
% \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
+% In this section a general mechanism for defining functions that handle
+% arguments 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 \cs{cs_set:Npx} at some
% point, and so is never going to be expandable.)
@@ -800,15 +815,12 @@
% method for efficiency, typically using calls to \cs{exp_after:wN}.
%
% \begin{variable}{\l_@@_internal_tl}
-% This scratch token list variable is defined in \pkg{l3basics}, as it
-% is needed \enquote{early}. This is just a reminder that is the
-% case!
+% This scratch token list variable is defined in \pkg{l3basics}.
% \end{variable}
%
-% This code uses internal functions with names that start with |\::|
-% 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.
+% This code uses internal functions with names that start with |\::| to
+% perform the expansions. All macros are |long| since the tokens
+% undergoing expansion may be arbitrary user input.
%
% An argument manipulator |\::|\meta{Z} always has signature |#1\:::#2#3|
% where |#1| holds the remaining argument manipulations to be performed,
@@ -861,7 +873,7 @@
%
% \begin{macro}[int, EXP]{\::p}
% This function is used to skip an argument that is delimited by a
-% left brace and doesn't need to be expanded. It should not be
+% left brace and doesn't need to be expanded. It is not
% wrapped in braces in the result.
% \begin{macrocode}
\cs_new:Npn \::p #1 \::: #2#3# { #1 \::: {#2#3} }
@@ -889,19 +901,18 @@
% \begin{macro}{\exp_stop_f:}
% This function is used to expand a token list until the first
% unexpandable token is found. This is achieved through \cs{exp:w}
-% \cs{exp_end_continue_f:w} that
-% expands everything in its way following it. This
-% scanning procedure is terminated once the expansion hits
-% something non-expandable or a space. We introduce \cs{exp_stop_f:}
-% to mark such an end of expansion marker.
-% In the example shown earlier the scanning was stopped
-% once \TeX{} had fully expanded |\cs_set_eq:Nc \aaa { b \l_tmpa_tl b }|
-% into |\cs_set_eq:NN \aaa = \blurb| which then turned out to contain
-% the non-expandable token \cs{cs_set_eq:NN}. Since the expansion of
-% \cs{exp:w} \cs{exp_end_continue_f:w} is \meta{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.
+% \cs{exp_end_continue_f:w} that expands everything in its way
+% following it. This scanning procedure is terminated once the
+% expansion hits something non-expandable (if that is a space it is
+% removed). We introduce \cs{exp_stop_f:} to mark such an
+% end-of-expansion marker. For example, |f|-expanding
+% |\cs_set_eq:Nc \aaa { b \l_tmpa_tl b }| where |\l_tmpa_tl| contains
+% the characters |lur| gives |\tex_let:D \aaa = \blurb| which then
+% turns out to start with the non-expandable token |\tex_let:D|.
+% Since the expansion of \cs{exp:w} \cs{exp_end_continue_f:w} is
+% empty, 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}
\cs_new:Npn \::f #1 \::: #2#3
{
@@ -928,7 +939,8 @@
% \begin{macro}[int, EXP]{\::v}
% \begin{macro}[int, EXP]{\::V}
% These functions return the value of a register, i.e., one of
-% |tl|, |clist|, |int|, |skip|, |dim| and |muskip|. The |V| version
+% |tl|, |clist|, |int|, |skip|, |dim|, |muskip|, or built-in
+% \TeX{} register. 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 \cs{exp:w} sets off an expansion
@@ -951,7 +963,7 @@
% \end{macro}
% \end{macro}
%
-% \begin{macro}[int, EXP]{\@@_eval_register:N, \@@_eval_register:c}
+% \begin{macro}[aux, EXP]{\@@_eval_register:N, \@@_eval_register:c}
% \begin{macro}[aux, 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{}
@@ -1027,8 +1039,7 @@
% \label{sec:l3expan:handtune}
%
% One of the most important features of these functions is that they
-% are fully expandable and therefore allow to prefix them with
-% \cs{tex_global:D} for example.
+% are fully expandable.
%
% \begin{macro}[EXP]{\exp_args:No}
% \begin{macro}[EXP]{\exp_args:NNo}
@@ -1178,7 +1189,7 @@
%
% Some of these could be done more efficiently, but the complexity of
% coding then becomes an issue. Notice that the auto-generated functions
-% are all not long: they don't actually take any arguments themselves.
+% actually take no arguments themselves.
%
% \begin{macro}{\exp_args:Nx}
% \begin{macrocode}
@@ -1513,7 +1524,7 @@
% four cases: the parent function can be a primitive or a macro, and
% can be expandable or not. For non-expandable primitives, all
% variants should be protected; skipping the \cs{else:} branch is safe
-% because all primitive \TeX{} conditionals are expandable.
+% because non-expandable primitives cannot be \TeX{} conditionals.
%
% The other case where variants should be protected is when the parent
% function is a protected macro: then |protected| appears in the
@@ -1781,7 +1792,8 @@
% When the base and variant letters are identical, don't do any
% expansion. For most argument types, we can use the |n|-type
% no-expansion, but the |N| and |p| types require a slightly different
-% behaviour with respect to braces.
+% behaviour with respect to braces. For |V|-type this function could
+% output |N| to avoid adding useless braces but that is not a problem.
% \begin{macrocode}
\cs_new:Npn \@@_generate_variant_same:N #1
{
More information about the latex3-commits
mailing list