检查密钥值的最佳方法(pgfkey)

检查密钥值的最佳方法(pgfkey)

我在看检查pgfkey的值 但我不想使用etoolbox

我找到了一种方法,但我不确定它是否正确,我想找到更简洁的方法。我的问题是使用密钥时测试所有情况。

它被调用from并与宏一起使用test。我考虑了以下情况:

  1. \test[](a,b)或者\test(a,b)
  2. \test[from](a,b)
  3. \test[from=](a,b)
  4. \test[from=c](a,b)

我暂时放弃了这个案子from=d (d undefined)

\documentclass[border=1cm]{standalone} 
\usepackage{tikz}
\def\empty{}
\makeatletter
\def\test{\pgfutil@ifnextchar[{\@test}{\@test[]}}
\pgfkeys{/test/.cd,
  from/.store in           = \from,
  from                     = {}}
  
\def\@test[#1](#2,#3){%
\begingroup
\pgfqkeys{/test}{#1}
\ifx\from\empty%
  \draw[red] (#2) -- (#3);
\else 
\expandafter\ifx\expandafter\pgfkeysnovalue\from\relax
  \draw[blue] (#2) -- (#3);
  \else
 \draw[green] (\from) -- (#3);
 \fi
 \fi
 \endgroup
}
\makeatother
\begin{document} 
\begin{tikzpicture}
\coordinate (a) at (0,0);
\coordinate (b) at (3,0);
\coordinate (c) at (1,2);
\test(a,b)
\end{tikzpicture}
\begin{tikzpicture}
\coordinate (a) at (0,0);
\coordinate (b) at (3,0);
\coordinate (c) at (1,2);
\test[from](a,b)
\end{tikzpicture}
\begin{tikzpicture}
\coordinate (a) at (0,0);
\coordinate (b) at (3,0);
\coordinate (c) at (1,2);
\test[from=](a,b)
\end{tikzpicture}
\begin{tikzpicture}
\coordinate (a) at (0,0);
\coordinate (b) at (3,0);
\coordinate (c) at (1,2);
\test[from=c](a,b)
\end{tikzpicture}
\end{document}

我的代码正确吗?还有其他什么可能性?是否可以避免同时进行这两项测试?

在此处输入图片描述

答案1

这里有一个具有两种变体的解决方案:简单的 pgf 键(key1)和密钥存储其自己的宏(key2)。

\documentclass[border=1cm]{standalone} 
\usepackage{tikz}
\makeatletter
\pgfkeys{/test/.is family}
\def\test@set#1{\pgfkeys{test,#1}}
\test@set{
  key1/.initial={initial 1},
  key1/.default={default 1},
  %
  key2/.store in=\test@keytwo,
  key2={initial 2},
  key2/.default={default 2},
}

\def\test{\pgfutil@ifnextchar[{\@test}{\@test[]}}
\def\@test[#1](#2,#3){%
  \begingroup
  \test@set{#1}
  %
  \pgfkeysgetvalue{/test/key1}\test@keyone
  key1=\pgfkeysvalueof{/test/key1}
  (\ifx\test@keyone\empty empty\else not empty\fi),
  %
  key2=\test@keytwo{}
  (\ifx\test@keytwo\empty empty\else not empty\fi),
  %
  2=#2,
  %
  3=#3
  \par
  \endgroup
}
\makeatother
\begin{document}
\begin{minipage}{16cm}
  \test(a,b)
  \test[key1,key2](a,b)
  \test[key1=test 1,key2=test 2](a,b)
  \test[key1=,key2=](a,b)
\end{minipage}
\end{document}

在此处输入图片描述

注意:我使用\emptyLaTeX 定义的宏。

答案2

我认为你可以解决以下情况:

  • 根本没有提供 from-key。
  • 提供的 from-key 没有值。
  • from-key 被赋予了空值。(我不知道是否真的需要推出这个案例 - 据我所知,你可以定义“无名”坐标/节点。)
  • from-key 所赋予的值可以是坐标/节点的名称,但并不表示所定义的坐标/节点。
  • from-key 被赋予一个值,该值表示定义的坐标/节点的名称。

\@undefined下面的例子(在执行\@test和时依赖于未定义\choosecolordraw)显示了我如何做到这一点。

然而,下面的例子并没有证明这一点

  • from-key 所赋予的值不能是坐标/节点的名称。

我认为解决该案例并不容易:
如果我正确理解了 tikz 文档/实现,则名称为模式的控制序列标记是通过从节点/坐标的名称形成的。因此,检查值是否可以/不能是坐标/节点的名称意味着检查标记是否可以在内部安全使用。我不知道是否可以在内部使用任意标记序列的 100% 可靠检查。pgf@sh@ns@⟨name of coordinate/node⟩\csname..\endcsnamepgf@sh@ns@⟨name of coordinate/node⟩\csname..\endcsname\csname..\endcsname

\documentclass[border=1cm]{standalone} 
\usepackage{tikz}
\makeatletter
\pgfkeys{/test/.cd, from/.store in = \from,}%
\newcommand\from{}%
\newcommand*\test{\pgfutil@ifnextchar[{\@test}{\@test[]}}%
\@ifdefinable\@test{%
  \def\@test[#1](#2,#3){%
    \begingroup
    \let\from\@undefined
    \pgfqkeys{/test}{#1}%
    \choosecolordraw{from}{#2}{teal}{blue}{red}{yellow}{green} -- (#3);
    \endgroup
  }%
}%
\newcommand\choosecolordraw[7]{%
  % #1 - Name of macro that should expand to name of from-node/from-coordinate.
  %      That macro is undefined when the from-key is not provided at all.
  % #2 - Default-node if macro whose name is provided is undefined or
  %      expands to no-value-marker or expands to emptiness or does not
  %      denote a defined node/coordinate.
  % #3 - Color if macro whose name is provided is undefined.
  % #4 - Color if macro whose name is provided expands to pgfkey's no-value-marker.
  %      This is the case when the from-key is provided without value.
  % #5 - Color if macro whose name is provided expands to emptiness.
  %      This is the case when the from-key is provided with empty value.
  %      I don't know if cranking out this case  is really needed - afaik you can define the "nameless" \coordinate.
  % #6 - Color if macro whose name is provided expands to a value that doesn't denote a defined coordinate/node.
  %      This is the case when the from-key is provided with a value that could be the name of a coordinate/node but 
  %      does not denote a coordinate/node that is defined.
  % #7 - Color if macro whose name is provided expands to a value that does denote a defined coordinate/node.
  %      This is the case when the from-key is provided with a value that denotes the name of a coordinate/node that is defined.
  \@ifundefined{#1}%
               {\draw[{#3}] (#2) }%
               {%
                 \expandafter\expandafter\expandafter\fromfork
                 \expandafter\expandafter\expandafter{\csname#1\endcsname}{#2}{#4}{#5}{#6}{#7}%
               }%
}%
\newcommand\fromfork[6]{%
  % #1 - From-node.
  % #2 - Default-node.
  % #3 - Color if macro whose name is provided expands to pgfkey's no-value-marker.
  % #4 - Color if macro whose name is provided expands to emptiness.
  % #5 - Color if macro whose name is provided expands to a value that doesn't denote a defined coordinate/node.
  % #6 - Color if macro whose name is provided expands to a value that does denote a defined coordinate/node.
  \ifcat$\detokenize\expandafter{\gobbletoexclam#1!}$%
  \expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi
  {%
    \forkfrom
    !#1!\pgfkeysnovalue!{\draw[{#4}] (#2) }% #1 is empty
    !!#1!{\draw[{#3}] (#2)}% #1 is \pgfkeysnovalue
    !!\pgfkeysnovalue!{% #1 is s.th else where testing is needed whether it is a defined node.
      \@ifundefined{pgf@sh@ns@#1}{\draw[{#5}] (#2) }{\draw[{#6}] (#1) }%
    }%
    !!!!%
  }{%
    % The argument holding name of node/coordinate contains ! and therefore
    % using !-delimited macro is unsafe. But the presence of ! implies exclusion of the cases
    % - from-key not being provided at all
    % - from-key being provided with no value
    % - from-key being provided with empty value
    \@ifundefined{pgf@sh@ns@#1}{\draw[{#5}] (#2) }{\draw[{#6}] (#1) }%
  }%
}%
\@ifdefinable\gobbletoexclam{\long\def\gobbletoexclam#1!{}}%
\@ifdefinable\forkfrom{\long\def\forkfrom#1!!\pgfkeysnovalue!#2#3!!!!{#2}}%
\makeatother
\begin{document}
\vbox{\hbox{%
\begin{tikzpicture}
\coordinate (a) at (0,0);
\coordinate (b) at (3,0);
\coordinate (c) at (1,2);
\test(a,b)
\end{tikzpicture}
}\hbox{\tiny from-key not provided}}%
\kern1em\vrule\kern1em
\vbox{\hbox{%
\begin{tikzpicture}
\coordinate (a) at (0,0);
\coordinate (b) at (3,0);
\coordinate (c) at (1,2);
\test[from](a,b)
\end{tikzpicture}
}\hbox{\tiny from-key provided without value}}%
\kern1em\vrule\kern1em
\vbox{\hbox{%
\begin{tikzpicture}
\coordinate (a) at (0,0);
\coordinate (b) at (3,0);
\coordinate (c) at (1,2);
\test[from=](a,b)
\end{tikzpicture}
}\hbox{\tiny from-key provided with empty value}}%
\kern1em\vrule\kern1em
\vbox{\hbox{%
\begin{tikzpicture}
\coordinate (a) at (0,0);
\coordinate (b) at (3,0);
\coordinate (c) at (1,2);
\test[from=d](a,b)
\end{tikzpicture}
}\hbox{\tiny from-key provided with undefined coordinate}}%
\kern1em\vrule\kern1em
\vbox{\hbox{%
\begin{tikzpicture}
\coordinate (a) at (0,0);
\coordinate (b) at (3,0);
\coordinate (c) at (1,2);
\test[from=c](a,b)
\end{tikzpicture}
}\hbox{\tiny from-key provided with defined coordinate}}%
\end{document}

在此处输入图片描述

相关内容