出于我自己的充分理由,我加载了\param_seq
一个参数数组,然后想通过弹出\param_seq
将的内容传输到,将弹出的项目暂时存储在中,然后推送到 。经过两次弹出和推送循环后,我已经看到事情出了问题;由于某种原因,最后弹出的项目的副本数与循环数一样多,现在没有丢失弹出的项目,而是用最后弹出的副本替换了它们。这不是人们对一对堆栈所期望的那种恶作剧。我做错了什么?我应该补充一点,在实际操作中,我对不同的参数做了不同的事情,因此有 case 子句。\aux_seq
\param_seq
\aux_tl
\aux_tl
\aux_seq
\aux_seq
\param_seq
\documentclass{minimal}
%-----------------------------
\usepackage{xparse}
\usepackage{amsmath}
%=============================
\ExplSyntaxOn
\tl_new:N \output_tl
\tl_new:N \aux_tl
\seq_new:N \params_seq
\seq_new:N \aux_seq
\int_new:N \index_i
%-----------------------------
\NewDocumentCommand\myFunction{O{,} m}{\myFunction_build:nn {#1}{#2}}
\cs_new:Npn \myFunction_build:nn #1 #2
{
\tl_clear:N \output_tl
\seq_clear:N \params_seq
\seq_set_split:Nnn \params_seq { #1 } { #2 }
\seq_pop_left:NN \params_seq \aux_tl
\tl_use:N \aux_tl \\
\seq_push:Nn \aux_seq \aux_tl
\seq_pop_left:NN \params_seq \aux_tl
\tl_use:N \aux_tl \\
\seq_push:Nn \aux_seq \aux_tl
\int_set:Nn \index_i { 0 }
\seq_map_inline:Nn \aux_seq
{
\int_incr:N \index_i
\int_case:nnTF {\index_i}
{
{1} {\tl_put_right:Nn \output_tl {##1,\c_space_tl}}
{2} {\tl_put_right:Nn \output_tl {##1,\c_space_tl}}
{3} {\tl_put_right:Nn \output_tl {##1,\c_space_tl}}
{4} {\tl_put_right:Nn \output_tl {##1,\c_space_tl}}
}
{}
{}
}
\text{contents\, of\, aux\, sequence\,after\,two\,pushes:\, } \tl_use:N \output_tl \\
\int_set:Nn \index_i { 0 }
\seq_map_inline:Nn \params_seq
{
\int_incr:N \index_i
\int_case:nnTF {\index_i}
{
{1} {\tl_put_right:Nn \output_tl {##1,\c_space_tl}}
{2} {\tl_put_right:Nn \output_tl {##1,\c_space_tl}}
{3} {\tl_put_right:Nn \output_tl {##1,\c_space_tl}}
{4} {\tl_put_right:Nn \output_tl {##1,\c_space_tl}}
}
{}
{}
}
\text{contents\, of\, params\, seq\,after\,two\,pops:\, } \tl_use:N \output_tl \\
}
\ExplSyntaxOff
%=======================================
\begin{document}
\noindent
\textbf{Function call:} \verb+\myFunction{1,2,3,4,5}+\\
\textbf{Disappointing result:} \\
\myFunction{1,2,3,4,5}\\
\end{document}
答案1
除了变量命名方案不当之外,问题还在于误用了\seq_push:Nn
应该改为
\seq_push:NV \l_neuwirth_aux_seq \l_neuwirth_aux_tl
和
\seq_push:NV \l_neuwirth_aux_seq \l_neuwirth_aux_tl
因为你想推动内容变量的,而不是变量本身。我根据声明使用了“正确的”变量名
\tl_new:N \l_neuwirth_output_tl
\tl_new:N \l_neuwirth_aux_tl
\seq_new:N \l_neuwirth_params_seq
\seq_new:N \l_neuwirth_aux_seq
\int_new:N \l_neuwirth_index_int
完整代码。另请注意
- 内部函数的命名
protected
\int_case:nn
而不是\int_case:nnTF
使用空的参数~
输出中的空格\seq_pop:NN
在将序列用作堆栈的情况下是首选:顶部是“左侧”这一事实不应引起关注。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \l_neuwirth_output_tl
\tl_new:N \l_neuwirth_aux_tl
\seq_new:N \l_neuwirth_params_seq
\seq_new:N \l_neuwirth_aux_seq
\int_new:N \l_neuwirth_index_int
\NewDocumentCommand\myFunction{O{,} m}
{
\neuwirth_myfunction_build:nn {#1}{#2}
}
\cs_new_protected:Npn \neuwirth_myfunction_build:nn #1 #2
{
\tl_clear:N \l_neuwirth_output_tl
\seq_clear:N \l_neuwirth_params_seq
\seq_set_split:Nnn \l_neuwirth_params_seq { #1 } { #2 }
\seq_pop:NN \l_neuwirth_params_seq \l_neuwirth_aux_tl
\tl_use:N \l_neuwirth_aux_tl \\
\seq_push:NV \l_neuwirth_aux_seq \l_neuwirth_aux_tl
\seq_pop:NN \l_neuwirth_params_seq \l_neuwirth_aux_tl
\tl_use:N \l_neuwirth_aux_tl \\
\seq_push:NV \l_neuwirth_aux_seq \l_neuwirth_aux_tl
\int_set:Nn \l_neuwirth_index_int { 0 }
\seq_map_inline:Nn \l_neuwirth_aux_seq
{
\int_incr:N \l_neuwirth_index_int
\int_case:nn {\l_neuwirth_index_int}
{
{1} {\tl_put_right:Nn \l_neuwirth_output_tl {##1,~}}
{2} {\tl_put_right:Nn \l_neuwirth_output_tl {##1,~}}
{3} {\tl_put_right:Nn \l_neuwirth_output_tl {##1,~}}
{4} {\tl_put_right:Nn \l_neuwirth_output_tl {##1,~}}
}
}
\mbox{contents~of~aux~sequence~after~two~pushes:~} \tl_use:N \l_neuwirth_output_tl \\
\int_set:Nn \l_neuwirth_index_int { 0 }
\seq_map_inline:Nn \l_neuwirth_params_seq
{
\int_incr:N \l_neuwirth_index_int
\int_case:nn {\l_neuwirth_index_int}
{
{1} {\tl_put_right:Nn \l_neuwirth_output_tl {##1,~}}
{2} {\tl_put_right:Nn \l_neuwirth_output_tl {##1,~}}
{3} {\tl_put_right:Nn \l_neuwirth_output_tl {##1,~}}
{4} {\tl_put_right:Nn \l_neuwirth_output_tl {##1,~}}
}
}
\mbox{contents~of~params~seq~after~two~pops:~} \tl_use:N \l_neuwirth_output_tl \\
}
\ExplSyntaxOff
\begin{document}
\noindent
\textbf{Function call:} \verb+\myFunction{1,2,3,4,5}+\\
\textbf{Disappointing result:} \\
\myFunction{1,2,3,4,5}
\end{document}
与所说的相反,结果应该不会再令人失望了。
实际上,您使用了错误的方法来显示序列;这里有一些可以正确执行的操作的代码:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \l_neuwirth_aux_tl
\seq_new:N \l_neuwirth_params_seq
\seq_new:N \l_neuwirth_aux_seq
\NewDocumentCommand\myFunction{O{,} m}
{
\neuwirth_myfunction_build:nn {#1}{#2}
}
\cs_new_protected:Npn \neuwirth_myfunction_build:nn #1 #2
{
\seq_set_split:Nnn \l_neuwirth_params_seq { #1 } { #2 }
\seq_pop:NN \l_neuwirth_params_seq \l_neuwirth_aux_tl
\tl_use:N \l_neuwirth_aux_tl \\
\seq_push:NV \l_neuwirth_aux_seq \l_neuwirth_aux_tl
\seq_pop:NN \l_neuwirth_params_seq \l_neuwirth_aux_tl
\tl_use:N \l_neuwirth_aux_tl \\
\seq_push:NV \l_neuwirth_aux_seq \l_neuwirth_aux_tl
\mbox{contents~of~aux~sequence~after~two~pushes:~} \seq_use:Nn \l_neuwirth_aux_seq {,~}\\
\mbox{contents~of~params~seq~after~two~pops:~} \seq_use:Nn \l_neuwirth_params_seq {,~}\\
}
\ExplSyntaxOff
\begin{document}
\noindent
\textbf{Function call:} \verb+\myFunction{1,2,3,4,5}+\\
\textbf{Expected result:} \\
\myFunction{1,2,3,4,5}
\end{document}