如何编写 pgfkeys 处理程序以便将其用作样式?

如何编写 pgfkeys 处理程序以便将其用作样式?

我想通过强制和推荐密钥的功能来丰富 pgfkeys。如果没有提供强制密钥,则会显示错误。如果没有提供推荐密钥,则会显示警告。

我的想法是有两个处理程序可以在处理完选项后使用:

\newcommand{\mycommand}[1][]{%
    \pgfqkeys{/path}{#1,
        key a/recommended,
        key b/mandatory,
    }%
    % ...
}

就我所知就是这样:

\documentclass{article}
\usepackage{pgfkeys}
\newcommand{\PackageName}{pgfkeys extended}

\makeatletter
\pgfqkeys{/handlers}{%
    % ------- if given -------
    if given/.code 2 args={%
        \typeout{! path: \pgfkeyscurrentpath}%
        \pgfkeys{\pgfkeyscurrentpath/.get=\tmp@value}%
        \expandafter \ifx \expandafter \pgfkeysnovalue \tmp@value
            #2%
        \else
            #1%
        \fi
    },
    % ------- recommended -------
    recommended/.style={%
        if given=
            \relax
            \PackageWarning{\PackageName}{Recommended key `\pgfkeyscurrentkeyRAW' not given.}%
    },
}
\makeatother

\pgfqkeys{/test}{%
    hello/.initial,
    hello/.value required,
}


\begin{document}
content\ldots

%\pgfqkeys{/test}{hello=true}
%\pgfkeysvalueof{/test/hello}
\pgfkeys{/test/hello/if given=10}
\pgfkeys{/test/hello/recommended}

\end{document}

if given处理程序本身运行良好。但是当它被recommended处理程序调用时\pgfkeyscurrentpath,它是空的。

我可以将recommended处理程序更改为自定义代码而不是样式,\pgfkeyscurrentpath在调用之前将保存在命令中if given,然后在if given检查此命令是否已定义。如果是,我使用它,如果不是,我使用\pgfkeyscurrentpath。最后,我一定不要忘记重置该命令。但这似乎过于复杂。难道没有更简单的解决方案吗?

如果我不能在这里以某种风格使用我自己的处理程序,那么我是否需要注意 TikZ 的某些键也不能以某种风格使用?

答案1

首先,tikz 的标准是让所有处理程序名称都以句点开头。如果不这样做,您可能会混淆普通键和处理程序,当然您可以自由地做任何您想做的事情。

如果您调用类似这样的处理程序/path/to/key/.handler,则存储在中的值\pgfkeyscurrentpath/path/to/key。如果您只是说,.handler=something那么您提供的路径是空的,\pgfkeyscurrentpath将被设置为空。一个解决方案是说\pgfkeyscurrentpath/.handler,所以你可以说:

\makeatletter
\pgfqkeys{/handlers}{%
    .if given/.code 2 args={%
        \typeout{! path: \pgfkeyscurrentpath}%
        \pgfkeys{\pgfkeyscurrentpath/.get=\tmp@value}%
        \expandafter \ifx \expandafter \pgfkeysnovalue \tmp@value
            #2%
        \else
            #1%
        \fi
    },
    .recommended/.style={%
        \pgfkeyscurrentpath/.if given= %%%% This is the only line that changed
            \relax
            \PackageWarning{\PackageName}{Recommended key `\pgfkeyscurrentkeyRAW' not given.}%
    },
}
\makeatother

但是,如果我是你,我可能会定义一个命令\ifkeyisgiven或类似的东西,然后在中调用它.recommended。我认为这更清楚:

\makeatletter
\def\ifkeyisgiven#1#2{
    \typeout{! path: \pgfkeyscurrentpath}%
    \pgfkeys{\pgfkeyscurrentpath/.get=\tmp@value}%
    \expandafter \ifx \expandafter \pgfkeysnovalue \tmp@value
        #2%
    \else
        #1%
    \fi
}

\pgfqkeys{/handlers}{%
    recommended/.code={%
       \ifkeyisgiven{}{
            \Packagewarning{\PackageName}{Recommended key `\pgfkeyscurrentkeyRAW' not given.}%
        }
    },
}
\makeatother

相关内容