使用 foreach 进行多个 TikZ 键

使用 foreach 进行多个 TikZ 键

在使用 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,而它应该查找两个键,即drawred

是否存在一些巧妙的 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@edefLaTeX。使用下一个方法,您可以使用\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 styleexpand 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}

相关内容