如何知道样式的状态?已定义?空?

如何知道样式的状态?已定义?空?

mystyle/.style= {...}也许被使用?

我想知道如何验证样式是否真正定义,在这种情况下,我想知道样式是否为空?

是否可以使用\pgfkeysifdefined来获取第一个结果?

答案1

\documentclass{standalone}
\usepackage{tikz}
\makeatletter
\def\pgfkeysifstyledefined#1#2#3{%
  \pgfkeys@ifcsname pgfk@#1/.@cmd\endcsname#2\else#3\fi}

\def\pgfkeysifstyleempty#1{%
  \expandafter\expandafter\expandafter\pgfkeysifstyleempty@i
  \csname pgfk@#1/.@cmd\endcsname\pgfeov}

\def\pgfkeysifstyleempty@i\pgfkeysalso#1#2#3{%
  \if\relax\detokenize{#1}\relax
    #2%
  \else
    #3%
  \fi}
\makeatother

\begin{document}

\pgfkeysifstyledefined{/tikz/my style}{Defined}{Undefined}

\tikzset{my style/.style = {}}
\pgfkeysifstyledefined{/tikz/my style}{Defined}{Undefined}

\pgfkeysifstyleempty{/tikz/my style}{Empty}{Non empty}

\tikzset{my style/.style = {Test}}
\pgfkeysifstyleempty{/tikz/my style}{Empty}{Non empty}

\end{document}

答案2

看起来不是——.style是一个设置 的处理程序.code,而后者又是一个设置内部.@cmd属性的处理程序。使用 Ryan Reich 的非常酷的trace-pgfkeys包(来自这个问题),以下代码

\documentclass{article}
\usepackage{pgfkeys}
\usepackage[tracemacros]{trace-pgfkeys}
\pgfkeystracelevel{verbose}
\begin{document}
\makeatletter

\typeout{Setting /test1/.style}
\pgfkeys{/test1/.style={shape=rectangle}}
\typeout{Checking ifdefine /test1/.style}
\pgfkeysifdefined{/test1/.style}{True}{False}
\typeout{Checking ifdefine /test1/.code}
\pgfkeysifdefined{/test1/.code}{True}{False}
\typeout{Checking ifdefine /test1/.@cmd}
\pgfkeysifdefined{/test1/.@cmd}{True}{False}


\typeout{Checking ifdefine /test-missing/.style}
\pgfkeysifdefined{/test-missing/.style}{True}{False}
\typeout{Checking ifdefine /test-missing/.code}
\pgfkeysifdefined{/test-missing/.code}{True}{False}
\typeout{Checking ifdefine /test-missing/.@cmd}
\pgfkeysifdefined{/test-missing/.@cmd}{True}{False}

\typeout{Setting /test2/.style to nothing}
\pgfkeys{/test2/.style=}

\pgfkeysgetvalue{/test2/.@cmd}{\test}
\ifx\test\relax Empty \else Not empty \fi
\end{document}

生成以下文件:

False False True
False False False
Not empty

以及大量有用的调试输出,以下是设置的跟踪/test1/.style

Setting /test1/.style
[trace-pgfkeys]-: Tracing \pgfkeys call.
[trace-pgfkeys]-+ Key/value list: (/test1/.style={shape=rectangle})
[trace-pgfkeys]-+ Current key-value: (/test1/.style={shape=rectangle})
[trace-pgfkeys]-+ \pgfkeyscurrentkey (given): /test1/.style
[trace-pgfkeys]-: Full key; no path added.
[trace-pgfkeys]-> \pgfkeyscurrentkey : /test1/.style
[trace-pgfkeys]-+ \pgfkeyscurrentvalue : (shape=rectangle)
[trace-pgfkeys]-: Case one: key code?
[trace-pgfkeys]-: Case two: key value?
[trace-pgfkeys]-: Case three: key unknown. Splitting the path.
[trace-pgfkeys]-+ \pgfkeyscurrentpath (/test1)
[trace-pgfkeys]-+ \pgfkeyscurrentname (.style)
[trace-pgfkeys]-: Checking whether a handler is defined.
[trace-pgfkeys]-+ Executing all handlers.
[trace-pgfkeys]-: Tracing \pgfkeysgetvalue .
[trace-pgfkeys]-: Value: (\long macro:#1\pgfeov ->\pgfkeys {\pgfkeyscurrentpath /.code=\pgfkeysalso {#1}})
[trace-pgfkeys]--+ Storing key value in \pgfkeys@code 
[trace-pgfkeys]--> Storing: /handlers/.style/.@cmd 
[trace-pgfkeys]--+ Done storing.
[trace-pgfkeys]-: Handler code:
[trace-pgfkeys]-: \long macro:#1\pgfeov ->\pgfkeys {\pgfkeyscurrentpath /.code=\pgfkeysalso {#1}}
[trace-pgfkeys]--+ Executing handler.
[trace-pgfkeys]--> Handler: /handlers/.style
[trace-pgfkeys]---: Tracing \pgfkeys call.
[trace-pgfkeys]---+ Key/value list: (\pgfkeyscurrentpath /.code=\pgfkeysalso {shape=rectangle})
[trace-pgfkeys]---+ Current key-value: (\pgfkeyscurrentpath /.code=\pgfkeysalso {shape=rectangle})
[trace-pgfkeys]---+ \pgfkeyscurrentkey (given): /test1/.code
[trace-pgfkeys]---: Full key; no path added.
[trace-pgfkeys]---> \pgfkeyscurrentkey : /test1/.code
[trace-pgfkeys]---+ \pgfkeyscurrentvalue : (\pgfkeysalso {shape=rectangle})
[trace-pgfkeys]---: Case one: key code?
[trace-pgfkeys]---: Case two: key value?
[trace-pgfkeys]---: Case three: key unknown. Splitting the path.
[trace-pgfkeys]---+ \pgfkeyscurrentpath (/test1)
[trace-pgfkeys]---+ \pgfkeyscurrentname (.code)
[trace-pgfkeys]---: Checking whether a handler is defined.
[trace-pgfkeys]---+ Executing all handlers.
[trace-pgfkeys]---: Tracing \pgfkeysgetvalue .
[trace-pgfkeys]---: Value: (\long macro:#1\pgfeov ->\pgfkeysdef {\pgfkeyscurrentpath }{#1})
[trace-pgfkeys]----+ Storing key value in \pgfkeys@code 
[trace-pgfkeys]----> Storing: /handlers/.code/.@cmd 
[trace-pgfkeys]----+ Done storing.
[trace-pgfkeys]---: Handler code:
[trace-pgfkeys]---: \long macro:#1\pgfeov ->\pgfkeysdef {\pgfkeyscurrentpath }{#1}
[trace-pgfkeys]----+ Executing handler.
[trace-pgfkeys]----> Handler: /handlers/.code
[trace-pgfkeys]----: Tracing \pgfkeysdef .
[trace-pgfkeys]----: Code: (\pgfkeysalso {shape=rectangle})
[trace-pgfkeys]-----+ Defining key code.
[trace-pgfkeys]-----> New code: /test1
[trace-pgfkeys]-----: Tracing \pgfkeyslet .
[trace-pgfkeys]------+ Assigning key from \pgfkeys@temp 
[trace-pgfkeys]------> Assigning: /test1/.@cmd
[trace-pgfkeys]------+ Done assigning.
[trace-pgfkeys]-----+ Done defining.
[trace-pgfkeys]----+ Done defining.
[trace-pgfkeys]---+ Execution finished.
[trace-pgfkeys]--+ Last key processed.
[trace-pgfkeys]-+ Execution finished.
[trace-pgfkeys]+ Last key processed.

请注意,/.style有一个/.@cmd,它反过来设置/.code,它本身有一个/.@cmd,它最终直接设置/test1/.@cmd属性。希望有所帮助!

答案3

以下是我对这个答案的看法。基本上,设置 a 的.style效果就是设置.@cmd为代码\pgfkeysalso{<keys>}。我认为这是定义“是一种风格”,因为没有办法检查这种代码不是通过.code直接设置产生的,但是,如果它像鸭子一样嘎嘎叫......

我提供了三个用户命令:

  • \pgfkeysifstyle{<full key>}{<true>}{<false>},其依据是键是否是上述意义上的样式。

  • \lastpgfkeysstyle,如果键是样式,则存储样式的内容。如果不是,则不要使用它。

  • \pgfkeysifstyleempty(相同的参数),根据样式是否为空来执行操作。如果不是样式,我会选择“true”,否则您可能想要使用\lastpgfkeysstyle

代码:

\documentclass{article}
\usepackage{filecontents}

\begin{filecontents*}{pgfkeys-ifstyle.sty}
 \RequirePackage{etoolbox}% for \ifstrequal, \ifdefempty

 \def\lastpgfkeysstyle{}
 % Checks if #1 = \pgfkeysalso{...} and, if so, puts the argument
 % in \lastpgfkeysstyle
 \def\@ifgetpgfkeysalso#1\pgfkeysalso#2#3\@nil{%
  \ifstrequal{#1.#3}{.\pgfkeysalso{}}% \pgfkeysalso{#2} is the only thing there
   {\def\lastpgfkeysstyle{#2}\@firstoftwo}
   {\@secondoftwo}%
 }

 % So I don't need to write this again
 \def\expandaftertwice{\expandafter\expandafter\expandafter}

 \def\pgfkeysifstyle#1{%
  % "Expand" the key's .@cmd until its code shows
  % Even if there is no .@cmd, we get #1\pgfeov, which will not screw us up.
  \toks0=\expandaftertwice{\csname pgfk@#1/.@cmd\endcsname##1\pgfeov}%
  \expandafter\@ifgetpgfkeysalso\the\toks0 \pgfkeysalso{}\@nil% That space is very important!
 }
 \def\pgfkeysifstyleempty#1{%
  \pgfkeysifstyle{#1}
   {\ifdefempty{\lastpgfkeysstyle}}
   {% We count a non-style as empty, since otherwise you might use \lastpgfkeysstyle
    \PackageWarning{pgfkeys-ifstyle}
     {In \noexpand\pgfkeysifstyleempty\MessageBreak
      The key #1 is not defined as a style!\MessageBreak}
    \@firstoftwo
   }%
 }
\end{filecontents*}

\usepackage{pgfkeys-ifstyle}
\usepackage{pgfkeys,pgffor}

\begin{document}
 \pgfkeys{
  /key 1/.style = {x, y, z},
  /key 2/.code = {Not a style #1},
  /key 3/.initial = {Not even a code},
  /key 4/.style = {},% Empty style
  /key 5/.code = {\pgfkeysalso{a, b, c} and other stuff},
  /key 6/.code = {\pgfkeysalso{a, b, c}},
 }

 \newcommand*\teststyle[1]{%
  \par\medskip\noindent
  \pgfkeysifstyle{#1}{#1 has a style: \lastpgfkeysstyle}{#1 is not a style}\\
  \pgfkeysifstyleempty{#1}{#1 has an empty style}{#1 does not have an empty style}
 }

 \foreach \n in {1,...,6} {\teststyle{/key \n}}
\end{document}

相关内容