我为自己的目的创建了一些包/类,并学习了(例如,那里)分别与、或\PassOptionsTo*[opt]
相似/等同。在几个\LoadClass[opt]
\RequirePackage[opt]
\usepackage[opt]
期权声明机制可用,我想知道何时使用哪种方式传递选项?例如,是否有要避免的过时组合或具有不良副作用的特定组合?
例如,我有时会使用
\DeclareStringOption{optA}
...
\DeclareOption{optB}{\PassOptionsToPackage{somethingRelToOptB}{pkg1}}
然后,例如,
\PassOptionsToPackage{key=\fam@optA}{pkg1}
或者
\RequirePackage[keyA=\fam@optA]{pkg1}
我知道这可能是一个很难的问题,尽管如此,我希望能够就某些变化是否比其他变化更好达成一致意见。
答案1
\PassOptionsToPackage{<options>}{<package>}\RequirePackage{<package>}
两者之间的一个很大的区别\RequirePackage[<options>]{<package>}
是,如果包已经加载了不同的选项(假设包不使用新机制来解决选项冲突),后者将抛出错误,而前者将默默地不做任何事情(也假设它不使用新的选项系统)。因此,行为上可能存在差异(假设您的类只有在包已经加载了这些选项时才能正常工作)。
要考虑的另一件事是,您是否要在任何情况下设置另一个包的关键选项,并且只公开一个选项来更改值,在这种情况下,在\RequirePackage[key=<foo>]{<package>}
您自己的选项声明之后是一个可行的解决方案,而如果您只想在使用您的选项时指定相关选项,则\PassOptionsToPackage{<option>}{<package>}
很可能会导致比后来的更简单的代码\if<opt-used> \RequirePackage[<related-opt>]{<package>}\else\RequirePackage{<package>}\fi
。
除此之外没有什么大的区别,人们可能会预期性能略有不同,但这应该可以忽略不计。
另外,以下是有关该新系统解决选项冲突的一些提示。
目前有两种解决方案(据我所知)可以解决多次加载包(选项冲突)的问题。这两种方法都通过解析每个后续调用的键来工作。这样您就可以对它们采取行动,但在加载时必须知道的键无法通过这种方式解析(在这种情况下应该设置为抛出错误)。
第一个解决方案是 LaTeX 内核。相关功能由 2022-06-01 更新添加。该功能的文档分布在几个文档中,相关信息可以在ltnews35.pdf
,以及“ltkeys.dtx” 部分source2e.pdf
。相关的宏是\DeclareKeys
(定义新的键或更改现有的键)、\SetKeys
(直接将键设置为值,可用于初始值)、\ProcessKeyOptions
(解析包/类选项,还自动设置以处理未来的选项)。
第二种解决方案是expkv-opt
将(部分expkv-bundle
,免责声明:我是作者) 在 2023-01-23 版本中添加了对此的支持。相关宏是\ekvoProcessOptions
(解析全局选项、直接传递给包/类的选项以及加载包/类的剩余尝试的所有选项) (仅解析加载包/类的剩余尝试的选项),可以使用基础包的\ekvoProcessFutureOptions
基本接口\ekvdef
和或扩展包的键定义来完成。\ekvdefNoVal
expkv
\ekvdefinekeys
expkv-def