处理多个命名空间中的 pgf 键

处理多个命名空间中的 pgf 键

我有一些宏,它们将键列表作为参数,并将此列表传递给\tikzset每个使用特定命名空间的 。在下面的示例中,这种类型的宏将是\marmot\koala。到目前为止,一切都运行良好。

现在我想\thing从这些宏中调用另一个宏(我们称之为),它再次具有一个\tikzset唯一的命名空间。

目前我只是将完整的键列表传递给\thing宏,这会产生两种可能性:

  • 要么它抱怨未知的密钥,例如如果hat,teeth传递给marmot\thing只知道hat但不知道teeth,这是密钥的marmot

  • 我可以添加一个解决方法/marmot,/koala.search also但是一旦有大量不同的宏可以调用,维护起来就会很烦人\thing

有没有更好的方法来解决这个困境?

\documentclass{article}
\usepackage{tikz}

% things %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand*{\thing}[1][]{%
    \begin{scope}%
        \tikzset{/thing/.cd,#1}%
        \fill[black] (0,0) rectangle (0.3,0.3);
    \end{scope}%
}

\tikzset{
  /thing/.search also={/tikz,/pgf,
    /marmot,/koala % HERE: I'm looking for a better way than to list all possible namespaces
  },
  /thing/.cd,
  hat/.code = {},
}

% marmot %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand*{\marmot}[1][]{%
    \begin{scope}%
        \tikzset{/marmot/.cd,#1}%
        \fill[brown] (0.15,-0.3) ellipse (0.3 and 0.5);
    \end{scope}%
    \thing[#1]%
}

\tikzset{
  /marmot/.search also={/tikz,/pgf,/thing},
  /marmot/.cd,
  teeth/.code = {},
}

% koala %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand*{\koala}[1][]{%
    \begin{scope}%
        \tikzset{/koala/.cd,#1}%
        \fill[gray] (0.15,-0.3) ellipse (0.3 and 0.5);
    \end{scope}%
    \thing[#1]%
}

\tikzset{
  /koala/.search also={/tikz,/pgf,/thing},
  /koala/.cd,
  sleep/.code = {},
}

\begin{document}

\begin{tikzpicture}
\thing[hat]
\end{tikzpicture}

\bigskip

\begin{tikzpicture}
\marmot[teeth]
\end{tikzpicture}

\bigskip

\begin{tikzpicture}
\koala[sleep]
\end{tikzpicture}

\bigskip

\begin{tikzpicture}
\marmot[hat,teeth]
\end{tikzpicture}

\end{document}

第二层疯狂

为了让事情变得更加复杂,我还有一个宏,我事先不知道我最终会得到一只土拨鼠还是考拉

% tikzling %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\pgfmathdeclarerandomlist{tikzlings}{{\marmot}{\koala}}
\newcommand{\tikzling}[1][]{%
    \tikzset{%
      /thing/.search also={/tikz,/pgf,/marmot,/koala}
    }
    \pgfmathrandomitem{\tikzlingrandom}{tikzlings}%
    \tikzlingrandom[#1]
}

这意味着\tikzling[hat,teeth]有一半的时间会导致错误......

如果它可以帮助任何人看到完整的代码,可以从https://github.com/samcarter/tikzlings

答案1

由于您只想避免使用不在当前命名空间中的键,但又不想在这个地方对它们进行任何操作,所以您能做的只是\relax所有未知的事情。

\pgfkeys{/thing/.unknown/.code=\relax}

这些键将在其他命令中再次调用,因此它们的定义不会丢失。当然,缺点是您无法对这些未知键执行任何特定操作,因为所有键都将被\relax编辑。

这有效:

 \documentclass{article}
\usepackage{tikz}

% things %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand*{\thing}[1][]{%
    \begin{scope}%
        \tikzset{/thing/.cd,#1}%
        \fill[black] (0,0) rectangle (0.3,0.3);
    \end{scope}%
}

\pgfkeys{/thing/.unknown/.code=\relax}

\tikzset{
  %/thing/.search also={/tikz,/pgf,
    %/marmot,/koala % HERE: I'm looking for a better way than to list all possible namespaces
  %},
  /thing/.cd,
  hat/.code = {},
}

% marmot %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand*{\marmot}[1][]{%
    \begin{scope}%
        \tikzset{/marmot/.cd,#1}%
        \fill[brown] (0.15,-0.3) ellipse (0.3 and 0.5);
    \end{scope}%
    \thing[#1]%
}

\pgfkeys{/marmot/.unknown/.code=\relax}

\tikzset{
  %/marmot/.search also={/tikz,/pgf,/thing},
  /marmot/.cd,
  teeth/.code = {},
}

% koala %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
\newcommand*{\koala}[1][]{%
    \begin{scope}%
        \tikzset{/koala/.cd,#1}%
        \fill[gray] (0.15,-0.3) ellipse (0.3 and 0.5);
    \end{scope}%
    \thing[#1]%
}

\pgfkeys{/koala/.unknown/.code=\relax}

\tikzset{
  %/koala/.search also={/tikz,/pgf,/thing},
  /koala/.cd,
  sleep/.code = {},
}

\begin{document}

\begin{tikzpicture}
\thing[hat]
\end{tikzpicture}

\bigskip

\begin{tikzpicture}
\marmot[teeth]
\end{tikzpicture}

\bigskip

\begin{tikzpicture}
\koala[sleep]
\end{tikzpicture}

\bigskip

\begin{tikzpicture}
\marmot[hat,teeth]
\end{tikzpicture}

\end{document}

在此处输入图片描述

相关内容