我相信下面的代码注释得足够好,无需进一步解释。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}