使用 key 选项对使用字符串案例的包进行封装

使用 key 选项对使用字符串案例的包进行封装

[Other]以下包和源文件有什么问题?我在 的第 14 行(之后)收到错误mypackage.sty,并导致“缺少 \begin{document}”错误。

来源:

\documentclass{article}

\usepackage[what=this]{mypackage}

\usepackage{blindtext}

\begin{document}
\blindtext
\end{document}

包装mypackage.sty

\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mypackage}

\RequirePackage{kvoptions}
\RequirePackage{xstring}

\DeclareStringOption{what}
\ProcessKeyvalOptions*

\IfStrEqCase{what}{%
    {this}{\dothis}%
    {that}{\dothat}%
    }%
    [Other]%

\newcommand{\dothis}{The magic word is ``this''}
\newcommand{\dothat}{The magic word is ``that''}

\endinput

我强烈怀疑其中存在一些我找不到的简单语法错误。或者存在一些我不明白的基本内容kvoptionsxstring

我认为我的语法\IfStrEqCase没有问题,因为文档texdoc xstring给出了以下形式:

\IfStrEqCase⟨[*]⟩{⟨string⟩}{% 
    {⟨string1⟩}{⟨code1⟩}% 
    {⟨string2 ⟩}{⟨code2 ⟩}%
    etc...
    {⟨stringN ⟩}{⟨codeN ⟩}}[⟨other cases code⟩]

我的实际目的

我的实际目的kvoptionsxstring针对一个复杂的文档,其中:

  • 在作为序言的一部分读入的一个自定义包中,我为文档文本/数学字体的几种可能选择之一设置了一个键值。 并在同一个包中,根据该值,给出使用该文本/数学字体组合的必要命令。 (例如,使用cm作为字体选择,这将是默认的,必要的命令将只是\usepackage{amsfonts};使用lucida作为字体选择,则必要的命令将是\usepackage[lucidasmallscale]{lucidabr}\linespread{1.04}。)
  • 作为序言的一部分读入的第二个自定义包提供了大量的数学命令定义,其中一些取决于所使用的数学字体。因此,第二个包将把该键值作为选项,在表达式中使用它来根据\IfStrEqCase需要更改命令。例如,对于选择cm,我指定\newcommand{\nsubset}{\not\subset}\newcommand{\tendsto}{\rightarrow};而对于lucida选择,由于\nsubset已经定义,我不需要定义它,但我使用来tikz创建作为定义\tendsto,一个箭头,以便与图表中出现的箭头更好地协调tikz-cd

这个看似复杂的设置的要点如下:

  1. 允许通过编辑第一个包中的单行来选择字体,而不必在源文件中注释和取消注释大块文本。
  2. 允许我的第二个包及其所有数学定义不仅适用于此特定文档,还适用于可能需要我的专门数学定义的任何文档。

答案1

导致错误的第一个问题是您正在执行\IfStrEqCase包代码中的语句以生成排版输出,但是您之前无法执行此操作。我将测试包装在可以在文档内部使用的\begin{document}定义中。\mytest

另一个问题是,您正在whatthis或进行比较that,这永远不会匹配,并将转到分支。当您使用other设置键值选项时,传递给选项的值将存储在 中。可以更改,但默认值是包名称,因此和在此处,因此您不应该测试 ,而应该测试。更改它后,代码将打印。<name>kvoptions<name>\<prefix>@<name><prefix>mypackage<name>whatwhat\mypackage@whatThe magic word is “this”

\documentclass{article}
\usepackage{filecontents}
\begin{filecontents}{mypackage.sty}
\NeedsTeXFormat{LaTeX2e}
\ProvidesPackage{mypackage}
\RequirePackage{kvoptions}
\RequirePackage{xstring}
\DeclareStringOption{what}
\ProcessKeyvalOptions*
\def\mytest{%
  \IfStrEqCase{\mypackage@what}{%
      {this}{\dothis}%
      {that}{\dothat}%
      }%
      [Other]%
  }
\newcommand{\dothis}{The magic word is ``this''}
\newcommand{\dothat}{The magic word is ``that''}
\endinput
\end{filecontents}
\usepackage[what=this]{mypackage}
\usepackage{blindtext}
\begin{document}
\mytest

\blindtext
\end{document}

对于这种情况,您可以删除xstring并测试是否存在宏\do<what>。如果存在,则使用它,否则采取适当的措施。此定义\mytest将产生与以下定义相同的输出xstring

\def\mytest{%
  \@ifundefined{do\mypackage@what}%
    {Other}%
    {\@nameuse{do\mypackage@what}}%
  }

相关内容