编辑

编辑

目前,我将所有tikz/pgf键/样式都放在全局范围内。但是,我现在想更正确地做到这一点,以免用无用的样式污染全局范围,我的目标是将样式分组到一个通用名称中,例如:

styleA/.style={
  amazing/.style={fill=red},
},
styleB/.style={
  amazing/.style={fill=orange},
}

然后我只需使用\node[styleA,amazing](或使用every node自动加载样式)加载给定的样式。

上面的代码运行良好……除非我为样式添加参数。然后我需要使用##1而不是#1来定位第一个参数(否则我猜它会采用父“styleA”对象的参数):

  mystyleA/.style={
    amazingCode/.style={fill=##1},
    amazingCode/.default=red,
  }

但是,它有点容易出错... 而有些库则\tikzcd没有这个问题。相反,它们会做一些事情styleA/.cd,但由于某些原因,如果在 中找不到键,它们会设法回退到 tikz styleA... 他们怎么能这样做呢?

编辑

在我找到答案的第一部分后,我仍然有一个问题:我可以执行\node[/mystyleDcd/.cd,amazingCode],但我无法/mystyleDcd使用移动every node/.prefix style{...}。知道为什么吗?

平均能量损失

\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-cd}
\usetikzlibrary{positioning}

\begin{document}

\pgfqkeys{/mystyleDcd}{
  .search also={/tikz}, % fallback to tikz, equivalent to /mystyleDcd/.search also={/tikz}
  default props/.style={
    shape=circle
  },
  amazingCode/.style={fill=#1}, % equivalent to /mystyleDcd/amazingCode/...
  amazingCode/.default=purple,
}

Works:
\begin{tikzpicture}
  \node[/mystyleDcd/.cd,amazingCode,text=green] {search also};
\end{tikzpicture}

Fails:
% \begin{tikzpicture}[every node/.prefix style={/mystyleDcd/.cd}]
%   \node[amazingCode,text=green] {search also};
% \end{tikzpicture}

\end{document}

答案1

好的,我终于找到了答案(当然不是全部,请参阅我的编辑)。 pgfkeys 中有一个键.search also(用法类似.search also={/tikz}),它允许您定义后备“文件夹”。这本身基于.unknown,并tikz-cd直接使用.unknown...我猜他们有一个很好的理由(可能是因为他们允许像这样的奇怪键rrrd),但在大多数情况下.search also就足够了:


\documentclass{article}
\usepackage{tikz}
\usepackage{tikz-cd}
\usetikzlibrary{positioning}

\begin{document}
\tikzset{
  mystyleA/.style={
    amazing/.style={fill=red},
    amazingCode/.style={fill=##1},
    amazingCode/.default=red,
  },
  mystyleB/.style={
    amazing/.style={fill=orange}
  },
  /mystyleC/amazing/.style={
    /tikz/fill=orange
  },
}

%% could also have been defined using:
%% /mystyleDcd/.cd, % Go to /mystyleDcd "folder"
%% .search also={/tikz}, % equivalent to /mystyleDcd/.search also={/tikz}. Fallback to tikz,
%% amazingCode/.style={fill=#1}, % equivalent to /mystyleDcd/amazingCode/...
%% amazingCode/.default=purple,

\pgfqkeys{/mystyleDcd}{
  .search also={/tikz}, % fallback to tikz, equivalent to /mystyleDcd/.search also={/tikz}
  amazingCode/.style={fill=#1}, % equivalent to /mystyleDcd/amazingCode/...
  amazingCode/.default=purple,
}


\section{Version with nested styles}
I can use tikz keys, redefine style locally...
\begin{tikzpicture}[mystyleA]
  \node[amazing]{Using nested mystyleA};
  \node[amazing,/tikz/text=green] at (3,0){/tikz/text};
  \node[mystyleB,amazing,text=green] at (5,0){text};
\end{tikzpicture}

With arguments:
\begin{tikzpicture}[mystyleA]
  \node[mystyleA,amazingCode] at (1,0){text};
  \node[mystyleA,amazingCode=yellow] at (5,0){text};
\end{tikzpicture}

\section{Version with cd}
I can't use tikz keys (see comments)
\begin{tikzpicture}%
  \node[/mystyleC/.cd,amazing] (a) {Forcing cd in node};
  \node[right=of a,/mystyleDcd/.cd,amazingCode,text=pink] {search also};
\end{tikzpicture}

\end{document}

答案2

回答你的第二个也是剩下的问题:

在我找到答案的第一部分后,我仍然有一个问题:我可以执行\node[/mystyleDcd/.cd,amazingCode],但我无法/mystyleDcd使用移动every node/.prefix style{...}。知道为什么吗?

首先是一些pgfkeys工作人员

pgfkeys,通过使用处理程序/mystyleDcd/.cd,您正在设置/mystyleDcd为新的默认路径

最初,默认路径为/,因此\pgfkeys{key1}相当于\pgfkeys{/key1}。还有另一个宏\pgfqkeys{<dpath>}{<keyvals>}相当于\pgfkeys{<dpath>/.cd, <keyvals>}

然后我们见面tikz

\tikzset定义为,\def\tikzset{\pgfqkeys{/tikz}}所以\tikz{<keyvals>}等同于\tikz{/tikz/.cd, <keyvals>}

这是关键点:在node内部(12), 用于输入\node[<options>],every node/.try并由<options>执行分离 \tikzsets. 因此节点选项总是在{scope}默认路径为 的范围(而不是环境)中进行解析/tikz

相关内容