![\seq_set_split:Nnn 函数中的分隔符](https://linux22.com/image/340165/%5Cseq_set_split%3ANnn%20%E5%87%BD%E6%95%B0%E4%B8%AD%E7%9A%84%E5%88%86%E9%9A%94%E7%AC%A6.png)
显然,该\seq_set_split:Nnn
函数允许明确使用分隔符;例如,该语句\seq_set_split:Nnn \Args_seq {,} {x,y,z}
将把x
、y
和z
放入 中的前三个位置\Args_seq
。
或者,将此功能包装到\NewDocumentCommand
可以作为参数传递的分隔符中,例如参见\myMacroA
下面的 MWE,其中\seq_set_split:Nnn \Args_seq #2 {#1}
参数#1
被拆分为\Args_seq
使用参数中指定的分隔符#2
。
但是,在我的一个小发明中,我想从堆栈中弹出分隔符(L3seq
当然由实现),将它们存储在_tl
类型变量中,然后在\seq_set_split
函数中使用该变量。所有尝试都失败了;\myMacroB_Main
下面的控制序列说明了这一点。分隔符需要什么类型的变量?
一如既往,非常感谢。
\documentclass{minimal}
% --------------------
\usepackage[check-declarations]{expl3}
\usepackage{xparse}
\usepackage{amsmath}
% --------------------
\ExplSyntaxOn
% VARIABLE DECLARATIONS:
\seq_new:N \Args_seq
\int_new:N \ItemCount_int
\int_new:N \index_i
\tl_new:N \aux_tl
\tl_new:N \sep_tl
% --------------------
\NewDocumentCommand\myMacroA{O{}O{,}}{\myMacroA_Main:nn {#1}{#2}}
\cs_new:Npn \myMacroA_Main:nn #1 #2
{
\seq_clear:N \Args_seq
\seq_set_split:Nnn \Args_seq #2 {#1}
\myShowArgs{\Args_seq}
}
\NewDocumentCommand\myMacroB{O{}O{,}}{\myMacroB_Main:nn {#1}{#2}}
\cs_new:Npn \myMacroB_Main:nn #1 #2
{
\seq_clear:N \Args_seq
\tl_set:Nn \sep_tl {#2}
\seq_set_split:Nnn \Args_seq \sep_tl {#1} %does not accept the delimiter as a _tl variable.
\myShowArgs{\Args_seq}
}
\cs_new:Npn \myShowArgs #1
{
\tl_clear:N \aux_tl
\int_set:Nn \ItemCount_int {\seq_count:N #1}
\int_set:Nn \index_i {1}
\int_do_until:nNnn \index_i > \ItemCount_int
{
\tl_set:Nx \aux_tl {\seq_item:Nn #1 {\index_i}}
\tl_use:N \aux_tl \text{~}
\int_incr:N \index_i
}
}
\ExplSyntaxOff
\begin{document}
1. \verb+\myMacroA[a,b,c,1,2,3]+\\
\myMacroA[a,b,c,1,2,3]
2. \verb+\myMacroA[1;2;3;a;b;c][;]+\\
\myMacroA[1;2;3;a;b;c][;]
3. \verb+\myMacroB[a,b,c,1,2,3]+\\
\myMacroB[a,b,c,1,2,3]
4. \verb+\myMacroB[1;2;3;a;b;c][;]+\\
\myMacroB[1;2;3;a;b;c][;]
\end{document}
答案1
您需要一个\seq_set_split:Nnn
使用值的变体\sep_tl
,而不是文字\sep_tl
——这不是那里的分隔符。
换句话说:\seq_set_split:NVn
,尚不存在,但可以使用以下方式生成
\cs_generate_variant:Nn \seq_set_split:Nnn {NVn}
现在\seq_set_split:NVn
将使用五值\sep_tl
(或任何其他可与V
类型一起使用的变量)。
这里是缩短的代码,清晰、缩短,使用expl3
命名语法,但首先是一些注释:
\seq_clear:N
如果使用,则没有必要\seq_set_split
——该命令无论如何都会清除序列\seq_use:Nn
\tl_map_inline
比用一些环把东西粘在一起要容易得多。- 几乎所有数据类型都有两个临时变量(“寄存器”)
expl3
,可用于存储中间数据,例如\l_tmpa_tl
和\l_tmpb_tl
或\l_tmpa_seq
等。
\documentclass{article}% Don't use minimal!
% --------------------
\usepackage[check-declarations]{expl3}
\usepackage{xparse}
\usepackage{amsmath}
% --------------------
\ExplSyntaxOn
% VARIABLE DECLARATIONS:
\seq_new:N \l_neuwirth_Args_seq
\tl_new:N \l_neuwirth_sep_tl
% --------------------
\cs_generate_variant:Nn \seq_set_split:Nnn {NVn}
\NewDocumentCommand\myMacroA{O{}O{,}}{\neuwirth_myMacroA:nn {#1}{#2}}
\NewDocumentCommand\myMacroB{O{}O{,}}{\neuwirth_myMacroB:nn {#1}{#2}}
\cs_new:Npn \neuwirth_myMacroA:nn #1 #2
{
%\seq_clear:N \l_neuwirth_Args_seq
\seq_set_split:Nnn \l_neuwirth_Args_seq #2 {#1}
\myShowArgs{\l_neuwirth_Args_seq}
}
\cs_new:Npn \neuwirth_myMacroB:nn #1 #2
{
%\seq_clear:N \l_neuwirth_Args_seq% Not necessary since \seq_set_split clears the seq-variable
\tl_set:Nn \l_neuwirth_sep_tl {#2}
\seq_set_split:NVn \l_neuwirth_Args_seq \l_neuwirth_sep_tl {#1}
\neuwirth_myShowArgs{\l_neuwirth_Args_seq}
}
\cs_new:Npn \neuwirth_myShowArgs #1 {%
\seq_use:Nn #1 {\c_space_token}
}
\ExplSyntaxOff
\begin{document}
1. \verb+\myMacroA[a,b,c,1,2,3]+\\
\myMacroA[a,b,c,1,2,3]
2. \verb+\myMacroA[1;2;3;a;b;c][;]+\\
\myMacroA[1;2;3;a;b;c][;]
3. \verb+\myMacroB[a,b,c,1,2,3]+\\
\myMacroB[a,b,c,1,2,3]
4. \verb+\myMacroB[1;2;3;a;b;c][;]+\\
\myMacroB[1;2;3;a;b;c][;]
\end{document}
答案2
你的代码中有几个错误。注释标记%%%
指向左侧的代码或后面的代码
\documentclass{article}
% --------------------
\usepackage[check-declarations]{expl3}
\usepackage{xparse}
\usepackage{amsmath}
% --------------------
\ExplSyntaxOn
% VARIABLE DECLARATIONS:
%%% the names are not compliant
\seq_new:N \Args_seq
\int_new:N \ItemCount_int
\int_new:N \index_i
\tl_new:N \aux_tl
\tl_new:N \sep_tl
% --------------------
\cs_generate_variant:Nn \seq_set_split:Nnn {NVn}
%%% one of the arguments ought to be mandatory
\NewDocumentCommand\myMacroA{O{}O{,}}{\myMacroA_Main:nn {#1}{#2}}
%%% the name is not compliant
\cs_new:Npn \myMacroA_Main:nn #1 #2
{
\seq_clear:N \Args_seq
\seq_set_split:Nnn {\Args_seq} #2 {#1}
\myShowArgs{\Args_seq}
}
\NewDocumentCommand\myMacroB{O{}O{,}}{\myMacroB_Main:nn {#1}{#2}}
%%% the name is not compliant; the function should be protected
\cs_new:Npn \myMacroB_Main:nn #1 #2
{
\seq_clear:N \Args_seq %%% useless
\tl_set:Nn \sep_tl {#2}
\seq_set_split:NVn \Args_seq \sep_tl {#1} %does not accept the delimiter as a _tl variable.
\myShowArgs{\Args_seq} %%% the call is not compliant
}
%%% the name is not compliant and the code below can be shortened
\cs_new:Npn \myShowArgs #1
{
\tl_clear:N \aux_tl
\int_set:Nn \ItemCount_int {\seq_count:N #1}
\int_set:Nn \index_i {1}
\int_do_until:nNnn \index_i > \ItemCount_int
{
\tl_set:Nx \aux_tl {\seq_item:Nn #1 {\index_i}}
\tl_use:N \aux_tl \text{~}
\int_incr:N \index_i
}
}
\ExplSyntaxOff
\begin{document}
1. \verb+\myMacroA[a,b,c,1,2,3]+\\
\myMacroA[a,b,c,1,2,3]
2. \verb+\myMacroA[1;2;3;a;b;c][;]+\\
\myMacroA[1;2;3;a;b;c][;]
3. \verb+\myMacroB[a,b,c,1,2,3]+\\
\myMacroB[a,b,c,1,2,3]
4. \verb+\myMacroB[1;2;3;a;b;c][;]+\\
\myMacroB[1;2;3;a;b;c][;]
\end{document}
现在,让我们看一下兼容且简化的代码。我用作rn
您的个人前缀。
强制执行的
\myMacroA
主要论点\myMacroB
设置变量的函数应该是
protected
。如果函数的参数应该是变量,那么参数类型应该是
N
使用
\seq_use:Nn
显示序列项的代码可以简化;如果您想对每个项执行某些操作,请使用\seq_map_inline:Nn
或\seq_map_function:NN
当你使用
\seq_set_split:Nnn
(或变体)时,你不需要事先清除变量;同样,\tl_set:Nn
\documentclass{article}
% --------------------
\usepackage[check-declarations]{expl3}
\usepackage{xparse}
\usepackage{amsmath}
% --------------------
\ExplSyntaxOn
% VARIABLE DECLARATIONS:
\seq_new:N \l_rn_args_seq
\tl_new:N \l_rn_sep_tl
% --------------------
\cs_generate_variant:Nn \seq_set_split:Nnn {NVn}
\NewDocumentCommand\myMacroA{O{,}m}
{
\rn_MacroA_Main:nn {#1}{#2}
}
\cs_new_protected:Npn \rn_MacroA_Main:nn #1 #2
{
\seq_set_split:Nnn \l_rn_args_seq {#1} {#2}
\rn_ShowArgs:N \l_rn_args_seq
}
\NewDocumentCommand\myMacroB{O{,}m}
{
\rn_MacroB_Main:nn {#1}{#2}
}
\cs_new_protected:Npn \rn_MacroB_Main:nn #1 #2
{
\tl_set:Nn \l_rn_sep_tl {#1}
\seq_set_split:NVn \l_rn_args_seq \l_rn_sep_tl {#2}
\rn_ShowArgs:N \l_rn_args_seq
}
\cs_new:Npn \rn_ShowArgs:N #1
{
\seq_use:Nn #1 { ~ }
}
\ExplSyntaxOff
\begin{document}
1. \verb+\myMacroA{a,b,c,1,2,3}+\\
\myMacroA{a,b,c,1,2,3}
2. \verb+\myMacroA[;]{1;2;3;a;b;c}+\\
\myMacroA[;]{1;2;3;a;b;c}
3. \verb+\myMacroB{a,b,c,1,2,3}+\\
\myMacroB{a,b,c,1,2,3}
4. \verb+\myMacroB[;]{1;2;3;a;b;c}+\\
\myMacroB[;]{1;2;3;a;b;c}
\end{document}