我有一些宏,它们将键列表作为参数,并将此列表传递给\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}