何时使用 \PassOptionsTo* 以及何时使用 \LoadClass/\RequirePackage?

何时使用 \PassOptionsTo* 以及何时使用 \LoadClass/\RequirePackage?

我为自己的目的创建了一些包/类,并学习了(例如,那里)分别与、或\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 和或扩展包的键定义来完成。\ekvdefNoValexpkv\ekvdefinekeysexpkv-def

相关内容