\seq_map_inline:Nn 和/或 \tl_clear:N 的使用

\seq_map_inline:Nn 和/或 \tl_clear:N 的使用

我相信下面的代码注释得足够好,无需进一步解释。MWE 中定义的宏不会产生预期的结果。我对 interface3 文档的理解是 ##1一次\seq_map_inline:Nn \params_seq显示一个存储在其中的标记,这将清除标记列表。结果表明我误读了其中一个或另一个,也可能是两个。\params_seq\tl_clear:N \output_tl

我将非常感激所得到的任何帮助。

\documentclass{minimal}
%-----------------------------
%RN 24 August 2015
%   BACKGROUND:
% The purpose of the macro is to provide the template for macros 
% that accept a parameter input stream of arbitrary length 
% (separator optionally definable), and partition it into chunks 
% of optionally defineable length for further processing.   
%   ISSUE:
% I expect the result to be:
%   1 2 3 4 5
%   6 7 8 9 10
%   11 12 13 14 15
%   16 17
% and not:       
%   1 2 3 4 5
%   1 2 3 4 5 6 7 8 9 10
%   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
%   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17        
%-----------------------------
\usepackage{xparse}
%=======================================
\ExplSyntaxOn
%-----------------------------
\tl_new:N \output_tl 
\seq_new:N \params_seq 
\int_new:N \index_i
%-----------------------------
\NewDocumentCommand\myPartitionerTemplate{O{,} m O{3}}{\myPartitioner_build:nn {#1}{#2}{#3}}
\cs_new:Npn \myPartitioner_build:nn #1 #2 #3
  { %begin control sequence
    \tl_clear:N \output_tl 
    \seq_clear:N \params_seq 
    \int_set:Nn \index_i { 0 }
  %load parameter #2 into the _seq array:
  \seq_set_split:Nnn \params_seq { #1 } { #2 }  
    \seq_map_inline:Nn \params_seq  
        {   %begin processing \params_seq inline
            % keep a count of how many parameters have been read:
            \int_incr:N \index_i    
            \tl_put_right:Nn \output_tl {\ ##1 }    
            %   once a partition is full, i.e. paramcount mod   param#3 = 0,
            % "use" it, then clear \output_tl: 
            \if_int_compare:w  \int_mod:nn {\index_i} {#3} = 0
                {
                \tl_use:N \output_tl \\ 
                \tl_clear:N \output_tl
                }       
            \fi:
        }   %end inline processing
        %   "use" final partially full partition, else it's 
        % been "used" already
        \if_int_compare:w  \int_mod:nn {\index_i} {#3} > 0
            \tl_use:N \output_tl \\
        \fi:
  } %end control sequence
\ExplSyntaxOff
%=======================================
\begin{document}
\verb+\myPartitionerTemplate{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}[5]+\\
\myPartitionerTemplate{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}[5]
\end{document} 

答案1

你的问题是

\if_int_compare:w  \int_mod:nn {\index_i} {#3} = 0
  {
    \tl_use:N \output_tl \\ 
    \tl_clear:N \output_tl
  }
\fi:

这里你使用的是最低级别的数值条件\if_int_compare:w(TeX\ifnum原语),它不是使用括号组作为其参数。因此,{ ... }此处的对导致组应用于\tl_clear:N,因此您无法获得预期的重置行为。

你可以通过移除散落的组来修复,但我更喜欢\int_comapre:nNnTF(或\int_compare:nTF),这使用括号组,这样就不需要你注意你没有安全地终止你的条件。整理代码以使用更高级别的接口(如果可用)、正确命名的变量,ETC。, 导致

\documentclass{article}
%-----------------------------
%RN 24 August 2015
%   BACKGROUND:
% The purpose of the macro is to provide the template for macros 
% that accept a parameter input stream of arbitrary length 
% (separator optionally definable), and partition it into chunks 
% of optionally definable length for further processing.   
%   ISSUE:
% I expect the result to be:
%   1 2 3 4 5
%   6 7 8 9 10
%   11 12 13 14 15
%   16 17

%-----------------------------
\usepackage{xparse}
%=======================================
\ExplSyntaxOn
%-----------------------------
\tl_new:N \l__myPartitioner_output_tl 
\seq_new:N \l__myPartitioner_params_seq 
\int_new:N \l__myPartitioner_index_int
%-----------------------------
\NewDocumentCommand\myPartitionerTemplate{O{,} m O{3}}
  {\myPartitioner_build:nnn {#1}{#2}{#3}}
\cs_new_protected:Npn \myPartitioner_build:nnn #1 #2 #3
  { %begin control sequence
    \tl_clear:N \l__myPartitioner_output_tl 
    \seq_clear:N \l__myPartitioner_params_seq 
    \int_zero:N \l__myPartitioner_index_int
  %load parameter #2 into the _seq array:
    \seq_set_split:Nnn \l__myPartitioner_params_seq {#1} {#2}  
    \seq_map_inline:Nn \l__myPartitioner_params_seq  
      { %begin processing \l__myPartitioner_params_seq inline
        % keep a count of how many parameters have been read:
        \int_incr:N \l__myPartitioner_index_int    
        \tl_put_right:Nn \l__myPartitioner_output_tl
           { \c_space_tl ##1 }    
        %   once a partition is full, i.e. paramcount mod   param#3 = 0,
        % "use" it, then clear \l__myPartitioner_output_tl: 
        \int_compare:nNnT
          { \int_mod:nn { \l__myPartitioner_index_int } {#3} } = \c_zero
          {
            \tl_use:N \l__myPartitioner_output_tl \\ 
            \tl_clear:N \l__myPartitioner_output_tl      
          }
      }   % end inline processing
      % "use" final partially full partition, else it's 
      % been "used" already
    \int_compare:nNnT
       { \int_mod:nn {\l__myPartitioner_index_int } {#3} } > \c_zero
       { \tl_use:N \l__myPartitioner_output_tl }
  } %end control sequence
\ExplSyntaxOff
%=======================================
\begin{document}
\verb+\myPartitionerTemplate{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}[5]+\\
\myPartitionerTemplate{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17}[5]
\end{document} 

相关内容