我有一个简短的演示,用于kvoptions
在加载时提供包选项。我想尝试使用包设置命令,发现从命令中删除选项\usepackage{kvtest}
并将其放入\kvtestsetup{...}
命令中会导致它们被忽略。我觉得解决方案可能非常简单,但我没有看到它。
这是示例包文件(是的,我知道,\left...\right
但这只是一个演示):
\ProvidesPackage{kvtest}
\RequirePackage[math-style=ISO]{unicode-math}
\setmathfont{Latin Modern Math}
\RequirePackage{kvoptions}
\SetupKeyvalOptions{%
family=kvtest,%
prefix=kvtest@%
}%
\DeclareBoolOption[false]{boldvectors}
\DeclareBoolOption[false]{doublemagbars}
\ProcessKeyvalOptions*
%\newcommand*{\kvtestsetup}{%
% \kvsetkeys{kvtest}%
%}%
\typeout{}
\ifkvtest@boldvectors
\typeout{kvtest: You'll get bold vectors.}
\renewcommand{\vec}{\symbfit}
\else
\typeout{kvtest: You'll get arrowed vectors.}
\fi
\ifkvtest@doublemagbars
\typeout{kvtest: You'll get double magnitude bars.}
\newcommand{\magvec}[1]{\left\lVert#1\right\rVert}
\else
\typeout{kvtest: You'll get single magnitude bars.}
\newcommand{\magvec}[1]{\left\lvert#1\right\rvert}
\fi
\typeout{}
以下是示例主文档:
% !TEX TS-program = lualatexmk
% !TEX encoding = UTF-8 Unicode
\documentclass{article}
\usepackage[doublemagbars=true]{kvtest}
%\kvtestsetup{doublemagbars=true}
\begin{document}
Hello, world!
The displacement is \( \vec{r} \). The magnitude of the displacement is \( \magvec{\vec{r}} \).
\end{document}
答案1
尽管我更愿意让doublemagbars
键重新定义内部宏而不是设置\ifkvtest@doublemagbars
1,但似乎无法\define@keys
直接与处理的键一起使用kvoptions
(如果有人知道这种可能性,请告诉我),因此以下定义\vec
和\magvec
的方式是它们评估条件并采取相应行动。这样,您可以\kvtestsetup
在任何喜欢的地方使用(但正确的定义\vec
仅在之后可用\begin{document}
,以便它尊重可能已重新定义的其他包\vec
)。
代碼kvtest.sty
:
\ProvidesPackage{kvtest}
\RequirePackage[math-style=ISO]{unicode-math}
\setmathfont{Latin Modern Math}
\RequirePackage{kvoptions}
\SetupKeyvalOptions{%
family=kvtest,%
prefix=kvtest@%
}%
\DeclareBoolOption[false]{doublemagbars}
\DeclareBoolOption[false]{boldvectors}
\ProcessKeyvalOptions*
\newcommand*{\kvtestsetup}{%
\kvsetkeys{kvtest}%
}%
\AtBeginDocument
{%
\let\kvtest@origvec\vec
\renewcommand*\vec
{%
\ifkvtest@boldvectors
\expandafter\symbfit
\else
\expandafter\kvtest@origvec
\fi
}%
}
\newcommand\kvtest@lvert{\ifkvtest@doublemagbars\lVert\else\lvert\fi}
\newcommand\kvtest@rvert{\ifkvtest@doublemagbars\rVert\else\rvert\fi}
\newcommand{\magvec}[1]{\left\kvtest@lvert#1\right\kvtest@rvert}
示例文档的代码:
\documentclass{article}
\usepackage[doublemagbars=true]{kvtest}
%\kvtestsetup{doublemagbars=true}
\begin{document}
Hello, world!
The displacement is \( \vec{r} \). The magnitude of the displacement is \( \magvec{\vec{r}} \).
\kvtestsetup{doublemagbars=false, boldvectors=true}
The displacement is \( \vec{r} \). The magnitude of the displacement is \( \magvec{\vec{r}} \).
\end{document}
结果:
1对于包选项的其他 key=value 解决方案,例如pgfopts
、l3keys2e
或exkpv-opt
,我会定义一个选择键,该选择键使用\let\kvtest@lvert\lVert
和\let\kvtest@rvert\rVert
代替doublemagbars=true
和\let\kvtest@lvert\lvert
和\let\kvtest@rvert\rvert
代替doublemagbars=false
(以及 的类似内容\vec
)。
下面是我如何使用expkv-opt
和完成此操作的示例expkv-def
,输出和示例文档代码与上面的相同。
法典kvtest.sty
\ProvidesPackage{kvtest}
\RequirePackage[math-style=ISO]{unicode-math}
\setmathfont{Latin Modern Math}
\RequirePackage{expkv-def, expkv-opt}
% define the keys
\ekvdefinekeys{kvtest}
{
% doublemagbars is a choice accepting true or false, which will execute the
% associated code
choice doublemagbars =
{
true = \let\kvtest@lvert\lVert\let\kvtest@rvert\rVert
,false = \let\kvtest@lvert\lvert\let\kvtest@rvert\rvert
}
% if no value is specified, use =true
,default doublemagbars = true
% execute the code associated with false now
,initial doublemagbars = false
% same for boldvectors
,choice boldvectors =
{
true = \def\kvtest@setupvec{\let\vec\symbfit}
,false = \let\kvtest@setupvec\@empty
}
,default boldvectors = true
,initial boldvectors = false
}
\ekvoProcessGlobalOptions{kvtest} % options given to \documentclass
\ekvoProcessLocalOptions{kvtest} % options given to \usepackage
% at \begin{document}, save the current definition of \vec, run setupvec,
% which will be defined to use \symbfit if boldvectors=true was used, and
% redefine the boldvectors choices to directly do the redefinition from
% now on
\AtBeginDocument
{%
\let\kvtest@origvec\vec
\kvtest@setupvec
\ekvdefinekeys{kvtest}
{
choice boldvectors =
{
true = \let\vec\symbfit
,false = \let\vec\kvtest@origvec
}
}%
}
% define a shorthand macro to set keys for kvtest
\ekvsetdef\kvtestsetup{kvtest}
\newcommand{\magvec}[1]{\left\kvtest@lvert#1\right\kvtest@rvert}
答案2
如果你打电话
\usepackage[doublemagbars=true]{kvtest}
然后设置布尔值,代码
\ifkvtest@doublemagbars
\typeout{kvtest: You'll get double magnitude bars.}
\newcommand{\magvec}[1]{\left\lVert#1\right\rVert}
\else
\typeout{kvtest: You'll get single magnitude bars.}
\newcommand{\magvec}[1]{\left\lvert#1\right\rvert}
\fi
在读入包时执行。
如果您这样做\kvtestsetup{doublemagbars=true}
,则包代码已被读取,您只是设置布尔值,但定义\magvec
保持与之前一样。
您可能希望根据中的布尔值来包装代码\AtBeginDocument
,因此当布尔值已知时执行操作,假设\kvtestsetup
仅在前言中使用。
答案3
经过大量实验,我终于找到了一种使设置命令工作的方法。我使用了\DeclareVoidOption{...}
,它分配了在提供选项时执行的代码。现在的问题是必须提供所涉及的两个选项中的至少一个。这个问题(kvoptions 可以使用动态默认值吗?) 尝试解决这种情况,但我还没有尝试过该解决方案。
这是新的 MWE 包文件:
\ProvidesPackage{kvtest}
\RequirePackage[math-style=ISO]{unicode-math}
\setmathfont{Latin Modern Math}
\RequirePackage{kvoptions}
\SetupKeyvalOptions{%
family=kvtest,%
prefix=kvtest@%
}%
\DeclareVoidOption{doublemagbars}{\let\mytestlvert\lVert\let\mytestrvert\rVert}
\DeclareVoidOption{singlemagbars}{\let\mytestlvert\lvert\let\mytestrvert\rvert}
\DeclareStringOption[stranger]{myname}[Joe]
\ProcessKeyvalOptions*
\newcommand*{\kvtestsetup}{%
\kvsetkeys{kvtest}%
}%
\newcommand*{\SayHello}{Hello, \kvtest@myname.}
\newcommand*{\magvec}[1]{\left\mytestlvert#1\right\mytestrvert}%
这是新的 MWE 文档文件:
% !TEX TS-program = lualatexmk
% !TEX encoding = UTF-8 Unicode
\documentclass{article}
\usepackage[singlemagbars]{kvtest}
\begin{document}
The displacement is \( \Delta\vec{r} \). The magnitude of the displacement is \( \magvec{\Delta\vec{r}} \).
\SayHello
\kvtestsetup{myname}
\SayHello
\kvtestsetup{myname=Jack}
\SayHello
\kvtestsetup{myname=Jill}
\SayHello
\kvtestsetup{doublemagbars}
The displacement is \( \Delta\vec{r} \). The magnitude of the displacement is \( \magvec{\Delta\vec{r}} \).
\kvtestsetup{singlemagbars}
The displacement is \( \Delta\vec{r} \). The magnitude of the displacement is \( \magvec{\Delta\vec{r}} \).
\end{document}