我有一个序列,我通过项目编号获取元素(这里没有显示宏所需的元素)。我试图在循环中迭代序列的元素,do_while
但出现整数比较错误。我读了文档,interface3
但找不到问题所在。
梅威瑟:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\DeclareDocumentCommand{\setlist}{}{
\seq_new:N \g_test_seq
\seq_gset_from_clist:Nn \g_test_seq {lin1, line2, line3}
}
\DeclareDocumentCommand{\insertdata}{m}{
\seq_item:Nn \g_test_seq #1
}
\DeclareDocumentCommand{\getitemswhile}{}{
\int_new:N \l_test_count
\int_set:Nn \l_test_count {\seq_count:N \g_test_seq}
\int_set:Nn \l_tmpa_int {1}
\int_do_while:nn {\l_tmpa_int < \l_test_count}
{
\insertdata{\int_use:N \l_tmpa_int}
\int_incr:N \l_tmpa_int
}
}
\ExplSyntaxOff
\begin{document}
\setlist
\getitemswhile
\end{document}
错误(运行 TexLive 2016 更新)显示:
?
! You can't use `the character <' after \the.
<argument> <
l.34 \getitemswhile
?
! Missing = inserted for \ifnum.
<to be read again>
\__int_eval:w
l.34 \getitemswhile
答案1
你的问题是
\seq_item:Nn \g_test_seq #1
你应该
\seq_item:Nn \g_test_seq { #1 }
无论如何,您可能想要解决的那些定义中都有用户界面和编程层的奇怪混合;此外,声明应该在命令之外;而且,您应该遵守命名约定(\l_test_int
而不是\l_test_count
)。
\documentclass{scrartcl}
\usepackage{xparse}
\ExplSyntaxOn
\seq_new:N \g_test_seq
\DeclareDocumentCommand \setlist { }
{
\seq_gset_from_clist:Nn \g_test_seq { lin1 , line2 , line3 }
}
\DeclareDocumentCommand \insertdata { m }
{
\seq_item:Nn \g_test_seq { #1 }
}
\int_new:N \l_test_int
\DeclareDocumentCommand \getitemswhile { }
{
\int_set:Nn \l_test_int { \seq_count:N \g_test_seq }
\int_set:Nn \l_tmpa_int { 1 }
\int_do_while:nn { \l_tmpa_int < \l_test_int }
{
\insertdata { \int_use:N \l_tmpa_int }
\int_incr:N \l_tmpa_int
}
}
\ExplSyntaxOff
\begin{document}
\setlist
\getitemswhile
\end{document}
答案2
其中有几种工具expl3
可以帮助完成某些任务。
仅在真正需要时使用\seq_item:Nn
;用于做某事全部序列中有\seq_map_inline:Nn
或项\seq_map_function:NN
。
Manuel 在他的回答中已经指出了代码中的一些问题;最主要的是变量的声明通常应该是外部宏/函数的定义。
当然可以在函数中声明变量,但只有当这些变量需要在运行时定义时才这样做,并且变量的名称取决于当前条件。
你也应该不是\DeclareDocumentCommand
一般来说,使用:这将覆盖同一宏的任何先前的定义。
以下是\seq_map_inline:Nn
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\setlist}{m}
{
\seq_gset_from_clist:Nn \g_textnik_test_seq { #1 }
}
\NewDocumentCommand{\getitems}{}
{
\seq_map_inline:Nn \g_textnik_test_seq
{
##1\par
}
}
\seq_new:N \g_textnik_test_seq
\ExplSyntaxOff
\begin{document}
\setlist{line1, line2, line3}
\getitems
\end{document}
您可以看到当前项被传递给映射部分#1
(这里##1
,因为我们在定义中)。您可以对它做任何您想做的事情,甚至可以将它作为参数传递给另一个宏。
同样\seq_map_function:NN
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\setlist}{m}
{
\seq_gset_from_clist:Nn \g_textnik_test_seq { #1 }
}
\NewDocumentCommand{\getitems}{}
{
\seq_map_function:NN \g_textnik_test_seq \textnik_dopar:n
}
\seq_new:N \g_textnik_test_seq
\cs_new_protected:Nn \textnik_dopar:n
{
#1\par
}
\ExplSyntaxOff
\begin{document}
\setlist{line1, line2, line3}
\getitems
\end{document}
在这种情况下,每个项目都作为参数传递给指示的一个参数函数。
您也可以添加计数器:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\setlist}{m}
{
\seq_gset_from_clist:Nn \g_textnik_test_seq { #1 }
}
\NewDocumentCommand{\getitems}{}
{
\int_zero:N \l_textnik_test_int
\seq_map_inline:Nn \g_textnik_test_seq
{
\int_incr:N \l_textnik_test_int
\int_to_arabic:n {\l_textnik_test_int}:~##1\par
}
}
\seq_new:N \g_textnik_test_seq
\int_new:N \l_textnik_test_int
\ExplSyntaxOff
\begin{document}
\setlist{line1, line2, line3}
\getitems
\end{document}