我已经看到了解决方案这个帖子
\pgfset{
foreach/parallel foreach/.style args={#1in#2via#3}{evaluate=#3 as #1 using {{#2}[#3-1]}},
}
但有一个错误:当所有列表都只有一个项目时,它不会按预期工作。原因是这个帖子。
因此我尝试引入 latex3 以使其无错误。
\documentclass[tikz, border=1cm]{standalone}
\usepackage{xparse}
\ExplSyntaxOn
\clist_new:N \g_list_clist
\NewDocumentCommand {\getitem} {m O{1}} {
\clist_gset:Nn \g_list_clist #1
\clist_item:Nn \g_list_clist {#2}
}
\ExplSyntaxOff
\pgfset{
foreach/parallel foreach/.style args={#1in#2via#3}{
evaluate=#3 as #1 using "before\getitem{#2}[#3]"
},
}
\begin{document}
\begin{tikzpicture}
\foreach \i [
count = \c,
parallel foreach = \x in {test} via \c,
] in {1}
\node at (\i, 0) {blank\x};
\node at (1, -1) {no blank\getitem{{test}}[1]};
\end{tikzpicture}
\end{document}
答案1
您定义parallel foreach
为具有参数文本的样式#1in#2via#3
,没有空格,然后使用:
parallel foreach = \x in {test} via \c
因此的参数为parallel foreach
、␣\x␣
和␣{test}␣
,␣\c
然后当您将其传递给时\getitem
,您将得到:
\clist_gset:Nn\g_list_clist␣{test}␣
在抓取第二个参数时,TeX 会使用第一个空格标记\clist_gset:Nn
,但第二个空格会在您的节点中排版。
这里有几种可能性,例如\tl_trim_spaces:n
:
\clist_gset:Nx \g_list_clist { \tl_trim_spaces:n {#1} }
(实际上,实现起来要复杂一些,需要检查 参数周围的括号parallel foreach
;请参见此答案底部的代码)。但是expl3
提供了\clist_item:nn
,因此您可以从逗号分隔的列表中获取项目,而无需将其存储在变量中,这使得这里的事情变得更简单:
\exp_args:Nx \clist_item:nn
{ \tl_trim_spaces:n {#1} } {#2}
虽然由于有额外的括号,这无法处理列表中存在多个项目的可能性。您需要检查参数是否parallel foreach
在括号内,如果是,则将其删除,如下所示:
\NewDocumentCommand {\getitem} {m O{1}} {
\exp_args:Nx \clist_item:nn
{ \tl_trim_spaces_apply:nN {#1} \zhiyuan_remove_braces:n } {#2}
}
\cs_new:Npn \zhiyuan_remove_braces:n #1
{
\tl_if_head_is_group:nTF {#1}
{ \exp_not:n #1 }
{ \exp_not:n {#1} }
}
这样,您的代码就会产生预期的输出:
\documentclass[tikz, border=1cm]{standalone}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand {\getitem} {m O{1}} {
\exp_args:Nx \clist_item:nn
{ \tl_trim_spaces_apply:nN {#1} \zhiyuan_remove_braces:n } {#2}
}
\cs_new:Npn \zhiyuan_remove_braces:n #1
{
\tl_if_head_is_group:nTF {#1}
{ \exp_not:n #1 }
{ \exp_not:n {#1} }
}
\ExplSyntaxOff
\pgfset{
foreach/parallel foreach/.style args={#1in#2via#3}{
evaluate=#3 as #1 using "before\getitem{#2}[#3]"
},
}
\begin{document}
\begin{tikzpicture}
\foreach \i [
count = \c,
parallel foreach = \x in {test,another} via \c,
] in {1,2}
\node at (1, \i) {blank\x};
\node at (1, -1) {no blank\getitem{{test}}[1]};
\end{tikzpicture}
\end{document}
clist
下面是使用变量而不是的代码\clist_item:nn
:
\documentclass[tikz, border=1cm]{standalone}
\usepackage{xparse}
\ExplSyntaxOn
\clist_new:N \g_list_clist
\NewDocumentCommand {\getitem} {m O{1}} {
\use:x
{
\clist_gset:Nx \exp_not:N \g_list_clist
{ \tl_trim_spaces_apply:nN {#1} \zhiyuan_remove_braces:n }
}
\clist_item:Nn \g_list_clist {#2}
}
\cs_new:Npn \zhiyuan_remove_braces:n #1
{
\tl_if_head_is_group:nTF {#1}
{ \exp_not:n #1 }
{ \exp_not:n {#1} }
}
\ExplSyntaxOff
\pgfset{
foreach/parallel foreach/.style args={#1in#2via#3}{
evaluate=#3 as #1 using "before\getitem{#2}[#3]"
},
}
\begin{document}
\begin{tikzpicture}
\foreach \i [
count = \c,
parallel foreach = \x in {test,another} via \c,
] in {1,2}
\node at (1, \i) {blank\x};
\node at (1, -1) {no blank\getitem{{test}}[1]};
\end{tikzpicture}
\end{document}