声明 这本是个绘图问题,然而 pgfkeys 具有通用性,类似的问题可以出现在非 tikz 环境中,因而问题分类是"宏编程".
我的问题 我希望用 pgfkeys 构造一个绘图命令:\mydraw
,为了简化问题,它只带一个键值对:color = <line color>
, 但我希望它还允许其他的 "draw 的参数" (键值对)加入。以下是它的定义过程:
\documentclass{article}
\usepackage{tikz}
\pgfkeys{%
/mycmd/.is family,
/mycmd/.cd,
default/.style={color=black},
color/.store in = \mycmdcolor,
}
\pgfkeys{%
/tikz/mycmd/.code args={#1}{%
\pgfkeys{/mycmd, default, #1}
\pgfkeysalso{color=\mycmdcolor,}
}
}
\newcommand{\mydraw}[1][]{%
\draw[mycmd={#1}] (0,0) -- (4,0); }
\begin{document}
\begin{tikzpicture}
\mydraw[color=blue]
\end{tikzpicture}
\end{document}
但我希望它可以这样调用
\begin{tikzpicture}
\mydraw[color=blue, option1, option2,...]
\end{tikzpicture}
甚至
\begin{tikzpicture}
\mydraw[option1, option2, ...]
\end{tikzpicture}
或者退而求次
\begin{tikzpicture}
\mydraw[[color=blue], option1, option2,...]
\end{tikzpicture}
其中,option1, option2,...
是标准的 \draw
的可选参数(键值对)形式,诸如 ->, line width = <num>, dashed
等等。
我对 pgfkeys
以及宏编程几乎一窍不通,我不确定这是个 pgfkeys
方面的问题,还是它就是一般的宏编程问题?
请问该如何解决?谢谢。
最简单的办法是加上这行
\pgfkeys{...
/mycmd/.search also={/tikz}, % <- 自动找 /tikz/...
}
\documentclass{article}
\usepackage{tikz}
\pgfkeys{%
/mycmd/.is family,
/mycmd/.cd,
/mycmd/.search also={/tikz},
default/.style={color=black},
color/.store in = \mycmdcolor,
}
\pgfkeys{%
/tikz/mycmd/.code args={#1}{%
\pgfkeys{/mycmd, default, #1}
\pgfkeysalso{color=\mycmdcolor,}
}
}
\newcommand{\mydraw}[1][]{%
\draw[mycmd={#1}] (0,0) -- (4,0); }
\begin{document}
\begin{tikzpicture}
\mydraw[color=blue, line width=1mm]
\end{tikzpicture}
\end{document}
要解决你的问题,我们需要让 mydraw 命令能够同时处理自定义的键值对(如 color)和标准的 TikZ 绘图选项。以下是改进后的解决方案:
\documentclass{article}
\usepackage{tikz}
\pgfkeys{
/mycmd/.is family,
/mycmd/.cd,
default/.style={color=black},
color/.store in = \mycmdcolor,
color=black, % 默认值
}
\newcommand{\mydraw}[1][]{%
\pgfkeys{/mycmd, default}% 先设置默认值
\pgfkeys{/mycmd, #1}% 处理用户提供的键值
\edef\myoptions{color=\mycmdcolor}% 基础选项
\pgfkeysgetvalue{/mycmd/@unknown}{\unknownkeys}% 获取未知键
\ifx\unknownkeys\empty\else
\edef\myoptions{\myoptions, \unknownkeys}% 添加未知键
\fi
\draw[\myoptions] (0,0) -- (4,0);%
}
\begin{document}
\begin{tikzpicture}
\mydraw[color=blue, ->, thick, dashed]
\mydraw[->, thick, dashed] % 使用默认颜色
\mydraw[red, line width=2pt] % 直接使用颜色名
\end{tikzpicture}
\end{document}
解决方案说明:
键处理机制:
我们使用 /mycmd 命名空间来处理自定义键(如 color)
默认值设为 black
使用 .store in 存储 color 值到 mycmdcolor
处理未知键:
pgfkeys 会自动将无法识别的键存储在 /mycmd/@unknown 中
我们通过 pgfkeysgetvalue 获取这些未知键
如果存在未知键,将它们添加到绘图选项中
灵活的调用方式:
可以混合使用自定义键和标准 TikZ 选项
可以直接使用颜色名(如 red)而不必写 color=red
支持所有标准 draw 选项(如 ->, thick, dashed 等)
调用示例:
\begin{tikzpicture}
\mydraw[color=blue, ->, thick, dashed] % 指定颜色和样式
\mydraw[->, thick, dashed] % 使用默认颜色
\mydraw[red, line width=2pt] % 直接使用颜色名
\mydraw[] % 完全使用默认值
\end{tikzpicture}
这种方法既保持了自定义键的处理能力,又能无缝集成所有标准 TikZ 绘图选项。
谢谢雾月大佬,很大程度上解决,但对于箭头似乎不行,以下代码报错
报错信息
@u26254 删掉
,/pgf
就行了,如果最后一项是/tikz
会自动找->
等箭头。@u10307 明白了,谢谢