我有许多类似 MWE 的函数,我想为函数的输入定义键;但是我没有成功。
\documentclass{standalone}
\usepackage{tikz}
\newcommand{\circleDraw}[1]{%
\begin{tikzpicture}
\pgfmathsetmacro\dh{{#1}[0]}%
\draw (0,0) circle ({0.5*\dh});
\end{tikzpicture}%
}
\begin{document}
\centering
\circleDraw{40}
\end{document}
这是我尝试使用 keyval 包做的事情,但显然有问题!
\documentclass{standalone}
\usepackage{tikz}
\usepackage{keyval}
\makeatletter
\define@key{keys}{h}{#1}
\makeatother
\newcommand{\circleDraw}[1]{%
\begin{tikzpicture}
\pgfmathsetmacro\dh{{#1}[0]}%
\draw (0,0) circle ({0.5*\dh});
\end{tikzpicture}%
}
\begin{document}
\centering
\circleDraw{h=40}
\end{document}
我很高兴收到 pgfkey 和 keyval 中的其他答案,请注意,在我的某些函数中,我有多个输入,形式为:{#1}[0] 到 {#1}[5]、{#2}[0] 到 {#2}[3] 等。
答案1
如果您有(我认为更强大的)pgf 密钥,则不需要 keyval。您只需定义自己的目录并将所有密钥存储在那里即可。
\documentclass{standalone}
\usepackage{tikz}
% EE/.cd serves two purposes: define a directory EE and switch to it
% h/.initial=1 just means we introduce a key "h" and assign it the
% initial value 1
\tikzset{EE/.cd,h/.initial=1}
\newcommand{\circleDraw}[1]{%
\begin{tikzpicture}
% this says switch to the EE directory and put the argument, #1, there
% #1 can contain arbitrarily many keys (here we only have one, but in principle it can)
\tikzset{EE/.cd,#1}
% \pgfkeysvalueof{/tikz/EE/h} is the value of h in the /tikz/EE/ directory
% the non-deprecated syntax for the circle path construction is
% \draw circle[radius=<value>];
\draw (0,0) circle [radius={0.5*\pgfkeysvalueof{/tikz/EE/h}*1pt}];
\end{tikzpicture}%
}
\begin{document}
\centering
\circleDraw{h=40}
\end{document}
当然,
\documentclass{standalone}
\usepackage{tikz}
\tikzset{EE/.cd,h/.initial=1}
\newcommand{\circleDraw}[1]{%
\begin{tikzpicture}
\tikzset{EE/.cd,#1}
\draw (0,0) circle [radius={0.5*{\pgfkeysvalueof{/tikz/EE/h}}[0]*1pt}];
\end{tikzpicture}%
}
\begin{document}
\centering
\circleDraw{h=40}
\end{document}
也可以,但此时你只有一个元素的列表。
附录:这是一个具有多个键的更复杂的例子。
\documentclass{article}
\usepackage{tikz}
% EE/.cd serves two purposes: define a directory EE and switch to it
% h/.initial=1 just means we introduce a key "h" and assign it the
% initial value 1, the other keys are analogous
\tikzset{EE/.cd,h/.initial=10,r/.initial=5,color 1/.initial=black,color 2/.initial=black,}
\newcommand{\circleDraw}[1]{%
\begin{tikzpicture}
% this says switch to the EE directory and put the argument, #1, there
% #1 can contain arbitrarily many keys
\tikzset{EE/.cd,#1}%
% it is often more convenient to have a shortcut for \pgfkeysvalueof{...}
% (of course, this macro is *local*)
\def\pv##1{\pgfkeysvalueof{/tikz/EE/##1}}%
% \pgfkeysvalueof{/tikz/EE/h} is the value of h in the /tikz/EE/ directory
% the non-deprecated syntax for the circle path construction is
% \draw circle[radius=<value>];
\draw[color=\pv{color 1}] (0,0) circle [radius={0.5*\pv{h}*1pt}];
\draw[color=\pv{color 2}] (0,0) circle [radius={0.5*\pv{r}*1pt}];
\end{tikzpicture}%
}
\begin{document}
\subsection*{Basic example}
For most of the values the initial values are taken, except for \texttt{h}.
\circleDraw{h=40}
\subsection*{Somewhat more complex example}
Now we change all values.
\circleDraw{h=50,r=20,color 1=blue,color 2=red}
\subsection*{Overriding the initial values}
Assume you want to have the circle of radius \texttt{h} always to be purple from
now on. Then you could do
\tikzset{EE/color 1=purple}
\circleDraw{h=40}~\circleDraw{h=50,r=20,color 2=red}
\dots but still the local argument ``wins''.
\circleDraw{h=50,r=20,color 1=blue,color 2=red}
\end{document}
不过,我要强调的是,这仅突出了 pgf 键的一小部分功能。如果您开始使用它们,最终您会真正喜欢上更高级的键,例如、/.search also
等等。/.try
/.expanded
答案2
你有一个误解。keyval
不会改变提供给某些宏的参数#1
,而只会使用该参数。因此,在代码中,\define@key
你可以使用提供给某些键的值#1
,但这是仅有的无论是内部\define@key
还是外部,#1
都仍然具有其没有它时的意义。
它的作用\define@key
是创建一个接受一个参数的宏,然后您可以指定该宏应该如何处理其参数。该宏定义稍后将被调用,\setkeys
并使用赋给定义键的值作为参数。
因此,如果您想定义一个h
键,您需要让该键定义一些临时的宏来存储赋予它的值,以便该值可以在宏的其余部分中使用。
\documentclass{standalone}
\usepackage{tikz}
\usepackage{keyval}
\makeatletter
% make sure \enthusiastic@h has an initial value and exists, even if the h key
% isn't used later.
\newcommand*\enthusiastic@h{0}
\define@key{enthusiastic}{h}{\pgfmathsetmacro\enthusiastic@h{#1}}
\newcommand{\circleDraw}[1]
{%
\begin{tikzpicture}
\setkeys{enthusiastic}{#1}% this will parse #1 and call the key-macros
\draw (0,0) circle ({0.5*\enthusiastic@h});
\end{tikzpicture}%
}
\makeatother
\begin{document}
\centering
\circleDraw{h=40}
\end{document}
答案3
使用expkv-cs
它可以定义一个宏,该宏采用单个 key=value 参数并将其拆分为不同的参数,然后您可以通过 引用#1
它#9
。
\documentclass[]{article}
\usepackage{tikz}
\usepackage{expkv-cs}
\ekvcSplit\circleDraw
{% fallback values if the keys aren't used
h=0 % #1
,color=black % #2
}
{%
\begin{tikzpicture}
\draw[#2] (0,0) circle[radius={0.5*#1}];
\end{tikzpicture}%
}
\begin{document}
\circleDraw{h=5pt}
\circleDraw{color=red, h=10pt}
\end{document}