30 使用 pgfkeys 构造命令,在可选参数中附加参数 (代码)

发布于 2025-08-03 17:02:29

声明 这本是个绘图问题,然而 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}

image.png

但我希望它可以这样调用

\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 方面的问题,还是它就是一般的宏编程问题?

请问该如何解决?谢谢。

查看更多

关注者
0
被浏览
151
雾月
雾月 1天前
这家伙很懒,什么也没写!

最简单的办法是加上这行

\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}
2 个回答
海波
海波 1天前
这家伙很懒,什么也没写!

要解决你的问题,我们需要让 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 绘图选项。

撰写答案

请登录后再发布答案,点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览