我正在努力理解pgfkeys
包。我目前使用keycommand
包,我发现它非常容易理解:它只是带有命名参数而不是编号参数的普通 LaTeX 命令。但是,我想使用它,pgfkeys
因为我的项目很大程度上基于 TikZ,我相信它是一个更强大的解决方案。我认为了解如何将以下小示例从 翻译成keycommand
将对pgfkeys
我有很大帮助。
例子
我创建了一个绘制doublecircle
小工具的命令。它有两个参数:diameter
和color
,均为可选参数,默认值分别为1
和red
。
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\usepackage{keycommand}
\newcounter{currentheight}
\setcounter{currentheight}{0}
\newkeycommand{\doublecircle}[diameter=1,color=red]{%
\fill[\commandkey{color}] (0,\thecurrentheight) circle (\commandkey{diameter}/2);
\fill[\commandkey{color}] (\commandkey{diameter}/2,\thecurrentheight) circle (\commandkey{diameter}/2);
}
\begin{document}
\begin{tikzpicture}[y=-1cm]
\doublecircle[color=blue]
\addtocounter{currentheight}{5}
\doublecircle[diameter=4]
\addtocounter{currentheight}{6}
\doublecircle[diameter=3,color=green]
\end{tikzpicture}
\end{document}
结果
答案1
可能的解决方案:
\documentclass[border=5mm]{standalone}
\usepackage{tikz}
\pgfkeys{/tikz/.cd,% to set the path
circle height/.initial=0, % initial value
circle height/.get=\circleheight, % to get the value from a macro
circle height/.store in=\circleheight, % to store the value into a macro
diameter/.initial=1,
diameter/.get=\diameter,
diameter/.store in=\diameter,
circle color/.initial=red,
circle color/.get=\circlecolor,
circle color/.store in=\circlecolor,
}
\newcommand{\pgfdoublecircle}[1][]{%
\tikzset{circle color=red,diameter=1,#1}% the default options will be overwritten by the one introduced
\fill[\circlecolor] (0,\circleheight) circle (\diameter/2);
\fill[\circlecolor] (\diameter/2,\circleheight) circle (\diameter/2);
}
\begin{document}
\begin{tikzpicture}[y=-1cm]
\pgfdoublecircle[circle color=blue]
\pgfdoublecircle[circle height=5,diameter=4]
\pgfdoublecircle[circle height=11,diameter=3,circle color=green]
\end{tikzpicture}
\end{document}
根据奎伯比尔贝尔 评论以及其他问答pgfkeys 密钥处理程序 .get 和 .store 起什么作用?和TikZ 风格的论据我决定放弃这种设置密钥的低效方法。因此,应该优先使用以下方法:
\pgfkeys{/tikz/.cd,% to set the path
circle height/.store in=\circleheight, % to store the value into a macro
circle height=0, % initial value
diameter/.store in=\diameter,
diameter=1,
circle color/.store in=\circlecolor,
circle color=red,
}
最终结果显然与后一种方法一致。
答案2
有几种方法可以获取、设置和存储值,另请参阅第一部分我的另一个答案.
根据密钥以及其值的需要,必须使用其中一种方式。
我们也常常看到
/my namespace/key/.code=\pgfmathsetmacro\namespace@key{#1}
也可以在这里使用,并以已经计算好的形式提供值,尽管这里实际上不需要它,因为 TikZ 几乎可以抛出 PGF Math 本身中的任何内容。请参阅(还有)我的另一个答案如何更有效地使用它(关于的部分+
)。
代码
\documentclass[tikz,border=5mm]{standalone}
\newcommand*{\doublecircleset}{\pgfqkeys{/double circle}}
\makeatletter
\doublecircleset{
/double circle/.code={\pgfqkeys{/double circle}{#1}},
color/.initial=red, % initialize key 'color' with value 'red'
height/.initial=0, % see color
diameter/.store in=\doublecircle@diameter, % the key 'diameter' will be used more than once and also in the 'scope', let's store it right away
diameter=1, % the default value is '1'
add to height/.style={height/.expanded=\pgfkeysvalueof{/double circle/height}+#1} % let's take the value of the 'height' key and add '#1'.
% expansion is needed otherwise we have a selv-referencing macro (and an infinite loop)
}
\newcommand{\doublecircle}[1][]{%
% let's group the whole macro so that the changes to the keys and whatnot are local, this is how TikZ works.
% we could have used '\begingroup \doublecircleset{#1} … … … \endgroup' here, but the scope allows us to set the radius too.
\scope[/double circle={#1}, radius=(\doublecircle@diameter)/2] % alright, execute the key=values and set the radius
\pgfkeysgetvalue{/double circle/height}\doublecircle@height % we need the height more than once, a single macro would be nice to use
\fill[color=\pgfkeysvalueof{/double circle/color}] %
(0,{\doublecircle@height}) circle [] % if we use () or , in the key (which is allowed: PGF math) we need to enclose it in braces
(xyz cs: x={(\doublecircle@diameter)/2}, % either way
y={\doublecircle@height}) circle []
;
\endscope
}
\makeatother
\begin{document}
\begin{tikzpicture}[y=-1cm]
\doublecircle[color=blue]
\doublecircleset{add to height=5}
\doublecircle[diameter=4]
\doublecircleset{add to height=6}
\doublecircle[diameter=3, height=2*(2+3), color=green]
\end{tikzpicture}
\end{document}