[latex3-commits] [git/LaTeX3-latex3-latex2e] gh569: Move code a couple of sections below (82907a05)
PhelypeOleinik
phelype.oleinik at latex-project.org
Mon Aug 9 04:46:03 CEST 2021
Repository : https://github.com/latex3/latex2e
On branch : gh569
Link : https://github.com/latex3/latex2e/commit/82907a05b776758cfa02207d9f428661ac2edfda
>---------------------------------------------------------------
commit 82907a05b776758cfa02207d9f428661ac2edfda
Author: PhelypeOleinik <phelype.oleinik at latex-project.org>
Date: Sun Aug 8 23:46:03 2021 -0300
Move code a couple of sections below
>---------------------------------------------------------------
82907a05b776758cfa02207d9f428661ac2edfda
base/ltcmd.dtx | 1038 ++++++++++++++++++++++++++++----------------------------
1 file changed, 519 insertions(+), 519 deletions(-)
diff --git a/base/ltcmd.dtx b/base/ltcmd.dtx
index cdec69ee..c3c04378 100644
--- a/base/ltcmd.dtx
+++ b/base/ltcmd.dtx
@@ -856,282 +856,6 @@
% \end{macro}
% \end{macro}
%
-% \subsubsection{Copying a command and its internal structure}
-%
-%<latexrelease>\IncludeInRelease{2021/11/15}{\@@_copy:NN}%
-%<latexrelease> {Support \NewCommandCopy and \ShowCommand in ltcmd}
-% Since the 2020-10-01 \LaTeXe{} release, support for copying and
-% showing the definition of robust commands is available, but the
-% specifics of each command is implemented separately. Here we'll add
-% support for copying and showing \pkg{ltcmd} definitions.
-%
-% To fully support copying, we need two commands: a conditional to test
-% if a command is in fact an \pkg{ltcmd} command, and another to
-% actually copy the command. The conditional is defined later as
-% \cs{__kernel_cmd_if_xparse:NTF}, so now to the copying:
-%
-% \begin{macro}{\@@_copy:NN}
-% \begin{macro}{\@@_set_eq_if_exist:NN,\@@_set_eq_if_exist:cc}
-% This macro just branches to the proper copying command by using
-% \cs{@@_cmd_type_cases:NnnnF}. The copying command takes the names
-% of the commands to be copied to and from, and the actual commands
-% as its four arguments.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_copy:NN #1 #2
- {
- \use:x
- {
- \int_set:Nn \tex_escapechar:D { 92 }
- \exp_not:N \@@_cmd_type_cases:NnnnF \exp_not:N #2
- { \@@_copy_command:nnNN }
- { \@@_copy_expandable:nnNN }
- { \@@_copy_environment:nnNN }
- { \@@_cant_copy:nwn { non-ltcmd } }
- { \cs_to_str:N #1 } { \cs_to_str:N #2 }
- \exp_not:N #1 \exp_not:N #2
- \exp_not:N \@@_break_point:n { \cs_to_str:N #2 }
- \int_set:Nn \tex_escapechar:D { \int_use:N \tex_escapechar:D }
- }
- }
-\cs_new_protected:Npn \@@_set_eq_if_exist:NN #1 #2
- { \cs_if_exist:NTF #2 { \cs_set_eq:NN } { \use_none:nn } #1 #2 }
-\cs_generate_variant:Nn \@@_set_eq_if_exist:NN { cc }
-% \end{macrocode}
-%
-% \begin{macro}{\@@_cant_copy:nwn}
-% An utility macro similar to \cs{@@_bad_def:wn} to abort a command
-% copy. Contrary to \cs{@@_bad_def:wn} though, when this happens the
-% issue is most likely internal, because the command was already
-% (supposedly) correcly defined so it should be copyable. Hopefully
-% this macro will never be used ever, but if it does, apologise and
-% give the reason for the failure so the user can report.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_cant_copy:nwn #1 #2 \@@_break_point:n #3
- { \msg_error:nnnn { cmd } { copy-bug } {#1} {#3} }
-\msg_new:nnn { cmd } { copy-bug }
- {
- Internal~error~while~copying~command~\iow_char:N\\#2:\\
- \str_case:nn {#1}
- {
- { non-ltcmd } { Command~is~not~a~valid~ltcmd~command. }
- { unknown-type } { Found~an~unknown~argument~type. }
- }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% And, of course, add \cs{__kernel_cmd_if_xparse:NTF} and
-% \cs{@@_copy:NN} to \cs{@declarecommandcopylisthook}:
-% \begin{macrocode}
-\tl_gput_right:Nn \@declarecommandcopylisthook
- { { \__kernel_cmd_if_xparse:NTF \@@_copy:NN } }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_copy_command:nnNN,\@@_copy_command:NnNNnnnn}
-% A normal (non-expandable) command has a pretty straightforward
-% structure. Its definition is stored in
-% \cs{\meta{cmd}\textvisiblespace code}, its defaults (if any) are
-% stored in \cs{\meta{cmd}\textvisiblespace defaults}, and its
-% top-level definition contains its signature, which can just be
-% copied over. \cs{@@_copy_command:nnNN} copies the command code and
-% defaults, and then defines the top-level command using the auxiliary
-% \cs{@@_copy_command:NnNNnnnn}. This macro takes the signature of
-% the command being copied from its top-level definition, and replaces
-% the named bits with the new name.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_copy_command:nnNN #1 #2 #3 #4
- {
- \cs_set_eq:cc { #1 ~ code } { #2 ~ code }
- \@@_set_eq_if_exist:cc { #1 ~ defaults } { #2 ~ defaults }
- \cs_set_protected_nopar:Npx #3
- { \exp_after:wN \@@_copy_command:NnNNnnnn #4 {#1} }
- }
-\cs_new:Npn \@@_copy_command:NnNNnnnn #1 #2 #3 #4 #5 #6 #7 #8
- {
- #1 \exp_not:n { {#2} }
- \exp_not:c { #8 ~ } \exp_not:c { #8 ~ code }
- \exp_not:n { {#5} {#6} {#7} }
- }
-% \end{macrocode}
-% \end{macro}
-%
-% \begin{macro}{\@@_copy_expandable:nnNN,\@@_copy_expandable:NnNNNNnnn}
-% An expandable command is slightly more complicated. Besides the
-% \cs{\meta{cmd}\textvisiblespace code}, and
-% \cs{\meta{cmd}\textvisiblespace defaults}, it also has an auxiliary
-% \cs{\meta{cmd}\textvisiblespace} for grabbing delimited arguments,
-% and possibly another auxiliary
-% \cs{\meta{cmd}\textvisiblespace\textvisiblespace}, if the command
-% has both long and short arguments. Then, its signature has also
-% several specific bits that are unique to that command, contrary to
-% non-expandable commands which use a common set of parsing functions.
-%
-% We'll start by copying the basics, then call
-% \cs{@@_copy_expandable_signature:NnNNNNnnn} to parse the signature
-% of the command and make the modified copy in a temporary token list,
-% then we call \cs{@@_copy_expandable:NnNNNNnnn} that will copy the
-% top-level definition of the command, with the proper internal
-% renames.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_copy_expandable:nnNN #1 #2 #3 #4
- {
- \cs_set_eq:cc { #1 ~ code } { #2 ~ code }
- \@@_set_eq_if_exist:cc { #1 ~ } { #2 ~ }
- \@@_set_eq_if_exist:cc { #1 ~ \c_space_tl } { #2 ~ \c_space_tl }
- \@@_set_eq_if_exist:cc { #1 ~ defaults } { #2 ~ defaults }
- \exp_after:wN \@@_copy_expandable_signature:NnNNNNnnn #4 {#1} {#2}
- \cs_set_nopar:Npx #3
- { \exp_after:wN \@@_copy_expandable:NnNNNNnnn #4 {#1} {#2} }
- }
-\cs_new:Npn \@@_copy_expandable:NnNNNNnnn #1 #2 #3 #4 #5 #6 #7 #8 #9
- {
- \exp_not:N #1 \exp_not:n { {#2} }
- \exp_not:c { #8 ~ }
- \exp_not:c
- {
- #8 ~
- \str_if_eq:eeT
- { \exp_not:c { #9 ~ \c_space_tl } } { \exp_not:N #4 }
- { \c_space_tl }
- }
- \exp_not:c { #8 ~ code }
- \str_if_eq:eeTF { \exp_not:N #6 } { ? }
- { ? }
- { \exp_not:c { #8 ~ defaults } }
- { \exp_not:V \l_@@_tmpa_tl }
- }
-% \end{macrocode}
-%
-% \begin{macro}{
-% \@@_copy_expandable_signature:NnNNNNnnn,
-% \@@_copy_expandable:nnN,
-% \@@_copy_parse_grabber:w,
-% }
-% A signature for an expandable command contains as many
-% \cs{expandable_grab_\meta{type}:w} as there are arguments, and what
-% follows this macro depends on the \meta{type}. We'll start a loop
-% through the signature, and at each argument grabber, we'll step the
-% argument count, and look for the \meta{type} with
-% \cs{@@_copy_parse_grabber:w} so we know which
-% \cs{@@_copy_grabber_\meta{type}:w} to call next.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_copy_expandable_signature:NnNNNNnnn
- #1 #2 #3 #4 #5 #6 #7 #8 #9
- {
- \int_zero:N \l_@@_current_arg_int
- \tl_clear:N \l_@@_tmpa_tl
- \@@_copy_expandable:nnN {#8} {#9} #7
- \q_recursion_tail \q_recursion_stop
- }
-\cs_new_protected:Npn \@@_copy_expandable:nnN #1 #2 #3
- {
- \quark_if_recursion_tail_stop:n {#3}
- \int_incr:N \l_@@_current_arg_int
- \exp_after:wN \@@_copy_parse_grabber:w \token_to_str:N #3 {#1} {#2}
- }
-\use:x
- {
- \cs_new_protected:Npn \exp_not:N \@@_copy_parse_grabber:w ##1
- \tl_to_str:n { expandable_grab_ } ##2 \tl_to_str:n { :w }
- {
- \tl_put_right:Nx \exp_not:N \l_@@_tmpa_tl
- { \exp_not:N \exp_not:c { @@_expandable_grab_##2:w } }
- \exp_not:N \cs_if_exist_use:cF { @@_copy_grabber_##2:w }
- { \@@_cant_copy:nwn { unknown-type } }
- }
- }
-% \end{macrocode}
-%
-% \begin{macro}{
-% \@@_copy_grabber_D:w,\@@_copy_grabber_D_alt:w,
-% \@@_copy_grabber_R:w,\@@_copy_grabber_R_alt:w,
-% \@@_copy_grabber_E:w,\@@_copy_grabber_E_long:w,
-% \@@_copy_grabber_t:w,
-% \@@_copy_grabber_m:w,\@@_copy_grabber_m_long:w,
-% }
-% The most complicated is the |D|elimited argument: each argument has
-% a dedicated grabbing function named after the command that has to be
-% copied over (of the form
-% \cs{\meta{cmd}\textvisiblespace(arg\textvisiblespace\meta{num})}).
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_copy_grabber_D:w #1 #2 #3 #4 #5
- {
- \tl_put_right:Nx \l_@@_tmpa_tl
- {
- \exp_not:c { #1 ~ (arg ~ \int_use:N \l_@@_current_arg_int ) }
- \exp_not:n { #4 #5 }
- }
- \cs_set_eq:cc
- { #1 ~ (arg ~ \int_use:N \l_@@_current_arg_int ) }
- { #2 ~ (arg ~ \int_use:N \l_@@_current_arg_int ) }
- \@@_copy_expandable:nnN {#1} {#2}
- }
-% \end{macrocode}
-%
-% |D_alt| is just a special case of |D| that uses a single delimiter
-% (used when both delimiters of the argument are identical):
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_copy_grabber_D_alt:w #1 #2 #3 #4
- { \@@_copy_grabber_D:w {#1} {#2} {#3} {#4} { } }
-% \end{macrocode}
-%
-% |R|, as far as copying is concerned, is identical to |D|:
-% \begin{macrocode}
-\cs_new_eq:NN \@@_copy_grabber_R:w \@@_copy_grabber_D:w
-\cs_new_eq:NN \@@_copy_grabber_R_alt:w \@@_copy_grabber_D_alt:w
-% \end{macrocode}
-%
-% |E| is straightforward: we just copy the embellishments over, and
-% increase the current argument number \cs{l_@@_current_arg_int} by
-% the number of embellishments (minus one because there is a
-% \cs{int_incr:N} down the line).
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_copy_grabber_E:w #1 #2 #3 #4
- {
- \tl_put_right:Nn \l_@@_tmpa_tl { {#3} {#4} }
- \int_add:Nn \l_@@_current_arg_int { \tl_count:n {#4} - 1 }
- \@@_copy_expandable:nnN {#1} {#2}
- }
-\cs_new_eq:NN \@@_copy_grabber_E_long:w \@@_copy_grabber_E:w
-% \end{macrocode}
-%
-% |t| just needs copying the token to be tested for:
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_copy_grabber_t:w #1 #2 #3 #4
- {
- \tl_put_right:Nn \l_@@_tmpa_tl { #3 #4 }
- \@@_copy_expandable:nnN {#1} {#2}
- }
-% \end{macrocode}
-%
-% And last but not least, |m| is the simplest; the grabber is just
-% \cs{@@_expandable_grab_m:w}, which is already added to the new
-% command so here we just resume the loop:
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_copy_grabber_m:w { \@@_copy_expandable:nnN }
-\cs_new_eq:NN \@@_copy_grabber_m_long:w \@@_copy_grabber_m:w
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_copy_environment:nnNN}
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_copy_environment:nnNN #1 #2 #3 #4
- { \msg_error:nn { cmd } { env-copy } }
-\msg_new:nnn { cmd } { env-copy }
- { Copying~environments~is~not~possible. }
-% \end{macrocode}
-%
-%<latexrelease>\EndIncludeInRelease
-%
-%<latexrelease>\IncludeInRelease{0000/00/00}{\@@_copy:NN}%
-%<latexrelease> {Support \NewCommandCopy and \ShowCommand in ltcmd}
-%
-%<latexrelease>\EndIncludeInRelease
-%
% \subsection{Normalizing the argument specifications}
%
% The goal here is to expand aliases and check that the argument
@@ -1878,336 +1602,612 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\@@_add_type_t:w}
-% Setting up a \texttt{t} argument means collecting one token for the test,
-% and adding it along with the grabber to the signature.
+% \begin{macro}{\@@_add_type_t:w}
+% Setting up a \texttt{t} argument means collecting one token for the test,
+% and adding it along with the grabber to the signature.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_add_type_t:w #1
+ {
+ \@@_flush_m_args:
+ \@@_add_default:
+ \@@_add_grabber:N t
+ \tl_put_right:Nn \l_@@_signature_tl {#1}
+ \@@_prepare_signature:N
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_type_v:w}
+% At this stage, the \texttt{v} argument is identical to \texttt{l}
+% except that since the grabber may fail to read a verbatim argument
+% we need a default value.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_add_type_v:w
+ {
+ \@@_flush_m_args:
+ \exp_args:No \@@_add_default:n \c_novalue_tl
+ \@@_add_grabber:N v
+ \@@_prepare_signature:N
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_flush_m_args:}
+% As \texttt{m} arguments are simply counted, there is a need to add
+% them to the token register in a block. As this function can only
+% be called if something other than \texttt{m} turns up, the flag can
+% be switched here.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_flush_m_args:
+ {
+ \int_compare:nNnT \l_@@_m_args_int > 0
+ {
+ \tl_put_right:Nx \l_@@_signature_tl
+ { \exp_not:c { @@_grab_m_ \int_use:N \l_@@_m_args_int :w } }
+ \tl_put_right:Nx \l_@@_process_all_tl
+ { \prg_replicate:nn { \l_@@_m_args_int } { { } } }
+ }
+ \int_zero:N \l_@@_m_args_int
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_grabber:N}
+% To keep the various checks needed in one place, adding the grabber
+% to the signature is done here. The only questions are whether the
+% grabber should be long or not, and whether to obey spaces. The
+% \cs{l_@@_obey_spaces_bool} boolean can only be \texttt{true} for
+% trailing optional arguments. In that case spaces will not be
+% ignored when looking for that optional argument.
+% \changes{v1.0g}{2021/08/07}
+% {Replicate argument processors for all embellishments (gh/639)}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_add_grabber:N #1
+ {
+ \tl_put_right:Nx \l_@@_signature_tl
+ {
+ \exp_not:c
+ {
+ @@_grab_ #1
+ \bool_if:NT \l_@@_long_bool { _long }
+ \bool_if:NT \l_@@_obey_spaces_bool { _obey_spaces }
+ :w
+ }
+ }
+ \bool_set_false:N \l_@@_long_bool
+ \bool_set_false:N \l_@@_obey_spaces_bool
+ \tl_put_right:Nx \l_@@_process_all_tl
+ {
+ {
+ \if_charcode:w E #1 \use_i:nn \fi:
+ \exp_not:o \l_@@_process_one_tl
+ }
+ }
+ \tl_clear:N \l_@@_process_one_tl
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_default:n, \@@_add_default:, \@@_add_default_E:nn}
+% Store the default value of an argument, or rather code that gives
+% that default value (it may involve other arguments). This is
+% \cs{c_novalue_tl} for arguments with no actual default or with
+% default |-NoValue-|; and (in a brace group) \cs{prg_do_nothing:}
+% followed by a default value for others. For \texttt{E}-type
+% arguments, pad the defaults |#2| with some \cs{c_novalue_tl}
+% until there are as many as embellishments~|#1|. These functions are
+% also used when defining expandable commands.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_add_default:n #1
+ {
+ \tl_if_novalue:nTF {#1}
+ { \@@_add_default: }
+ {
+ \int_incr:N \l_@@_current_arg_int
+ \bool_set_true:N \l_@@_defaults_bool
+ \tl_put_right:Nn \l_@@_defaults_tl { { \prg_do_nothing: #1 } }
+ }
+ }
+\cs_new_protected:Npn \@@_add_default:
+ {
+ \int_incr:N \l_@@_current_arg_int
+ \tl_put_right:Nn \l_@@_defaults_tl { \c_novalue_tl }
+ }
+\cs_new_protected:Npn \@@_add_default_E:nn #1#2
+ {
+ \tl_map_function:nN {#2} \@@_add_default:n
+ \prg_replicate:nn
+ { \tl_count:n {#1} - \tl_count:n {#2} }
+ { \@@_add_default: }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Setting up expandable types}
+%
+% The approach here is not dissimilar to that for standard types, but fewer types
+% are supported. There is
+% also a need to define the per-function auxiliaries: this is done here, while
+% the general grabbers are dealt with later.
+%
+% \begin{macro}{\@@_add_expandable_type_+:w}
+% We have already checked that short arguments are before long
+% arguments, so \cs{l_@@_long_bool} only changes from \texttt{false}
+% to \texttt{true} once (and there is no need to reset it after each
+% argument). Continue the loop.
+% \begin{macrocode}
+\cs_new_protected:cpn { @@_add_expandable_type_+:w }
+ {
+ \bool_set_true:N \l_@@_long_bool
+ \@@_prepare_signature:N
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_expandable_type_D:w}
+% \begin{macro}{\@@_add_expandable_type_D_aux:NNNn}
+% \begin{macro}{\@@_add_expandable_type_D_aux:NNN}
+% \begin{macro}{\@@_add_expandable_type_D_aux:NN}
+% The set up for \texttt{D}-type arguments involves constructing a
+% rather complex auxiliary which is used
+% repeatedly when grabbing. There is an auxiliary here so that the
+% \texttt{R}-type can share code readily: |#1| is |D| or~|R|.
+% The |_aux:NN| auxiliary is needed if the two delimiting tokens are
+% identical: in contrast to the non-expandable route, the grabber here
+% has to act differently for this case.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_add_expandable_type_D:w
+ { \@@_add_expandable_type_D_aux:NNNn D }
+\cs_new_protected:Npn \@@_add_expandable_type_D_aux:NNNn #1#2#3#4
+ {
+ \@@_add_default:n {#4}
+ \tl_if_eq:nnTF {#2} {#3}
+ { \@@_add_expandable_type_D_aux:NN #1 #2 }
+ { \@@_add_expandable_type_D_aux:NNN #1 #2 #3 }
+ \@@_prepare_signature:N
+ }
+\cs_new_protected:Npn \@@_add_expandable_type_D_aux:NNN #1#2#3
+ {
+ \bool_if:NTF \l_@@_long_bool
+ { \cs_set:cpx }
+ { \cs_set_nopar:cpx }
+ { \l_@@_expandable_aux_name_tl } ##1 ##2 #2 ##3 \q_@@ ##4 #3
+ { ##1 {##2} {##3} {##4} }
+ \@@_add_expandable_grabber:nn {#1}
+ {
+ \exp_not:c { \l_@@_expandable_aux_name_tl }
+ \exp_not:n { #2 #3 }
+ }
+ }
+\cs_new_protected:Npn \@@_add_expandable_type_D_aux:NN #1#2
+ {
+ \bool_if:NTF \l_@@_long_bool
+ { \cs_set:cpx }
+ { \cs_set_nopar:cpx }
+ { \l_@@_expandable_aux_name_tl } ##1 #2 ##2 #2
+ { ##1 {##2} }
+ \@@_add_expandable_grabber:nn { #1_alt }
+ {
+ \exp_not:c { \l_@@_expandable_aux_name_tl }
+ \exp_not:n {#2}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_expandable_type_E:w}
+% \begin{macro}{\@@_add_expandable_type_E_aux:n}
+% For each embellishment, use \cs{@@_get_grabber:NN} to obtain an
+% auxiliary delimited by that token and store a pair constituted of
+% the auxiliary and the token in \cs{l_@@_tmpb_tl}, before appending
+% the whole set of these pairs to the signature, and an equal number
+% of |-NoValue-| markers (regardless of the default values of
+% arguments). Set the current argument appropriately.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_add_expandable_type_E:w #1#2
+ {
+ \@@_add_default_E:nn {#1} {#2}
+ \tl_clear:N \l_@@_tmpb_tl
+ \tl_map_function:nN {#1} \@@_add_expandable_type_E_aux:n
+ \@@_add_expandable_grabber:nn
+ { E \bool_if:NT \l_@@_long_bool { _long } }
+ {
+ { \exp_not:o \l_@@_tmpb_tl }
+ {
+ \prg_replicate:nn { \tl_count:n {#1} }
+ { { \c_novalue_tl } }
+ }
+ }
+ \@@_prepare_signature:N
+ }
+\cs_new_protected:Npn \@@_add_expandable_type_E_aux:n #1
+ {
+ \@@_get_grabber:NN #1 \l_@@_tmpa_tl
+ \tl_put_right:Nx \l_@@_tmpb_tl
+ { \exp_not:o \l_@@_tmpa_tl \exp_not:N #1 }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_expandable_type_m:w}
+% Unlike the standard case, when working expandably each argument is always
+% grabbed separately.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_add_expandable_type_m:w
+ {
+ \@@_add_default:
+ \@@_add_expandable_grabber:nn
+ { m \bool_if:NT \l_@@_long_bool { _long } } { }
+ \@@_prepare_signature:N
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_expandable_type_R:w}
+% The \texttt{R}-type is very similar to the \texttt{D}-type
+% argument, and so the same internals are used.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_add_expandable_type_R:w
+ { \@@_add_expandable_type_D_aux:NNNn R }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@@_add_expandable_type_t:w}
+% An auxiliary delimited by |#1| is built now. It will be used to
+% test for the presence of that token.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_add_type_t:w #1
+\cs_new_protected:Npn \@@_add_expandable_type_t:w #1
{
- \@@_flush_m_args:
\@@_add_default:
- \@@_add_grabber:N t
- \tl_put_right:Nn \l_@@_signature_tl {#1}
+ \@@_get_grabber:NN #1 \l_@@_tmpa_tl
+ \@@_add_expandable_grabber:nn { t }
+ {
+ \exp_not:o \l_@@_tmpa_tl
+ \exp_not:N #1
+ }
\@@_prepare_signature:N
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\@@_add_type_v:w}
-% At this stage, the \texttt{v} argument is identical to \texttt{l}
-% except that since the grabber may fail to read a verbatim argument
-% we need a default value.
+% \begin{macro}{\@@_add_expandable_grabber:nn}
+% This is called for all arguments to place the right grabber in the
+% signature.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_add_type_v:w
+\cs_new_protected:Npn \@@_add_expandable_grabber:nn #1#2
{
- \@@_flush_m_args:
- \exp_args:No \@@_add_default:n \c_novalue_tl
- \@@_add_grabber:N v
- \@@_prepare_signature:N
+ \tl_put_right:Nx \l_@@_signature_tl
+ { \exp_not:c { @@_expandable_grab_ #1 :w } #2 }
}
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\@@_flush_m_args:}
-% As \texttt{m} arguments are simply counted, there is a need to add
-% them to the token register in a block. As this function can only
-% be called if something other than \texttt{m} turns up, the flag can
-% be switched here.
+% \begin{macro}{\@@_get_grabber:NN}
+% \begin{macro}{\@@_get_grabber_auxi:NN}
+% \begin{macro}{\@@_get_grabber_auxii:NN}
+% Given a token |#1|, defines an expandable function delimited by that
+% token and stores it in the token list~|#2|. The function is named
+% after the token, unless that function name is already taken by some
+% other grabber (this can happen in the rare case where delimiters
+% with different category codes are used in the same document): in
+% that case use a global counter to get a unique name. Since the
+% grabbers are not named after \pkg{xparse} commands they should not
+% be used to get material from the input stream.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_flush_m_args:
+\cs_new_protected:Npn \@@_get_grabber:NN #1#2
{
- \int_compare:nNnT \l_@@_m_args_int > 0
+ \cs_set:Npn \@@_tmp:w ##1 #1 {##1}
+ \exp_args:Nc \@@_get_grabber_auxi:NN
+ { @@_grabber_ \token_to_str:N #1 :w } #2
+ }
+\cs_new_protected:Npn \@@_get_grabber_auxi:NN #1#2
+ {
+ \cs_if_eq:NNTF \@@_tmp:w #1
+ { \tl_set:Nn #2 {#1} }
{
- \tl_put_right:Nx \l_@@_signature_tl
- { \exp_not:c { @@_grab_m_ \int_use:N \l_@@_m_args_int :w } }
- \tl_put_right:Nx \l_@@_process_all_tl
- { \prg_replicate:nn { \l_@@_m_args_int } { { } } }
+ \cs_if_exist:NTF #1
+ {
+ \int_gincr:N \g_@@_grabber_int
+ \exp_args:Nc \@@_get_grabber_auxi:NN
+ {
+ @@_grabber_
+ - \int_use:N \g_@@_grabber_int :w
+ }
+ #2
+ }
+ { \@@_get_grabber_auxii:NN #1 #2 }
}
- \int_zero:N \l_@@_m_args_int
+ }
+\cs_new_protected:Npn \@@_get_grabber_auxii:NN #1#2
+ {
+ \cs_set_eq:NN #1 \@@_tmp:w
+ \tl_set:Nn #2 {#1}
}
% \end{macrocode}
% \end{macro}
+% \end{macro}
+% \end{macro}
%
-% \begin{macro}{\@@_add_grabber:N}
-% To keep the various checks needed in one place, adding the grabber
-% to the signature is done here. The only questions are whether the
-% grabber should be long or not, and whether to obey spaces. The
-% \cs{l_@@_obey_spaces_bool} boolean can only be \texttt{true} for
-% trailing optional arguments. In that case spaces will not be
-% ignored when looking for that optional argument.
-% \changes{v1.0g}{2021/08/07}
-% {Replicate argument processors for all embellishments (gh/639)}
+% \subsubsection{Copying a command and its internal structure}
+%
+%<latexrelease>\IncludeInRelease{2021/11/15}{\@@_copy:NN}%
+%<latexrelease> {Support \NewCommandCopy and \ShowCommand in ltcmd}
+% Since the 2020-10-01 \LaTeXe{} release, support for copying and
+% showing the definition of robust commands is available, but the
+% specifics of each command is implemented separately. Here we'll add
+% support for copying and showing \pkg{ltcmd} definitions.
+%
+% To fully support copying, we need two commands: a conditional to test
+% if a command is in fact an \pkg{ltcmd} command, and another to
+% actually copy the command. The conditional is defined later as
+% \cs{__kernel_cmd_if_xparse:NTF}, so now to the copying:
+%
+% \begin{macro}{\@@_copy:NN}
+% \begin{macro}{\@@_set_eq_if_exist:NN,\@@_set_eq_if_exist:cc}
+% This macro just branches to the proper copying command by using
+% \cs{@@_cmd_type_cases:NnnnF}. The copying command takes the names
+% of the commands to be copied to and from, and the actual commands
+% as its four arguments.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_add_grabber:N #1
+\cs_new_protected:Npn \@@_copy:NN #1 #2
{
- \tl_put_right:Nx \l_@@_signature_tl
- {
- \exp_not:c
- {
- @@_grab_ #1
- \bool_if:NT \l_@@_long_bool { _long }
- \bool_if:NT \l_@@_obey_spaces_bool { _obey_spaces }
- :w
- }
- }
- \bool_set_false:N \l_@@_long_bool
- \bool_set_false:N \l_@@_obey_spaces_bool
- \tl_put_right:Nx \l_@@_process_all_tl
+ \use:x
{
- {
- \if_charcode:w E #1 \use_i:nn \fi:
- \exp_not:o \l_@@_process_one_tl
- }
+ \int_set:Nn \tex_escapechar:D { 92 }
+ \exp_not:N \@@_cmd_type_cases:NnnnF \exp_not:N #2
+ { \@@_copy_command:nnNN }
+ { \@@_copy_expandable:nnNN }
+ { \@@_copy_environment:nnNN }
+ { \@@_cant_copy:nwn { non-ltcmd } }
+ { \cs_to_str:N #1 } { \cs_to_str:N #2 }
+ \exp_not:N #1 \exp_not:N #2
+ \exp_not:N \@@_break_point:n { \cs_to_str:N #2 }
+ \int_set:Nn \tex_escapechar:D { \int_use:N \tex_escapechar:D }
}
- \tl_clear:N \l_@@_process_one_tl
}
+\cs_new_protected:Npn \@@_set_eq_if_exist:NN #1 #2
+ { \cs_if_exist:NTF #2 { \cs_set_eq:NN } { \use_none:nn } #1 #2 }
+\cs_generate_variant:Nn \@@_set_eq_if_exist:NN { cc }
% \end{macrocode}
-% \end{macro}
%
-% \begin{macro}{\@@_add_default:n, \@@_add_default:, \@@_add_default_E:nn}
-% Store the default value of an argument, or rather code that gives
-% that default value (it may involve other arguments). This is
-% \cs{c_novalue_tl} for arguments with no actual default or with
-% default |-NoValue-|; and (in a brace group) \cs{prg_do_nothing:}
-% followed by a default value for others. For \texttt{E}-type
-% arguments, pad the defaults |#2| with some \cs{c_novalue_tl}
-% until there are as many as embellishments~|#1|. These functions are
-% also used when defining expandable commands.
+% \begin{macro}{\@@_cant_copy:nwn}
+% An utility macro similar to \cs{@@_bad_def:wn} to abort a command
+% copy. Contrary to \cs{@@_bad_def:wn} though, when this happens the
+% issue is most likely internal, because the command was already
+% (supposedly) correcly defined so it should be copyable. Hopefully
+% this macro will never be used ever, but if it does, apologise and
+% give the reason for the failure so the user can report.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_add_default:n #1
+\cs_new_protected:Npn \@@_cant_copy:nwn #1 #2 \@@_break_point:n #3
+ { \msg_error:nnnn { cmd } { copy-bug } {#1} {#3} }
+\msg_new:nnn { cmd } { copy-bug }
{
- \tl_if_novalue:nTF {#1}
- { \@@_add_default: }
+ Internal~error~while~copying~command~\iow_char:N\\#2:\\
+ \str_case:nn {#1}
{
- \int_incr:N \l_@@_current_arg_int
- \bool_set_true:N \l_@@_defaults_bool
- \tl_put_right:Nn \l_@@_defaults_tl { { \prg_do_nothing: #1 } }
+ { non-ltcmd } { Command~is~not~a~valid~ltcmd~command. }
+ { unknown-type } { Found~an~unknown~argument~type. }
}
}
-\cs_new_protected:Npn \@@_add_default:
+% \end{macrocode}
+% \end{macro}
+%
+% And, of course, add \cs{__kernel_cmd_if_xparse:NTF} and
+% \cs{@@_copy:NN} to \cs{@declarecommandcopylisthook}:
+% \begin{macrocode}
+\tl_gput_right:Nn \@declarecommandcopylisthook
+ { { \__kernel_cmd_if_xparse:NTF \@@_copy:NN } }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\@@_copy_command:nnNN,\@@_copy_command:NnNNnnnn}
+% A normal (non-expandable) command has a pretty straightforward
+% structure. Its definition is stored in
+% \cs{\meta{cmd}\textvisiblespace code}, its defaults (if any) are
+% stored in \cs{\meta{cmd}\textvisiblespace defaults}, and its
+% top-level definition contains its signature, which can just be
+% copied over. \cs{@@_copy_command:nnNN} copies the command code and
+% defaults, and then defines the top-level command using the auxiliary
+% \cs{@@_copy_command:NnNNnnnn}. This macro takes the signature of
+% the command being copied from its top-level definition, and replaces
+% the named bits with the new name.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_copy_command:nnNN #1 #2 #3 #4
{
- \int_incr:N \l_@@_current_arg_int
- \tl_put_right:Nn \l_@@_defaults_tl { \c_novalue_tl }
+ \cs_set_eq:cc { #1 ~ code } { #2 ~ code }
+ \@@_set_eq_if_exist:cc { #1 ~ defaults } { #2 ~ defaults }
+ \cs_set_protected_nopar:Npx #3
+ { \exp_after:wN \@@_copy_command:NnNNnnnn #4 {#1} }
}
-\cs_new_protected:Npn \@@_add_default_E:nn #1#2
+\cs_new:Npn \@@_copy_command:NnNNnnnn #1 #2 #3 #4 #5 #6 #7 #8
{
- \tl_map_function:nN {#2} \@@_add_default:n
- \prg_replicate:nn
- { \tl_count:n {#1} - \tl_count:n {#2} }
- { \@@_add_default: }
+ #1 \exp_not:n { {#2} }
+ \exp_not:c { #8 ~ } \exp_not:c { #8 ~ code }
+ \exp_not:n { {#5} {#6} {#7} }
}
% \end{macrocode}
% \end{macro}
%
-% \subsection{Setting up expandable types}
-%
-% The approach here is not dissimilar to that for standard types, but fewer types
-% are supported. There is
-% also a need to define the per-function auxiliaries: this is done here, while
-% the general grabbers are dealt with later.
+% \begin{macro}{\@@_copy_expandable:nnNN,\@@_copy_expandable:NnNNNNnnn}
+% An expandable command is slightly more complicated. Besides the
+% \cs{\meta{cmd}\textvisiblespace code}, and
+% \cs{\meta{cmd}\textvisiblespace defaults}, it also has an auxiliary
+% \cs{\meta{cmd}\textvisiblespace} for grabbing delimited arguments,
+% and possibly another auxiliary
+% \cs{\meta{cmd}\textvisiblespace\textvisiblespace}, if the command
+% has both long and short arguments. Then, its signature has also
+% several specific bits that are unique to that command, contrary to
+% non-expandable commands which use a common set of parsing functions.
%
-% \begin{macro}{\@@_add_expandable_type_+:w}
-% We have already checked that short arguments are before long
-% arguments, so \cs{l_@@_long_bool} only changes from \texttt{false}
-% to \texttt{true} once (and there is no need to reset it after each
-% argument). Continue the loop.
+% We'll start by copying the basics, then call
+% \cs{@@_copy_expandable_signature:NnNNNNnnn} to parse the signature
+% of the command and make the modified copy in a temporary token list,
+% then we call \cs{@@_copy_expandable:NnNNNNnnn} that will copy the
+% top-level definition of the command, with the proper internal
+% renames.
% \begin{macrocode}
-\cs_new_protected:cpn { @@_add_expandable_type_+:w }
+\cs_new_protected:Npn \@@_copy_expandable:nnNN #1 #2 #3 #4
+ {
+ \cs_set_eq:cc { #1 ~ code } { #2 ~ code }
+ \@@_set_eq_if_exist:cc { #1 ~ } { #2 ~ }
+ \@@_set_eq_if_exist:cc { #1 ~ \c_space_tl } { #2 ~ \c_space_tl }
+ \@@_set_eq_if_exist:cc { #1 ~ defaults } { #2 ~ defaults }
+ \exp_after:wN \@@_copy_expandable_signature:NnNNNNnnn #4 {#1} {#2}
+ \cs_set_nopar:Npx #3
+ { \exp_after:wN \@@_copy_expandable:NnNNNNnnn #4 {#1} {#2} }
+ }
+\cs_new:Npn \@@_copy_expandable:NnNNNNnnn #1 #2 #3 #4 #5 #6 #7 #8 #9
{
- \bool_set_true:N \l_@@_long_bool
- \@@_prepare_signature:N
+ \exp_not:N #1 \exp_not:n { {#2} }
+ \exp_not:c { #8 ~ }
+ \exp_not:c
+ {
+ #8 ~
+ \str_if_eq:eeT
+ { \exp_not:c { #9 ~ \c_space_tl } } { \exp_not:N #4 }
+ { \c_space_tl }
+ }
+ \exp_not:c { #8 ~ code }
+ \str_if_eq:eeTF { \exp_not:N #6 } { ? }
+ { ? }
+ { \exp_not:c { #8 ~ defaults } }
+ { \exp_not:V \l_@@_tmpa_tl }
}
% \end{macrocode}
-% \end{macro}
%
-% \begin{macro}{\@@_add_expandable_type_D:w}
-% \begin{macro}{\@@_add_expandable_type_D_aux:NNNn}
-% \begin{macro}{\@@_add_expandable_type_D_aux:NNN}
-% \begin{macro}{\@@_add_expandable_type_D_aux:NN}
-% The set up for \texttt{D}-type arguments involves constructing a
-% rather complex auxiliary which is used
-% repeatedly when grabbing. There is an auxiliary here so that the
-% \texttt{R}-type can share code readily: |#1| is |D| or~|R|.
-% The |_aux:NN| auxiliary is needed if the two delimiting tokens are
-% identical: in contrast to the non-expandable route, the grabber here
-% has to act differently for this case.
+% \begin{macro}{
+% \@@_copy_expandable_signature:NnNNNNnnn,
+% \@@_copy_expandable:nnN,
+% \@@_copy_parse_grabber:w,
+% }
+% A signature for an expandable command contains as many
+% \cs{expandable_grab_\meta{type}:w} as there are arguments, and what
+% follows this macro depends on the \meta{type}. We'll start a loop
+% through the signature, and at each argument grabber, we'll step the
+% argument count, and look for the \meta{type} with
+% \cs{@@_copy_parse_grabber:w} so we know which
+% \cs{@@_copy_grabber_\meta{type}:w} to call next.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_add_expandable_type_D:w
- { \@@_add_expandable_type_D_aux:NNNn D }
-\cs_new_protected:Npn \@@_add_expandable_type_D_aux:NNNn #1#2#3#4
+\cs_new_protected:Npn \@@_copy_expandable_signature:NnNNNNnnn
+ #1 #2 #3 #4 #5 #6 #7 #8 #9
{
- \@@_add_default:n {#4}
- \tl_if_eq:nnTF {#2} {#3}
- { \@@_add_expandable_type_D_aux:NN #1 #2 }
- { \@@_add_expandable_type_D_aux:NNN #1 #2 #3 }
- \@@_prepare_signature:N
+ \int_zero:N \l_@@_current_arg_int
+ \tl_clear:N \l_@@_tmpa_tl
+ \@@_copy_expandable:nnN {#8} {#9} #7
+ \q_recursion_tail \q_recursion_stop
}
-\cs_new_protected:Npn \@@_add_expandable_type_D_aux:NNN #1#2#3
+\cs_new_protected:Npn \@@_copy_expandable:nnN #1 #2 #3
{
- \bool_if:NTF \l_@@_long_bool
- { \cs_set:cpx }
- { \cs_set_nopar:cpx }
- { \l_@@_expandable_aux_name_tl } ##1 ##2 #2 ##3 \q_@@ ##4 #3
- { ##1 {##2} {##3} {##4} }
- \@@_add_expandable_grabber:nn {#1}
- {
- \exp_not:c { \l_@@_expandable_aux_name_tl }
- \exp_not:n { #2 #3 }
- }
+ \quark_if_recursion_tail_stop:n {#3}
+ \int_incr:N \l_@@_current_arg_int
+ \exp_after:wN \@@_copy_parse_grabber:w \token_to_str:N #3 {#1} {#2}
}
-\cs_new_protected:Npn \@@_add_expandable_type_D_aux:NN #1#2
+\use:x
{
- \bool_if:NTF \l_@@_long_bool
- { \cs_set:cpx }
- { \cs_set_nopar:cpx }
- { \l_@@_expandable_aux_name_tl } ##1 #2 ##2 #2
- { ##1 {##2} }
- \@@_add_expandable_grabber:nn { #1_alt }
+ \cs_new_protected:Npn \exp_not:N \@@_copy_parse_grabber:w ##1
+ \tl_to_str:n { expandable_grab_ } ##2 \tl_to_str:n { :w }
{
- \exp_not:c { \l_@@_expandable_aux_name_tl }
- \exp_not:n {#2}
+ \tl_put_right:Nx \exp_not:N \l_@@_tmpa_tl
+ { \exp_not:N \exp_not:c { @@_expandable_grab_##2:w } }
+ \exp_not:N \cs_if_exist_use:cF { @@_copy_grabber_##2:w }
+ { \@@_cant_copy:nwn { unknown-type } }
}
}
% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\@@_add_expandable_type_E:w}
-% \begin{macro}{\@@_add_expandable_type_E_aux:n}
-% For each embellishment, use \cs{@@_get_grabber:NN} to obtain an
-% auxiliary delimited by that token and store a pair constituted of
-% the auxiliary and the token in \cs{l_@@_tmpb_tl}, before appending
-% the whole set of these pairs to the signature, and an equal number
-% of |-NoValue-| markers (regardless of the default values of
-% arguments). Set the current argument appropriately.
+% \begin{macro}{
+% \@@_copy_grabber_D:w,\@@_copy_grabber_D_alt:w,
+% \@@_copy_grabber_R:w,\@@_copy_grabber_R_alt:w,
+% \@@_copy_grabber_E:w,\@@_copy_grabber_E_long:w,
+% \@@_copy_grabber_t:w,
+% \@@_copy_grabber_m:w,\@@_copy_grabber_m_long:w,
+% }
+% The most complicated is the |D|elimited argument: each argument has
+% a dedicated grabbing function named after the command that has to be
+% copied over (of the form
+% \cs{\meta{cmd}\textvisiblespace(arg\textvisiblespace\meta{num})}).
% \begin{macrocode}
-\cs_new_protected:Npn \@@_add_expandable_type_E:w #1#2
+\cs_new_protected:Npn \@@_copy_grabber_D:w #1 #2 #3 #4 #5
{
- \@@_add_default_E:nn {#1} {#2}
- \tl_clear:N \l_@@_tmpb_tl
- \tl_map_function:nN {#1} \@@_add_expandable_type_E_aux:n
- \@@_add_expandable_grabber:nn
- { E \bool_if:NT \l_@@_long_bool { _long } }
+ \tl_put_right:Nx \l_@@_tmpa_tl
{
- { \exp_not:o \l_@@_tmpb_tl }
- {
- \prg_replicate:nn { \tl_count:n {#1} }
- { { \c_novalue_tl } }
- }
+ \exp_not:c { #1 ~ (arg ~ \int_use:N \l_@@_current_arg_int ) }
+ \exp_not:n { #4 #5 }
}
- \@@_prepare_signature:N
- }
-\cs_new_protected:Npn \@@_add_expandable_type_E_aux:n #1
- {
- \@@_get_grabber:NN #1 \l_@@_tmpa_tl
- \tl_put_right:Nx \l_@@_tmpb_tl
- { \exp_not:o \l_@@_tmpa_tl \exp_not:N #1 }
+ \cs_set_eq:cc
+ { #1 ~ (arg ~ \int_use:N \l_@@_current_arg_int ) }
+ { #2 ~ (arg ~ \int_use:N \l_@@_current_arg_int ) }
+ \@@_copy_expandable:nnN {#1} {#2}
}
% \end{macrocode}
-% \end{macro}
-% \end{macro}
%
-% \begin{macro}{\@@_add_expandable_type_m:w}
-% Unlike the standard case, when working expandably each argument is always
-% grabbed separately.
+% |D_alt| is just a special case of |D| that uses a single delimiter
+% (used when both delimiters of the argument are identical):
% \begin{macrocode}
-\cs_new_protected:Npn \@@_add_expandable_type_m:w
- {
- \@@_add_default:
- \@@_add_expandable_grabber:nn
- { m \bool_if:NT \l_@@_long_bool { _long } } { }
- \@@_prepare_signature:N
- }
+\cs_new_protected:Npn \@@_copy_grabber_D_alt:w #1 #2 #3 #4
+ { \@@_copy_grabber_D:w {#1} {#2} {#3} {#4} { } }
% \end{macrocode}
-% \end{macro}
%
-% \begin{macro}{\@@_add_expandable_type_R:w}
-% The \texttt{R}-type is very similar to the \texttt{D}-type
-% argument, and so the same internals are used.
+% |R|, as far as copying is concerned, is identical to |D|:
% \begin{macrocode}
-\cs_new_protected:Npn \@@_add_expandable_type_R:w
- { \@@_add_expandable_type_D_aux:NNNn R }
+\cs_new_eq:NN \@@_copy_grabber_R:w \@@_copy_grabber_D:w
+\cs_new_eq:NN \@@_copy_grabber_R_alt:w \@@_copy_grabber_D_alt:w
% \end{macrocode}
-% \end{macro}
%
-% \begin{macro}{\@@_add_expandable_type_t:w}
-% An auxiliary delimited by |#1| is built now. It will be used to
-% test for the presence of that token.
+% |E| is straightforward: we just copy the embellishments over, and
+% increase the current argument number \cs{l_@@_current_arg_int} by
+% the number of embellishments (minus one because there is a
+% \cs{int_incr:N} down the line).
% \begin{macrocode}
-\cs_new_protected:Npn \@@_add_expandable_type_t:w #1
+\cs_new_protected:Npn \@@_copy_grabber_E:w #1 #2 #3 #4
{
- \@@_add_default:
- \@@_get_grabber:NN #1 \l_@@_tmpa_tl
- \@@_add_expandable_grabber:nn { t }
- {
- \exp_not:o \l_@@_tmpa_tl
- \exp_not:N #1
- }
- \@@_prepare_signature:N
+ \tl_put_right:Nn \l_@@_tmpa_tl { {#3} {#4} }
+ \int_add:Nn \l_@@_current_arg_int { \tl_count:n {#4} - 1 }
+ \@@_copy_expandable:nnN {#1} {#2}
}
+\cs_new_eq:NN \@@_copy_grabber_E_long:w \@@_copy_grabber_E:w
% \end{macrocode}
-% \end{macro}
%
-% \begin{macro}{\@@_add_expandable_grabber:nn}
-% This is called for all arguments to place the right grabber in the
-% signature.
+% |t| just needs copying the token to be tested for:
% \begin{macrocode}
-\cs_new_protected:Npn \@@_add_expandable_grabber:nn #1#2
+\cs_new_protected:Npn \@@_copy_grabber_t:w #1 #2 #3 #4
{
- \tl_put_right:Nx \l_@@_signature_tl
- { \exp_not:c { @@_expandable_grab_ #1 :w } #2 }
+ \tl_put_right:Nn \l_@@_tmpa_tl { #3 #4 }
+ \@@_copy_expandable:nnN {#1} {#2}
}
% \end{macrocode}
-% \end{macro}
%
-% \begin{macro}{\@@_get_grabber:NN}
-% \begin{macro}{\@@_get_grabber_auxi:NN}
-% \begin{macro}{\@@_get_grabber_auxii:NN}
-% Given a token |#1|, defines an expandable function delimited by that
-% token and stores it in the token list~|#2|. The function is named
-% after the token, unless that function name is already taken by some
-% other grabber (this can happen in the rare case where delimiters
-% with different category codes are used in the same document): in
-% that case use a global counter to get a unique name. Since the
-% grabbers are not named after \pkg{xparse} commands they should not
-% be used to get material from the input stream.
+% And last but not least, |m| is the simplest; the grabber is just
+% \cs{@@_expandable_grab_m:w}, which is already added to the new
+% command so here we just resume the loop:
% \begin{macrocode}
-\cs_new_protected:Npn \@@_get_grabber:NN #1#2
- {
- \cs_set:Npn \@@_tmp:w ##1 #1 {##1}
- \exp_args:Nc \@@_get_grabber_auxi:NN
- { @@_grabber_ \token_to_str:N #1 :w } #2
- }
-\cs_new_protected:Npn \@@_get_grabber_auxi:NN #1#2
- {
- \cs_if_eq:NNTF \@@_tmp:w #1
- { \tl_set:Nn #2 {#1} }
- {
- \cs_if_exist:NTF #1
- {
- \int_gincr:N \g_@@_grabber_int
- \exp_args:Nc \@@_get_grabber_auxi:NN
- {
- @@_grabber_
- - \int_use:N \g_@@_grabber_int :w
- }
- #2
- }
- { \@@_get_grabber_auxii:NN #1 #2 }
- }
- }
-\cs_new_protected:Npn \@@_get_grabber_auxii:NN #1#2
- {
- \cs_set_eq:NN #1 \@@_tmp:w
- \tl_set:Nn #2 {#1}
- }
+\cs_new_protected:Npn \@@_copy_grabber_m:w { \@@_copy_expandable:nnN }
+\cs_new_eq:NN \@@_copy_grabber_m_long:w \@@_copy_grabber_m:w
% \end{macrocode}
% \end{macro}
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\@@_copy_environment:nnNN}
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_copy_environment:nnNN #1 #2 #3 #4
+ { \msg_error:nn { cmd } { env-copy } }
+\msg_new:nnn { cmd } { env-copy }
+ { Copying~environments~is~not~possible. }
+% \end{macrocode}
+%
+%<latexrelease>\EndIncludeInRelease
+%
+%<latexrelease>\IncludeInRelease{0000/00/00}{\@@_copy:NN}%
+%<latexrelease> {Support \NewCommandCopy and \ShowCommand in ltcmd}
+%
+%<latexrelease>\EndIncludeInRelease
+%
% \subsection{Grabbing arguments}
%
% All of the grabbers follow the same basic pattern. The initial
More information about the latex3-commits
mailing list.