包安装命令中的 kvoptions 不起作用

包安装命令中的 kvoptions 不起作用

我有一个简短的演示,用于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@doublemagbars1,但似乎无法\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 解决方案,例如pgfoptsl3keys2eexkpv-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}

相关内容