\seq_set_split:Nnn 函数中的分隔符

\seq_set_split:Nnn 函数中的分隔符

显然,该\seq_set_split:Nnn函数允许明确使用分隔符;例如,该语句\seq_set_split:Nnn \Args_seq {,} {x,y,z}将把xyz放入 中的前三个位置\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您的个人前缀。

  1. 强制执行的\myMacroA主要论点\myMacroB

  2. 设置变量的函数应该是protected

  3. 如果函数的参数应该是变量,那么参数类型应该是N

  4. 使用\seq_use:Nn显示序列项的代码可以简化;如果您想对每个项执行某些操作,请使用\seq_map_inline:Nn\seq_map_function:NN

  5. 当你使用\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}

在此处输入图片描述

相关内容