我想编写一个命令,允许用户更改 tikz 样式。我的代码如下:
\documentclass{article}
\usepackage{tikz,xkeyval}
\makeatletter
\def\DEFstyle{}
\define@key{styles}{styleA}{\def\DEFstyle{#1}}
\newcommand{\setstyles}[1]{%
\setkeys{styles}{styleA={}}
\setkeys{styles}{#1}
\tikzstyle{TIKZSTYLE}=[\DEFstyle]
}
\makeatother
\begin{document}
\setstyles{styleA={top color=green,bottom color=red}}
\end{document}
但是,我总是收到一条错误消息:
!软件包 pgfkeys 错误:我不知道密钥“/tikz/top color=green,bottom color=red”,我将忽略它。也许你拼错了。
但是的内容\DEFstyle
肯定是top color=green,bottom color=red
,当我直接写入时\tikzstyle{TIKZSTYLE}=[top color=green,bottom color=red]
,一切正常。错误隐藏在哪里?
答案1
首先,
\tikzstyle{<key>}=[<value>]
是相同的
\tikzset{<key>/.style={<value>}}
从现在起,我将只使用语法\tikzset
(→应该使用 \tikzset 还是 \tikzstyle 来定义 TikZ 样式?)。但是您在使用 时也会遇到同样的问题\tikzset
。
分配不是问题,样式TIKZStyle
仅包含您对的参数styleA
。但是当 TikZ 执行此样式时(例如,当\draw[TIKZSTYLE]
),它首先看到\DEFstyle
它的定义并尝试将其作为键,但名为的键top color=green,bottom color=red
(对于 TikZ,这只是此刻的一个“字符串”)不存在。
即使top color=green
不起作用,因为 TikZ 也无法识别=
中的隐藏项\DEFstyle
。
唯一可行的是没有参数的样式,例如
\setstyles{styleA={rounded corners}}%
\tikz \draw[TIKZSTYLE] (0,0) rectangle (1em,2ex);
结果是。但即使这样也不够安全:
\setstyles{styleA={rounded corners}}%
\def\DEFstyle{fill}%
\tikz \draw[TIKZSTYLE] (0,0) rectangle (1em,2ex);
(但是再次,@
在\DEFstyle
宏的名称中添加一些...)。
\DEFstyle
这些是我们在将其分配给样式之前需要进行扩展的原因TIKZSTYLE
:
\tikzset{TIKZSTYLE/.style/.expand once=\DEFstyle}%
在您对宏的定义中\setstyles
存在一些虚假空格:
- 行末百分号(%)有什么用?
- 为什么宏定义中要用到行尾%?
- 以及数十个相关问题……
我不太了解您的项目,但提醒一下,您可以使用 PGF 键完成所有操作。请参阅第二个代码块。
代码
\documentclass[tikz]{standalone}
\usepackage{xkeyval}
\makeatletter
\def\DEFstyle{}
\define@key{styles}{styleA}{\def\DEFstyle{#1}}
\newcommand{\setstyles}[1]{%
\setkeys{styles}{styleA={}}%
\setkeys{styles}{#1}%
\tikzset{TIKZSTYLE/.style/.expand once=\DEFstyle}%
}
\makeatother
\begin{document}
\setstyles{styleA={top color=green,bottom color=red}}
\tikz \draw[TIKZSTYLE] (0,0) rectangle (1em,2ex);
\end{document}
代碼(無- xkeyval
)
\documentclass[tikz]{standalone}
\pgfkeys{
/no xkeyval/styleA/.style={
/tikz/TIKZSTYLE/.style={#1}
}
}
\newcommand*{\setstyles}[1]{%
\pgfqkeys{/no xkeyval}{#1}%
}
\begin{document}%
\setstyles{styleA={top color=green,bottom color=red}}%
\tikz \draw[TIKZSTYLE] (0,0) rectangle (1em,2ex);
\end{document}
答案2
一种用途键值包可能会预设一些键,以便在没有为它们提供用户值时可以使用它们的预设值。
\documentclass{article}
\usepackage{tikz,xkeyval}
\makeatletter
\define@key{styles}{color set}{\def\rectstyle{#1}}
\define@key{styles}{rect size}{\def\rectsize{#1}}
\presetkeys{styles}{color set={top color=white,bottom color=gray},rect size={5em,5em}}{}
\newcommand*{\setstyles}[1][]{%
\setkeys{styles}{#1}%
\edef\tempa{\unexpanded{\tikz\draw}[\rectstyle](0,0)rectangle(\rectsize)}\tempa;
}
\makeatother
\begin{document}
\begin{tikzpicture}
\setstyles
\hspace{1cm}
\setstyles[color set={top color=green,bottom color=red},rect size={5ex,6ex}]
\hspace{1cm}
\setstyles[rect size={10ex,8ex}]
\end{tikzpicture}
\end{document}