pgfkeys、tikz 和个人宏之间的问题

pgfkeys、tikz 和个人宏之间的问题

以下最小工作示例显示了问题。 mainmacro 是我需要的示例;在这里我想使用我的键和来自 tikz 的键(如 draw、color、shape)。只有使用 . 时结果才正常。 是不够的shape = circlecircle如果我想要红色,则同上。color = red是强制性的。 我的代码有什么问题? 您知道实现我想要的更好的方法吗?

\documentclass[a4paper]{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\makeatletter
\pgfkeys{/mykeys/.cd,
d/.code                     = {\def\macro@d{#1}},   
a/.code                     = {\def\macro@a{#1}},
/mykeys/.unknown/.code      = {\let\searchname=\pgfkeyscurrentname
                                               \pgfkeysalso{\searchname/.try=#1,
                                                    /tikz/\searchname/.retry=#1}
                              }    
        }  
\def\mainmacro{\pgfutil@ifnextchar[{\main@macro}{\main@macro[]}}
\def\main@macro[#1](#2)#3{%
\begingroup
  \pgfkeys{mykeys/.cd,
           d = 1,
           a = 45}
  \pgfqkeys{/mykeys}{#1}
  \path (#2) --+(\macro@a:\macro@d) node[/mykeys/.cd,#1] {#3};
\endgroup
}
\makeatother

\begin{document} 

    \begin{tikzpicture}
        \draw (0,0) --( 1,1) coordinate (a) ;
        \mainmacro[a=0,d=12pt,draw,shape=circle](a){label 1}    
        \mainmacro[d=2cm,draw,circle](a){label 2}       
    \end{tikzpicture}

\end{document}

在此处输入图片描述

更新

\documentclass[a4paper]{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\makeatletter
\pgfkeys{/mykeys/.cd,
d/.store in                 = {\macro@d},   
a/.store in                 = {\macro@a},
/mykeys/.unknown/.code      = {\let\searchname=\pgfkeyscurrentname
                                               \pgfkeysalso{\searchname/.try=#1,
                                                    /tikz/\searchname/.retry=#1,
                                                    /tikz/.cd,#1}}}  

\def\mainmacro{\pgfutil@ifnextchar[{\main@macro}{\main@macro[]}}
\def\main@macro[#1](#2){%
\begingroup
\pgfkeys{mykeys/.cd,
           d = 1,
           a = 1}
\pgfqkeys{/mykeys}{#1}

\draw[/mykeys/.cd,#1] (\macro@a,\macro@a) circle (\macro@d) --++(1,1) node[#1] {label};% 
\endgroup
}
\makeatother

\begin{document} 
    \begin{tikzpicture}
        \draw (0,0) -- (5,0) ;
        \mainmacro[red,ultra thick](a)       
    \end{tikzpicture}

\end{document}

在此处输入图片描述

这个技巧对节点有效,但对节点无效,\draw也许我的代码中某处是错的

答案1

发生这种情况是因为形状、颜色名称(和一些其他内容)不是键。换句话说,当您写入reddiamond时,它没有针对此类内容的专用键。因此,它会通过 TikZ 机制,searchname/.retry但由于没有这样的键,它会失败。相反,/tikz/.unknown/.code它更加全面和复杂。例如

{%
        % Ok, second chance: This might be an arrow specification:
        \expandafter\pgfutil@in@\expandafter-\expandafter{\tikz@key}%
        \ifpgfutil@in@%
          % Ah, an arrow spec!
          \expandafter\tikz@processarrows\expandafter{\tikz@key}%
        \else%
          % Ok, third chance: A shape!
          \expandafter\ifx\csname pgf@sh@s@\tikz@key\endcsname\relax%
            \pgfkeys{/errors/unknown key/.expand
            once=\expandafter{\expandafter/\expandafter t\expandafter
            i\expandafter k\expandafter z\expandafter/\tikz@key}{##1}}%
          \else%
            \edef\tikz@shape{\tikz@key}%
          \fi%
        \fi%
      }%

我想到两种方法来做到这一点:

  1. 您可以在密钥试验结束时明确传递给 TikZ,让它决定要做什么。因此,您添加以下内容

    \pgfkeys{/mykeys/.cd,
    d/.store in            = {\macro@d},   
    a/.store in            = {\macro@a},
    /mykeys/.unknown/.code = {\let\searchname=\pgfkeyscurrentname%
                              \pgfkeysalso{\searchname/.try=#1,
                              /tikz/\searchname/.retry=#1,
                              /tikz/.cd,#1}% <--- Now invoked under TikZ
                             }
    }  
    

    这里,我们明确触发 TikZ 未知机制,因为现在该系列是 TikZ。因此会进行所有形状名称检查等等。

  2. 编写自己的/.unknown/.code处理程序来处理已知名称。例如使 PGFkeys 路径在整个范围内优先于其他路径有几个例子。

答案2

这里有两个简单的解决方案。

第一个解决方案(更好?)

您可以使用/.search also处理程序(参见 pgfmanual v3.0.1a 的第 891 页):

\documentclass[a4paper]{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\makeatletter
\pgfkeys{
  /mykeys/.cd,
  d/.code                     = {\def\macro@d{#1}},   
  a/.code                     = {\def\macro@a{#1}},
  /mykeys/.search also={/tikz},
}  
\def\mainmacro{\pgfutil@ifnextchar[{\main@macro}{\main@macro[]}}
\def\main@macro[#1](#2)#3{%
\begingroup
  \pgfkeys{mykeys/.cd,
           d = 1,
           a = 45}
  \pgfqkeys{/mykeys}{#1}
  \path (#2) --+(\macro@a:\macro@d) node[/mykeys/.cd,#1] {#3};
\endgroup
}
\makeatother

\begin{document} 

    \begin{tikzpicture}
        \draw (0,0) --( 1,1) coordinate (a) ;
        \mainmacro[a=0,d=12pt,draw,red,shape=circle](a){label 1}    
        \mainmacro[d=2cm,draw,circle](a){label 2}       
    \end{tikzpicture}

\end{document}

第二种解决方案

您可以使用/.forward to处理程序(参见 pgfmanual v3.0.1a 的第 890 页):

\documentclass[a4paper]{article}
\usepackage{tikz}
\usetikzlibrary{calc}

\makeatletter
\pgfkeys{
  /mykeys/.cd,
  d/.code                     = {\def\macro@d{#1}},   
  a/.code                     = {\def\macro@a{#1}},
  /mykeys/.unknown/.forward to=/tikz/\pgfkeyscurrentname,
}  
\def\mainmacro{\pgfutil@ifnextchar[{\main@macro}{\main@macro[]}}
\def\main@macro[#1](#2)#3{%
\begingroup
  \pgfkeys{mykeys/.cd,
           d = 1,
           a = 45}
  \pgfqkeys{/mykeys}{#1}
  \path (#2) --+(\macro@a:\macro@d) node[/mykeys/.cd,#1] {#3};
\endgroup
}
\makeatother

\begin{document} 
    \begin{tikzpicture}
        \draw (0,0) --( 1,1) coordinate (a) ;
        \mainmacro[a=0,d=12pt,draw,red,shape=circle](a){label 1}    
        \mainmacro[d=2cm,draw,circle](a){label 2}       
    \end{tikzpicture}
\end{document}

相关内容