在使用 pgffor 时,我尝试稍微修改 TikZ/pgf 手册中的一个示例:
\path \foreach \x/\content/\style in {%
0/a/draw,
1/b/{draw,red},
2/c/{circle,blue},
3/d/draw%
} {
node[\style] at (\x,0) {\content}
} ;
不幸的是,这不适用于\style
设置了多个选项的节点。TikZ 抱怨
! Package pgfkeys Error: I do not know the key '/tikz/draw,red' and I am going to ignore it. Perhaps you misspelled it.
现在,当我对其他变量(例如\content
)使用逗号分隔列表时,此方法可以完美运行。所以现在,我的问题是:如何\style
在执行循环时进行拆分?显然,pgf 尝试查找一个名为 的键draw,red
,而它应该查找两个键,即draw
和red
。
是否存在一些巧妙的 LaTeX 宏可以正确扩展循环变量或告诉 pgf 期望多个键?
答案1
这是另一个版本,与之前提供的版本并没有什么不同,只是以略有不同的方式将它们组合在一起。实际上,这有点像定义一个扩展为给定选项列表的动态样式别名。当red drawing/.style={draw,red}
定义了类似的样式后,调用red drawing
就会执行\tikzset{draw,red}
(有点像,实际上是pgfkeys
)。因此,我们通过定义一个键来模拟这一点,该键会对\tikzset
传递的任何内容执行。所以apply style={do,something,and,something,else}
会执行\tikzset{do,something,and,something,else}
。就其本身而言,这并不是那么有用。但是当与/.expand once
键处理程序结合使用时,我们可以向它传递一个宏,让该宏扩展一次,然后执行它包含的样式。
\documentclass{article}
\usepackage{tikz}
\tikzset{%
apply style/.code={%
\tikzset{#1}%
}
}
\begin{document}
\begin{tikzpicture}
\path \foreach \x/\content/\style in {%
0/a/draw,
1/b/{draw,red},
2/c/{circle,draw=blue},
3/d/draw%
} {
node[apply style/.expand once=\style] at (\x,0) {\content}
} ;
\end{tikzpicture}
\end{document}
答案2
使用编号的间接样式(可能更冗长但更灵活):
\documentclass[tikz]{standalone}
\begin{document}
\begin{tikzpicture}
\tikzset{
s0/.style={draw},
s1/.style={draw,red},
s2/.style={circle,draw=blue},
s3/.style={draw},
}
\foreach \x/\content in {%
0/a,
1/b,
2/c,
3/d%
} {
\node[s\x] at (\x,0) {\content};
};
\end{tikzpicture}
\end{document}
答案3
我个人总是使用下一个方法,在很多情况下,我使用 \protected@edef
LaTeX。使用下一个方法,您可以使用\path node ... node ... ;
。
\documentclass{standalone}
\usepackage{tikz}
% \makeatletter\let\protectededef\protected@edef not useful here but It' sometimes
% interesting
\begin{document}
\begin{tikzpicture}
\path
\foreach \x/\content/\style in {0/a/draw,
1/b/{draw,red},
2/c/{draw,circle,blue},
3/d/draw}{
\pgfextra{\edef\tmp{ % or \pgfextra{\protectededef\tmp{
node[\style] at (\x,0) {\content}}}
\tmp
};
\end{tikzpicture}
\end{document}
答案4
我一直在使用一些使用与 Loop Space 的答案中描述的相同机制的键。用户语法更简单,更符合键值方法。它通过扩展价值一次、两次或完全处理,然后作为钥匙。问题中的例子稍作修改,包括需要扩展两次的例子。
要回答这个问题,以下键set style
和 expand style once
就足够了。我包括expand style twice
解决示例修改的键。我还包括expand style
当完全扩展是目标并且所需的扩展次数未知时有用的键。
您可能需要查看说明这些事实的最小示例在我的相关回答中。
\documentclass{article}
\usepackage{tikz}
\tikzset{%
set style/.style={#1},
expand style/.style={%completely expands the <value> of its argument (using \edef) before processing the result as a <key>
set style/.expanded={#1}% needs braces around the argument
},
expand style once/.style={% expands the <value> of its argument once before processing the result as a <key>
set style/.expand once={#1}% needs braces around the argument
},
expand style twice/.style={% expands the <value> of its argument twice before processing the result as a <key>
set style/.expand twice={#1}% needs braces around the argument
}
}
\begin{document}
\begin{tikzpicture}
\def\mystyle{fill=yellow}
\path \foreach \x/\content/\style in {%
0/a/draw,
1/b/{draw,red},
2/c/{circle,draw=blue},
3/d/\mystyle% \mystyle needs one more expansion after \style has been expanded once.
} {
node[expand style=\style] at (\x,0) {\content}
} ;
\end{tikzpicture}
\end{document}