我在看检查pgfkey的值 但我不想使用etoolbox
。
我找到了一种方法,但我不确定它是否正确,我想找到更简洁的方法。我的问题是使用密钥时测试所有情况。
它被调用from
并与宏一起使用test
。我考虑了以下情况:
\test[](a,b)
或者\test(a,b)
\test[from](a,b)
\test[from=](a,b)
\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}
注意:我使用\empty
LaTeX 定义的宏。
答案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..\endcsname
pgf@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}