我不知道如何让 tikz 和 pgfkeys 按照我的意愿行事。我想定义一个绘制小 tikz 图片的命令。我希望这个命令能够接受可选的 keyval 参数,这些参数会传递给可选的参数,\tikz
并得到适当的处理。最后一个阶段让我很头疼。以下是我目前所拥有的
\documentclass{article}
\usepackage{tikz}
\usepackage{xparse}
\tikzset{
foo/.style={color=#1},
foo/.default=black,
bar/.style={color=#1},
bar/.default=black,
}
\NewDocumentCommand{\drawthing}{o}{
\tikz[#1]{\draw[thick,foo] (0,1)--(1,0);
\draw[thick,foo] (0,0)--(1,1);
\draw[thick,bar] (0,0) -- (0,1);
}
}
\begin{document}
Here is text\drawthing[foo=red,bar=blue]
\end{document}
因此,它的作用是\drawthing
绘制三条线。两条是“ foo
”线,一条是“ bar
”线。我希望能够分别控制这两种类型的东西的颜色。默认样式应该是两者都是黑色。
问题是我不明白这些键是如何工作的。我确信这很简单,但我真的很难理解。所以看起来好像foo=red
没有效果。当我写下来时,\draw[thick,foo=green]
它工作正常。但我想为这张图片全局设置它,所以我希望有一个选项可以作为整个 tikzpicture 的参数。
我错过了什么明显而简单的技巧?
答案1
原因是您已foo
使用默认键指定了样式,如果没有指定,则默认键会启动。
您需要意识到的是,样式仅适用于当前的代码段。\draw[foo] ...
并且\draw[color=black]
在您的情况下是等效的。
密钥的使用
当您使用键时,您必须明确使用它们或重新定义它们。
考虑一下:
\tikzset{
foo/.style={#1},
bar/.style={foo={#1}}
}
这将使foo
拥有一个空的样式!除非你添加参数,否则它什么也不做。
\draw[foo={color=green,thick}]
因此相当于\draw[color=green,thick]
。也\draw[bar={color=green,thick}]
相当于\draw[foo={color=green,thick}]
。它只是同一键的另一个别名。
但是如果你采用如下风格:
\tikzset{
foo/.style={#1},
bar/.style={foo/.append style={#1}}
}
你会收集foo
使用style 将样式添加到键中bar
。这在使用作用域环境的情况下非常有用:
\begin{tikzpicture} % Now all styles who uses foo will do nothing
\draw[foo] (0,0) -- ++(1,0);
\begin{scope}[foo=very thick,bar={color=red},yshift=-1ex]
\draw[foo] (0,0) -- ++(1,0); % Will be red and thick
\draw[foo=dotted] (0,-1ex) -- ++(1,0); % Will be red and thick and dashed
\end{scope}
\end{tikzpicture}
但是,正如您所看到的,使用bar
会产生添加样式的效果foo
,直到环境结束。
在你的情况下
出了什么问题?
如果我们使用以下定义和以下代码,就会看到其他行为正在发生
\tikzset{
foo/.style={color=#1},
foo/.default=black, % If no argument is given then this kicks in as argument.
bar/.style={foo/.append style={#1}}
}
\begin{tikzpicture}[foo=red] % Now everything will have the style red attached
\draw (0,0) -- ++(1,0); % red
\draw[foo] (0,-1ex) -- ++(1,0); % will have black color as foo is called without an argument, so /.default kicks in!
\begin{scope}[bar=very thick,yshift=-2ex]
\draw[foo] (0,0) -- ++(1,0); % Will be thick, but not red
\draw[foo=red] (0,-1ex) -- ++(1,0); % Will be red and thick
\end{scope}
\end{tikzpicture}
记住每次定义时,default
如果没有给出参数,则将传递该参数。因此,它可能会覆盖您所做的操作。
然而,正如你在这里看到的,与论点无关的一切都#1
得到了妥善处理
\tikzset{
foo/.style={dashed,color=#1},
foo/.default=black, % If no argument is given then this kicks in as argument.
bar/.style={foo/.append style={#1}}
}
\begin{tikzpicture}[foo=red] % Now everything will have the style red and dashed attached
\draw (0,0) -- ++(1,0); % red, dashed
\draw[foo] (0,-1ex) -- ++(1,0); % will have black color and dashed as foo is called with out an argument, so /.default kicks in!
\begin{scope}[bar=very thick,yshift=-2ex]
\draw[foo] (0,0) -- ++(1,0); % Will be dashed, thick, but not red
\draw[foo=red] (0,-1ex) -- ++(1,0); % Will be red and thick and dashed
\end{scope}
\end{tikzpicture}
连续读取按键
如果你写的dashed,very thick,dotted,thick
话仅有的用点状粗线,不要太粗,也不要用虚线和点线混合的线。
解决您的问题
解决方案是使用另一个键作为样式,但是否则您永远不需要使用它。
\tikzset{
foo hidden/.style={}, % Provide a hidden style
foo/.style={foo hidden/.append style={color=#1}}, % foo changes `foo hidden`
foo/.default=orange,
bar hidden/.style={},
bar/.style={bar hidden/.append style={color=#1}}, % bar changes `bar hidden`
bar/.default=green,
}
\NewDocumentCommand{\drawthing}{o}{
\tikz[#1]{\draw[thick,foo hidden] (0,1)--(1,0);
\draw[thick,foo hidden] (0,0)--(1,1);
\draw[thick,bar hidden] (0,0) -- (0,1);
}
}
Blue and red: \drawthing[foo=red,bar=blue]
Green and blue: \drawthing[foo=blue,bar]
Black and orange: \drawthing[foo]
如果您希望它始终具有默认值,那么您可以执行以下操作:
\NewDocumentCommand{\drawthing}{o}{
\tikz[foo,bar,#1]{\draw[thick,foo hidden] (0,1)--(1,0);
\draw[thick,foo hidden] (0,0)--(1,1);
\draw[thick,bar hidden] (0,0) -- (0,1);
}
}