这是我上一个问题的后续为什么在这些情况下 pgfkeys .initial 不起作用?。在那个问题中,我使用创建了一个带有键值接口的宏pgfkeys
,它运行完美。现在,我正在使用一个包实现相同的选项,这样当使用适当的选项加载包时,上一个问题中的宏的功能就会被复制。
使用宏,如果我在不提供任何选项的情况下调用该宏,我可以调用密钥的.initial
处理程序,获取密钥的值\pgfkeysvalueof{...}
并执行需要执行的操作,而不会出现问题。换句话说,如果没有提供任何选项,宏“知道”该做什么。我的问题是,我似乎无法使用下面的包示例复制该功能。
如果我加载包时不使用任何键,\usepackage{selectunits}
我希望包的行为就像[sunits=alternate]
在加载时已经给出一样,但我无法让它工作。所有其他可能的键值组合似乎都运行良好。我几乎可以通过在块sunits=alternate,
内添加\pgfkeys{...}
(目前在 MWE 中注释掉)来让一切完美运行,但这会导致始终使用该键和值,而不管加载包时提供的任何其他键和值。
因此,最终的问题是:有没有一种方法可以让\usepackage{selectunits}
,不使用任何键,就像sunits=alternate
在加载时已经给出一样,最好不调用多个键值组合?它也应该适用于这两个\pgfkeys{...}
块中的任何一个。
以下是 MWE:
% !TEX TS-program = lualatexmk
% !TEX encoding = UTF-8 Unicode
\documentclass{article}
\begin{filecontents}[overwrite,noheader]{selectunits.sty}
% !TEX encoding = UTF-8 Unicode
\ProvidesPackage{selectunits}[2021-01-22 v1.0 Example package]
\NeedsTeXFormat{LaTeX2e}
\RequirePackage{pgfopts}
\newcommand*{\perpusebaseunits}{\typeout{You'll get base units.}}
\newcommand*{\perpusederivedunits}{\typeout{You'll get derived units.}}
\newcommand*{\perpusealternateunits}{\typeout{You'll get alternate units.}}
% Either one of the two following blocks should work.
% This block does not use .is choice
\pgfkeys{%
/selectunits/.is family, /selectunits,%
sunits/.initial=alternate,%
sunits/.default=derived,%
sunits/.code={%
\ifcsname perpuse#1units\endcsname
\csname perpuse#1units\endcsname
\else
\GenericError{}
{\MessageBreak settheunits: Illegal key value}
{Key 'sunits' can only base, derived, or alternate.}
{Read the documentation for help.}
\fi
},%
%sunits=alternate, % almost works, key used even in the presence of other keys
}%
% This block uses .is choice
%\pgfkeys{%
% /selectunits/.is family, /selectunits,%
% sunits/.is choice,%
% sunits/.initial=alternate,%
% sunits/.default=derived,%
% sunits/base/.code={\perpusebaseunits},%
% sunits/derived/.code={\perpusederivedunits},%
% sunits/alternate/.code={\perpusealternateunits},%
% %sunits=alternate, % almost works, key used even in the presence of other keys
%}%
\ProcessPgfPackageOptions{/selectunits}
\NewDocumentCommand{\selectunitssetup}{ o }{%
\IfValueTF {#1}
{ \pgfqkeys{/selectunits}{#1} }
{ \csname perpuse\pgfkeysvalueof{/selectunits/sunits}units\endcsname }
}%
\end{filecontents}
\usepackage{selectunits} % should set alternate units, doesn't work
%\usepackage[sunits]{selectunits} % should set derived units, works
%\usepackage[sunits=base]{selectunits} % should set base units, works
%\usepackage[sunits=derived]{selectunits} % should set derived units, works
%\usepackage[sunits=alternate]{selectunits} % should set alternate units, works
%\usepackage[sunits]{selectunits} % should set derived units, works
%\usepackage{selectunits} % should set alternate units, doesn't works
%\usepackage[sunits=blubb]{selectunits} % should throw an error and stop, works
\begin{document}
Hello.
\selectunitssetup\par % should set alternate units, works
\selectunitssetup[sunits]\par % should set derived units, works
\selectunitssetup[sunits=base]\par % should set base units, works
\selectunitssetup[sunits=derived]\par % should set derived units, works
\selectunitssetup[sunits=alternate]\par % should set alternate units, works
\selectunitssetup[sunits]\par % should set derived units, works
\selectunitssetup\par % should set alternate units, works
%\selectunitssetup[sunits=blubb]\par % should throw an error and stop, works
\end{document}
答案1
如果这是我的包裹,我会发出\selectunitssetup
一个命令:
采取强制性论点;
如果此参数为空,则不会修改设置。
但是,您要求的不是这个,下面的代码实现了您的要求。还请注意使用:
/some key/.initial=...
其次是/some key/.code={<some code>}
总体来说没什么意义。事实上,(1) 的主要目的之一是允许/some key
使用存储一个值\pgfkeys{/some key=<value>}
,而 (2) 将使\pgfkeys{/some key=<value>}
执行<some code>
时#1
用 代替<value>
。
\begin{filecontents}[noheader]{selectunits.sty}
\ProvidesPackage{selectunits}[2021-01-22 v1.0 Example package]
\NeedsTeXFormat{LaTeX2e}
\RequirePackage{expl3} % for \NewDocumentCommand when LaTeX format < 2020-10-01
\RequirePackage{pgfopts}
\newcommand*{\perpusebaseunits}{\typeout{You'll get base units.}}
\newcommand*{\perpusederivedunits}{\typeout{You'll get derived units.}}
\newcommand*{\perpusealternateunits}{\typeout{You'll get alternate units.}}
\pgfkeys{
/selectunits/options/.cd,
%
initial@setup/.style={
/selectunits/options/buffered@sunits/.initial=alternate,
},
initial@setup,
%
sunits/.is choice,
sunits/.default=derived,
sunits/alternate/.style={/selectunits/options/buffered@sunits=alternate},
sunits/base/.style={/selectunits/options/buffered@sunits=base},
sunits/derived/.style={/selectunits/options/buffered@sunits=derived},
}
\ProcessPgfPackageOptions{/selectunits/options}
\NewDocumentCommand{\selectunitssetup}{ o }{%
\pgfkeys{/selectunits/options/initial@setup}%
\IfValueT{#1}{\pgfqkeys{/selectunits/options}{#1}}%
%
\selectunits@do@setup
}
\NewDocumentCommand{\selectunits@do@setup}{}{%
\csname
perpuse\pgfkeysvalueof{/selectunits/options/buffered@sunits}units%
\endcsname
}
\selectunits@do@setup
\endinput
\end{filecontents}
\documentclass{article}
\usepackage{selectunits}
%\usepackage{selectunits} % sets alternate units
%\usepackage[sunits]{selectunits} % sets derived units
%\usepackage[sunits=base]{selectunits} % sets base units
%\usepackage[sunits=derived]{selectunits} % sets derived units
%\usepackage[sunits=alternate]{selectunits} % sets alternate units
%\usepackage[sunits=blubb]{selectunits} % throws an error and stops
\begin{document}
\selectunitssetup % sets alternate units
\selectunitssetup[sunits] % sets derived units
\selectunitssetup[sunits=base] % sets base units
\selectunitssetup[sunits=derived] % sets derived units
\selectunitssetup[sunits=alternate] % sets alternate units
\selectunitssetup[sunits] % sets derived units
\selectunitssetup % sets alternate units
%\selectunitssetup[sunits=blubb] % throws an error and stops
\end{document}